Made testing of stdout and stderr more consistent.

Refs #23663.
This commit is contained in:
Loic Bistuer 2014-10-22 00:15:10 +07:00
parent 533532302a
commit 494ba051bb
6 changed files with 123 additions and 135 deletions

View File

@ -1524,40 +1524,36 @@ class CommandTypes(AdminScriptTestCase):
Test run_from_argv properly terminates even with custom execute() (#19665) Test run_from_argv properly terminates even with custom execute() (#19665)
Also test proper traceback display. Also test proper traceback display.
""" """
command = BaseCommand() err = StringIO()
command = BaseCommand(stderr=err)
def raise_command_error(*args, **kwargs): def raise_command_error(*args, **kwargs):
raise CommandError("Custom error") raise CommandError("Custom error")
old_stderr = sys.stderr command.execute = lambda args: args # This will trigger TypeError
sys.stderr = err = StringIO()
try:
command.execute = lambda args: args # This will trigger TypeError
# If the Exception is not CommandError it should always # If the Exception is not CommandError it should always
# raise the original exception. # raise the original exception.
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
command.run_from_argv(['', '']) command.run_from_argv(['', ''])
# If the Exception is CommandError and --traceback is not present # If the Exception is CommandError and --traceback is not present
# this command should raise a SystemExit and don't print any # this command should raise a SystemExit and don't print any
# traceback to the stderr. # traceback to the stderr.
command.execute = raise_command_error command.execute = raise_command_error
err.truncate(0) err.truncate(0)
with self.assertRaises(SystemExit): with self.assertRaises(SystemExit):
command.run_from_argv(['', '']) command.run_from_argv(['', ''])
err_message = err.getvalue() err_message = err.getvalue()
self.assertNotIn("Traceback", err_message) self.assertNotIn("Traceback", err_message)
self.assertIn("CommandError", err_message) self.assertIn("CommandError", err_message)
# If the Exception is CommandError and --traceback is present # If the Exception is CommandError and --traceback is present
# this command should raise the original CommandError as if it # this command should raise the original CommandError as if it
# were not a CommandError. # were not a CommandError.
err.truncate(0) err.truncate(0)
with self.assertRaises(CommandError): with self.assertRaises(CommandError):
command.run_from_argv(['', '', '--traceback']) command.run_from_argv(['', '', '--traceback'])
finally:
sys.stderr = old_stderr
def test_run_from_argv_non_ascii_error(self): def test_run_from_argv_non_ascii_error(self):
""" """
@ -1567,9 +1563,8 @@ class CommandTypes(AdminScriptTestCase):
def raise_command_error(*args, **kwargs): def raise_command_error(*args, **kwargs):
raise CommandError("Erreur personnalisée") raise CommandError("Erreur personnalisée")
command = BaseCommand() command = BaseCommand(stderr=StringIO())
command.execute = raise_command_error command.execute = raise_command_error
command.stderr = StringIO()
with self.assertRaises(SystemExit): with self.assertRaises(SystemExit):
command.run_from_argv(['', '']) command.run_from_argv(['', ''])

15
tests/cache/tests.py vendored
View File

@ -912,12 +912,9 @@ class DBCacheTests(BaseCacheTests, TransactionTestCase):
self._perform_cull_test(caches['zero_cull'], 50, 18) self._perform_cull_test(caches['zero_cull'], 50, 18)
def test_second_call_doesnt_crash(self): def test_second_call_doesnt_crash(self):
stdout = six.StringIO() out = six.StringIO()
management.call_command( management.call_command('createcachetable', stdout=out)
'createcachetable', self.assertEqual(out.getvalue(),
stdout=stdout
)
self.assertEqual(stdout.getvalue(),
"Cache table 'test cache table' already exists.\n" * len(settings.CACHES)) "Cache table 'test cache table' already exists.\n" * len(settings.CACHES))
def test_createcachetable_with_table_argument(self): def test_createcachetable_with_table_argument(self):
@ -926,14 +923,14 @@ class DBCacheTests(BaseCacheTests, TransactionTestCase):
specifying the table name). specifying the table name).
""" """
self.drop_table() self.drop_table()
stdout = six.StringIO() out = six.StringIO()
management.call_command( management.call_command(
'createcachetable', 'createcachetable',
'test cache table', 'test cache table',
verbosity=2, verbosity=2,
stdout=stdout stdout=out,
) )
self.assertEqual(stdout.getvalue(), self.assertEqual(out.getvalue(),
"Cache table 'test cache table' created.\n") "Cache table 'test cache table' created.\n")
def test_clear_commits_transaction(self): def test_clear_commits_transaction(self):

