def test_assign_assignment(): code = """\ a = b = 2 """ expected_report = """\ a = b = 2 """ tracer = TraceRunner() report = tracer.trace_code(code) assert expected_report == trim_report(report)
def test_assign_generator_unpacked(): code = """\ a, b = (3*i for i in range(2)) """ expected_report = """\ (a, b) = (0, 3) """ tracer = TraceRunner() report = tracer.trace_code(code) assert expected_report == trim_report(report)
def test_assign_tuple_list(): code = """\ a, [b, c] = (1, (2, 3)) """ expected_report = """\ (a, (b, c)) = (1, (2, 3)) """ tracer = TraceRunner() report = tracer.trace_code(code) assert expected_report == trim_report(report)
def test_docstring(): code = """\ '' """ expected_report = """\ """ tracer = TraceRunner() report = tracer.trace_code(code) assert expected_report == trim_report(report)
def test_infinite_loop_pass(): code = """\ while True: pass """ expected_report = """\ RuntimeError: live coding message limit exceeded""" tracer = TraceRunner() tracer.message_limit = 3 report = tracer.trace_code(code) assert report in (expected_report + '\n', '\n' + expected_report)
def test_loop_target_list(): code = """\ for a,b in [(1,2)]: c = a + b """ expected_report = """\ a = 1 | b = 2 c = 3""" tracer = TraceRunner() report = tracer.trace_code(code) assert report == expected_report
def test_numpy_random(): code = """\ import numpy as np x = np.random.normal(size=3) """ tracer = TraceRunner() original_report = tracer.trace_code(code) for _ in range(5): report = tracer.trace_code(code) assert original_report == report
def test_assign_starred(): code = """\ a, *b = (1, 2, 3) print(b) """ expected_report = """\ (a, *b) = (1, 2, 3) print('[2, 3]') """ tracer = TraceRunner() report = tracer.trace_code(code) assert expected_report == trim_report(report)
def test_runtime_error(): code = """\ x = 2 raise RuntimeError('Bad stuff happened.') """ expected_report = """\ x = 2 RuntimeError: Bad stuff happened. """ tracer = TraceRunner() report = tracer.trace_code(code) assert expected_report == trim_report(report)
def test_call_on_literal(self): # SETUP code = """\ s = 'abc'.replace('a', 'A') """ expected_report = """\ s = 'Abc' """ tracer = TraceRunner() # EXEC report = tracer.trace_code(code) # VERIFY self.assertReportEqual(expected_report, report)
def test_print(): code = """\ s = 'x' print(s) """ expected_report_python = """\ s = 'x' print('x') """ expected_report = expected_report_python tracer = TraceRunner() report = tracer.trace_code(code) assert expected_report == trim_report(report)
def test_lambda(self): # SETUP code = """\ f = lambda n: n + 1 x = f(10) """ expected_report = """\ (10 => 11) x = 11 """ tracer = TraceRunner() # EXEC report = tracer.trace_code(code) # VERIFY self.assertReportEqual(expected_report, report)
def test_loop_starred_target_list(): code = """\ words = ['foo', 'bar'] for (head, *tail) in words: print(head, tail) """ expected_report = """\ words = ['foo', 'bar'] head = 'f' | tail = ['o', 'o'] | head = 'b' | tail = ['a', 'r'] print("f ['o', 'o']") | print("b ['a', 'r']")""" tracer = TraceRunner() report = tracer.trace_code(code) assert report == expected_report
def test_command_line(): """ Specify a traced method with command-line option --traced. """ code = """\ def foo(n): s = 'x' for i in range(n): s += 'y' return s def bar(num): s = 'a' for i in range(num): s += 'b' return s print(foo(3)) print(bar(3)) """ expected_report = """\ def bar(num): | num = 3 s = 'a' | s = 'a' for i in range(num): | i = 0 | i = 1 | i = 2 s += 'b' | s = 'ab' | s = 'abb' | s = 'abbb' return s | return 'abbb'""" with replace_input(code): report = TraceRunner().trace_command([ 'space_tracer', '--traced', '__main__.bar', '--traced_file', 'example.py', 'example.py' ]) assert expected_report == report
def test_attribute_decorator(): """ The decorator is a module attribute. """ code = """\ from __future__ import print_function class Foo(object): def foo(self, x): return x + 1 @__builtins__.staticmethod def bar(x): return x + 2 f = Foo() print(f.foo(10)) print(f.bar(20)) """ expected_report = """\ from __future__ import print_function | class Foo(object): | def foo(self, x): | x = 10 return x + 1 | return 11 | @__builtins__.staticmethod | def bar(x): | x = 20 return x + 2 | return 22 | f = Foo() | print(f.foo(10)) | print('11') print(f.bar(20)) | print('22')""" with replace_input(code): report = TraceRunner().trace_command( ['space_tracer', '--traced_file', 'example.py', 'example.py']) assert expected_report == report
def test_other_decorator(): """ Other decorators shouldn't affect tracing. """ code = """\ from __future__ import print_function class Foo(object): def foo(self, x): return x + 1 @staticmethod def bar(x): return x + 2 f = Foo() print(f.foo(10)) print(f.bar(20)) """ expected_report = """\ from __future__ import print_function | class Foo(object): | def foo(self, x): | x = 10 return x + 1 | return 11 | @staticmethod | def bar(x): | x = 20 return x + 2 | return 22 | f = Foo() | print(f.foo(10)) | print('11') print(f.bar(20)) | print('22')""" with replace_input(code): report = TraceRunner().trace_command( ['space_tracer', '--traced_file', 'example.py', 'example.py']) assert expected_report == report
def test_delete_attribute(self): code = """\ class Foo(object): def __init__(self, name=None): self.name = name def __repr__(self): name = getattr(self, 'name', None) if name is None: return 'Foo()' return 'Foo({!r})'.format(name) f = Foo('Bob') del f.name g = f """ expected_report = """\ name = 'Bob' self.name = 'Bob' f = Foo('Bob') f = Foo() g = Foo() """ report = TraceRunner().trace_code(code) self.assertReportEqual(expected_report, report)
def test_random(self): code = """\ from random import randint i = randint(1, 100) j = randint(1, 100) """ if sys.version_info < (3, 0): expected_report = """\ i = 85 j = 76 """ else: expected_report = """\ i = 50 j = 98 """ report = TraceRunner().trace_code(code) self.assertReportEqual(expected_report, report)
def test_traced_driver_environment(): code = '''\ try: sys.exit("Sys exists, but it wasn't imported!") except NameError: pass sys = None # Would mess up driver script if they shared module name spaces. def foo(x): return x + 20 ''' expected_report = '''\ NameError: name 'sys' is not defined sys = None x = 42 return 62''' with replace_input(code): report = TraceRunner().trace_command([ 'space_tracer', '--source_width', '0', '--traced_file', EXAMPLE_SOURCE_PATH, '--traced', 'example_source', EXAMPLE_DRIVER_PATH ]) assert report == expected_report
def test_module_in_package(self): code = """\ from unittest import TestCase class FooTest(TestCase): def test_foo(self): s = __package__ self.assertEqual('example_package', s) """ expected_report = """\ s = 'example_package' """ with replace_input(code): report = TraceRunner().trace_command([ 'space_tracer', '--source_width', '0', '--traced', 'example_package.lib_in_package', '--traced_file', EXAMPLE_LIB_PATH, '-m', 'unittest', 'example_package.lib_in_package' ]) self.assertReportEqual(expected_report, report)
def test_repr_unnamed_mock(): code = """\ from unittest.mock import Mock m = Mock() """ expected_report = """\ m = Mock() """ tracer = TraceRunner() report = tracer.trace_code(code) assert trim_report(expected_report) == trim_report(report)
def test_mutable(): code = """\ a = [1, 2, [3, 4]] a[0] = 9 a[2][1] = 8 b = a i, j = 2, 1 a[i][j] = 7 a[0:2] = list(reversed(a[0:2])) b = a d = -1 a[i:j:d] = [100] b = a """ expected_report = """\ a = [1, 2, [3, 4]] a[0] = 9 a[2][1] = 8 b = [9, 2, [3, 8]] (i, j) = (2, 1) a[2][1] = 7 a[0:2] = [2, 9] b = [2, 9, [3, 7]] d = -1 a[2:1:-1] = [100] b = [2, 9, 100] """ report = TraceRunner().trace_code(code) assert trim_report(expected_report) == trim_report(report)
def test_line_numbers_live(): code = """\ def foo(n): s = 'x' for i in range(n): s += 'y' return s print(foo(3)) """ expected_report = """\ def foo(n): | s = 'x' | for i in range(n): | i = 0 | i = 1 | i = 2 s += 'y' | s = 'xy' | s = 'xyy' | s = 'xyyy' return s | return 'xyyy' | print(foo(3)) |""" with replace_input(code): report = TraceRunner().trace_command([ 'space_tracer', '--start_line', '3', '--end_line', '5', '--live', '--traced_file', 'example.py', 'example.py' ]) assert report == expected_report
def test_empty(self): # EXEC report = TraceRunner().trace_code("") expected_report = "" # VERIFY self.assertReportEqual(expected_report, report)
def test_yield_from(self): # SETUP code = """\ def foo(n): yield 10 + n yield 20 + n def bar(): for i in range(2): yield from foo(i) for x in bar(): pass """ expected_report = """\ n = 0 | n = 1 yield 10 | yield 11 yield 20 | yield 21 i = 0 | i = 1 yield 10 | yield 20 | yield 11 | yield 21 x = 10 | x = 20 | x = 11 | x = 21 | | | """ # EXEC report = TraceRunner().trace_code(code) # VERIFY self.assertReportEqual(expected_report, report)
def test_no_driver(capsys): expected_error = ('space_tracer: error: one of the following arguments ' 'are required: driver or traced_file') with pytest.raises(SystemExit): TraceRunner().trace_command(['space_tracer']) error = capsys.readouterr().err.splitlines()[-1] assert error == expected_error
def test_bad_driver_for_traced_file_without_traced(): code = '''\ def foo(n): return n + 20 ''' expected_report = '''\ --------------------------------------------------------------------------- | example_driver.py doesn't call example_printing.py. Try a different driver. | --------------------------------------------------------------------------- | ''' with replace_input(code): report = TraceRunner().trace_command([ 'space_tracer', '--traced_file', EXAMPLE_PRINTING_PATH, EXAMPLE_DRIVER_PATH ]) assert report == expected_report
def test_infinite_loop_by_width(): code = """\ n = 0 while True: n += 1 """ expected_report = """\ n = 0 | | n = 1 | n = 2 | RuntimeError: live coding message limit exceeded""" tracer = TraceRunner() tracer.max_width = 20 report = tracer.trace_code(code) assert report == expected_report
def test_slice(): code = """\ a = [1, 2, 3, 4, 5] i, j = 1, 4 a[i:j] = [20, 30] b = a a[2:] = [300] b = a a[:2] *= 2 b = a a[:2] += [21] b = a """ expected_report = """\ a = [1, 2, 3, 4, 5] (i, j) = (1, 4) a[1:4] = [20, 30] b = [1, 20, 30, 5] a[2:] = [300] b = [1, 20, 300] a[:2] *= 2 b = [1, 20, 1, 20, 300] a[:2] += [21] b = [1, 20, 21, 1, 20, 300] """ report = TraceRunner().trace_code(code) assert trim_report(expected_report) == trim_report(report)
def test_infinite_loop_pass(self): # SETUP code = """\ while True: pass """ expected_report = """\ RuntimeError: live coding message limit exceeded """ tracer = TraceRunner() tracer.message_limit = 3 # EXEC report = tracer.trace_code(code) # VERIFY self.assertReportEqual(expected_report, report)