kopia lustrzana https://github.com/wagtail/wagtail
Merge branch 'feature/migration-tests' of https://github.com/takeflight/wagtail into takeflight-feature/migration-tests
Conflicts: wagtail/wagtailsnippets/tests.pypull/845/head
commit
3535b5ca21
|
@ -0,0 +1,23 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('tests', '0006_merge'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='RegisterDecorator',
|
||||
fields=[
|
||||
('id', models.AutoField(serialize=False, auto_created=True, verbose_name='ID', primary_key=True)),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,26 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('tests', '0007_registerdecorator'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='pagechoosermodel',
|
||||
name='page',
|
||||
field=models.ForeignKey(help_text='help text', to='wagtailcore.Page'),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='snippetchoosermodel',
|
||||
name='advert',
|
||||
field=models.ForeignKey(help_text='help text', to='tests.Advert'),
|
||||
preserve_default=True,
|
||||
),
|
||||
]
|
|
@ -497,3 +497,8 @@ class SnippetChooserModel(models.Model):
|
|||
panels = [
|
||||
SnippetChooserPanel('advert', Advert),
|
||||
]
|
||||
|
||||
|
||||
@register_snippet
|
||||
class RegisterDecorator(models.Model):
|
||||
pass
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
"""
|
||||
Check that all changes to Wagtail models have had migrations created. If there
|
||||
are outstanding model changes that need migrations, fail the tests.
|
||||
"""
|
||||
|
||||
from django import VERSION
|
||||
from django.test import TransactionTestCase
|
||||
|
||||
from django.utils.six import iteritems
|
||||
import south.management.commands.schemamigration
|
||||
|
||||
try:
|
||||
from unittest import skipIf, skipUnless
|
||||
except ImportError:
|
||||
from django.utils.unittest import skipIf, skipUnless
|
||||
|
||||
|
||||
class TestForMigrations(TransactionTestCase):
|
||||
|
||||
@skipIf(VERSION < (1, 7), "Migrations introduced in Django 1.7")
|
||||
def test_django_17_migrations(self):
|
||||
|
||||
from django.apps import apps
|
||||
from django.db.migrations.loader import MigrationLoader
|
||||
from django.db.migrations.autodetector import MigrationAutodetector
|
||||
from django.db.migrations.state import ProjectState
|
||||
from django.db.migrations.questioner import MigrationQuestioner
|
||||
app_labels = set(app.label for app in apps.get_app_configs()
|
||||
if app.name.startswith('wagtail.'))
|
||||
for app_label in app_labels:
|
||||
apps.get_app_config(app_label.split('.')[-1])
|
||||
loader = MigrationLoader(None, ignore_no_migrations=True)
|
||||
|
||||
conflicts = dict(
|
||||
(app_label, conflict)
|
||||
for app_label, conflict in iteritems(loader.detect_conflicts())
|
||||
if app_label in app_labels
|
||||
)
|
||||
|
||||
if conflicts:
|
||||
name_str = "; ".join("%s in %s" % (", ".join(names), app)
|
||||
for app, names in conflicts.items())
|
||||
self.fail("Conflicting migrations detected (%s)." % name_str)
|
||||
|
||||
autodetector = MigrationAutodetector(
|
||||
loader.project_state(),
|
||||
ProjectState.from_apps(apps),
|
||||
MigrationQuestioner(specified_apps=app_labels, dry_run=True),
|
||||
)
|
||||
|
||||
changes = autodetector.changes(
|
||||
graph=loader.graph,
|
||||
trim_to_apps=app_labels or None,
|
||||
convert_apps=app_labels or None,
|
||||
)
|
||||
|
||||
if changes:
|
||||
apps = ', '.join(apps.get_app_config(label).name
|
||||
for label in changes.keys())
|
||||
migrations = '\n'.join((
|
||||
' {migration}\n{changes}'.format(
|
||||
migration=migration,
|
||||
changes='\n'.join(' {0}'.format(operation.describe())
|
||||
for operation in migration.operations))
|
||||
for (_, migrations) in changes.items()
|
||||
for migration in migrations))
|
||||
|
||||
self.fail('Model changes with no migrations detected:\n%s' % migrations)
|
||||
|
||||
@skipUnless(VERSION < (1, 7), "South migrations used for Django < 1.7")
|
||||
def test_south_migrations(self):
|
||||
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.conf import settings
|
||||
from django.db import models
|
||||
|
||||
from south.migration import Migrations, migrate_app
|
||||
from south.models import MigrationHistory
|
||||
from south.exceptions import NoMigrations
|
||||
from south.creator import changes, actions, freezer
|
||||
from south.management.commands.datamigration import Command as DataCommand
|
||||
|
||||
apps = [app for app in settings.INSTALLED_APPS
|
||||
if app.startswith('wagtail.')]
|
||||
failing_apps = []
|
||||
for app_name in apps:
|
||||
app = app_name.split('.')[-1]
|
||||
try:
|
||||
models.get_app(app)
|
||||
except ImproperlyConfigured:
|
||||
# This module fails to load, probably because it has no
|
||||
# models.py. Ignore it and move on
|
||||
continue
|
||||
|
||||
try:
|
||||
migrations = Migrations(app, force_creation=False, verbose_creation=False)
|
||||
last_migration = migrations[-1]
|
||||
except (NoMigrations, IndexError):
|
||||
# No migrations for this app, probably doesnt have models
|
||||
continue
|
||||
|
||||
if migrations.app_label() not in getattr(last_migration.migration_class(), "complete_apps", []):
|
||||
self.fail("Automatic migrations checking failed, since the previous migration does not have this whole app frozen.\nEither make migrations using '--freeze %s' or set 'SOUTH_AUTO_FREEZE_APP = True' in your settings.py." % migrations.app_label())
|
||||
|
||||
# Alright, construct two model dicts to run the differ on.
|
||||
old_defs = dict(
|
||||
(k, v) for k, v in last_migration.migration_class().models.items()
|
||||
if k.split(".")[0] == migrations.app_label()
|
||||
)
|
||||
new_defs = dict(
|
||||
(k, v) for k, v in freezer.freeze_apps([migrations.app_label()]).items()
|
||||
if k.split(".")[0] == migrations.app_label()
|
||||
)
|
||||
change_source = changes.AutoChanges(
|
||||
migrations = migrations,
|
||||
old_defs = old_defs,
|
||||
old_orm = last_migration.orm(),
|
||||
new_defs = new_defs,
|
||||
)
|
||||
|
||||
name = 'test'
|
||||
|
||||
# Get the actions, and then insert them into the actions lists
|
||||
if list(change_source.get_changes()):
|
||||
failing_apps.append(app_name)
|
||||
|
||||
if failing_apps:
|
||||
self.fail('Model changes with no South migration detected in apps: %s' % (
|
||||
', '.join(failing_apps)))
|
|
@ -6,6 +6,8 @@ from south.db import db
|
|||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
from wagtail.wagtailcore.compat import AUTH_USER_MODEL, AUTH_USER_MODEL_NAME
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
|
@ -79,8 +81,8 @@ class Migration(SchemaMigration):
|
|||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
'auth.user': {
|
||||
'Meta': {'object_name': 'User'},
|
||||
AUTH_USER_MODEL: {
|
||||
'Meta': {'object_name': AUTH_USER_MODEL_NAME},
|
||||
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
|
@ -118,7 +120,7 @@ class Migration(SchemaMigration):
|
|||
'height': ('django.db.models.fields.IntegerField', [], {}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'uploaded_by_user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
|
||||
'uploaded_by_user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % AUTH_USER_MODEL, 'null': 'True', 'blank': 'True'}),
|
||||
'width': ('django.db.models.fields.IntegerField', [], {})
|
||||
},
|
||||
'wagtailimages.rendition': {
|
||||
|
@ -133,4 +135,4 @@ class Migration(SchemaMigration):
|
|||
}
|
||||
}
|
||||
|
||||
complete_apps = ['wagtailimages']
|
||||
complete_apps = ['wagtailimages']
|
||||
|
|
|
@ -6,6 +6,8 @@ from south.db import db
|
|||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
from wagtail.wagtailcore.compat import AUTH_USER_MODEL, AUTH_USER_MODEL_NAME
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
|
@ -39,8 +41,8 @@ class Migration(SchemaMigration):
|
|||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
'auth.user': {
|
||||
'Meta': {'object_name': 'User'},
|
||||
AUTH_USER_MODEL: {
|
||||
'Meta': {'object_name': AUTH_USER_MODEL_NAME},
|
||||
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
|
@ -78,7 +80,7 @@ class Migration(SchemaMigration):
|
|||
'height': ('django.db.models.fields.IntegerField', [], {}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'uploaded_by_user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
|
||||
'uploaded_by_user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % AUTH_USER_MODEL, 'null': 'True', 'blank': 'True'}),
|
||||
'width': ('django.db.models.fields.IntegerField', [], {})
|
||||
},
|
||||
'wagtailimages.rendition': {
|
||||
|
@ -93,4 +95,4 @@ class Migration(SchemaMigration):
|
|||
}
|
||||
}
|
||||
|
||||
complete_apps = ['wagtailimages']
|
||||
complete_apps = ['wagtailimages']
|
||||
|
|
|
@ -4,7 +4,7 @@ from django.db import models
|
|||
|
||||
from wagtail.tests.utils import WagtailTestUtils
|
||||
from django.test.utils import override_settings
|
||||
from wagtail.tests.models import Advert, AlphaSnippet, ZuluSnippet, SnippetChooserModel
|
||||
from wagtail.tests.models import Advert, AlphaSnippet, ZuluSnippet, SnippetChooserModel, RegisterDecorator
|
||||
from wagtail.wagtailsnippets.models import register_snippet, SNIPPET_MODELS
|
||||
|
||||
from wagtail.wagtailsnippets.views.snippets import (
|
||||
|
@ -189,10 +189,6 @@ class TestSnippetRegistering(TestCase):
|
|||
self.assertIn(RegisterFunction, SNIPPET_MODELS)
|
||||
|
||||
def test_register_decorator(self):
|
||||
@register_snippet
|
||||
class RegisterDecorator(models.Model):
|
||||
pass
|
||||
|
||||
# Misbehaving decorators often return None
|
||||
self.assertIsNotNone(RegisterDecorator)
|
||||
self.assertIn(RegisterDecorator, SNIPPET_MODELS)
|
||||
|
|
Ładowanie…
Reference in New Issue