View File

@ -10,10 +10,6 @@ class MultiDBChangepasswordManagementCommandTestCase(TestCase):
def setUp(self): def setUp(self):
self.user = models.User.objects.db_manager('other').create_user(username='joe', password='qwerty') self.user = models.User.objects.db_manager('other').create_user(username='joe', password='qwerty')
self.stdout = StringIO()
def tearDown(self):
self.stdout.close()
def test_that_changepassword_command_with_database_option_uses_given_db(self): def test_that_changepassword_command_with_database_option_uses_given_db(self):
""" """
@ -24,8 +20,9 @@ class MultiDBChangepasswordManagementCommandTestCase(TestCase):
command = changepassword.Command() command = changepassword.Command()
command._get_pass = lambda *args: 'not qwerty' command._get_pass = lambda *args: 'not qwerty'
command.execute(username="joe", database='other', stdout=self.stdout) out = StringIO()
command_output = self.stdout.getvalue().strip() command.execute(username="joe", database='other', stdout=out)
command_output = out.getvalue().strip()
self.assertEqual(command_output, "Changing password for user 'joe'\nPassword changed successfully for user 'joe'") self.assertEqual(command_output, "Changing password for user 'joe'\nPassword changed successfully for user 'joe'")
self.assertTrue(models.User.objects.using('other').get(username="joe").check_password("not qwerty")) self.assertTrue(models.User.objects.using('other').get(username="joe").check_password("not qwerty"))

View File

