mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 02:15:10 +00:00 
			
		
		
		
	 391659b3da
			
		
	
	
		391659b3da
		
			
		
	
	
	
	
		
			
			Add test annotations required to run the test suite on iOS (PEP 730). The majority of the change involve annotating tests that use subprocess, but are skipped on Emscripten/WASI for other reasons, and including iOS/tvOS/watchOS under the same umbrella as macOS/darwin checks. `is_apple` and `is_apple_mobile` test helpers have been added to identify *any* Apple platform, and "any Apple platform except macOS", respectively.
		
			
				
	
	
		
			175 lines
		
	
	
	
		
			6.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			175 lines
		
	
	
	
		
			6.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| "Test InteractiveConsole and InteractiveInterpreter from code module"
 | |
| import sys
 | |
| import unittest
 | |
| from textwrap import dedent
 | |
| from contextlib import ExitStack
 | |
| from unittest import mock
 | |
| from test.support import import_helper
 | |
| 
 | |
| 
 | |
| code = import_helper.import_module('code')
 | |
| 
 | |
| 
 | |
| class MockSys:
 | |
| 
 | |
|     def mock_sys(self):
 | |
|         "Mock system environment for InteractiveConsole"
 | |
|         # use exit stack to match patch context managers to addCleanup
 | |
|         stack = ExitStack()
 | |
|         self.addCleanup(stack.close)
 | |
|         self.infunc = stack.enter_context(mock.patch('code.input',
 | |
|                                           create=True))
 | |
|         self.stdout = stack.enter_context(mock.patch('code.sys.stdout'))
 | |
|         self.stderr = stack.enter_context(mock.patch('code.sys.stderr'))
 | |
|         prepatch = mock.patch('code.sys', wraps=code.sys, spec=code.sys)
 | |
|         self.sysmod = stack.enter_context(prepatch)
 | |
|         if sys.excepthook is sys.__excepthook__:
 | |
|             self.sysmod.excepthook = self.sysmod.__excepthook__
 | |
|         del self.sysmod.ps1
 | |
|         del self.sysmod.ps2
 | |
| 
 | |
| 
 | |
| class TestInteractiveConsole(unittest.TestCase, MockSys):
 | |
| 
 | |
|     def setUp(self):
 | |
|         self.console = code.InteractiveConsole()
 | |
|         self.mock_sys()
 | |
| 
 | |
|     def test_ps1(self):
 | |
|         self.infunc.side_effect = EOFError('Finished')
 | |
|         self.console.interact()
 | |
|         self.assertEqual(self.sysmod.ps1, '>>> ')
 | |
|         self.sysmod.ps1 = 'custom1> '
 | |
|         self.console.interact()
 | |
|         self.assertEqual(self.sysmod.ps1, 'custom1> ')
 | |
| 
 | |
|     def test_ps2(self):
 | |
|         self.infunc.side_effect = EOFError('Finished')
 | |
|         self.console.interact()
 | |
|         self.assertEqual(self.sysmod.ps2, '... ')
 | |
|         self.sysmod.ps1 = 'custom2> '
 | |
|         self.console.interact()
 | |
|         self.assertEqual(self.sysmod.ps1, 'custom2> ')
 | |
| 
 | |
|     def test_console_stderr(self):
 | |
|         self.infunc.side_effect = ["'antioch'", "", EOFError('Finished')]
 | |
|         self.console.interact()
 | |
|         for call in list(self.stdout.method_calls):
 | |
|             if 'antioch' in ''.join(call[1]):
 | |
|                 break
 | |
|         else:
 | |
|             raise AssertionError("no console stdout")
 | |
| 
 | |
|     def test_syntax_error(self):
 | |
|         self.infunc.side_effect = ["undefined", EOFError('Finished')]
 | |
|         self.console.interact()
 | |
|         for call in self.stderr.method_calls:
 | |
|             if 'NameError' in ''.join(call[1]):
 | |
|                 break
 | |
|         else:
 | |
|             raise AssertionError("No syntax error from console")
 | |
| 
 | |
|     def test_sysexcepthook(self):
 | |
|         self.infunc.side_effect = ["raise ValueError('')",
 | |
|                                     EOFError('Finished')]
 | |
|         hook = mock.Mock()
 | |
|         self.sysmod.excepthook = hook
 | |
|         self.console.interact()
 | |
|         self.assertTrue(hook.called)
 | |
| 
 | |
|     def test_banner(self):
 | |
|         # with banner
 | |
|         self.infunc.side_effect = EOFError('Finished')
 | |
