Moved migrations.test_operations.OperationTestBase to migrations.test_base.

Co-Authored-By: Daniel Tao <daniel.tao@gmail.com>
This commit is contained in:
Mads Jensen 2019-07-25 13:43:23 +02:00 committed by Mariusz Felisiak
parent 85458e94e3
commit b10d322c41
3 changed files with 151 additions and 153 deletions

View File

@ -5,12 +5,16 @@ from contextlib import contextmanager
from importlib import import_module from importlib import import_module
from django.apps import apps from django.apps import apps
from django.db import connections from django.db import connection, connections, migrations, models
from django.db.migrations.migration import Migration
from django.db.migrations.recorder import MigrationRecorder from django.db.migrations.recorder import MigrationRecorder
from django.db.migrations.state import ProjectState
from django.test import TransactionTestCase from django.test import TransactionTestCase
from django.test.utils import extend_sys_path from django.test.utils import extend_sys_path
from django.utils.module_loading import module_dir from django.utils.module_loading import module_dir
from .models import FoodManager, FoodQuerySet
class MigrationTestBase(TransactionTestCase): class MigrationTestBase(TransactionTestCase):
""" """
@ -130,3 +134,147 @@ class MigrationTestBase(TransactionTestCase):
new_module = os.path.basename(target_dir) + '.migrations' new_module = os.path.basename(target_dir) + '.migrations'
with self.settings(MIGRATION_MODULES={app_label: new_module}): with self.settings(MIGRATION_MODULES={app_label: new_module}):
yield target_migrations_dir yield target_migrations_dir
class OperationTestBase(MigrationTestBase):
"""Common functions to help test operations."""
@classmethod
def setUpClass(cls):
super().setUpClass()
cls._initial_table_names = frozenset(connection.introspection.table_names())
def tearDown(self):
self.cleanup_test_tables()
super().tearDown()
def cleanup_test_tables(self):
table_names = frozenset(connection.introspection.table_names()) - self._initial_table_names
with connection.schema_editor() as editor:
with connection.constraint_checks_disabled():
for table_name in table_names:
editor.execute(editor.sql_delete_table % {
'table': editor.quote_name(table_name),
})
def apply_operations(self, app_label, project_state, operations, atomic=True):
migration = Migration('name', app_label)
migration.operations = operations
with connection.schema_editor(atomic=atomic) as editor:
return migration.apply(project_state, editor)
def unapply_operations(self, app_label, project_state, operations, atomic=True):
migration = Migration('name', app_label)
migration.operations = operations
with connection.schema_editor(atomic=atomic) as editor:
return migration.unapply(project_state, editor)
def make_test_state(self, app_label, operation, **kwargs):
"""
Makes a test state using set_up_test_model and returns the
original state and the state after the migration is applied.
"""
project_state = self.set_up_test_model(app_label, **kwargs)
new_state = project_state.clone()
operation.state_forwards(app_label, new_state)
return project_state, new_state
def set_up_test_model(
self, app_label, second_model=False, third_model=False, index=False,
multicol_index=False, related_model=False, mti_model=False,
proxy_model=False, manager_model=False, unique_together=False,
options=False, db_table=None, index_together=False, constraints=None,
):
"""Creates a test model state and database table."""
# Make the "current" state.
model_options = {
'swappable': 'TEST_SWAP_MODEL',
'index_together': [['weight', 'pink']] if index_together else [],
'unique_together': [['pink', 'weight']] if unique_together else [],
}
if options:
model_options['permissions'] = [('can_groom', 'Can groom')]
if db_table:
model_options['db_table'] = db_table
operations = [migrations.CreateModel(
'Pony',
[
('id', models.AutoField(primary_key=True)),
('pink', models.IntegerField(default=3)),
('weight', models.FloatField()),
],
options=model_options,
)]
if index:
operations.append(migrations.AddIndex(
'Pony',
models.Index(fields=['pink'], name='pony_pink_idx'),
))
if multicol_index:
operations.append(migrations.AddIndex(
'Pony',
models.Index(fields=['pink', 'weight'], name='pony_test_idx'),
))
if constraints:
for constraint in constraints:
operations.append(migrations.AddConstraint('Pony', constraint))
if second_model:
operations.append(migrations.CreateModel(
'Stable',
[
('id', models.AutoField(primary_key=True)),
]
))
if third_model:
operations.append(migrations.CreateModel(
'Van',
[
('id', models.AutoField(primary_key=True)),
]
))
if related_model:
operations.append(migrations.CreateModel(
'Rider',
[
('id', models.AutoField(primary_key=True)),
('pony', models.ForeignKey('Pony', models.CASCADE)),
('friend', models.ForeignKey('self', models.CASCADE))
],
))
if mti_model:
operations.append(migrations.CreateModel(
'ShetlandPony',
fields=[
('pony_ptr', models.OneToOneField(
'Pony',
models.CASCADE,
auto_created=True,
parent_link=True,
primary_key=True,
to_field='id',
serialize=False,
)),
('cuteness', models.IntegerField(default=1)),
],
bases=['%s.Pony' % app_label],
))
if proxy_model:
operations.append(migrations.CreateModel(
'ProxyPony',
fields=[],
options={'proxy': True},
bases=['%s.Pony' % app_label],
))
if manager_model:
operations.append(migrations.CreateModel(
'Food',
fields=[
('id', models.AutoField(primary_key=True)),
],
managers=[
('food_qs', FoodQuerySet.as_manager()),
('food_mgr', FoodManager('a', 'b')),
('food_mgr_kwargs', FoodManager('x', 'y', 3, 4)),
]
))
return self.apply_operations(app_label, ProjectState(), operations)

