def test_infinite_loop_before_traced_block(): code = """\ from space_tracer import traced def foo(): while True: pass @traced def bar(n): s = 'a' for i in range(n): s += 'b' return s foo() print(bar(3)) """ expected_report = """\ from space_tracer import traced | -------------------------------- | | Traced blocks were never called. | | -------------------------------- |""" tracer = TraceRunner() tracer.message_limit = 20 with replace_input(code): report = tracer.trace_command( ['space_tracer', '--traced_file', 'example.py', 'example.py']) assert report == expected_report
def test_traced_function_not_called(): code = """\ from space_tracer import traced def foo(n): s = 'x' for i in range(n): s += 'y' return s @traced def bar(n): s = 'a' for i in range(n): s += 'b' return s print(foo(3)) """ expected_report = """\ from space_tracer import traced | -------------------------------- | | Traced blocks were never called. | | -------------------------------- |""" tracer = TraceRunner() with replace_input(code): report = tracer.trace_command( ['space_tracer', '--traced_file', 'example.py', 'example.py']) assert report == expected_report
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_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_hide_garbage(): """ Not a string or iterable collection of strings, ignore it. """ code = """\ from space_tracer import traced @traced(hide=42) def foo(n): s = 'x' for i in range(n): s += 'y' return s print(foo(3)) """ expected_report = """\ @traced(hide=42) | def foo(n): | n = 3 s = 'x' | 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'""" with replace_input(code): report = TraceRunner().trace_command([ 'space_tracer', '--source_indent', '4', '--traced_file', 'example.py', 'example.py' ]) assert report == expected_report
def test_hide_from_command_line(): code = """\ from space_tracer import traced def foo(n): s = 'x' for i in range(n): s += 'y' return s print(foo(3)) """ expected_report = """\ def foo(n): | s = 'x' | s = 'x' for i in range(n): | | | s += 'y' | s = 'xy' | s = 'xyy' | s = 'xyyy' return s | return 'xyyy'""" with replace_input(code): report = TraceRunner().trace_command([ 'space_tracer', '--source_indent', '4', '--traced', 'foo', '--hide', 'n', 'i', '--traced_file', 'example.py', 'example.py' ]) assert report == expected_report
def test_traced_renamed(): code = """\ from space_tracer import traced as space_traced @space_traced def foo(n): s = 'x' for i in range(n): s += 'y' return s print(foo(3)) """ expected_report = """\ @space_traced | def foo(n): | n = 3 s = 'x' | 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' """ with replace_input(code): report = TraceRunner().trace_command([ 'space_tracer', '--source_indent', '4', '--traced_file', 'example.py', 'example.py' ]) assert trim_report(expected_report) == trim_report(report)
def test_traced_with_block(): code = """\ from space_tracer import traced def foo(n): s = 'x' with traced(): t = 23 for i in range(n): s += 'y' return s print(foo(3)) """ expected_report = """\ with traced(): | t = 23 | t = 23 for i in range(n): | i = 0 | i = 1 | i = 2 s += 'y' | s = 'xy' | s = 'xyy' | s = 'xyyy'""" with replace_input(code): report = TraceRunner().trace_command( ['space_tracer', '--traced_file', 'example.py', 'example.py']) assert report == expected_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_redirect_both(tmpdir): code = """\ import sys print('Hello,', file=sys.stderr) print(6*7) """ expected_report = """\ sys.stderr.write('Hello,\\n') print('42')""" expected_redirect = """\ Hello, 42 """ out_path = tmpdir.join('out.txt') with replace_input(code): report = TraceRunner().trace_command([ 'space_tracer', '--stdout', str(out_path), '--stderr', str(out_path), '--source_width', '0', '--traced_file', 'example.py', 'example.py']) out_redirect = out_path.read_text('utf8') assert report == expected_report assert out_redirect == expected_redirect
def test_stdout_redirect(tmpdir): code = """\ print('Hello,') print(6*7) """ expected_report = """\ print('Hello,') print('42')""" expected_redirect = """\ Hello, 42 """ stdout_path = tmpdir.join('stdout.txt') with replace_input(code): report = TraceRunner().trace_command([ 'space_tracer', '--stdout', str(stdout_path), '--source_width', '0', '--traced_file', 'example.py', 'example.py']) stdout_redirect = stdout_path.read_text('utf8') assert report == expected_report assert stdout_redirect == expected_redirect
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_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_module_name(self): # SETUP code = """\ def foo(x): return x + 3 if __name__ == '__main__': y = foo(10) """ expected_report = """\ x = 10 return 13 y = 13 """ tracer = TraceRunner() # EXEC with replace_input(code): report = tracer.trace_command([ 'space_tracer', '--source_width', '0', '--traced_file', 'example.py', 'example.py' ]) # VERIFY self.assertReportEqual(expected_report, report)
def test_zoom_big(is_matplotlib_cleared): code = """\ import matplotlib.pyplot as plt f = plt.gcf() print(f.dpi) """ expected_report = """\ print('125.0')""" tracer = TraceRunner() with replace_input(code): report = tracer.trace_command(['space_tracer', '--traced_file', 'example.py', '--source_width', '0', '--live', '-x1200', '-y600', '--zoomed', 'example.py']) 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_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_one_function_live_mode(): """ Need to keep original vertical position to line up with editor. """ code = """\ from space_tracer import traced @traced 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 = """\ n = 3 s = 'x' i = 0 | i = 1 | i = 2 s = 'xy' | s = 'xyy' | s = 'xyyy' return 'xyyy' """ with replace_input(code): report = TraceRunner().trace_command([ 'space_tracer', '--source_width', '0', '--live', '--traced_file', 'example.py', 'example.py' ]) assert trim_report(expected_report) == trim_report(report)
def test_trace_width(): code = """\ i = 1 + 1 """ expected_report = """\ i = 1 + 1 | i =""" with replace_input(code): report = TraceRunner().trace_command(['space_tracer', '--trace_width', '15', '--traced_file', 'foo.py']) assert report == expected_report
def test_source_width_positive(): code = """\ i = 1 + 1 """ expected_report = """\ i = 1 + | i = 2""" with replace_input(code): report = TraceRunner().trace_command(['space_tracer', '--source_width', '8', '--traced_file', 'foo.py']) assert report == expected_report
def test_source_indent_negative(): code = """\ i = 1 + 1 """ expected_report = """\ = 1 + 1 | i = 2""" with replace_input(code): report = TraceRunner().trace_command(['space_tracer', '--source_indent', '-2', '--traced_file', 'foo.py']) assert report == expected_report
def test_default_input(tmpdir): code = "s = input()" expected_report = """\ EOFError: EOF when reading a line """ with replace_input(code): report = TraceRunner().trace_command([ 'space_tracer', '--source_width', '0', '--traced_file', 'example.py', 'example.py']) assert expected_report == trim_report(report)
def test_top_level_error(): code = '''\ exit('Failed') ''' expected_report = '''\ SystemExit: Failed''' with replace_input(code): report = TraceRunner().trace_command([ 'space_tracer', '--source_width', '0', '--traced_file', EXAMPLE_DRIVER_PATH, '--traced=__main__', EXAMPLE_DRIVER_PATH ]) assert report == expected_report
def test_trace_width_negative(): code = """\ i = 1 + 1 s = 'a' * 10 """ expected_report = """\ i = 1 + 1 | i = 2 s = 'a' * 10 | s = 'aaaaaa""" with replace_input(code): report = TraceRunner().trace_command(['space_tracer', '--trace_width', '-5', '--traced_file', 'foo.py']) assert report == expected_report
def test_traced_file_without_traced(): code = '''\ def foo(n): return n + 20 ''' expected_report = '''\ n = 42 return 62''' with replace_input(code): report = TraceRunner().trace_command([ 'space_tracer', '--source_width', '0', '--traced_file', EXAMPLE_SOURCE_PATH, EXAMPLE_DRIVER_PATH ]) assert report == expected_report
def test_relative_traced_file(): code = """\ def foo(x): return x + 100 """ expected_report = """\ def foo(x): | x = 42 return x + 100 | return 142""" relative_path = os.path.relpath(EXAMPLE_SOURCE_PATH, os.getcwd()) with replace_input(code): report = TraceRunner().trace_command([ 'space_tracer', '--traced_file', relative_path, EXAMPLE_DRIVER_PATH ]) assert report == expected_report
def test_show_line_numbers(): code = """\ a = 1 b = 2 print(a + b) """ expected_report = """\ 2) b = 2 | b = 2 3) print(a + b) | print('3')""" with replace_input(code): report = TraceRunner().trace_command([ 'space_tracer', '--start_line', '2', '--end_line', '3', '--line_numbers', '--traced_file', 'example.py', 'example.py' ]) assert report == expected_report
def test_two_functions(): code = """\ from space_tracer import traced @traced def foo(n): s = 'x' for i in range(n): s += 'y' return s @traced def bar(num): s = 'a' for i in range(num): s += 'b' return s print(foo(3)) print(bar(3)) """ expected_report = """\ @traced | def foo(n): | n = 3 s = 'x' | 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' @traced | 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', '--source_indent', '4', '--traced_file', 'example.py', 'example.py' ]) assert trim_report(expected_report) == trim_report(report)
def test_traced_decorator_in_another_file(): code = """\ import example_traced print('Done.') """ expected_report = """\ import example_traced | | print('Done.') | print('Done.')""" tracer = TraceRunner() with replace_input(code): report = tracer.trace_command( ['space_tracer', '--traced_file', 'example.py', 'example.py']) assert report == expected_report
def test_report_default(): code = """\ print('Hello,') print(6*7) """ expected_report = """\ print('Hello,') print('42')""" with replace_input(code): report = TraceRunner().trace_command([ 'space_tracer', '--report', '-', '--source_width', '0', '--traced_file', 'example.py', 'example.py']) assert report == expected_report