import sys import unittest from unittest import mock from django import __version__ from django.core.management import CommandError, call_command from django.test import SimpleTestCase from django.test.utils import captured_stdin, captured_stdout, patch_logger class ShellCommandTestCase(SimpleTestCase): def test_command_option(self): with patch_logger('test', 'info') as logger: call_command( 'shell', command=( 'import django; from logging import getLogger; ' 'getLogger("test").info(django.__version__)' ), ) self.assertEqual(len(logger), 1) self.assertEqual(logger[0], __version__) @unittest.skipIf(sys.platform == 'win32', "Windows select() doesn't support file descriptors.") @mock.patch('django.core.management.commands.shell.select') def test_stdin_read(self, select): with captured_stdin() as stdin, captured_stdout() as stdout: stdin.write('print(100)\n') stdin.seek(0) call_command('shell') self.assertEqual(stdout.getvalue().strip(), '100') @mock.patch('django.core.management.commands.shell.select.select') # [1] @mock.patch.dict('sys.modules', {'IPython': None}) def test_shell_with_ipython_not_installed(self, select): select.return_value = ([], [], []) with self.assertRaisesMessage(CommandError, "Couldn't import ipython interface."): call_command('shell', interface='ipython') @mock.patch('django.core.management.commands.shell.select.select') # [1] @mock.patch.dict('sys.modules', {'bpython': None}) def test_shell_with_bpython_not_installed(self, select): select.return_value = ([], [], []) with self.assertRaisesMessage(CommandError, "Couldn't import bpython interface."): call_command('shell', interface='bpython') # [1] Patch select to prevent tests failing when when the test suite is run # in parallel mode. The tests are run in a subprocess and the subprocess's # stdin is closed and replaced by /dev/null. Reading from /dev/null always # returns EOF and so select always shows that sys.stdin is ready to read. # This causes problems because of the call to select.select() towards the # end of shell's handle() method.