View File

@ -2,7 +2,7 @@ from django.db import connection, migrations, models
from django.db.migrations.state import ProjectState from django.db.migrations.state import ProjectState
from django.test import override_settings from django.test import override_settings
from .test_operations import OperationTestBase from .test_base import OperationTestBase
class AgnosticRouter: class AgnosticRouter:

View File

@ -10,163 +10,13 @@ from django.db.utils import IntegrityError
from django.test import SimpleTestCase, override_settings, skipUnlessDBFeature from django.test import SimpleTestCase, override_settings, skipUnlessDBFeature
from .models import FoodManager, FoodQuerySet, UnicodeModel from .models import FoodManager, FoodQuerySet, UnicodeModel
from .test_base import MigrationTestBase from .test_base import OperationTestBase
class Mixin: class Mixin:
pass pass
class OperationTestBase(MigrationTestBase):
"""
Common functions to help test operations.
"""
@classmethod
def setUpClass(cls):
super().setUpClass()
cls._initial_table_names = frozenset(connection.introspection.table_names())
def tearDown(self):
self.cleanup_test_tables()
super().tearDown()
def cleanup_test_tables(self):
table_names = frozenset(connection.introspection.table_names()) - self._initial_table_names
with connection.schema_editor() as editor:
with connection.constraint_checks_disabled():
for table_name in table_names:
editor.execute(editor.sql_delete_table % {
'table': editor.quote_name(table_name),
})
def apply_operations(self, app_label, project_state, operations, atomic=True):
migration = Migration('name', app_label)
migration.operations = operations
with connection.schema_editor(atomic=atomic) as editor:
return migration.apply(project_state, editor)
def unapply_operations(self, app_label, project_state, operations, atomic=True):
migration = Migration('name', app_label)
migration.operations = operations
with connection.schema_editor(atomic=atomic) as editor:
return migration.unapply(project_state, editor)
def make_test_state(self, app_label, operation, **kwargs):
"""
Makes a test state using set_up_test_model and returns the
original state and the state after the migration is applied.
"""
project_state = self.set_up_test_model(app_label, **kwargs)
new_state = project_state.clone()
operation.state_forwards(app_label, new_state)
return project_state, new_state
def set_up_test_model(
self, app_label, second_model=False, third_model=False, index=False, multicol_index=False,
related_model=False, mti_model=False, proxy_model=False, manager_model=False,
unique_together=False, options=False, db_table=None, index_together=False, constraints=None):
"""
Creates a test model state and database table.
"""
# Make the "current" state
model_options = {
"swappable": "TEST_SWAP_MODEL",
"index_together": [["weight", "pink"]] if index_together else [],
"unique_together": [["pink", "weight"]] if unique_together else [],
}
if options:
model_options["permissions"] = [("can_groom", "Can groom")]
if db_table:
model_options["db_table"] = db_table
operations = [migrations.CreateModel(
"Pony",
[
("id", models.AutoField(primary_key=True)),
("pink", models.IntegerField(default=3)),
("weight", models.FloatField()),
],
options=model_options,
)]
if index:
operations.append(migrations.AddIndex(
"Pony",
models.Index(fields=["pink"], name="pony_pink_idx")
))
if multicol_index:
operations.append(migrations.AddIndex(
"Pony",
models.Index(fields=["pink", "weight"], name="pony_test_idx")
))
if constraints:
for constraint in constraints:
operations.append(migrations.AddConstraint(
"Pony",
constraint,
))
if second_model:
operations.append(migrations.CreateModel(
"Stable",
[
("id", models.AutoField(primary_key=True)),
]
))
if third_model:
operations.append(migrations.CreateModel(
"Van",
[
("id", models.AutoField(primary_key=True)),
]
))
if related_model:
operations.append(migrations.CreateModel(
"Rider",
[
("id", models.AutoField(primary_key=True)),
("pony", models.ForeignKey("Pony", models.CASCADE)),
("friend", models.ForeignKey("self", models.CASCADE))
],
))
if mti_model:
operations.append(migrations.CreateModel(
"ShetlandPony",
fields=[
('pony_ptr', models.OneToOneField(
'Pony',
models.CASCADE,
auto_created=True,
parent_link=True,
primary_key=True,
to_field='id',
serialize=False,
)),
("cuteness", models.IntegerField(default=1)),
],
bases=['%s.Pony' % app_label],
))
if proxy_model:
operations.append(migrations.CreateModel(
"ProxyPony",
fields=[],
options={"proxy": True},
bases=['%s.Pony' % app_label],
))
if manager_model:
operations.append(migrations.CreateModel(
"Food",
fields=[
("id", models.AutoField(primary_key=True)),
],
managers=[
("food_qs", FoodQuerySet.as_manager()),
("food_mgr", FoodManager("a", "b")),
("food_mgr_kwargs", FoodManager("x", "y", 3, 4)),
]
))
return self.apply_operations(app_label, ProjectState(), operations)
class OperationTests(OperationTestBase): class OperationTests(OperationTestBase):
""" """
Tests running the operations and making sure they do what they say they do. Tests running the operations and making sure they do what they say they do.