tests.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import sys
  2. import unittest
  3. from unittest import mock
  4. from django import __version__
  5. from django.core.management import CommandError, call_command
  6. from django.test import SimpleTestCase
  7. from django.test.utils import captured_stdin, captured_stdout
  8. class ShellCommandTestCase(SimpleTestCase):
  9. script_globals = 'print("__name__" in globals())'
  10. script_with_inline_function = (
  11. 'import django\n'
  12. 'def f():\n'
  13. ' print(django.__version__)\n'
  14. 'f()'
  15. )
  16. def test_command_option(self):
  17. with self.assertLogs('test', 'INFO') as cm:
  18. call_command(
  19. 'shell',
  20. command=(
  21. 'import django; from logging import getLogger; '
  22. 'getLogger("test").info(django.__version__)'
  23. ),
  24. )
  25. self.assertEqual(cm.records[0].getMessage(), __version__)
  26. def test_command_option_globals(self):
  27. with captured_stdout() as stdout:
  28. call_command('shell', command=self.script_globals)
  29. self.assertEqual(stdout.getvalue().strip(), 'True')
  30. def test_command_option_inline_function_call(self):
  31. with captured_stdout() as stdout:
  32. call_command('shell', command=self.script_with_inline_function)
  33. self.assertEqual(stdout.getvalue().strip(), __version__)
  34. @unittest.skipIf(sys.platform == 'win32', "Windows select() doesn't support file descriptors.")
  35. @mock.patch('django.core.management.commands.shell.select')
  36. def test_stdin_read(self, select):
  37. with captured_stdin() as stdin, captured_stdout() as stdout:
  38. stdin.write('print(100)\n')
  39. stdin.seek(0)
  40. call_command('shell')
  41. self.assertEqual(stdout.getvalue().strip(), '100')
  42. @unittest.skipIf(
  43. sys.platform == 'win32',
  44. "Windows select() doesn't support file descriptors.",
  45. )
  46. @mock.patch('django.core.management.commands.shell.select') # [1]
  47. def test_stdin_read_globals(self, select):
  48. with captured_stdin() as stdin, captured_stdout() as stdout:
  49. stdin.write(self.script_globals)
  50. stdin.seek(0)
  51. call_command('shell')
  52. self.assertEqual(stdout.getvalue().strip(), 'True')
  53. @unittest.skipIf(
  54. sys.platform == 'win32',
  55. "Windows select() doesn't support file descriptors.",
  56. )
  57. @mock.patch('django.core.management.commands.shell.select') # [1]
  58. def test_stdin_read_inline_function_call(self, select):
  59. with captured_stdin() as stdin, captured_stdout() as stdout:
  60. stdin.write(self.script_with_inline_function)
  61. stdin.seek(0)
  62. call_command('shell')
  63. self.assertEqual(stdout.getvalue().strip(), __version__)
  64. @mock.patch('django.core.management.commands.shell.select.select') # [1]
  65. @mock.patch.dict('sys.modules', {'IPython': None})
  66. def test_shell_with_ipython_not_installed(self, select):
  67. select.return_value = ([], [], [])
  68. with self.assertRaisesMessage(CommandError, "Couldn't import ipython interface."):
  69. call_command('shell', interface='ipython')
  70. @mock.patch('django.core.management.commands.shell.select.select') # [1]
  71. @mock.patch.dict('sys.modules', {'bpython': None})
  72. def test_shell_with_bpython_not_installed(self, select):
  73. select.return_value = ([], [], [])
  74. with self.assertRaisesMessage(CommandError, "Couldn't import bpython interface."):
  75. call_command('shell', interface='bpython')
  76. # [1] Patch select to prevent tests failing when when the test suite is run
  77. # in parallel mode. The tests are run in a subprocess and the subprocess's
  78. # stdin is closed and replaced by /dev/null. Reading from /dev/null always
  79. # returns EOF and so select always shows that sys.stdin is ready to read.
  80. # This causes problems because of the call to select.select() toward the
  81. # end of shell's handle() method.