| # A test suite for pdb; not very comprehensive at the moment. |
| |
| import imp |
| import sys |
| |
| from test import support |
| # This little helper class is essential for testing pdb under doctest. |
| from test.test_doctest import _FakeInput |
| |
| |
| class PdbTestInput(object): |
| """Context manager that makes testing Pdb in doctests easier.""" |
| |
| def __init__(self, input): |
| self.input = input |
| |
| def __enter__(self): |
| self.real_stdin = sys.stdin |
| sys.stdin = _FakeInput(self.input) |
| |
| def __exit__(self, *exc): |
| sys.stdin = self.real_stdin |
| |
| |
| def test_pdb_displayhook(): |
| """This tests the custom displayhook for pdb. |
| |
| >>> def test_function(foo, bar): |
| ... import pdb; pdb.Pdb().set_trace() |
| ... pass |
| |
| >>> with PdbTestInput([ |
| ... 'foo', |
| ... 'bar', |
| ... 'for i in range(5): print(i)', |
| ... 'continue', |
| ... ]): |
| ... test_function(1, None) |
| > <doctest test.test_pdb.test_pdb_displayhook[0]>(3)test_function() |
| -> pass |
| (Pdb) foo |
| 1 |
| (Pdb) bar |
| (Pdb) for i in range(5): print(i) |
| 0 |
| 1 |
| 2 |
| 3 |
| 4 |
| (Pdb) continue |
| """ |
| |
| |
| def test_pdb_skip_modules(): |
| """This illustrates the simple case of module skipping. |
| |
| >>> def skip_module(): |
| ... import string |
| ... import pdb; pdb.Pdb(skip=['stri*']).set_trace() |
| ... string.capwords('FOO') |
| |
| >>> with PdbTestInput([ |
| ... 'step', |
| ... 'continue', |
| ... ]): |
| ... skip_module() |
| > <doctest test.test_pdb.test_pdb_skip_modules[0]>(4)skip_module() |
| -> string.capwords('FOO') |
| (Pdb) step |
| --Return-- |
| > <doctest test.test_pdb.test_pdb_skip_modules[0]>(4)skip_module()->None |
| -> string.capwords('FOO') |
| (Pdb) continue |
| """ |
| |
| |
| # Module for testing skipping of module that makes a callback |
| mod = imp.new_module('module_to_skip') |
| exec('def foo_pony(callback): x = 1; callback(); return None', mod.__dict__) |
| |
| |
| def test_pdb_skip_modules_with_callback(): |
| """This illustrates skipping of modules that call into other code. |
| |
| >>> def skip_module(): |
| ... def callback(): |
| ... return None |
| ... import pdb; pdb.Pdb(skip=['module_to_skip*']).set_trace() |
| ... mod.foo_pony(callback) |
| |
| >>> with PdbTestInput([ |
| ... 'step', |
| ... 'step', |
| ... 'step', |
| ... 'step', |
| ... 'step', |
| ... 'continue', |
| ... ]): |
| ... skip_module() |
| ... pass # provides something to "step" to |
| > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(5)skip_module() |
| -> mod.foo_pony(callback) |
| (Pdb) step |
| --Call-- |
| > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(2)callback() |
| -> def callback(): |
| (Pdb) step |
| > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(3)callback() |
| -> return None |
| (Pdb) step |
| --Return-- |
| > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(3)callback()->None |
| -> return None |
| (Pdb) step |
| --Return-- |
| > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(5)skip_module()->None |
| -> mod.foo_pony(callback) |
| (Pdb) step |
| > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[1]>(10)<module>() |
| -> pass # provides something to "step" to |
| (Pdb) continue |
| """ |
| |
| |
| def test_pdb_continue_in_bottomframe(): |
| """Test that "continue" and "next" work properly in bottom frame (issue #5294). |
| |
| >>> def test_function(): |
| ... import pdb, sys; inst = pdb.Pdb() |
| ... inst.set_trace() |
| ... inst.botframe = sys._getframe() # hackery to get the right botframe |
| ... print(1) |
| ... print(2) |
| ... print(3) |
| ... print(4) |
| |
| >>> with PdbTestInput([ |
| ... 'next', |
| ... 'break 7', |
| ... 'continue', |
| ... 'next', |
| ... 'continue', |
| ... 'continue', |
| ... ]): |
| ... test_function() |
| > <doctest test.test_pdb.test_pdb_continue_in_bottomframe[0]>(4)test_function() |
| -> inst.botframe = sys._getframe() # hackery to get the right botframe |
| (Pdb) next |
| > <doctest test.test_pdb.test_pdb_continue_in_bottomframe[0]>(5)test_function() |
| -> print(1) |
| (Pdb) break 7 |
| Breakpoint 1 at <doctest test.test_pdb.test_pdb_continue_in_bottomframe[0]>:7 |
| (Pdb) continue |
| 1 |
| 2 |
| > <doctest test.test_pdb.test_pdb_continue_in_bottomframe[0]>(7)test_function() |
| -> print(3) |
| (Pdb) next |
| 3 |
| > <doctest test.test_pdb.test_pdb_continue_in_bottomframe[0]>(8)test_function() |
| -> print(4) |
| (Pdb) continue |
| 4 |
| """ |
| |
| |
| def pdb_invoke(method, arg): |
| """Run pdb.method(arg).""" |
| import pdb; getattr(pdb, method)(arg) |
| |
| |
| def test_pdb_run_with_incorrect_argument(): |
| """Testing run and runeval with incorrect first argument. |
| |
| >>> pti = PdbTestInput(['continue',]) |
| >>> with pti: |
| ... pdb_invoke('run', lambda x: x) |
| Traceback (most recent call last): |
| TypeError: exec() arg 1 must be a string, bytes or code object |
| |
| >>> with pti: |
| ... pdb_invoke('runeval', lambda x: x) |
| Traceback (most recent call last): |
| TypeError: eval() arg 1 must be a string, bytes or code object |
| """ |
| |
| |
| def test_pdb_run_with_code_object(): |
| """Testing run and runeval with code object as a first argument. |
| |
| >>> with PdbTestInput(['step','x', 'continue']): |
| ... pdb_invoke('run', compile('x=1', '<string>', 'exec')) |
| > <string>(1)<module>() |
| (Pdb) step |
| --Return-- |
| > <string>(1)<module>()->None |
| (Pdb) x |
| 1 |
| (Pdb) continue |
| |
| >>> with PdbTestInput(['x', 'continue']): |
| ... x=0 |
| ... pdb_invoke('runeval', compile('x+1', '<string>', 'eval')) |
| > <string>(1)<module>()->None |
| (Pdb) x |
| 1 |
| (Pdb) continue |
| """ |
| |
| |
| def test_main(): |
| from test import test_pdb |
| support.run_doctest(test_pdb, verbosity=True) |
| |
| |
| if __name__ == '__main__': |
| test_main() |