@ -60,7 +60,7 @@ class TestFixtures(TestCase):
name='Platypus', name='Platypus',
latin_name='Ornithorhynchus anatinus', latin_name='Ornithorhynchus anatinus',
count=2, count=2,
weight=2.2 weight=2.2,
) )
animal.save() animal.save()
self.assertGreater(animal.id, 1) self.assertGreater(animal.id, 1)
@ -75,7 +75,7 @@ class TestFixtures(TestCase):
management.call_command( management.call_command(
'loaddata', 'loaddata',
'sequence_extra', 'sequence_extra',
verbosity=0 verbosity=0,
) )
def test_loaddata_not_found_fields_ignore(self): def test_loaddata_not_found_fields_ignore(self):
@ -359,20 +359,20 @@ class TestFixtures(TestCase):
name='Platypus', name='Platypus',
latin_name='Ornithorhynchus anatinus', latin_name='Ornithorhynchus anatinus',
count=2, count=2,
weight=2.2 weight=2.2,
) )
animal.save() animal.save()
stdout = StringIO() out = StringIO()
management.call_command( management.call_command(
'dumpdata', 'dumpdata',
'fixtures_regress.animal', 'fixtures_regress.animal',
format='json', format='json',
stdout=stdout stdout=out,
) )
# Output order isn't guaranteed, so check for parts # Output order isn't guaranteed, so check for parts
data = stdout.getvalue() data = out.getvalue()
# Get rid of artifacts like '000000002' to eliminate the differences # Get rid of artifacts like '000000002' to eliminate the differences
# between different Python versions. # between different Python versions.
@ -393,7 +393,7 @@ class TestFixtures(TestCase):
""" """
Regression for #11428 - Proxy models aren't included when you dumpdata Regression for #11428 - Proxy models aren't included when you dumpdata
""" """
stdout = StringIO() out = StringIO()
# Create an instance of the concrete class # Create an instance of the concrete class
widget = Widget.objects.create(name='grommet') widget = Widget.objects.create(name='grommet')
management.call_command( management.call_command(
@ -401,10 +401,10 @@ class TestFixtures(TestCase):
'fixtures_regress.widget', 'fixtures_regress.widget',
'fixtures_regress.widgetproxy', 'fixtures_regress.widgetproxy',
format='json', format='json',
stdout=stdout stdout=out,
) )
self.assertJSONEqual( self.assertJSONEqual(
stdout.getvalue(), out.getvalue(),
"""[{"pk": %d, "model": "fixtures_regress.widget", "fields": {"name": "grommet"}}]""" """[{"pk": %d, "model": "fixtures_regress.widget", "fields": {"name": "grommet"}}]"""
% widget.pk % widget.pk
) )
@ -554,7 +554,7 @@ class NaturalKeyFixtureTests(TestCase):
verbosity=0, verbosity=0,
) )
stdout = StringIO() out = StringIO()
management.call_command( management.call_command(
'dumpdata', 'dumpdata',
'fixtures_regress.book', 'fixtures_regress.book',
@ -564,10 +564,10 @@ class NaturalKeyFixtureTests(TestCase):
format='json', format='json',
use_natural_foreign_keys=True, use_natural_foreign_keys=True,
use_natural_primary_keys=True, use_natural_primary_keys=True,
stdout=stdout, stdout=out,
) )
self.assertJSONEqual( self.assertJSONEqual(
stdout.getvalue(), out.getvalue(),
"""[{"fields": {"main": null, "name": "Amazon"}, "model": "fixtures_regress.store"}, {"fields": {"main": null, "name": "Borders"}, "model": "fixtures_regress.store"}, {"fields": {"name": "Neal Stephenson"}, "model": "fixtures_regress.person"}, {"pk": 1, "model": "fixtures_regress.book", "fields": {"stores": [["Amazon"], ["Borders"]], "name": "Cryptonomicon", "author": ["Neal Stephenson"]}}]""" """[{"fields": {"main": null, "name": "Amazon"}, "model": "fixtures_regress.store"}, {"fields": {"main": null, "name": "Borders"}, "model": "fixtures_regress.store"}, {"fields": {"name": "Neal Stephenson"}, "model": "fixtures_regress.person"}, {"pk": 1, "model": "fixtures_regress.book", "fields": {"stores": [["Amazon"], ["Borders"]], "name": "Cryptonomicon", "author": ["Neal Stephenson"]}}]"""
) )
@ -800,19 +800,19 @@ class M2MNaturalKeyFixtureTests(TestCase):
a.b_set.add(b1) a.b_set.add(b1)
a.b_set.add(b2) a.b_set.add(b2)
stdout = StringIO() out = StringIO()
management.call_command( management.call_command(
'dumpdata', 'dumpdata',
'fixtures_regress.M2MSimpleA', 'fixtures_regress.M2MSimpleA',
'fixtures_regress.M2MSimpleB', 'fixtures_regress.M2MSimpleB',
use_natural_foreign_keys=True, use_natural_foreign_keys=True,
stdout=stdout stdout=out,
) )
for model in [M2MSimpleA, M2MSimpleB]: for model in [M2MSimpleA, M2MSimpleB]:
model.objects.all().delete() model.objects.all().delete()
objects = serializers.deserialize("json", stdout.getvalue()) objects = serializers.deserialize("json", out.getvalue())
for obj in objects: for obj in objects:
obj.save() obj.save()

View File

