def test_dictionary(self):
        with pytest.raises(TypeError):
            # noinspection PyTypeChecker
            Dictionary({'foo': UnicodeString()},
                       additional_validator='Not a validator')  # type: ignore

        field = Dictionary({
            'foo': UnicodeString(),
            'bar': Integer(),
            'baz': UnicodeString(),
        })

        assert field.errors(['foo', 'bar',
                             'baz']) == [Error(message='Not a dict')]
        assert field.errors(
            ('foo', 'bar', 'baz')) == [Error(message='Not a dict')]
        assert field.errors({'foo', 'bar',
                             'baz'}) == [Error(message='Not a dict')]
        assert field.errors({
            'foo': 'Hello',
            'bar': 12,
            'baz': True
        }) == [
            Error(message='Not a unicode string', pointer='baz'),
        ]
        assert field.errors({
            'foo': 'Hello',
            'bar': 12,
            'baz': 'Goodbye'
        }) == []

        class V(AdditionalCollectionValidator[Mapping[HashableType, AnyType]]):
            def errors(self, value):
                if value['foo'] != value['baz']:
                    return [
                        Error('Value foo does not match value baz',
                              pointer='foo')
                    ]
                return []

        field = field.extend(additional_validator=V())

        assert field.errors({
            'foo': 'Hello',
            'bar': 12,
            'baz': 'Goodbye'
        }) == [
            Error(message='Value foo does not match value baz', pointer='foo'),
        ]
        assert field.errors({'foo': 'Hello', 'bar': 12, 'baz': 'Hello'}) == []
示例#2
0
    def test_dictionary_ordering(self):  # type: () -> None
        schema1 = Dictionary(
            OrderedDict((
                ('foo', UnicodeString()),
                ('bar', Boolean()),
                ('baz', List(Integer())),
            )),
            optional_keys=('foo', ),
            description='Hello, world',
        )

        assert schema1.introspect()['contents'] == {
            'baz': List(Integer()).introspect(),
            'foo': UnicodeString().introspect(),
            'bar': Boolean().introspect(),
        }

        assert schema1.introspect()['display_order'] == ['foo', 'bar', 'baz']

        schema2 = schema1.extend(
            OrderedDict((
                ('bar', Integer()),
                ('qux', Set(UnicodeString())),
                ('moon', Tuple(Decimal(), UnicodeString())),
            )))

        assert schema2.introspect()['contents'] == {
            'baz': List(Integer()).introspect(),
            'foo': UnicodeString().introspect(),
            'moon': Tuple(Decimal(), UnicodeString()).introspect(),
            'bar': Integer().introspect(),
            'qux': Set(UnicodeString()).introspect(),
        }

        assert schema2.introspect()['display_order'] == [
            'foo', 'bar', 'baz', 'qux', 'moon'
        ]

        assert not schema1.errors({'bar': True, 'foo': 'Hello', 'baz': [15]})

        errors = schema1.errors({
            'baz': 'Nope',
            'foo': False,
            'bar': ['Heck nope']
        })

        assert errors == [
            Error(code='INVALID',
                  pointer='foo',
                  message='Not a unicode string'),
            Error(code='INVALID', pointer='bar', message='Not a boolean'),
            Error(code='INVALID', pointer='baz', message='Not a list'),
        ]

        assert not schema2.errors(
            {
                'bar': 91,
                'foo': 'Hello',
                'qux': {'Yes'},
                'baz': [15],
                'moon': (decimal.Decimal('15.25'), 'USD')
            }, )

        errors = schema2.errors({
            'baz': 'Nope',
            'foo': False,
            'bar': ['Heck nope'],
            'qux': 'Denied',
            'moon': 72
        })

        assert errors == [
            Error(code='INVALID',
                  pointer='foo',
                  message='Not a unicode string'),
            Error(code='INVALID', pointer='bar', message='Not an integer'),
            Error(code='INVALID', pointer='baz', message='Not a list'),
            Error(code='INVALID',
                  pointer='qux',
                  message='Not a set or frozenset'),
            Error(code='INVALID', pointer='moon', message='Not a tuple'),
        ]
示例#3
0
    def test_complex(self):  # type: () -> None

        schema = Dictionary({
            'child_ids':
            List(Integer(gt=0)),
            'address':
            Dictionary(
                {
                    'line1': UnicodeString(),
                    'line2': UnicodeString(),
                    'city': UnicodeString(),
                    'postcode': UnicodeString(),
                    'state': UnicodeString(),
                    'country': UnicodeString(),
                },
                optional_keys=('line2', 'state'),
            ),
            'unique_things':
            Set(UnicodeString()),
        })

        self.assertEqual(
            schema.errors(None),
            [Error('Not a dict')],
        )

        self.assertEqual(
            sorted(
                schema.errors(
                    {
                        'child_ids': [1, 2, 'ten'],
                        'unsolicited_item': 'Should not be here',
                        'another_bad': 'Also extra',
                        'unique_things': ['hello', 'world'],
                    }, )),
            sorted([
                Error('Not an integer', pointer='child_ids.2'),
                Error('Missing key: address',
                      code=ERROR_CODE_MISSING,
                      pointer='address'),
                Error('Extra keys present: another_bad, unsolicited_item',
                      code=ERROR_CODE_UNKNOWN),
                Error('Not a set or frozenset', pointer='unique_things'),
            ]),
        )

        self.assertEqual(
            schema.errors({
                'child_ids': [1, 2, 3, 4],
                'address': {
                    'line1': '115 5th Street',
                    'city': 'San Francisco',
                    'state': 'CA',
                    'country': 'USA',
                    'postcode': '94103',
                },
                'unique_things': {'hello', b'world'},
            }),
            [
                Error('Not a unicode string',
                      pointer='unique_things.[{}]'.format(str(b'world')))
            ],
        )

        self.assertEqual(
            schema.errors({
                'child_ids': [1, 2, 3, 4],
                'address': {
                    'line1': '115 5th Street',
                    'city': 'San Francisco',
                    'state': 'CA',
                    'country': 'USA',
                    'postcode': '94103',
                },
                'unique_things': {'hello', 'world'},
            }),
            [],
        )

        introspection = schema.introspect()
        self.assertEqual('dictionary', introspection['type'])
        self.assertFalse(introspection['allow_extra_keys'])
        self.assertEqual([], introspection['optional_keys'])
        self.assertEqual(3, len(introspection['contents']))
        self.assertIn('child_ids', introspection['contents'])
        self.assertEqual(
            {
                'type': 'list',
                'contents': {
                    'gt': 0,
                    'type': 'integer'
                },
            },
            introspection['contents']['child_ids'],
        )
        self.assertIn('address', introspection['contents'])
        self.assertEqual('dictionary',
                         introspection['contents']['address']['type'])
        self.assertFalse(
            introspection['contents']['address']['allow_extra_keys'])
        self.assertEqual(
            {'line2', 'state'},
            set(introspection['contents']['address']['optional_keys']))
        self.assertEqual(
            {
                'city': {
                    'type': 'unicode'
                },
                'country': {
                    'type': 'unicode'
                },
                'line1': {
                    'type': 'unicode'
                },
                'line2': {
                    'type': 'unicode'
                },
                'postcode': {
                    'type': 'unicode'
                },
                'state': {
                    'type': 'unicode'
                },
            },
            introspection['contents']['address']['contents'],
        )
        self.assertEqual(
            {
                'type': 'set',
                'contents': {
                    'type': 'unicode'
                },
            },
            introspection['contents']['unique_things'],
        )