Refs #27236 -- Added test_autodetector.BaseAutodetectorTests.
This commit is contained in:
parent
de1c8320ce
commit
457cfd6f39
|
@ -31,7 +31,196 @@ class DeconstructibleObject:
|
|||
return (self.__module__ + "." + self.__class__.__name__, self.args, self.kwargs)
|
||||
|
||||
|
||||
class AutodetectorTests(TestCase):
|
||||
class BaseAutodetectorTests(TestCase):
|
||||
def repr_changes(self, changes, include_dependencies=False):
|
||||
output = ""
|
||||
for app_label, migrations_ in sorted(changes.items()):
|
||||
output += " %s:\n" % app_label
|
||||
for migration in migrations_:
|
||||
output += " %s\n" % migration.name
|
||||
for operation in migration.operations:
|
||||
output += " %s\n" % operation
|
||||
if include_dependencies:
|
||||
output += " Dependencies:\n"
|
||||
if migration.dependencies:
|
||||
for dep in migration.dependencies:
|
||||
output += " %s\n" % (dep,)
|
||||
else:
|
||||
output += " None\n"
|
||||
return output
|
||||
|
||||
def assertNumberMigrations(self, changes, app_label, number):
|
||||
if len(changes.get(app_label, [])) != number:
|
||||
self.fail(
|
||||
"Incorrect number of migrations (%s) for %s (expected %s)\n%s"
|
||||
% (
|
||||
len(changes.get(app_label, [])),
|
||||
app_label,
|
||||
number,
|
||||
self.repr_changes(changes),
|
||||
)
|
||||
)
|
||||
|
||||
def assertMigrationDependencies(self, changes, app_label, position, dependencies):
|
||||
if not changes.get(app_label):
|
||||
self.fail(
|
||||
"No migrations found for %s\n%s"
|
||||
% (app_label, self.repr_changes(changes))
|
||||
)
|
||||
if len(changes[app_label]) < position + 1:
|
||||
self.fail(
|
||||
"No migration at index %s for %s\n%s"
|
||||
% (position, app_label, self.repr_changes(changes))
|
||||
)
|
||||
migration = changes[app_label][position]
|
||||
if set(migration.dependencies) != set(dependencies):
|
||||
self.fail(
|
||||
"Migration dependencies mismatch for %s.%s (expected %s):\n%s"
|
||||
% (
|
||||
app_label,
|
||||
migration.name,
|
||||
dependencies,
|
||||
self.repr_changes(changes, include_dependencies=True),
|
||||
)
|
||||
)
|
||||
|
||||
def assertOperationTypes(self, changes, app_label, position, types):
|
||||
if not changes.get(app_label):
|
||||
self.fail(
|
||||
"No migrations found for %s\n%s"
|
||||
% (app_label, self.repr_changes(changes))
|
||||
)
|
||||
if len(changes[app_label]) < position + 1:
|
||||
self.fail(
|
||||
"No migration at index %s for %s\n%s"
|
||||
% (position, app_label, self.repr_changes(changes))
|
||||
)
|
||||
migration = changes[app_label][position]
|
||||
real_types = [
|
||||
operation.__class__.__name__ for operation in migration.operations
|
||||
]
|
||||
if types != real_types:
|
||||
self.fail(
|
||||
"Operation type mismatch for %s.%s (expected %s):\n%s"
|
||||
% (
|
||||
app_label,
|
||||
migration.name,
|
||||
types,
|
||||
self.repr_changes(changes),
|
||||
)
|
||||
)
|
||||
|
||||
def assertOperationAttributes(
|
||||
self, changes, app_label, position, operation_position, **attrs
|
||||
):
|
||||
if not changes.get(app_label):
|
||||
self.fail(
|
||||
"No migrations found for %s\n%s"
|
||||
% (app_label, self.repr_changes(changes))
|
||||
)
|
||||
if len(changes[app_label]) < position + 1:
|
||||
self.fail(
|
||||
"No migration at index %s for %s\n%s"
|
||||
% (position, app_label, self.repr_changes(changes))
|
||||
)
|
||||
migration = changes[app_label][position]
|
||||
if len(changes[app_label]) < position + 1:
|
||||
self.fail(
|
||||
"No operation at index %s for %s.%s\n%s"
|
||||
% (
|
||||
operation_position,
|
||||
app_label,
|
||||
migration.name,
|
||||
self.repr_changes(changes),
|
||||
)
|
||||
)
|
||||
operation = migration.operations[operation_position]
|
||||
for attr, value in attrs.items():
|
||||
if getattr(operation, attr, None) != value:
|
||||
self.fail(
|
||||
"Attribute mismatch for %s.%s op #%s, %s (expected %r, got %r):\n%s"
|
||||
% (
|
||||
app_label,
|
||||
migration.name,
|
||||
operation_position,
|
||||
attr,
|
||||
value,
|
||||
getattr(operation, attr, None),
|
||||
self.repr_changes(changes),
|
||||
)
|
||||
)
|
||||
|
||||
def assertOperationFieldAttributes(
|
||||
self, changes, app_label, position, operation_position, **attrs
|
||||
):
|
||||
if not changes.get(app_label):
|
||||
self.fail(
|
||||
"No migrations found for %s\n%s"
|
||||
% (app_label, self.repr_changes(changes))
|
||||
)
|
||||
if len(changes[app_label]) < position + 1:
|
||||
self.fail(
|
||||
"No migration at index %s for %s\n%s"
|
||||
% (position, app_label, self.repr_changes(changes))
|
||||
)
|
||||
migration = changes[app_label][position]
|
||||
if len(changes[app_label]) < position + 1:
|
||||
self.fail(
|
||||
"No operation at index %s for %s.%s\n%s"
|
||||
% (
|
||||
operation_position,
|
||||
app_label,
|
||||
migration.name,
|
||||
self.repr_changes(changes),
|
||||
)
|
||||
)
|
||||
operation = migration.operations[operation_position]
|
||||
if not hasattr(operation, "field"):
|
||||
self.fail(
|
||||
"No field attribute for %s.%s op #%s."
|
||||
% (
|
||||
app_label,
|
||||
migration.name,
|
||||
operation_position,
|
||||
)
|
||||
)
|
||||
field = operation.field
|
||||
for attr, value in attrs.items():
|
||||
if getattr(field, attr, None) != value:
|
||||
self.fail(
|
||||
"Field attribute mismatch for %s.%s op #%s, field.%s (expected %r, "
|
||||
"got %r):\n%s"
|
||||
% (
|
||||
app_label,
|
||||
migration.name,
|
||||
operation_position,
|
||||
attr,
|
||||
value,
|
||||
getattr(field, attr, None),
|
||||
self.repr_changes(changes),
|
||||
)
|
||||
)
|
||||
|
||||
def make_project_state(self, model_states):
|
||||
"Shortcut to make ProjectStates from lists of predefined models"
|
||||
project_state = ProjectState()
|
||||
for model_state in model_states:
|
||||
project_state.add_model(model_state.clone())
|
||||
return project_state
|
||||
|
||||
def get_changes(self, before_states, after_states, questioner=None):
|
||||
if not isinstance(before_states, ProjectState):
|
||||
before_states = self.make_project_state(before_states)
|
||||
if not isinstance(after_states, ProjectState):
|
||||
after_states = self.make_project_state(after_states)
|
||||
return MigrationAutodetector(
|
||||
before_states,
|
||||
after_states,
|
||||
questioner,
|
||||
)._detect_changes()
|
||||
|
||||
|
||||
class AutodetectorTests(BaseAutodetectorTests):
|
||||
"""
|
||||
Tests the migration autodetector.
|
||||
"""
|
||||
|
@ -954,193 +1143,6 @@ class AutodetectorTests(TestCase):
|
|||
},
|
||||
)
|
||||
|
||||
def repr_changes(self, changes, include_dependencies=False):
|
||||
output = ""
|
||||
for app_label, migrations_ in sorted(changes.items()):
|
||||
output += " %s:\n" % app_label
|
||||
for migration in migrations_:
|
||||
output += " %s\n" % migration.name
|
||||
for operation in migration.operations:
|
||||
output += " %s\n" % operation
|
||||
if include_dependencies:
|
||||
output += " Dependencies:\n"
|
||||
if migration.dependencies:
|
||||
for dep in migration.dependencies:
|
||||
output += " %s\n" % (dep,)
|
||||
else:
|
||||
output += " None\n"
|
||||
return output
|
||||
|
||||
def assertNumberMigrations(self, changes, app_label, number):
|
||||
if len(changes.get(app_label, [])) != number:
|
||||
self.fail(
|
||||
"Incorrect number of migrations (%s) for %s (expected %s)\n%s"
|
||||
% (
|
||||
len(changes.get(app_label, [])),
|
||||
app_label,
|
||||
number,
|
||||
self.repr_changes(changes),
|
||||
)
|
||||
)
|
||||
|
||||
def assertMigrationDependencies(self, changes, app_label, position, dependencies):
|
||||
if not changes.get(app_label):
|
||||
self.fail(
|
||||
"No migrations found for %s\n%s"
|
||||
% (app_label, self.repr_changes(changes))
|
||||
)
|
||||
if len(changes[app_label]) < position + 1:
|
||||
self.fail(
|
||||
"No migration at index %s for %s\n%s"
|
||||
% (position, app_label, self.repr_changes(changes))
|
||||
)
|
||||
migration = changes[app_label][position]
|
||||
if set(migration.dependencies) != set(dependencies):
|
||||
self.fail(
|
||||
"Migration dependencies mismatch for %s.%s (expected %s):\n%s"
|
||||
% (
|
||||
app_label,
|
||||
migration.name,
|
||||
dependencies,
|
||||
self.repr_changes(changes, include_dependencies=True),
|
||||
)
|
||||
)
|
||||
|
||||
def assertOperationTypes(self, changes, app_label, position, types):
|
||||
if not changes.get(app_label):
|
||||
self.fail(
|
||||
"No migrations found for %s\n%s"
|
||||
% (app_label, self.repr_changes(changes))
|
||||
)
|
||||
if len(changes[app_label]) < position + 1:
|
||||
self.fail(
|
||||
"No migration at index %s for %s\n%s"
|
||||
% (position, app_label, self.repr_changes(changes))
|
||||
)
|
||||
migration = changes[app_label][position]
|
||||
real_types = [
|
||||
operation.__class__.__name__ for operation in migration.operations
|
||||
]
|
||||
if types != real_types:
|
||||
self.fail(
|
||||
"Operation type mismatch for %s.%s (expected %s):\n%s"
|
||||
% (
|
||||
app_label,
|
||||
migration.name,
|
||||
types,
|
||||
self.repr_changes(changes),
|
||||
)
|
||||
)
|
||||
|
||||
def assertOperationAttributes(
|
||||
self, changes, app_label, position, operation_position, **attrs
|
||||
):
|
||||
if not changes.get(app_label):
|
||||
self.fail(
|
||||
"No migrations found for %s\n%s"
|
||||
% (app_label, self.repr_changes(changes))
|
||||
)
|
||||
if len(changes[app_label]) < position + 1:
|
||||
self.fail(
|
||||
"No migration at index %s for %s\n%s"
|
||||
% (position, app_label, self.repr_changes(changes))
|
||||
)
|
||||
migration = changes[app_label][position]
|
||||
if len(changes[app_label]) < position + 1:
|
||||
self.fail(
|
||||
"No operation at index %s for %s.%s\n%s"
|
||||
% (
|
||||
operation_position,
|
||||
app_label,
|
||||
migration.name,
|
||||
self.repr_changes(changes),
|
||||
)
|
||||
)
|
||||
operation = migration.operations[operation_position]
|
||||
for attr, value in attrs.items():
|
||||
if getattr(operation, attr, None) != value:
|
||||
self.fail(
|
||||
"Attribute mismatch for %s.%s op #%s, %s (expected %r, got %r):\n%s"
|
||||
% (
|
||||
app_label,
|
||||
migration.name,
|
||||
operation_position,
|
||||
attr,
|
||||
value,
|
||||
getattr(operation, attr, None),
|
||||
self.repr_changes(changes),
|
||||
)
|
||||
)
|
||||
|
||||
def assertOperationFieldAttributes(
|
||||
self, changes, app_label, position, operation_position, **attrs
|
||||
):
|
||||
if not changes.get(app_label):
|
||||
self.fail(
|
||||
"No migrations found for %s\n%s"
|
||||
% (app_label, self.repr_changes(changes))
|
||||
)
|
||||
if len(changes[app_label]) < position + 1:
|
||||
self.fail(
|
||||
"No migration at index %s for %s\n%s"
|
||||
% (position, app_label, self.repr_changes(changes))
|
||||
)
|
||||
migration = changes[app_label][position]
|
||||
if len(changes[app_label]) < position + 1:
|
||||
self.fail(
|
||||
"No operation at index %s for %s.%s\n%s"
|
||||
% (
|
||||
operation_position,
|
||||
app_label,
|
||||
migration.name,
|
||||
self.repr_changes(changes),
|
||||
)
|
||||
)
|
||||
operation = migration.operations[operation_position]
|
||||
if not hasattr(operation, "field"):
|
||||
self.fail(
|
||||
"No field attribute for %s.%s op #%s."
|
||||
% (
|
||||
app_label,
|
||||
migration.name,
|
||||
operation_position,
|
||||
)
|
||||
)
|
||||
field = operation.field
|
||||
for attr, value in attrs.items():
|
||||
if getattr(field, attr, None) != value:
|
||||
self.fail(
|
||||
"Field attribute mismatch for %s.%s op #%s, field.%s (expected %r, "
|
||||
"got %r):\n%s"
|
||||
% (
|
||||
app_label,
|
||||
migration.name,
|
||||
operation_position,
|
||||
attr,
|
||||
value,
|
||||
getattr(field, attr, None),
|
||||
self.repr_changes(changes),
|
||||
)
|
||||
)
|
||||
|
||||
def make_project_state(self, model_states):
|
||||
"Shortcut to make ProjectStates from lists of predefined models"
|
||||
project_state = ProjectState()
|
||||
for model_state in model_states:
|
||||
project_state.add_model(model_state.clone())
|
||||
return project_state
|
||||
|
||||
def get_changes(self, before_states, after_states, questioner=None):
|
||||
if not isinstance(before_states, ProjectState):
|
||||
before_states = self.make_project_state(before_states)
|
||||
if not isinstance(after_states, ProjectState):
|
||||
after_states = self.make_project_state(after_states)
|
||||
return MigrationAutodetector(
|
||||
before_states,
|
||||
after_states,
|
||||
questioner,
|
||||
)._detect_changes()
|
||||
|
||||
def test_arrange_for_graph(self):
|
||||
"""Tests auto-naming of migrations for graph matching."""
|
||||
# Make a fake graph
|
||||
|
|
Loading…
Reference in New Issue