@ -57,10 +57,10 @@ class ExtractorTests(SimpleTestCase):
def _run_makemessages(self, **options): def _run_makemessages(self, **options):
os.chdir(self.test_dir) os.chdir(self.test_dir)
stdout = StringIO() out = StringIO()
management.call_command('makemessages', locale=[LOCALE], verbosity=2, management.call_command('makemessages', locale=[LOCALE], verbosity=2,
stdout=stdout, **options) stdout=out, **options)
output = stdout.getvalue() output = out.getvalue()
self.assertTrue(os.path.exists(self.PO_FILE)) self.assertTrue(os.path.exists(self.PO_FILE))
with open(self.PO_FILE, 'r') as fp: with open(self.PO_FILE, 'r') as fp:
po_contents = fp.read() po_contents = fp.read()
@ -224,19 +224,19 @@ class BasicExtractorTests(ExtractorTests):
os.chdir(self.test_dir) os.chdir(self.test_dir)
shutil.copyfile('./not_utf8.sample', './not_utf8.txt') shutil.copyfile('./not_utf8.sample', './not_utf8.txt')
self.addCleanup(self.rmfile, os.path.join(self.test_dir, 'not_utf8.txt')) self.addCleanup(self.rmfile, os.path.join(self.test_dir, 'not_utf8.txt'))
stdout = StringIO() out = StringIO()
management.call_command('makemessages', locale=[LOCALE], stdout=stdout) management.call_command('makemessages', locale=[LOCALE], stdout=out)
self.assertIn("UnicodeDecodeError: skipped file not_utf8.txt in .", self.assertIn("UnicodeDecodeError: skipped file not_utf8.txt in .",
force_text(stdout.getvalue())) force_text(out.getvalue()))
def test_extraction_warning(self): def test_extraction_warning(self):
"""test xgettext warning about multiple bare interpolation placeholders""" """test xgettext warning about multiple bare interpolation placeholders"""
os.chdir(self.test_dir) os.chdir(self.test_dir)
shutil.copyfile('./code.sample', './code_sample.py') shutil.copyfile('./code.sample', './code_sample.py')
self.addCleanup(self.rmfile, os.path.join(self.test_dir, 'code_sample.py')) self.addCleanup(self.rmfile, os.path.join(self.test_dir, 'code_sample.py'))
stdout = StringIO() out = StringIO()
management.call_command('makemessages', locale=[LOCALE], stdout=stdout) management.call_command('makemessages', locale=[LOCALE], stdout=out)
self.assertIn("code_sample.py:4", force_text(stdout.getvalue())) self.assertIn("code_sample.py:4", force_text(out.getvalue()))
def test_template_message_context_extractor(self): def test_template_message_context_extractor(self):
""" """

View File

