def test_optional(): s = spec_from(HasOptional) assert assert_spec(s, {'k': 123}) == {'k': 123} assert assert_spec(s, {'k': None}) == {'k': None} check_spec_error(s, {'k': "not an int"}, "not an int")
def test_assert(): s = specize(int) assert_spec(s, 1) try: assert_spec(s, "one") assert False, "Expected exception" except SpecError as e: error = e assert error.explanation == Explanation.with_problems(Problem(path(), "one", s, "expected an int but got a str"))
def test_generic_typevars_unconstrained_bound(): s = spec_from(BoundGeneric) d = assert_spec(s, {'t': 123, 'v': 'string'}) assert d == {'t': 123, 'v': 'string'} check_spec_error(s, {'t': "not an int", 'v': 'string'}, "not an int")
def test_lists_of_forward_references(): s = spec_from(HasListsOfForwardReference) d = assert_spec(s, {'k': [{'k': []}]}) assert d == {'k': [{'k': []}]} check_spec_error(s, {'k': ["not a NeedsForwardReference"]}, "not a NeedsForwardReference")
def test_forward_references(): s = spec_from(HasForwardReference) d = assert_spec(s, {'k': {'k': None}}) assert d == {'k': {'k': None}} check_spec_error(s, {'k': "not a NeedsForwardReference"}, "not a NeedsForwardReference")
def test_list(): s = spec_from(HasList) d = assert_spec(s, {'k': [123, 456]}) assert d == {'k': [123, 456]} check_spec_error(s, {'k': ["not an int"]}, "not an int")
def test_primitives(): s = spec_from(JustPrimitive) d = assert_spec(s, {'k': 123}) assert d == {'k': 123} check_spec_error(s, {'k': "not an int"}, "not an int")
def test_classvar_should_never_appear(): s = spec_from(HasClassVar) d = assert_spec(s, {}) assert d == {} check_spec_error(s, {'a': 123}, "ClassVar") check_spec_error(s, {'a': "wrong type doesn't matter"}, "ClassVar")
def test_non_generic_class_with_typevar_annotations(): s = spec_from(NonGenericWithTypevars) d = assert_spec(s, {'a': 123, 'b': 456}) assert d == {'a': 123, 'b': 456} # Need to ensure all annotations marked with unbound generic V # are of the same type int_T = 123 str_T = "mooooo" check_spec_error(s, {'a': int_T, 'b': str_T}, str_T)
def test_generic_typevars_unconstrained_unbound(): s = spec_from(UnboundGeneric) d = assert_spec(s, {'t': 123, 'v': "V type", 'another_v': "V type"}) assert d == {'t': 123, 'v': "V type", 'another_v': "V type"} # Should not conform if all annotations marked with unbound generic V # are not of the same type int_V = 123 str_V = "mooooo" check_spec_error(s, {'t': 123, 'v': int_V, 'another_v': str_V}, str_V)
def test_coll_of(): item_spec = specize(int) s = coll_of(item_spec) check_spec(s, [1]) check_spec(s, [1, 2]) check_spec(s, (1, 2)) try: assert_spec(s, ["one", 2, "three"]) assert False, "Expected exception" except SpecError as e: error = e assert error.explanation == Explanation.with_problems( Problem(path(0), "one", item_spec, "expected an int but got a str"), Problem(path(2), "three", item_spec, "expected an int but got a str")) try: assert_spec(s, 1) assert False, "Expected exception" except SpecError as e: error = e assert error.explanation == Explanation.with_problems(Problem(path(), 1, s, "not iterable"))
def check_spec_error(s, value, expected_error_text): try: assert_spec(s, value) assert False, "Expected exception" except SpecError as e: assert expected_error_text in str(e)
def test_any(): s = spec_from(HasAny) d = assert_spec(s, {'a': "Whatever"}) assert d == {'a': "Whatever"}