def test_exists(): must_exist = Exists() assert repr(must_exist) == 'must exist' with raises_regexp(ValidationError, 'must exist'): must_exist(MISSING) must_exist(None) must_exist(0) must_exist(False) must_exist('foo') must_exist([]) # negated must_not_exist = ~Exists() assert repr(must_not_exist) == 'must not exist' must_not_exist(MISSING) with raises_regexp(ValidationError, 'must not exist'): must_not_exist(None) with raises_regexp(ValidationError, 'must not exist'): must_not_exist('foo')
def test_custom_validators_in_dict_keys(self): # FIXME this is one of those cases where "human-readable" errors # are much less readable than "mechanical" ones (as before). # Can we do anything? day_note_schema = translate({ InRange(2000, 2020): { InRange(1, 12): { InRange(1, 31): str, }, }, }) good_note = {2013: {12: {9: 'it is a good day today'}}} bad_note1 = {1999: {12: {9: 'wrong year: below min'}}} bad_note2 = {2013: {13: {9: 'wrong month: above max'}}} bad_note3 = {2013: {12: {40: 'wrong day of month: above max'}}} day_note_schema(good_note) #with raises_regexp(InvalidKeys, '^1999$'): with raises_regexp(ValidationError, "^must not have keys like 1999$"): day_note_schema(bad_note1) #with raises_regexp(InvalidKeys, '^2013: 13$'): with raises_regexp(ValidationError, "^2013 value must not have keys like 13$"): day_note_schema(bad_note2) #with raises_regexp(InvalidKeys, '^2013: 12: 40$'): with raises_regexp( ValidationError, "^in 2013 \(12 value must not have keys like 40\)$"): day_note_schema(bad_note3)
def test_nonlinear_ancestry(self, empty_dendrifier): repo = empty_dendrifier.repo populate_repo(repo, ['.develop', '.', '.', '[', '.', '.', ']']) empty_dendrifier.dendrify('dendrified', 'develop', 'linear') pytest.raises_regexp(ValueError, 'ancestry of "dendrified" is not linear', empty_dendrifier.dendrify, 're-dendrified', 'develop', 'dendrified')
def test_list_of_all(): v = ListOfAll(IsA(str)) assert repr(v) == 'ListOfAll(must be str)' with raises_regexp(ValidationError, '^must be list$'): v('foo') with raises_regexp(ValidationError, '^lacks item: must be str$'): v([]) # positive v(['foo']) v(['foo', 'bar']) with raises_regexp(ValidationError, '^item #2: must be str$'): v(['foo', 'bar', 123]) # negated v = ~v with raises_regexp(ValidationError, '^~ListOfAll\(must be str\)$'): v(['foo']) with raises_regexp(ValidationError, '^~ListOfAll\(must be str\)$'): v(['foo', 'bar']) v(['foo', 'bar', 123])
def test_int_in_list(self): spec = ListOf(int) # outer value is missing with raises_regexp(ValidationError, 'must be list'): spec(None) # outer value is present, inner value is missing with raises_regexp(ValidationError, 'lacks item: must be int'): spec([]) # outer value is present, inner optional value is missing relaxed_spec = ListOf(int) | None relaxed_spec([]) # inner value is present but is None with raises_regexp(ValidationError, 'item #0: must be int'): spec([None]) # inner value is present spec([123]) # multiple inner values are present spec([123, 456]) # one of the inner values is of a wrong type with raises_regexp(ValidationError, 'item #1: must be int'): spec([123, 'bogus'])
def test_source_branch_does_not_exist_caught(self, empty_dendrifier): repo = empty_dendrifier.repo # Doesn't really matter that these branches are unrelated: dendrify.create_base(repo, 'test-base') pytest.raises_regexp(ValueError, 'source branch "linear" does not exist', empty_dendrifier.dendrify, 'dendrified', 'test-base', 'linear')
def test_int_in_list_in_dict_in_list_in_dict(self): spec = translate({'foo': [{'bar': [int]}]}) with raises_regexp(ValidationError, "'foo' value must be list"): spec({'foo': None}) with raises_regexp(ValidationError, "'foo' value item #0: 'bar' value must be list"): spec({'foo': [{'bar': None}]}) with raises_regexp(ValidationError, "'foo' value lacks item: must be dict"): spec({'foo': []}) with raises_regexp(ValidationError, "'foo' value item #0: 'bar' value lacks item: must be int"): spec({'foo': [{'bar': []}]}) spec({'foo': [{'bar': [1]}]}) spec({'foo': [{'bar': [1, 2]}]}) with raises_regexp(ValidationError, "'foo' value item #0: 'bar' value item #1: must be int"): spec({'foo': [{'bar': [1, 'bogus']}]})
def test_schemed_dict_in_list(self): spec = ListOf({'foo': int}) # dict in list: missing key with raises(ValidationError): spec([{}]) with raises_regexp(ValidationError, "item #1: must have keys: 'foo'"): spec([{'foo': 123}, {}]) # dict in list: missing value with raises_regexp(ValidationError, "item #0: 'foo' value must be int"): spec([{'foo': None}]) with raises_regexp(ValidationError, "item #1: 'foo' value must be int"): spec([{'foo': 123}, {'foo': None}]) # multiple innermost values are present spec([{'foo': 123}]) spec([{'foo': 123}, {'foo': 456}]) # one of the innermost values is of a wrong type with raises_regexp(ValidationError, "item #2: 'foo' value must be int"): spec([{'foo': 123}, {'foo': 456}, {'foo': 'bogus'}])
def test_int_in_list_in_dict_in_list_in_dict(self): spec = translate({'foo': [{'bar': [int]}]}) with raises_regexp(ValidationError, "'foo' value must be list"): spec({'foo': None}) with raises_regexp(ValidationError, "'foo' value item #0: 'bar' value must be list"): spec({'foo': [{'bar': None}]}) with raises_regexp(ValidationError, "'foo' value lacks item: must be dict"): spec({'foo': []}) with raises_regexp( ValidationError, "'foo' value item #0: 'bar' value lacks item: must be int"): spec({'foo': [{'bar': []}]}) spec({'foo': [{'bar': [1]}]}) spec({'foo': [{'bar': [1, 2]}]}) with raises_regexp( ValidationError, "'foo' value item #0: 'bar' value item #1: must be int"): spec({'foo': [{'bar': [1, 'bogus']}]})
def test_functional_syntax(): raises_regexp( ExpectedException, r"Args and kwargs raised: .*param1.*param4", function_to_test_with_args_and_kwargs, 'param1', 'param2', kwarg1='param3', kwarg2='param4' )
def test_pytest_raises_regexp(): def f(): raise ValueError('f') pytest.raises_regexp(ValueError, 'f', f) with pytest.raises_regexp(ValueError, 'f'): f()
def test_corrupt_index(self, tmpfile): with io.open(tmpfile, 'wb') as f: f.write(FORMAT_STRING) write_i64(f, FORMAT_VERSION) f.write(b'foo') pytest.raises_regexp(IOError, 'unable to read index', File, tmpfile)
def test_list_of_any(): v = ListOfAny(IsA(str)) assert repr(v) == 'ListOfAny(must be str)' with raises_regexp(ValidationError, '^must be list$'): v('foo') with raises_regexp(ValidationError, '^lacks item: must be str$'): v([]) # positive v(['foo']) v(['foo', 123]) with raises_regexp(ValidationError, '^item #0: must be str or item #1: must be str$'): v([123, 5.5]) # negated v = ~v with raises_regexp(ValidationError, '^~ListOfAny\(must be str\)$'): v(['foo']) with raises_regexp(ValidationError, '^~ListOfAny\(must be str\)$'): v(['foo', 123]) v([123, 5.5])
def test_custom_validators_in_dict_keys(self): # FIXME this is one of those cases where "human-readable" errors # are much less readable than "mechanical" ones (as before). # Can we do anything? day_note_schema = translate({ InRange(2000, 2020): { InRange(1, 12): { InRange(1, 31): str, }, }, }) good_note = {2013: {12: {9: 'it is a good day today'}}} bad_note1 = {1999: {12: {9: 'wrong year: below min'}}} bad_note2 = {2013: {13: {9: 'wrong month: above max'}}} bad_note3 = {2013: {12: {40: 'wrong day of month: above max'}}} day_note_schema(good_note) #with raises_regexp(InvalidKeys, '^1999$'): with raises_regexp(ValidationError, "^must not have keys like 1999$"): day_note_schema(bad_note1) #with raises_regexp(InvalidKeys, '^2013: 13$'): with raises_regexp(ValidationError, "^2013 value must not have keys like 13$"): day_note_schema(bad_note2) #with raises_regexp(InvalidKeys, '^2013: 12: 40$'): with raises_regexp(ValidationError, "^in 2013 \(12 value must not have keys like 40\)$"): day_note_schema(bad_note3)
def test_dendrified_ancestry_reaches_root(self, empty_dendrifier): repo = empty_dendrifier.repo populate_repo(repo, ['.develop', '.', '.', '[', '.', '.', ']']) empty_dendrifier.dendrify('dendrified', 'develop', 'linear') # Deliberately swap args so that base is not ancestor of branch: pytest.raises_regexp(ValueError, '"dendrified" is not an ancestor of "develop"', empty_dendrifier.linearize, 'linear-1', 'dendrified', 'develop')
def test_fail_on_write(self, tmpfile): with File(tmpfile, 'w') as f: f.write_json('a', 42) pytest.raises_regexp(ValueError, 'unable to serialize: invalid dtype', f.write_array, 'b', {}) with File(tmpfile) as f: assert list(f) == ['a'] assert f.read('a') == 42
def test_linear_ancestry_reaches_root(self, empty_dendrifier): repo = empty_dendrifier.repo populate_repo(repo, ['.develop', '.', '.']) # Deliberately swap args to linear_ancestry() such that the # 'base' is not an ancestor of the branch: pytest.raises_regexp(ValueError, '"linear" is not an ancestor of "develop"', empty_dendrifier.linear_ancestry, 'linear', 'develop')
def test_destination_branch_exists_caught(self, empty_dendrifier): repo = empty_dendrifier.repo # Doesn't really matter that these branches are unrelated: dendrify.create_base(repo, 'test-base') dendrify.create_base(repo, 'dendrified') dendrify.create_base(repo, 'linear') pytest.raises_regexp(ValueError, 'destination branch "dendrified" exists', empty_dendrifier.dendrify, 'dendrified', 'test-base', 'linear')
def test_invert_requirement(): says_hello = Equals('hello') says_hello('hello') with raises_regexp(ValidationError, "^must equal 'hello'$"): says_hello('bye') says_not_hello = ~says_hello with raises_regexp(ValidationError, "^not \(must equal 'hello'\)$"): says_not_hello('hello') says_not_hello('bye')
def test_mode_writable(self, tmpfile): raises_regexp(ValueError, 'invalid mode', File, tmpfile, 'foo') f1 = File(tmpfile) assert f1.mode == 'r' and not f1.writable f2 = File(tmpfile, 'w') assert f2.mode == 'r+' and f2.writable f3 = File(tmpfile, 'r') assert f3.mode == 'r' and not f3.writable f4 = File(tmpfile, 'r+') assert f4.mode == 'r+' and f4.writable
def test_void_tags(self, all_tags): for tag in all_tags: if tag['void']: with pytest.raises_regexp( Exception, 'not a container: {}'.format(tag['name'])): tag['cls']['foo'] with pytest.raises_regexp( Exception, 'not a container: {}'.format(tag['name'])): tag['cls']()['foo'] else: assert tag['cls']['foo', 'bar'] == tag['cls']()['foo', 'bar']
def test_combinator_all(): v = All([ Length(min=2), Length(max=3) ]) assert repr(v) == '(must have length of 2.. and must have length of ..3)' with raises_regexp(ValidationError, '^must have length of 2\.\.$'): v('f') v('fo') v('foo') with raises_regexp(ValidationError, '^must have length of \.\.3$'): v('fooo')
def test_list_with_opt_elem(self): v = translate([optional(str)]) with raises_regexp(ValidationError, 'must be list'): v(None) v([]) with raises_regexp(ValidationError, 'must be str or must not exist'): v([None]) v(['hi']) with raises_regexp(ValidationError, 'must be str'): v([1234])
def test_list_with_req_elem(self): v = translate([str]) with raises_regexp(ValidationError, 'must be list'): v(None) with raises_regexp(ValidationError, 'lacks item: must be str'): v([]) with raises_regexp(ValidationError, '#0: must be str'): v([None]) v(['hi']) with raises_regexp(ValidationError, '#0: must be str'): v([1234])
def test_read_into(self, tmpfile): arr = np.arange(6).reshape(2, 3) with File(tmpfile, 'w') as f: f.write_json('a', 42) f.write_array('b', arr) with File(tmpfile) as f: pytest.raises_regexp(ValueError, 'can only specify output for array values', f.read, 'a', out='foo') pytest.raises_regexp(TypeError, 'expected ndarray', f.read, 'b', out='foo') out = np.empty_like(arr) assert f.read('b', out=out) is out np.testing.assert_array_equal(out, arr)
def test_linearize_swapped_parents(self, empty_dendrifier): repo = empty_dendrifier.repo # Get repo started then manually create 'swapped' merge; we have to # try quite hard to arrange this as git tries quite hard to stop you # making that mistake. populate_repo(repo, ['.dev', '.', '.', '.'], branch_name='dendrified-0') feature_start_parent = repo.revparse_single('dev') tip = repo.revparse_single('dendrified-0') sig = dendrify.create_signature(repo) merge_oid = repo.create_commit(None, sig, sig, 'swapped merge test', tip.tree_id, [tip.oid, feature_start_parent.oid]) repo.create_branch('dendrified', repo[merge_oid]) pytest.raises_regexp(ValueError, 'expected .* to be pure merge', empty_dendrifier.linearize, 'linear', 'dev', 'dendrified')
def test_double_invert_requirement(): a = Equals('hello') a('hello') with raises_regexp(ValidationError, "^must equal 'hello'$"): a('bye') b = ~a with raises_regexp(ValidationError, "^not \(must equal 'hello'\)$"): b('hello') b('bye') c = ~b c('hello') with raises_regexp(ValidationError, "^must equal 'hello'$"): c('bye')
def test_typed_required(self): "A value of given type" spec = IsA(int) # value is present and matches datatype spec(1) # value is present but does not match datatype with raises_regexp(ValidationError, 'must be int'): spec('bogus') # value is missing with raises_regexp(ValidationError, 'must be int'): spec(None)
def test_typed_required_list(self): "A value of given type (list)" spec = IsA(list) # value is present spec([]) with raises_regexp(ValidationError, 'must be list'): spec('bogus') # value is missing with raises_regexp(ValidationError, 'must be list'): spec(None)
def test_contains(): v = Contains('tech') assert repr(v) == "must contain 'tech'" v('technology') v('Autechre') # wrong case with raises_regexp(ValidationError, "^must contain 'tech'$"): v('Technology') # wrong destiny with raises_regexp(ValidationError, "^must contain 'tech'$"): v('Arthur "Two Sheds" Jackson')
def test_invert_combinator(): hello_or_bye = Equals('hello') | Equals('bye') hello_or_bye('hello') hello_or_bye('bye') with raises_regexp(ValidationError, "^must equal 'hello' or must equal 'bye'$"): hello_or_bye('albatross!') neither_hello_nor_bye = ~hello_or_bye with raises_regexp(ValidationError, "^not \(must equal 'hello' or must equal 'bye'\)$"): neither_hello_nor_bye('hello') with raises_regexp(ValidationError, "^not \(must equal 'hello' or must equal 'bye'\)$"): neither_hello_nor_bye('bye') neither_hello_nor_bye('albatross!')
def test_invalid_key(self, tmpfile): f = File(tmpfile, 'w') pytest.raises_regexp(ValueError, 'invalid key: expected string', f.write_json, 42, 0) pytest.raises_regexp(ValueError, 'invalid key: empty string', f.write_json, '', 0) f.write_json('foo', 'bar') pytest.raises_regexp(ValueError, "key already exists: 'foo'", f.write_json, 'foo', 'baz') f.close() f = File(tmpfile) pytest.raises_regexp(ValueError, 'invalid key: expected string', f.read, 42) pytest.raises_regexp(KeyError, 'bar', f.read, 'bar')
def test_hasattr(): v = HasAttr('__len__') v('string does have length') with raises_regexp(ValidationError, "^must have attribute '__len__'$"): v(123)
def test_sign_request_path_error(): with pytest.raises_regexp(ValueError, 'The `path` parameter must always start with / \(forwardslash\)\.'): AWSV4Signer('access_key', 'secret_key').sign_request(None, None, None, 'bad_path')
def test_create_record_with_dup_field_name(self, builder): with pytest.raises_regexp( schema.SchemaParseException, "{0} already in use.".format(self.another_name)): builder.begin_record(self.name).add_field( self.another_name, builder.create_int()).add_field(self.another_name, builder.create_string()).end()
def test_combinator_edge_cases(): with raises_regexp(TypeError, 'got Exists class instead of its instance'): IsA(str) | Exists # translate() is applied to the right argument assert IsA(str) | 'Albatross!' == IsA(str) | IsA(str, default='Albatross!') assert IsA(str) | None == IsA(str) | Anything() assert Length(min=3) & [] == Length(min=3) & IsA(list)
def test_chunked_encoding_forbidden_for_http_10(): req = make_request('GET', '/', version=HttpVersion10) resp = StreamResponse() resp.enable_chunked_encoding() with pytest.raises_regexp( RuntimeError, "Using chunked encoding is forbidden for HTTP/1.0"): yield from resp.prepare(req)
def test_connector_loop(loop): with contextlib.ExitStack() as stack: another_loop = asyncio.new_event_loop() stack.enter_context(contextlib.closing(another_loop)) connector = TCPConnector(loop=another_loop) stack.enter_context(contextlib.closing(connector)) with pytest.raises_regexp(ValueError, "loop argument must agree with connector"): ClientSession(connector=connector, loop=loop)
def test_create_record_with_dup_name(self, builder): with pytest.raises_regexp(schema.SchemaParseException, self.duplicate_name_err.format(self.name)): builder.begin_record(self.another_name).add_field( 'bar1', builder.begin_enum( self.name, self.enum_symbols).end()).add_field( 'bar2', builder.begin_record(self.name).end()).end()
def test_translate_list(): assert translate(list) == IsA(list) assert translate([]) == IsA(list) assert translate([int]) == ListOf(IsA(int)) assert translate([1]) == ListOf(IsA(int, default=1)) with raises_regexp(StructureSpecificationError, 'Expected a list containing exactly 1 item; ' 'got 3: \[1, 2, 3\]'): translate([1, 2, 3])
def test_isa(): v = IsA(str) assert repr(v) == 'must be str' v('foo') with raises_regexp(ValidationError, '^must be str'): v(123)
def test_equals(): v = Equals('foo') assert repr(v) == "must equal 'foo'" v('foo') with raises_regexp(ValidationError, "^must equal 'foo'"): v('bar')
def test_int_in_dict(self): "A required int nested in a required dict" spec = translate({'foo': int}) # key is missing with raises_regexp(MissingKeys, "must have keys: 'foo'"): spec({}) # key is present, value is missing with raises_regexp(ValidationError, "'foo' value must be int"): spec({'foo': None}) # key is present, value is present spec({'foo': 1})
def test_dict_in_dict(self): "A required dict nested in another required dict" spec = translate({'foo': dict}) # key is missing with raises_regexp(MissingKeys, "must have keys: 'foo'"): spec({}) # key is present, value is missing with raises_regexp(ValidationError, "'foo' value must be dict"): spec({'foo': None}) # value is present validate(spec, {'foo': {}})
def test_list_type(self): v = translate(list) with raises_regexp(ValidationError, 'must be list'): v(None) v([]) v(['hi']) v([1234])