def test_differing_field_lengths(self): assert format_summary( compare_sources("foo(a, b)", "foo(a, b, c, d)", Identical())) == ( "2 extra values in implementation's args (in reference code, " "line 1 col 7 and implementation code, line 1 col 13)") assert format_summary( compare_sources("foo(a, b, c)", "foo(a, b)", Identical())) == ( "1 extra value in reference's args (in reference code, " "line 1 col 10 and implementation code, line 1 col 7)")
def test_syntax_errors(self): # NB: Syntax error reported column numbers differ depending on the # python interpreter used. with pytest.raises(ComparisonError) as exc_info: compare_sources("1 +/", "", Identical()) assert (re.match( r"invalid syntax \(in reference code, line 1 col [34]\)", format_summary(exc_info.value), ) is not None) with pytest.raises(ComparisonError) as exc_info: compare_sources("", "1 +/", Identical()) assert (re.match( r"invalid syntax \(in implementation code, line 1 col [34]\)", format_summary(exc_info.value), ) is not None)
def test_same(self): assert (compare_sources( ("def foo(a, b, c):\n" " return a + b + c\n"), ("def foo(a,b,c): return a+b+c\n"), Identical(), ) is True)
def test_unclosed_not_in_spec_block(self): # Can only occur in implementation code since these come from # undo_amendments with pytest.raises(ComparisonError) as exc_info: compare_sources("", "## Begin not in spec", Identical()) assert format_summary(exc_info.value) == ( "'## Begin not in spec' block not closed (in implementation code, line 1)" )
def test_bad_amendment_comment(self): # Can only occur in implementation code since these come from # undo_amendments with pytest.raises(ComparisonError) as exc_info: compare_sources("", "## Foobar", Identical()) assert format_summary( exc_info.value) == ("Unrecognised amendment comment '## Foobar' " "(in implementation code, line 1 col 0)")
def test_tokenisation_errors(self): # Can only occur in implementation code since these come from # undo_amendments with pytest.raises(ComparisonError) as exc_info: compare_sources("", "[", Identical()) assert format_summary(exc_info.value) == ( "EOF in multi-line statement (in implementation code, line 2 col 0)" )
def test_ammendments_not_applied_to_reference(self): assert (compare_sources( ("def foo(a, b, c):\n" " print(a, b, c) ## Not in spec\n" " return a + b + c\n"), ("def foo(a, b, c):\n" " return a + b + c\n"), Identical(), ) is not True)
def test_amendment_makes_same(self): assert (compare_sources( ("def foo(a, b, c):\n" " return a + b + c\n"), ("def foo(a, b, c):\n" " print(a, b, c) ## Not in spec\n" " return a + b + c\n"), Identical(), ) is True)
def test_equivalence_of_vc2_pseudocode(name, pseudocode_derived_function): ref_func = getattr(reference_pseudocode, name) imp_func = pseudocode_derived_function.function # Same function assert compare_functions(ref_func, imp_func, Identical()) is True # Same reference to the spec expected_ref = "({})".format(pseudocode_derived_function.section) assert ref_func.__doc__.lstrip().startswith(expected_ref)
def test_differing_node_types(self): assert format_summary( compare_sources( ("def foo(a, b):\n" " return a + b\n"), ("def foo(a, b): return a - b\n"), Identical(), )) == ( "Mismatched Add vs. Sub (in reference code, line 2 col 10 and " "implementation code, line 1 col 22)")
def test_different(self): match = compare_functions(f1, f3, Identical()) assert match is not True assert match.message == "Mismatched Add vs. Sub" assert match.ref_row == 3 assert match.ref_col == 11 assert match.imp_row == 5 assert match.imp_col == 11 assert match.ref_func is f1 assert match.imp_func is f3
def test_parse_error(self): with pytest.raises(ComparisonError) as exc_info: compare_functions(f1, f4, Identical()) assert ( exc_info.value.message == "Unrecognised amendment comment '## Invalid amendment comment'") assert exc_info.value.ref_row is None assert exc_info.value.ref_col is None assert exc_info.value.imp_row == 2 assert exc_info.value.imp_col == 4 assert exc_info.value.ref_func is f1 assert exc_info.value.imp_func is f4
def test_allow_swapping_literals_for_named_constants(self): c = Identical() n1 = ast.parse("13") n2 = ast.parse("PARSE_INFO_HEADER_BYTES") n3 = ast.parse("0x10") n4 = ast.parse("ParseCodes.end_of_sequence") n5 = ast.parse("ParseCodes.end_of_sequence.value") assert c.compare(n1, n2) is True assert c.compare(n2, n1) is not True assert c.compare(n3, n2) is not True assert c.compare(n3, n4) is True assert c.compare(n3, n5) is True assert c.compare(n4, n3) is not True assert c.compare(n5, n3) is not True
def test_allow_differing_decorators_and_docstrings(self): c = Identical() n1 = ast.parse("def func(arg1, args2): return 123") n2 = ast.parse("@ref_pseudocode('1.2.3')\n" "def func(arg1, args2):\n" " '''Docs'''\n" " return 123") n3 = ast.parse("def func(arg1, args2): return 321") n4 = ast.parse("def func(arg1, args2):\n '''Doc'''\n return 123") assert c.compare(n1, n1) is True assert c.compare(n1, n2) is True assert c.compare(n1, n4) is True assert c.compare(n4, n1) is True # Different return value assert c.compare(n2, n3) is not True # First value not allowed to contain extra decorators (only second one # may have which may be ignored decorators) assert c.compare(n2, n1) is not True
def test_same(self): assert compare_functions(f1, f2, Identical()) is True
def test_differing_field_values(self): assert format_summary(compare_sources( "a + b", "a+cde", Identical())) == ( "Different id values (in reference code, line 1 col 4 and " "implementation code, line 1 col 2)")