summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob Walls <jacobtylerwalls@gmail.com>2021-11-07 09:34:16 -0500
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2021-12-20 11:11:39 +0100
commit1833a9eee90b97bf862b725c88faba19157b7160 (patch)
tree429b1dcc6cc23a0f3c38c15e9dbd1103e7113bbc
parent448145092c23074b5c3b6c0502358c1d7eface8b (diff)
Increased test coverage of django.db.migrations.questioner.
-rw-r--r--tests/migrations/test_commands.py40
-rw-r--r--tests/migrations/test_questioner.py67
2 files changed, 101 insertions, 6 deletions
diff --git a/tests/migrations/test_commands.py b/tests/migrations/test_commands.py
index 9755af9f6d..ebaaccb1db 100644
--- a/tests/migrations/test_commands.py
+++ b/tests/migrations/test_commands.py
@@ -1458,6 +1458,12 @@ class MakeMigrationsTests(MigrationTestBase):
" 3) Quit and manually define a default value in models.py."
)
with self.temporary_migration_module(module='migrations.test_migrations'):
+ # No message appears if --dry-run.
+ with captured_stdout() as out:
+ call_command(
+ 'makemigrations', 'migrations', interactive=True, dry_run=True,
+ )
+ self.assertNotIn(input_msg, out.getvalue())
# 3 - quit.
with mock.patch('builtins.input', return_value='3'):
with captured_stdout() as out, self.assertRaises(SystemExit):
@@ -1512,6 +1518,39 @@ class MakeMigrationsTests(MigrationTestBase):
self.assertIn("Remove field silly_field from sillymodel", out.getvalue())
self.assertIn("Add field silly_rename to sillymodel", out.getvalue())
+ @mock.patch('builtins.input', return_value='Y')
+ def test_makemigrations_model_rename_interactive(self, mock_input):
+ class RenamedModel(models.Model):
+ silly_field = models.BooleanField(default=False)
+
+ class Meta:
+ app_label = 'migrations'
+
+ with self.temporary_migration_module(
+ module='migrations.test_migrations_no_default',
+ ):
+ with captured_stdout() as out:
+ call_command('makemigrations', 'migrations', interactive=True)
+ self.assertIn('Rename model SillyModel to RenamedModel', out.getvalue())
+
+ @mock.patch('builtins.input', return_value='Y')
+ def test_makemigrations_field_rename_interactive(self, mock_input):
+ class SillyModel(models.Model):
+ silly_rename = models.BooleanField(default=False)
+
+ class Meta:
+ app_label = 'migrations'
+
+ with self.temporary_migration_module(
+ module='migrations.test_migrations_no_default',
+ ):
+ with captured_stdout() as out:
+ call_command('makemigrations', 'migrations', interactive=True)
+ self.assertIn(
+ 'Rename field silly_field on sillymodel to silly_rename',
+ out.getvalue(),
+ )
+
def test_makemigrations_handle_merge(self):
"""
makemigrations properly merges the conflicting migrations with --noinput.
@@ -1581,6 +1620,7 @@ class MakeMigrationsTests(MigrationTestBase):
class SillyModel(models.Model):
silly_field = models.BooleanField(default=False)
silly_date = models.DateField() # Added field without a default
+ silly_auto_now = models.DateTimeField(auto_now_add=True)
class Meta:
app_label = "migrations"
diff --git a/tests/migrations/test_questioner.py b/tests/migrations/test_questioner.py
index 9ab7756ab5..57749ed912 100644
--- a/tests/migrations/test_questioner.py
+++ b/tests/migrations/test_questioner.py
@@ -18,12 +18,9 @@ class QuestionerTests(SimpleTestCase):
questioner = MigrationQuestioner()
self.assertIs(False, questioner.ask_initial('migrations'))
- @mock.patch('builtins.input', return_value='datetime.timedelta(days=1)')
- def test_timedelta_default(self, mock):
- questioner = InteractiveMigrationQuestioner()
- with captured_stdout():
- value = questioner._ask_default()
- self.assertEqual(value, datetime.timedelta(days=1))
+ def test_ask_not_null_alteration(self):
+ questioner = MigrationQuestioner()
+ self.assertIsNone(questioner.ask_not_null_alteration('field_name', 'model_name'))
@mock.patch('builtins.input', return_value='2')
def test_ask_not_null_alteration_not_provided(self, mock):
@@ -31,3 +28,61 @@ class QuestionerTests(SimpleTestCase):
with captured_stdout():
question = questioner.ask_not_null_alteration('field_name', 'model_name')
self.assertEqual(question, NOT_PROVIDED)
+
+
+class QuestionerHelperMethodsTests(SimpleTestCase):
+ questioner = InteractiveMigrationQuestioner()
+
+ @mock.patch('builtins.input', return_value='datetime.timedelta(days=1)')
+ def test_questioner_default_timedelta(self, mock_input):
+ questioner = InteractiveMigrationQuestioner()
+ with captured_stdout():
+ value = questioner._ask_default()
+ self.assertEqual(value, datetime.timedelta(days=1))
+
+ @mock.patch('builtins.input', return_value='')
+ def test_questioner_default_no_user_entry(self, mock_input):
+ with captured_stdout():
+ value = self.questioner._ask_default(default='datetime.timedelta(days=1)')
+ self.assertEqual(value, datetime.timedelta(days=1))
+
+ @mock.patch('builtins.input', side_effect=['', 'exit'])
+ def test_questioner_no_default_no_user_entry(self, mock_input):
+ with captured_stdout() as stdout, self.assertRaises(SystemExit):
+ self.questioner._ask_default()
+ self.assertIn(
+ "Please enter some code, or 'exit' (without quotes) to exit.",
+ stdout.getvalue(),
+ )
+
+ @mock.patch('builtins.input', side_effect=['bad code', 'exit'])
+ def test_questioner_no_default_bad_user_entry_code(self, mock_input):
+ with captured_stdout() as stdout, self.assertRaises(SystemExit):
+ self.questioner._ask_default()
+ self.assertIn('Invalid input: unexpected EOF while parsing', stdout.getvalue())
+
+ @mock.patch('builtins.input', side_effect=['', 'n'])
+ def test_questioner_no_default_no_user_entry_boolean(self, mock_input):
+ with captured_stdout():
+ value = self.questioner._boolean_input('Proceed?')
+ self.assertIs(value, False)
+
+ @mock.patch('builtins.input', return_value='')
+ def test_questioner_default_no_user_entry_boolean(self, mock_input):
+ with captured_stdout():
+ value = self.questioner._boolean_input('Proceed?', default=True)
+ self.assertIs(value, True)
+
+ @mock.patch('builtins.input', side_effect=[10, 'garbage', 1])
+ def test_questioner_bad_user_choice(self, mock_input):
+ question = 'Make a choice:'
+ with captured_stdout() as stdout:
+ value = self.questioner._choice_input(question, choices='abc')
+ expected_msg = (
+ f'{question}\n'
+ f' 1) a\n'
+ f' 2) b\n'
+ f' 3) c\n'
+ )
+ self.assertIn(expected_msg, stdout.getvalue())
+ self.assertEqual(value, 1)