diff --git a/README.md b/README.md index df35bda..5193716 100644 --- a/README.md +++ b/README.md @@ -53,12 +53,13 @@ To test all migrations we have a [`Migrator`](https://github.com/wemake-services It has three methods to work with: -- `.before()` which takes app and migration names to generate a state - before the actual migration happens. - It creates the `before state` by applying all migrations up to and including - the one passed as an argument. +- `.apply_initial_migration()` which takes app and migration names to generate + a state before the actual migration happens. It creates the `before state` + by applying all migrations up to and including the ones passed as an argument. + +- `.apply_tested_migration()` which takes app and migration names to perform the + actual migration -- `.after()` which takes app and migration names to perform the actual migration - `.reset()` to clean everything up after we are done with testing So, here's an example: @@ -71,11 +72,11 @@ migrator = Migrator(database='default') # Initial migration, currently our model has only a single string field: # Note: # We are testing migration `0002_someitem_is_clean`, so we are specifying -# the name of the previous migration (`0001_initial`) in the .before() -# method in order to prepare a state of the database before applying -# the migration we are going to test. +# the name of the previous migration (`0001_initial`) in the +# .apply_initial_migration() method in order to prepare a state of the database +# before applying the migration we are going to test. # -old_state = migrator.before(('main_app', '0001_initial')) +old_state = migrator.apply_initial_migration(('main_app', '0001_initial')) SomeItem = old_state.apps.get_model('main_app', 'SomeItem') # Let's create a model with just a single field specified: @@ -83,7 +84,9 @@ SomeItem.objects.create(string_field='a') assert len(SomeItem._meta.get_fields()) == 2 # id + string_field # Now this migration will add `is_clean` field to the model: -new_state = migrator.after(('main_app', '0002_someitem_is_clean')) +new_state = migrator.apply_tested_migration( + ('main_app', '0002_someitem_is_clean'), +) SomeItem = new_state.apps.get_model('main_app', 'SomeItem') # We can now test how our migration worked, new field is there: @@ -105,14 +108,16 @@ Nothing really changes except migration names that you pass and your logic: migrator = Migrator() # Currently our model has two field, but we need a rollback: -old_state = migrator.before(('main_app', '0002_someitem_is_clean')) +old_state = migrator.apply_initial_migration( + ('main_app', '0002_someitem_is_clean'), +) SomeItem = old_state.apps.get_model('main_app', 'SomeItem') # Create some data to illustrate your cases: # ... # Now this migration will drop `is_clean` field: -new_state = migrator.after(('main_app', '0001_initial')) +new_state = migrator.apply_tested_migration(('main_app', '0001_initial')) # Assert the results: # ... @@ -170,13 +175,13 @@ import pytest @pytest.mark.django_db def test_pytest_plugin_initial(migrator): """Ensures that the initial migration works.""" - old_state = migrator.before(('main_app', None)) + old_state = migrator.apply_initial_migration(('main_app', None)) with pytest.raises(LookupError): # Models does not yet exist: old_state.apps.get_model('main_app', 'SomeItem') - new_state = migrator.after(('main_app', '0001_initial')) + new_state = migrator.apply_tested_migration(('main_app', '0001_initial')) # After the initial migration is done, we can use the model state: SomeItem = new_state.apps.get_model('main_app', 'SomeItem') assert SomeItem.objects.filter(string_field='').count() == 0 diff --git a/django_test_migrations/contrib/pytest_plugin.py b/django_test_migrations/contrib/pytest_plugin.py index dc6b843..82fca2f 100644 --- a/django_test_migrations/contrib/pytest_plugin.py +++ b/django_test_migrations/contrib/pytest_plugin.py @@ -16,8 +16,10 @@ def migrator_factory(request, transactional_db, django_db_use_migrations): @pytest.mark.django_db def test_migration(migrator_factory): migrator = migrator_factory('custom_db_alias') - old_state = migrator.before(('main_app', None)) - new_state = migrator.after(('main_app', '0001_initial')) + old_state = migrator.apply_initial_migration(('main_app', None)) + new_state = migrator.apply_tested_migration( + ('main_app', '0001_initial'), + ) assert isinstance(old_state, ProjectState) assert isinstance(new_state, ProjectState) @@ -55,8 +57,10 @@ def migrator(migrator_factory): # noqa: WPS442 @pytest.mark.django_db def test_migration(migrator): - old_state = migrator.before(('main_app', None)) - new_state = migrator.after(('main_app', '0001_initial')) + old_state = migrator.apply_initial_migration(('main_app', None)) + new_state = migrator.apply_tested_migration( + ('main_app', '0001_initial'), + ) assert isinstance(old_state, ProjectState) assert isinstance(new_state, ProjectState) diff --git a/django_test_migrations/contrib/unittest_case.py b/django_test_migrations/contrib/unittest_case.py index bfb7b35..ac417da 100644 --- a/django_test_migrations/contrib/unittest_case.py +++ b/django_test_migrations/contrib/unittest_case.py @@ -31,9 +31,11 @@ def setUp(self) -> None: """ super().setUp() self._migrator = Migrator(self.database_name) - self.old_state = self._migrator.before(self.migrate_from) + self.old_state = self._migrator.apply_initial_migration( + self.migrate_from, + ) self.prepare() - self.new_state = self._migrator.after(self.migrate_to) + self.new_state = self._migrator.apply_tested_migration(self.migrate_to) def prepare(self) -> None: """ diff --git a/django_test_migrations/migrator.py b/django_test_migrations/migrator.py index 5b4a66a..794aef4 100644 --- a/django_test_migrations/migrator.py +++ b/django_test_migrations/migrator.py @@ -62,9 +62,9 @@ def __init__( self._database: str = database self._executor = MigrationExecutor(connections[self._database]) - def before(self, migrate_from: MigrationSpec) -> ProjectState: + def apply_initial_migration(self, targets: MigrationSpec) -> ProjectState: """Reverse back to the original migration.""" - migrate_from = normalize(migrate_from) + targets = normalize(targets) style = no_style() # start from clean database state @@ -77,17 +77,17 @@ def before(self, migrate_from: MigrationSpec) -> ProjectState: self._executor.loader.graph.leaf_nodes(), clean_start=True, ) - plan = truncate_plan(migrate_from, full_plan) + plan = truncate_plan(targets, full_plan) # apply all migrations from generated plan on clean database # (only forward, so any unexpected migration won't be applied) # to restore database state before tested migration - return self._migrate(migrate_from, plan=plan) + return self._migrate(targets, plan=plan) - def after(self, migrate_to: MigrationSpec) -> ProjectState: + def apply_tested_migration(self, targets: MigrationSpec) -> ProjectState: """Apply the next migration.""" self._executor.loader.build_graph() # reload - return self._migrate(normalize(migrate_to)) + return self._migrate(normalize(targets)) def reset(self) -> None: """Reset the state to the most recent one.""" diff --git a/tests/test_contrib/test_pytest_plugin/test_pytest_plugin_direct.py b/tests/test_contrib/test_pytest_plugin/test_pytest_plugin_direct.py index 8d6c68d..37c4ccc 100644 --- a/tests/test_contrib/test_pytest_plugin/test_pytest_plugin_direct.py +++ b/tests/test_contrib/test_pytest_plugin/test_pytest_plugin_direct.py @@ -12,13 +12,13 @@ @pytest.mark.django_db def test_pytest_plugin_initial(migrator): """Ensures that the initial migration works.""" - old_state = migrator.before(('main_app', None)) + old_state = migrator.apply_initial_migration(('main_app', None)) with pytest.raises(LookupError): # Models does not yet exist: old_state.apps.get_model('main_app', 'SomeItem') - new_state = migrator.after(('main_app', '0001_initial')) + new_state = migrator.apply_tested_migration(('main_app', '0001_initial')) # After the initial migration is done, we can use the model state: SomeItem = new_state.apps.get_model('main_app', 'SomeItem') assert SomeItem.objects.filter(string_field='').count() == 0 @@ -27,13 +27,15 @@ def test_pytest_plugin_initial(migrator): @pytest.mark.django_db def test_pytest_plugin0001(migrator): """Ensures that the first migration works.""" - old_state = migrator.before(('main_app', '0001_initial')) + old_state = migrator.apply_initial_migration(('main_app', '0001_initial')) SomeItem = old_state.apps.get_model('main_app', 'SomeItem') with pytest.raises(FieldError): SomeItem.objects.filter(is_clean=True) - new_state = migrator.after(('main_app', '0002_someitem_is_clean')) + new_state = migrator.apply_tested_migration( + ('main_app', '0002_someitem_is_clean'), + ) SomeItem = new_state.apps.get_model('main_app', 'SomeItem') assert SomeItem.objects.filter(is_clean=True).count() == 0 @@ -42,7 +44,9 @@ def test_pytest_plugin0001(migrator): @pytest.mark.django_db def test_pytest_plugin0002(migrator): """Ensures that the second migration works.""" - old_state = migrator.before(('main_app', '0002_someitem_is_clean')) + old_state = migrator.apply_initial_migration( + ('main_app', '0002_someitem_is_clean'), + ) SomeItem = old_state.apps.get_model('main_app', 'SomeItem') SomeItem.objects.create(string_field='a') SomeItem.objects.create(string_field='a b') @@ -50,7 +54,9 @@ def test_pytest_plugin0002(migrator): assert SomeItem.objects.count() == 2 assert SomeItem.objects.filter(is_clean=True).count() == 2 - new_state = migrator.after(('main_app', '0003_update_is_clean')) + new_state = migrator.apply_tested_migration( + ('main_app', '0003_update_is_clean'), + ) SomeItem = new_state.apps.get_model('main_app', 'SomeItem') assert SomeItem.objects.count() == 2 @@ -60,14 +66,18 @@ def test_pytest_plugin0002(migrator): @pytest.mark.django_db def test_pytest_plugin0003(migrator): """Ensures that the third migration works.""" - old_state = migrator.before(('main_app', '0003_update_is_clean')) + old_state = migrator.apply_initial_migration( + ('main_app', '0003_update_is_clean'), + ) SomeItem = old_state.apps.get_model('main_app', 'SomeItem') SomeItem.objects.create(string_field='a') # default is still there assert SomeItem.objects.count() == 1 assert SomeItem.objects.filter(is_clean=True).count() == 1 - new_state = migrator.after(('main_app', '0004_auto_20191119_2125')) + new_state = migrator.apply_tested_migration( + ('main_app', '0004_auto_20191119_2125'), + ) SomeItem = new_state.apps.get_model('main_app', 'SomeItem') with pytest.raises(IntegrityError): diff --git a/tests/test_contrib/test_pytest_plugin/test_pytest_plugin_reverse.py b/tests/test_contrib/test_pytest_plugin/test_pytest_plugin_reverse.py index ee4aef9..2940d26 100644 --- a/tests/test_contrib/test_pytest_plugin/test_pytest_plugin_reverse.py +++ b/tests/test_contrib/test_pytest_plugin/test_pytest_plugin_reverse.py @@ -12,12 +12,14 @@ @pytest.mark.django_db def test_pytest_plugin0001(migrator): """Ensures that the first migration works.""" - old_state = migrator.before(('main_app', '0002_someitem_is_clean')) + old_state = migrator.apply_initial_migration( + ('main_app', '0002_someitem_is_clean'), + ) SomeItem = old_state.apps.get_model('main_app', 'SomeItem') assert SomeItem.objects.filter(is_clean=True).count() == 0 - new_state = migrator.after(('main_app', '0001_initial')) + new_state = migrator.apply_tested_migration(('main_app', '0001_initial')) SomeItem = new_state.apps.get_model('main_app', 'SomeItem') with pytest.raises(FieldError): @@ -27,7 +29,9 @@ def test_pytest_plugin0001(migrator): @pytest.mark.django_db def test_pytest_plugin0002(migrator): """Ensures that the second migration works.""" - old_state = migrator.before(('main_app', '0003_update_is_clean')) + old_state = migrator.apply_initial_migration( + ('main_app', '0003_update_is_clean'), + ) SomeItem = old_state.apps.get_model('main_app', 'SomeItem') SomeItem.objects.create(string_field='a', is_clean=True) SomeItem.objects.create(string_field='a b', is_clean=False) @@ -35,7 +39,9 @@ def test_pytest_plugin0002(migrator): assert SomeItem.objects.count() == 2 assert SomeItem.objects.filter(is_clean=True).count() == 1 - new_state = migrator.after(('main_app', '0002_someitem_is_clean')) + new_state = migrator.apply_tested_migration( + ('main_app', '0002_someitem_is_clean'), + ) SomeItem = new_state.apps.get_model('main_app', 'SomeItem') assert SomeItem.objects.count() == 2 diff --git a/tests/test_migrator/test_migrator.py b/tests/test_migrator/test_migrator.py index bc3b047..455bffa 100644 --- a/tests/test_migrator/test_migrator.py +++ b/tests/test_migrator/test_migrator.py @@ -8,8 +8,8 @@ def test_migrator(transactional_db): """We only need this test for coverage.""" migrator = Migrator() - old_state = migrator.before(('main_app', None)) - new_state = migrator.after(('main_app', '0001_initial')) + old_state = migrator.apply_initial_migration(('main_app', None)) + new_state = migrator.apply_tested_migration(('main_app', '0001_initial')) assert isinstance(old_state, ProjectState) assert isinstance(new_state, ProjectState) @@ -20,8 +20,8 @@ def test_migrator(transactional_db): def test_migrator_list(transactional_db): """We only need this test for coverage.""" migrator = Migrator() - old_state = migrator.before([('main_app', None)]) - new_state = migrator.after([('main_app', '0001_initial')]) + old_state = migrator.apply_initial_migration([('main_app', None)]) + new_state = migrator.apply_tested_migration([('main_app', '0001_initial')]) assert isinstance(old_state, ProjectState) assert isinstance(new_state, ProjectState)