@ -56,20 +56,20 @@ class MigrateTests(MigrationTestBase):
""" """
Tests --list output of migrate command Tests --list output of migrate command
""" """
stdout = six.StringIO() out = six.StringIO()
call_command("migrate", list=True, stdout=stdout, verbosity=0) call_command("migrate", list=True, stdout=out, verbosity=0)
self.assertIn("migrations", stdout.getvalue().lower()) self.assertIn("migrations", out.getvalue().lower())
self.assertIn("[ ] 0001_initial", stdout.getvalue().lower()) self.assertIn("[ ] 0001_initial", out.getvalue().lower())
self.assertIn("[ ] 0002_second", stdout.getvalue().lower()) self.assertIn("[ ] 0002_second", out.getvalue().lower())
call_command("migrate", "migrations", "0001", verbosity=0) call_command("migrate", "migrations", "0001", verbosity=0)
stdout = six.StringIO() out = six.StringIO()
# Giving the explicit app_label tests for selective `show_migration_list` in the command # Giving the explicit app_label tests for selective `show_migration_list` in the command
call_command("migrate", "migrations", list=True, stdout=stdout, verbosity=0) call_command("migrate", "migrations", list=True, stdout=out, verbosity=0)
self.assertIn("migrations", stdout.getvalue().lower()) self.assertIn("migrations", out.getvalue().lower())
self.assertIn("[x] 0001_initial", stdout.getvalue().lower()) self.assertIn("[x] 0001_initial", out.getvalue().lower())
self.assertIn("[ ] 0002_second", stdout.getvalue().lower()) self.assertIn("[ ] 0002_second", out.getvalue().lower())
# Cleanup by unmigrating everything # Cleanup by unmigrating everything
call_command("migrate", "migrations", "zero", verbosity=0) call_command("migrate", "migrations", "zero", verbosity=0)
@ -87,24 +87,24 @@ class MigrateTests(MigrationTestBase):
Makes sure that sqlmigrate does something. Makes sure that sqlmigrate does something.
""" """
# Make sure the output is wrapped in a transaction # Make sure the output is wrapped in a transaction
stdout = six.StringIO() out = six.StringIO()
call_command("sqlmigrate", "migrations", "0001", stdout=stdout) call_command("sqlmigrate", "migrations", "0001", stdout=out)
output = stdout.getvalue() output = out.getvalue()
self.assertIn(connection.ops.start_transaction_sql(), output) self.assertIn(connection.ops.start_transaction_sql(), output)
self.assertIn(connection.ops.end_transaction_sql(), output) self.assertIn(connection.ops.end_transaction_sql(), output)
# Test forwards. All the databases agree on CREATE TABLE, at least. # Test forwards. All the databases agree on CREATE TABLE, at least.
stdout = six.StringIO() out = six.StringIO()
call_command("sqlmigrate", "migrations", "0001", stdout=stdout) call_command("sqlmigrate", "migrations", "0001", stdout=out)
self.assertIn("create table", stdout.getvalue().lower()) self.assertIn("create table", out.getvalue().lower())
# Cannot generate the reverse SQL unless we've applied the migration. # Cannot generate the reverse SQL unless we've applied the migration.
call_command("migrate", "migrations", verbosity=0) call_command("migrate", "migrations", verbosity=0)
# And backwards is a DROP TABLE # And backwards is a DROP TABLE
stdout = six.StringIO() out = six.StringIO()
call_command("sqlmigrate", "migrations", "0001", stdout=stdout, backwards=True) call_command("sqlmigrate", "migrations", "0001", stdout=out, backwards=True)
self.assertIn("drop table", stdout.getvalue().lower()) self.assertIn("drop table", out.getvalue().lower())
# Cleanup by unmigrating everything # Cleanup by unmigrating everything
call_command("migrate", "migrations", "zero", verbosity=0) call_command("migrate", "migrations", "zero", verbosity=0)
@ -128,8 +128,7 @@ class MigrateTests(MigrationTestBase):
"B" was not included in the ProjectState that is used to detect "B" was not included in the ProjectState that is used to detect
soft-applied migrations. soft-applied migrations.
""" """
stdout = six.StringIO() call_command("migrate", "migrated_unapplied_app", stdout=six.StringIO())
call_command("migrate", "migrated_unapplied_app", stdout=stdout)
class MakeMigrationsTests(MigrationTestBase): class MakeMigrationsTests(MigrationTestBase):
@ -235,21 +234,21 @@ class MakeMigrationsTests(MigrationTestBase):
""" """
Makes sure that makemigrations exits if in merge mode with no conflicts. Makes sure that makemigrations exits if in merge mode with no conflicts.
""" """
stdout = six.StringIO() out = six.StringIO()
try: try:
call_command("makemigrations", merge=True, stdout=stdout) call_command("makemigrations", merge=True, stdout=out)
except CommandError: except CommandError:
self.fail("Makemigrations errored in merge mode with no conflicts") self.fail("Makemigrations errored in merge mode with no conflicts")
self.assertIn("No conflicts detected to merge.", stdout.getvalue()) self.assertIn("No conflicts detected to merge.", out.getvalue())
def test_makemigrations_no_app_sys_exit(self): def test_makemigrations_no_app_sys_exit(self):
""" """
Makes sure that makemigrations exits if a non-existent app is specified. Makes sure that makemigrations exits if a non-existent app is specified.
""" """
stderr = six.StringIO() err = six.StringIO()
with self.assertRaises(SystemExit): with self.assertRaises(SystemExit):
call_command("makemigrations", "this_app_does_not_exist", stderr=stderr) call_command("makemigrations", "this_app_does_not_exist", stderr=err)
self.assertIn("'this_app_does_not_exist' could not be found.", stderr.getvalue()) self.assertIn("'this_app_does_not_exist' could not be found.", err.getvalue())
def test_makemigrations_empty_no_app_specified(self): def test_makemigrations_empty_no_app_specified(self):
""" """
@ -286,27 +285,27 @@ class MakeMigrationsTests(MigrationTestBase):
""" """
Makes sure that makemigrations exits when there are no changes and no apps are specified. Makes sure that makemigrations exits when there are no changes and no apps are specified.
""" """
stdout = six.StringIO() out = six.StringIO()
call_command("makemigrations", stdout=stdout) call_command("makemigrations", stdout=out)
self.assertIn("No changes detected", stdout.getvalue()) self.assertIn("No changes detected", out.getvalue())
@override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_no_changes"}) @override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_no_changes"})
def test_makemigrations_no_changes(self): def test_makemigrations_no_changes(self):
""" """
Makes sure that makemigrations exits when there are no changes to an app. Makes sure that makemigrations exits when there are no changes to an app.
""" """
stdout = six.StringIO() out = six.StringIO()
call_command("makemigrations", "migrations", stdout=stdout) call_command("makemigrations", "migrations", stdout=out)
self.assertIn("No changes detected in app 'migrations'", stdout.getvalue()) self.assertIn("No changes detected in app 'migrations'", out.getvalue())
def test_makemigrations_migrations_announce(self): def test_makemigrations_migrations_announce(self):
""" """
Makes sure that makemigrations announces the migration at the default verbosity level. Makes sure that makemigrations announces the migration at the default verbosity level.
""" """
stdout = six.StringIO() out = six.StringIO()
with override_settings(MIGRATION_MODULES={"migrations": self.migration_pkg}): with override_settings(MIGRATION_MODULES={"migrations": self.migration_pkg}):
call_command("makemigrations", "migrations", stdout=stdout) call_command("makemigrations", "migrations", stdout=out)
self.assertIn("Migrations for 'migrations'", stdout.getvalue()) self.assertIn("Migrations for 'migrations'", out.getvalue())
@override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_no_ancestor"}) @override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_no_ancestor"})
def test_makemigrations_no_common_ancestor(self): def test_makemigrations_no_common_ancestor(self):
@ -345,9 +344,9 @@ class MakeMigrationsTests(MigrationTestBase):
# Monkeypatch interactive questioner to auto accept # Monkeypatch interactive questioner to auto accept
old_input = questioner.input old_input = questioner.input
questioner.input = lambda _: "y" questioner.input = lambda _: "y"
stdout = six.StringIO() out = six.StringIO()
try: try:
call_command("makemigrations", "migrations", merge=True, interactive=True, stdout=stdout) call_command("makemigrations", "migrations", merge=True, interactive=True, stdout=out)
merge_file = os.path.join(self.test_dir, 'test_migrations_conflict', '0003_merge.py') merge_file = os.path.join(self.test_dir, 'test_migrations_conflict', '0003_merge.py')
self.assertTrue(os.path.exists(merge_file)) self.assertTrue(os.path.exists(merge_file))
os.remove(merge_file) os.remove(merge_file)
@ -356,23 +355,23 @@ class MakeMigrationsTests(MigrationTestBase):
self.fail("Makemigrations failed while running interactive questioner") self.fail("Makemigrations failed while running interactive questioner")
finally: finally:
questioner.input = old_input questioner.input = old_input
self.assertIn("Created new merge migration", stdout.getvalue()) self.assertIn("Created new merge migration", out.getvalue())
@override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_conflict"}) @override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_conflict"})
def test_makemigrations_handle_merge(self): def test_makemigrations_handle_merge(self):
""" """
Makes sure that makemigrations properly merges the conflicting migrations with --noinput. Makes sure that makemigrations properly merges the conflicting migrations with --noinput.
""" """
stdout = six.StringIO() out = six.StringIO()
call_command("makemigrations", "migrations", merge=True, interactive=False, stdout=stdout) call_command("makemigrations", "migrations", merge=True, interactive=False, stdout=out)
self.assertIn("Merging migrations", stdout.getvalue()) self.assertIn("Merging migrations", out.getvalue())
self.assertIn("Branch 0002_second", stdout.getvalue()) self.assertIn("Branch 0002_second", out.getvalue())
self.assertIn("Branch 0002_conflicting_second", stdout.getvalue()) self.assertIn("Branch 0002_conflicting_second", out.getvalue())
merge_file = os.path.join(self.test_dir, 'test_migrations_conflict', '0003_merge.py') merge_file = os.path.join(self.test_dir, 'test_migrations_conflict', '0003_merge.py')
self.assertTrue(os.path.exists(merge_file)) self.assertTrue(os.path.exists(merge_file))
os.remove(merge_file) os.remove(merge_file)
self.assertFalse(os.path.exists(merge_file)) self.assertFalse(os.path.exists(merge_file))
self.assertIn("Created new merge migration", stdout.getvalue()) self.assertIn("Created new merge migration", out.getvalue())
@override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_no_default"}) @override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_no_default"})
def test_makemigrations_dry_run(self): def test_makemigrations_dry_run(self):
@ -387,10 +386,10 @@ class MakeMigrationsTests(MigrationTestBase):
class Meta: class Meta:
app_label = "migrations" app_label = "migrations"
stdout = six.StringIO() out = six.StringIO()
call_command("makemigrations", "migrations", dry_run=True, stdout=stdout) call_command("makemigrations", "migrations", dry_run=True, stdout=out)
# Output the expected changes directly, without asking for defaults # Output the expected changes directly, without asking for defaults
self.assertIn("Add field silly_date to sillymodel", stdout.getvalue()) self.assertIn("Add field silly_date to sillymodel", out.getvalue())
@override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_no_default"}) @override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_no_default"})
def test_makemigrations_dry_run_verbosity_3(self): def test_makemigrations_dry_run_verbosity_3(self):
@ -406,21 +405,21 @@ class MakeMigrationsTests(MigrationTestBase):
class Meta: class Meta:
app_label = "migrations" app_label = "migrations"
stdout = six.StringIO() out = six.StringIO()
call_command("makemigrations", "migrations", dry_run=True, stdout=stdout, verbosity=3) call_command("makemigrations", "migrations", dry_run=True, stdout=out, verbosity=3)
# Normal --dry-run output # Normal --dry-run output
self.assertIn("- Add field silly_char to sillymodel", stdout.getvalue()) self.assertIn("- Add field silly_char to sillymodel", out.getvalue())
# Additional output caused by verbosity 3 # Additional output caused by verbosity 3
# The complete migrations file that would be written # The complete migrations file that would be written
self.assertIn("# -*- coding: utf-8 -*-", stdout.getvalue()) self.assertIn("# -*- coding: utf-8 -*-", out.getvalue())
self.assertIn("class Migration(migrations.Migration):", stdout.getvalue()) self.assertIn("class Migration(migrations.Migration):", out.getvalue())
self.assertIn("dependencies = [", stdout.getvalue()) self.assertIn("dependencies = [", out.getvalue())
self.assertIn("('migrations', '0001_initial'),", stdout.getvalue()) self.assertIn("('migrations', '0001_initial'),", out.getvalue())
self.assertIn("migrations.AddField(", stdout.getvalue()) self.assertIn("migrations.AddField(", out.getvalue())
self.assertIn("model_name='sillymodel',", stdout.getvalue()) self.assertIn("model_name='sillymodel',", out.getvalue())
self.assertIn("name='silly_char',", stdout.getvalue()) self.assertIn("name='silly_char',", out.getvalue())
@override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_path_doesnt_exist.foo.bar"}) @override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_path_doesnt_exist.foo.bar"})
def test_makemigrations_migrations_modules_path_not_exist(self): def test_makemigrations_migrations_modules_path_not_exist(self):
@ -436,11 +435,11 @@ class MakeMigrationsTests(MigrationTestBase):
class Meta: class Meta:
app_label = "migrations" app_label = "migrations"
stdout = six.StringIO() out = six.StringIO()
call_command("makemigrations", "migrations", stdout=stdout) call_command("makemigrations", "migrations", stdout=out)
# Command output indicates the migration is created. # Command output indicates the migration is created.
self.assertIn(" - Create model SillyModel", stdout.getvalue()) self.assertIn(" - Create model SillyModel", out.getvalue())
# Migrations file is actually created in the expected path. # Migrations file is actually created in the expected path.
self.assertTrue(os.path.isfile(os.path.join(self.test_dir, self.assertTrue(os.path.isfile(os.path.join(self.test_dir,
@ -457,10 +456,10 @@ class MakeMigrationsTests(MigrationTestBase):
# Monkeypatch interactive questioner to auto reject # Monkeypatch interactive questioner to auto reject
old_input = questioner.input old_input = questioner.input
questioner.input = lambda _: "N" questioner.input = lambda _: "N"
stdout = six.StringIO() out = six.StringIO()
merge_file = os.path.join(self.test_dir, 'test_migrations_conflict', '0003_merge.py') merge_file = os.path.join(self.test_dir, 'test_migrations_conflict', '0003_merge.py')
try: try:
call_command("makemigrations", "migrations", merge=True, stdout=stdout) call_command("makemigrations", "migrations", merge=True, stdout=out)
# This will fail if interactive is False by default # This will fail if interactive is False by default
self.assertFalse(os.path.exists(merge_file)) self.assertFalse(os.path.exists(merge_file))
except CommandError: except CommandError:
@ -469,7 +468,7 @@ class MakeMigrationsTests(MigrationTestBase):
questioner.input = old_input questioner.input = old_input
if os.path.exists(merge_file): if os.path.exists(merge_file):
os.remove(merge_file) os.remove(merge_file)
self.assertNotIn("Created new merge migration", stdout.getvalue()) self.assertNotIn("Created new merge migration", out.getvalue())
@override_settings( @override_settings(
MIGRATION_MODULES={"migrations": "migrations.test_migrations_no_changes"}, MIGRATION_MODULES={"migrations": "migrations.test_migrations_no_changes"},
@ -498,16 +497,16 @@ class MakeMigrationsTests(MigrationTestBase):
# Monkeypatch interactive questioner to auto accept # Monkeypatch interactive questioner to auto accept
old_input = questioner.input old_input = questioner.input
questioner.input = lambda _: "y" questioner.input = lambda _: "y"
stdout = six.StringIO() out = six.StringIO()
merge_file = os.path.join(self.test_dir, merge_file = os.path.join(self.test_dir,
'migrations_test_apps', 'migrations_test_apps',
'unspecified_app_with_conflict', 'unspecified_app_with_conflict',
'migrations', 'migrations',
'0003_merge.py') '0003_merge.py')
try: try:
call_command("makemigrations", "migrated_app", merge=True, interactive=True, stdout=stdout) call_command("makemigrations", "migrated_app", merge=True, interactive=True, stdout=out)
self.assertFalse(os.path.exists(merge_file)) self.assertFalse(os.path.exists(merge_file))
self.assertIn("No conflicts detected to merge.", stdout.getvalue()) self.assertIn("No conflicts detected to merge.", out.getvalue())
except CommandError: except CommandError:
self.fail("Makemigrations fails resolving conflicts in an unspecified app") self.fail("Makemigrations fails resolving conflicts in an unspecified app")
finally: finally: