def test_totally_empty(self): """ SimpleReporter should be fine if two packages are totally empty. """ reporter = SimpleReporter( pkgs=[PackageAPI(PACKAGE_EMPTY), PackageAPI(PACKAGE_EMPTY2)], errors_allowed=0) reporter._check_function_args() self.assertTrue(reporter.errors == [])
def test_same_names(self): """ PackageCollection should reject attempts to add two packages with the same name """ self.assertRaisesRegex( ValueError, "All packages provided to PackageCollection must have unique names", lambda: PackageCollection(packages=[ PackageAPI.from_json(self.py_pkg_file), PackageAPI.from_json(self.py_pkg_file) ]))
def test_identical_functions(self): """ SimpleReporter should not create any errors if the shared function is the same in both packages. """ reporter = SimpleReporter( pkgs=[PackageAPI(BASE_PACKAGE), PackageAPI(BASE_PACKAGE2)], errors_allowed=0) reporter._check_function_args() errors = reporter.errors self.assertTrue(len(errors) == 0, )
def test_works_with_ten_packages(self): """ SimpleReporter should work correctly if you have ten packages (yes I know this is extreme) """ pkgs = [ PackageAPI(BASE_PACKAGE_WITH_CLASSES), PackageAPI(PACKAGE_WITH_DIFFERENT_PM_ARG_ORDER), PackageAPI(PACKAGE_WITH_DIFFERENT_PM_ARG_NUMBER) ] for i in range(7): new_pkg = copy.deepcopy(BASE_PACKAGE_WITH_CLASSES) new_pkg['name'] = 'test_package_' + str(i) pkgs.append(PackageAPI(new_pkg)) reporter = SimpleReporter(pkgs=pkgs, errors_allowed=100) # SimpleReporter has a sys.exit() in it. Mock that out def f(): pass reporter._respond = f # check packages reporter.compare() # This check (exactly 3 errors) is important. To be sure # that other problems aren't getting silenced by short-circuiting self.assertTrue(len(reporter.errors) == 3) self.assertTrue(len(reporter.pkgs) == 10) # at least one should be the number-of-arguments error self.assertTrue( any([ bool(re.search('differing number of arguments', err.msg)) for err in reporter.errors ])) # at least one should be the some-args-not-shared self.assertTrue( any([ bool(re.search('some arguments are not shared', err.msg)) for err in reporter.errors ])) # at least one should be the different-order one self.assertTrue( any([ bool(re.search('differing order of keyword arguments', err.msg)) for err in reporter.errors ]))
def test_works_with_three_packages(self): """ SimpleReporter should work correctly if you have three packages """ reporter = SimpleReporter( pkgs=[ PackageAPI(BASE_PACKAGE_WITH_CLASSES), PackageAPI(PACKAGE_WITH_DIFFERENT_PM_ARG_ORDER), PackageAPI(PACKAGE_WITH_DIFFERENT_PM_ARG_NUMBER), ], errors_allowed=100, ) # SimpleReporter has a sys.exit() in it. Mock that out def f(): pass reporter._respond = f # check packages reporter.compare() # This check (exactly 3 errors) is important. To be sure # that other problems aren't getting silenced by short-circuiting self.assertTrue(len(reporter.errors) == 3) self.assertTrue(len(reporter.pkgs) == 3) # at least one should be the number-of-arguments error self.assertTrue( any([ bool(re.search("differing number of arguments", err.msg)) for err in reporter.errors ])) # at least one should be the some-args-not-shared self.assertTrue( any([ bool(re.search("some arguments are not shared", err.msg)) for err in reporter.errors ])) # at least one should be the different-order one self.assertTrue( any([ bool(re.search("differing order of keyword arguments", err.msg)) for err in reporter.errors ]))
def test_function_all_wrong(self): """ SimpleReporter should throw 3 errors if one package has a function with different args, more args and different order. """ reporter = SimpleReporter(pkgs=[ PackageAPI(BASE_PACKAGE), PackageAPI(PACKAGE_SUPER_DIFFERENT) ], errors_allowed=100) reporter._check_function_args() errors = reporter.errors self.assertTrue(len(errors) == 3, ) self.assertTrue(all([isinstance(x, DoppelTestError) for x in errors])) self.assertTrue(errors[0].msg.startswith( "Function 'playback()' exists in all packages but with differing number of arguments" ))
def test_smoke_test(self): """ SimpleReporter should run end-to-end without error """ reporter = SimpleReporter(pkgs=[ PackageAPI(PACKAGE_BEEFY), PackageAPI(PACKAGE_SUPER_DIFFERENT) ], errors_allowed=100) # SimpleReporter has a sys.exit() in it. Mock that out def f(): pass reporter._respond = f # check packages reporter.compare() self.assertTrue(True)
def test_public_method_arg_order(self): """ SimpleReporter should catch errors of the form 'this function has the same keyword args in both packages but they are in different orders' """ reporter = SimpleReporter(pkgs=[ PackageAPI(BASE_PACKAGE_WITH_CLASSES), PackageAPI(PACKAGE_WITH_DIFFERENT_PM_ARG_ORDER) ], errors_allowed=100) reporter._check_class_public_method_args() errors = reporter.errors self.assertTrue(len(errors) == 1, ) self.assertTrue(all([isinstance(x, DoppelTestError) for x in errors])) self.assertTrue( errors[0].msg == "Public method 'no_days_off()' on class 'WaleFolarin' exists in all packages but with differing order of keyword arguments." )
def test_public_method_arg_number(self): """ SimpleReporter should catch the condition where public method implementations (same method, same class) in two packages have different number of keyword arguments """ reporter = SimpleReporter(pkgs=[ PackageAPI(BASE_PACKAGE_WITH_CLASSES), PackageAPI(PACKAGE_WITH_DIFFERENT_PM_ARG_NUMBER) ], errors_allowed=100) reporter._check_class_public_method_args() errors = reporter.errors self.assertTrue(len(errors) == 3, ) self.assertTrue(all([isinstance(x, DoppelTestError) for x in errors])) self.assertTrue( errors[0].msg == "Public method 'no_days_off()' on class 'WaleFolarin' exists in all packages but with differing number of arguments (2,3)." )
def test_different_public_methods(self): """ SimpleReporter should handle the case where a class exists in both packages, with the same number of public methods, but with different methods. """ reporter = SimpleReporter( pkgs=[ PackageAPI(PACKAGE_DIFFERENT_METHODS_1), PackageAPI(PACKAGE_DIFFERENT_METHODS_2), ], errors_allowed=2, ) reporter._check_class_public_methods() errors = reporter.errors self.assertTrue(len(errors) == 2) self.assertTrue(all([isinstance(x, DoppelTestError) for x in errors])) self.assertTrue(errors[0].msg.startswith( "Not all implementations of class 'SomeClass' have public method"))
def test_function_arg_order(self): """ SimpleReporter should catch errors of the form 'this function has the same keyword args in both packages but they are in different orders' """ reporter = SimpleReporter(pkgs=[ PackageAPI(BASE_PACKAGE), PackageAPI(PACKAGE_WITH_DIFFERENT_ARG_ORDER) ], errors_allowed=100) reporter._check_function_args() errors = reporter.errors self.assertTrue(len(errors) == 1, ) self.assertTrue(all([isinstance(x, DoppelTestError) for x in errors])) self.assertTrue( errors[0].msg == "Function 'playback()' exists in all packages but with differing order of keyword arguments." )
def test_function_arg_number(self): """ SimpleReporter should catch the condition where function implementations in two packages have different number of keyword arguments. """ reporter = SimpleReporter(pkgs=[ PackageAPI(BASE_PACKAGE), PackageAPI(PACKAGE_WITH_DIFFERENT_ARG_NUMBER) ], errors_allowed=100) reporter._check_function_args() errors = reporter.errors self.assertTrue(len(errors) == 3, ) self.assertTrue(all([isinstance(x, DoppelTestError) for x in errors])) self.assertTrue( errors[0].msg == "Function 'playback()' exists in all packages but with differing number of arguments (2,3)." )
def test_function_args(self): """ SimpleReporter should catch the condition where function implementations in two packages have different different arguments (even if they have the same number of arguments) """ reporter = SimpleReporter(pkgs=[ PackageAPI(BASE_PACKAGE), PackageAPI(PACKAGE_WITH_DIFFERENT_ARGS) ], errors_allowed=100) reporter._check_function_args() errors = reporter.errors self.assertTrue(len(errors) == 2, ) self.assertTrue(all([isinstance(x, DoppelTestError) for x in errors])) self.assertTrue( errors[0].msg == "Function 'playback()' exists in all packages but some arguments are not shared in all implementations." )
def test_other_smoke_test(self): """ SimpleReporter should run end-to-end without error. This test compares a package to itself (to get basic coverage of code that works on shared classes and functions) """ reporter = SimpleReporter( pkgs=[PackageAPI(PACKAGE_BEEFY), PackageAPI(PACKAGE_BEEFY2)], errors_allowed=100) # SimpleReporter has a sys.exit() in it. Mock that out def f(): pass reporter._respond = f # check packages reporter.compare() self.assertTrue(True)
def test_public_method_args(self): """ SimpleReporter should catch the condition where public method implementations (same method, same class) in two packages have different different arguments (even if they have the same number of arguments) """ reporter = SimpleReporter( pkgs=[ PackageAPI(BASE_PACKAGE_WITH_CLASSES), PackageAPI(PACKAGE_WITH_DIFFERENT_PM_ARGS), ], errors_allowed=100, ) reporter._check_class_public_method_args() errors = reporter.errors self.assertTrue(len(errors) == 2) self.assertTrue(all([isinstance(x, DoppelTestError) for x in errors])) expected_message = ( "Public method 'no_days_off()' on class 'WaleFolarin' exists in " "all packages but some arguments are not shared in all implementations." ) self.assertTrue(errors[0].msg == expected_message)
def test_works_with_one_package(self): """ SimpleReporter should not return any errors if you only use a single package """ reporter = SimpleReporter(pkgs=[PackageAPI(BASE_PACKAGE_WITH_CLASSES)], errors_allowed=0) # SimpleReporter has a sys.exit() in it. Mock that out def f(): pass reporter._respond = f # check packages reporter.compare() self.assertTrue(len(reporter.pkgs) == 1) self.assertTrue(reporter.errors == [])
def test_from_json_py(self): """ PackageAPI.from_json() should work for Python packages """ pkg = PackageAPI.from_json(self.py_pkg_file) self.assertEqual(pkg.name(), 'boombap [python]') self.assertEqual(pkg.num_functions(), 1) self.assertEqual(pkg.function_names(), ['playback']) self.assertEqual(pkg.functions_with_args(), {'playback': { 'args': ['bpm', 'bass'] }}) self.assertEqual(pkg.num_classes(), 1) self.assertEqual(pkg.class_names(), ["LupeFiasco"]) self.assertEqual(pkg.public_methods("LupeFiasco"), ["coast", "~~CONSTRUCTOR~~"]) self.assertEqual( pkg.public_method_args("LupeFiasco", "~~CONSTRUCTOR~~"), ["kick", "push"]) self.assertEqual(pkg.public_method_args("LupeFiasco", "coast"), [])
def test_from_json_r(self): """ PackageAPI.from_json() should work for R packages """ pkg = PackageAPI.from_json(self.r_pkg_file) self.assertEqual(pkg.name(), "boombap [r]") self.assertEqual(pkg.num_functions(), 1) self.assertEqual(pkg.function_names(), ["playback"]) self.assertEqual(pkg.functions_with_args(), {"playback": { "args": ["bpm", "bass"] }}) self.assertEqual(pkg.num_classes(), 1) self.assertEqual(pkg.class_names(), ["LupeFiasco"]) self.assertEqual(pkg.public_methods("LupeFiasco"), ["coast", "words", "~~CONSTRUCTOR~~"]) self.assertEqual( pkg.public_method_args("LupeFiasco", "~~CONSTRUCTOR~~"), ["kick", "push"]) self.assertEqual(pkg.public_method_args("LupeFiasco", "coast"), []) self.assertEqual(pkg.public_method_args("LupeFiasco", "words"), ["i_said", "i_never_said"])
def setUp(self): self.pkg_collection = PackageCollection(packages=[ PackageAPI.from_json(self.py_pkg_file), PackageAPI.from_json(self.r_pkg_file), ])