def test_check_by_class(self): simplefs(self.root, FOO_CLASS) with add_to_pypath(self.root): retcode, lines, _ = call_check(["foo.Fooey"]) self.assertEqual(retcode, 1) self.assertEqual(len(lines), 1) self.assertIn("foo.py:4: error: false when calling incr", lines[0])
def test_check_by_module(self): simplefs(self.root, SIMPLE_FOO) with add_to_pypath(self.root): retcode, lines = call_check(['foo']) self.assertEqual(retcode, 2) self.assertEqual(len(lines), 1) self.assertIn('foo.py:3:error:false when calling foofn', lines[0])
def test_diff_behavior_via_main(self): simplefs(self.root, SIMPLE_FOO) try: sys.stdout = io.StringIO() with add_to_pypath(self.root), self.assertRaises(SystemExit) as ctx: unwalled_main(["diffbehavior", "foo.foofn", "foo.foofn"]) self.assertEqual(0, ctx.exception.code) finally: out = sys.stdout.getvalue() sys.stdout = sys.__stdout__ self.assertRegex(out, "No differences found")
def test_diff_behavior_via_main(self): simplefs(self.root, SIMPLE_FOO) sys.stdout = io.StringIO() try: with add_to_pypath(self.root): self.assertEqual( 0, unwalled_main(["diffbehavior", "foo.foofn", "foo.foofn"]) ) finally: out = sys.stdout.getvalue() sys.stdout = sys.__stdout__ self.assertRegex(out, "No differences found")
def test_diff_behavior_same(self): simplefs(self.root, SIMPLE_FOO) with add_to_pypath(self.root): retcode, lines = call_diffbehavior("foo.foofn", str(self.root / "foo.py:2")) self.assertEqual( lines, [ "No differences found. (attempted 2 iterations)", "All paths exhausted, functions are likely the same!", ], ) self.assertEqual(retcode, 0)
def unwalled_main(cmd_args: Union[List[str], argparse.Namespace]) -> int: parser = command_line_parser() if isinstance(cmd_args, argparse.Namespace): args = cmd_args else: args = parser.parse_args(cmd_args) if not args.action: parser.print_help(sys.stderr) return 2 set_debug(args.verbose) debug("Installed plugins:", installed_plugins) options = option_set_from_dict(args.__dict__) # fall back to current directory to look up modules with add_to_pypath(*([""] if sys.path and sys.path[0] != "" else [])): if args.action == "check": return check(args, options, sys.stdout, sys.stderr) elif args.action == "diffbehavior": defaults = DEFAULT_OPTIONS.overlay( AnalysisOptionSet( per_condition_timeout=2.5, per_path_timeout= 30.0, # mostly, we don't want to time out paths )) return diffbehavior(args, defaults.overlay(options), sys.stdout, sys.stderr) elif args.action == "cover": defaults = DEFAULT_OPTIONS.overlay( AnalysisOptionSet( per_condition_timeout=2.5, per_path_timeout= 30.0, # mostly, we don't want to time out paths )) return cover(args, defaults.overlay(options), sys.stdout, sys.stderr) elif args.action == "watch": return watch(args, options) else: print(f'Unknown action: "{args.action}"', file=sys.stderr) return 2
def test_diff_behavior_different(self): simplefs( self.root, { "foo.py": """ def add(x: int, y: int) -> int: return x + y def faultyadd(x: int, y: int) -> int: return 42 if (x, y) == (10, 10) else x + y """ }, ) with add_to_pypath(self.root): retcode, lines = call_diffbehavior("foo.add", "foo.faultyadd") self.assertEqual(retcode, 1) self.assertEqual( lines, [ "Given: (x=10, y=10),", " foo.add : returns 20", " foo.faultyadd : returns 42", ], )
def test_check_nonexistent_member(self): simplefs(self.root, OUTER_INNER) with add_to_pypath(self.root): self.assertRaises(NotFound, lambda: call_check(['outer.inner.nonexistent']))
def test_check_by_package(self): simplefs(self.root, OUTER_INNER) with add_to_pypath(self.root): retcode, lines = call_check(['outer.inner.foofn']) self.assertEqual(retcode, 0) self.assertEqual(len(lines), 0)
def test_package_directives(tmp_path: Path): simplefs(tmp_path, DIRECTIVES_TREE) with add_to_pypath(tmp_path): innermod = importlib.import_module("pkg1.pkg2.pkg3.mod") assert collect_options(innermod) == AnalysisOptionSet( enabled=True, max_iterations=5, per_condition_timeout=42)
def test_diff_behavior_targeting_error(self): simplefs(self.root, SIMPLE_FOO) with add_to_pypath(self.root): retcode, lines = call_diffbehavior("foo.foofn", "foo") self.assertEqual(retcode, 2) self.assertEqual(lines, ['"foo" does not target a function.'])
def test_check_circular_with_guard(self): simplefs(self.root, CIRCULAR_WITH_GUARD) with add_to_pypath(self.root): retcode, lines, _ = call_check([join(self.root, "first.py")]) self.assertEqual(retcode, 0)
def test_cover(tmp_path: Path, capsys: pytest.CaptureFixture[str]): simplefs(tmp_path, SIMPLE_FOO) with add_to_pypath(str(tmp_path)): assert unwalled_main(["cover", "foo.foofn"]) == 0 assert capsys.readouterr().out == "foofn(0)\n"