Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions grace/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,16 @@
from alembic.util.exc import CommandError

from .application import Application
from .exceptions import ConfigError


def generate_migration(app: Application, message: str):
if not app.has_database:
raise ConfigError(
"This project has no database configured. "
"Run 'grace generate database' to add one."
)

try:
alembic_cfg = Config("alembic.ini")
alembic_cfg.config_ini_section = app.environment
Expand Down
13 changes: 10 additions & 3 deletions grace/generators/migration_generator.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from logging import info
from logging import info, warning

from click.core import Argument

Expand All @@ -22,11 +22,18 @@ def generate(self, message: str):
grace generate migration "Add Greeting model"
```
"""
info(f"Generating migration '{message}'")

if not self.app:
raise ValueError("app is not initialized")

if not self.app.has_database:
warning(
"This project has no database configured. "
"Run 'grace generate database' to add one."
)
return

info(f"Generating migration '{message}'")

generate_migration(self.app, message)

def validate(self, message: str, **_kwargs) -> bool:
Expand Down
15 changes: 11 additions & 4 deletions grace/generators/model_generator.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from logging import info
from logging import info, warning
from re import match

from click.core import Argument
Expand Down Expand Up @@ -33,6 +33,16 @@ def generate(self, name: str, params: tuple[str]):
grace generate model Greeting message:String lang:String
```
"""
if not self.app:
raise ValueError("app is not initialized")

if not self.app.has_database:
warning(
"This project has no database configured. "
"Run 'grace generate database' to add one."
)
return

info(f"Generating model '{name}'")

columns, types = self.extract_columns(params)
Expand All @@ -49,9 +59,6 @@ def generate(self, name: str, params: tuple[str]):
output_dir="bot/models",
)

if not self.app:
raise ValueError("app is not initialized")

generate_migration(self.app, f"Create {name}")

def validate(self, name: str, **_kwargs) -> bool:
Expand Down
43 changes: 43 additions & 0 deletions tests/generators/test_migration_generator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from unittest.mock import MagicMock

import pytest

from grace.generators.migration_generator import MigrationGenerator


@pytest.fixture
def generator():
generator = MigrationGenerator()
generator.app = MagicMock(has_database=True)
return generator


def test_generate_without_app__expect_value_error(generator):
generator.app = None

with pytest.raises(ValueError):
generator.generate("Add Greeting model")


def test_generate_without_database__expect_warning_and_no_migration(
mocker, generator, caplog
):
generator.app.has_database = False
mock_generate_migration = mocker.patch(
"grace.generators.migration_generator.generate_migration"
)

generator.generate("Add Greeting model")

mock_generate_migration.assert_not_called()
assert "no database configured" in caplog.text.lower()


def test_generate_with_database__expect_migration_generated(mocker, generator):
mock_generate_migration = mocker.patch(
"grace.generators.migration_generator.generate_migration"
)

generator.generate("Add Greeting model")

mock_generate_migration.assert_called_once_with(generator.app, "Add Greeting model")
46 changes: 46 additions & 0 deletions tests/generators/test_model_generator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from unittest.mock import MagicMock

import pytest

from grace.generator import Generator
from grace.generators.model_generator import ModelGenerator


@pytest.fixture
def generator():
generator = ModelGenerator()
generator.app = MagicMock(has_database=True)
return generator


def test_generate_without_app__expect_value_error(generator):
generator.app = None

with pytest.raises(ValueError):
generator.generate("Greeting", ("message:String",))


def test_generate_without_database__expect_no_file_and_warning(
mocker, generator, caplog
):
generator.app.has_database = False
mock_generate_file = mocker.patch.object(Generator, "generate_file")

generator.generate("Greeting", ("message:String",))

mock_generate_file.assert_not_called()
assert "no database configured" in caplog.text.lower()


def test_generate_with_database__expect_model_file_and_migration_generated(
mocker, generator
):
mock_generate_file = mocker.patch.object(Generator, "generate_file")
mock_generate_migration = mocker.patch(
"grace.generators.model_generator.generate_migration"
)

generator.generate("Greeting", ("message:String",))

mock_generate_file.assert_called_once()
mock_generate_migration.assert_called_once_with(generator.app, "Create Greeting")
23 changes: 23 additions & 0 deletions tests/test_database.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from unittest.mock import MagicMock

import pytest

from grace.database import generate_migration
from grace.exceptions import ConfigError


def test_generate_migration_without_database__expect_config_error():
app = MagicMock(has_database=False)

with pytest.raises(ConfigError):
generate_migration(app, "Add Greeting model")


def test_generate_migration_with_database__expect_revision_called(mocker):
app = MagicMock(has_database=True, environment="development")
mock_revision = mocker.patch("grace.database.revision")
mocker.patch("grace.database.Config")

generate_migration(app, "Add Greeting model")

mock_revision.assert_called_once()
Loading