|         self.console.interact(banner='Foo')
 | |
|         self.assertEqual(len(self.stderr.method_calls), 3)
 | |
|         banner_call = self.stderr.method_calls[0]
 | |
|         self.assertEqual(banner_call, ['write', ('Foo\n',), {}])
 | |
| 
 | |
|         # no banner
 | |
|         self.stderr.reset_mock()
 | |
|         self.infunc.side_effect = EOFError('Finished')
 | |
|         self.console.interact(banner='')
 | |
|         self.assertEqual(len(self.stderr.method_calls), 2)
 | |
| 
 | |
|     def test_exit_msg(self):
 | |
|         # default exit message
 | |
|         self.infunc.side_effect = EOFError('Finished')
 | |
|         self.console.interact(banner='')
 | |
|         self.assertEqual(len(self.stderr.method_calls), 2)
 | |
|         err_msg = self.stderr.method_calls[1]
 | |
|         expected = 'now exiting InteractiveConsole...\n'
 | |
|         self.assertEqual(err_msg, ['write', (expected,), {}])
 | |
| 
 | |
|         # no exit message
 | |
|         self.stderr.reset_mock()
 | |
|         self.infunc.side_effect = EOFError('Finished')
 | |
|         self.console.interact(banner='', exitmsg='')
 | |
|         self.assertEqual(len(self.stderr.method_calls), 1)
 | |
| 
 | |
|         # custom exit message
 | |
|         self.stderr.reset_mock()
 | |
|         message = (
 | |
|             'bye! \N{GREEK SMALL LETTER ZETA}\N{CYRILLIC SMALL LETTER ZHE}'
 | |
|             )
 | |
|         self.infunc.side_effect = EOFError('Finished')
 | |
|         self.console.interact(banner='', exitmsg=message)
 | |
|         self.assertEqual(len(self.stderr.method_calls), 2)
 | |
|         err_msg = self.stderr.method_calls[1]
 | |
|         expected = message + '\n'
 | |
|         self.assertEqual(err_msg, ['write', (expected,), {}])
 | |
| 
 | |
| 
 | |
|     def test_cause_tb(self):
 | |
|         self.infunc.side_effect = ["raise ValueError('') from AttributeError",
 | |
|                                     EOFError('Finished')]
 | |
|         self.console.interact()
 | |
|         output = ''.join(''.join(call[1]) for call in self.stderr.method_calls)
 | |
|         expected = dedent("""
 | |
|         AttributeError
 | |
| 
 | |
|         The above exception was the direct cause of the following exception:
 | |
| 
 | |
|         Traceback (most recent call last):
 | |
|           File "<console>", line 1, in <module>
 | |
|         ValueError
 | |
|         """)
 | |
|         self.assertIn(expected, output)
 | |
| 
 | |
|     def test_context_tb(self):
 | |
|         self.infunc.side_effect = ["try: ham\nexcept: eggs\n",
 | |
|                                     EOFError('Finished')]
 | |
|         self.console.interact()
 | |
|         output = ''.join(''.join(call[1]) for call in self.stderr.method_calls)
 | |
|         expected = dedent("""
 | |
|         Traceback (most recent call last):
 | |
|           File "<console>", line 1, in <module>
 | |
|         NameError: name 'ham' is not defined
 | |
| 
 | |
|         During handling of the above exception, another exception occurred:
 | |
| 
 | |
|         Traceback (most recent call last):
 | |
|           File "<console>", line 2, in <module>
 | |
|         NameError: name 'eggs' is not defined
 | |
|         """)
 | |
|         self.assertIn(expected, output)
 | |
| 
 | |
| 
 | |
| class TestInteractiveConsoleLocalExit(unittest.TestCase, MockSys):
 | |
| 
 | |
|     def setUp(self):
 | |
|         self.console = code.InteractiveConsole(local_exit=True)
 | |
|         self.mock_sys()
 | |
| 
 | |
|     @unittest.skipIf(sys.flags.no_site, "exit() isn't defined unless there's a site module")
 | |
|     def test_exit(self):
 | |
|         # default exit message
 | |
|         self.infunc.side_effect = ["exit()"]
 | |
|         self.console.interact(banner='')
 | |
|         self.assertEqual(len(self.stderr.method_calls), 2)
 | |
|         err_msg = self.stderr.method_calls[1]
 | |
|         expected = 'now exiting InteractiveConsole...\n'
 | |
|         self.assertEqual(err_msg, ['write', (expected,), {}])
 | |
| 
 | |
| 
 | |
| if __name__ == "__main__":
 | |
|     unittest.main()
 |