Ejemplo n.º 1
0
    def test_get_example(self):
        S = string('A string.', example='Foo')
        assert 'Foo' == S.get_example()

        # Default example
        S = string('A string.')
        assert 'string' == S.get_example()
Ejemplo n.º 2
0
    def test_type(self):
        S = string('Starts with S.', pattern=r'^S.*')
        T = string('Starts with T.', pattern=r'^T.*')

        class SOrT(UnionType):
            description = 'S or T.'
            types = [S, T]

            @classmethod
            def validate(cls, value):
                if not value.endswith('ring'):
                    raise TypeSystemError('Value does not end with ring')

        # No exception, matches `S` type.
        SOrT('S string')
        # No exception, matches `T` type.
        SOrT('T string')

        # Neither `S` or `T` type.
        with pytest.raises(TypeSystemError, match='Value is not one of'):
            SOrT('B')

        # Custom validation
        with pytest.raises(TypeSystemError, match='Value does not end with '):
            SOrT('S foo')
Ejemplo n.º 3
0
class PropertyDependenciesObject(Object):
    description = 'An item.'
    properties = {
        'type': string('Type of item'),
        'name': string('Name of item'),
        'category': string('Category of item'),
    }
    property_dependencies = {
        'type': ['name'],
        'name': ['category'],
    }
Ejemplo n.º 4
0
    def test_additional_items(self):
        A = array('a', items=[
            string('string', max_length=1), integer('int', maximum=1234)],
            additional_items=True)
        # no exception
        A(['a', 2, 3, 4, True])

        A = array('a', items=[
            string('string', max_length=1), integer('int', maximum=1234)],
            additional_items=False)
        with pytest.raises(TypeSystemError, match='Too many items.'):
            A(['a', 2, 3, 4, True])
Ejemplo n.º 5
0
 def test_min_length(self):
     S = string('a string', min_length=2)
     # No exception
     S('foo')
     # String too short
     with pytest.raises(TypeSystemError,
                        match='Must have at least 2 characters'):
         S('f')
     # Empty string when min_length is 1
     S = string('empty', min_length=1)
     with pytest.raises(TypeSystemError, match='Must not be blank.'):
         S('')
Ejemplo n.º 6
0
    def test_get_example(self):
        A = array('No example of items')
        assert [1] == A.get_example()

        A = array('Defined example', example=['a', 'b'])
        assert ['a', 'b'] == A.get_example()

        A = array('No example, defined items', items=string('letter'))
        assert ['string'] == A.get_example()

        A = array('a', items=[
            string('string', max_length=1, example='foo'),
            integer('int', maximum=1234, example=123)])
        assert ['foo', 123] == A.get_example()
Ejemplo n.º 7
0
 def test_pattern(self):
     S = string('a regex', pattern=r'^foo*')
     # No exception
     S('foo bar')
     # Does not begin with `foo`
     with pytest.raises(TypeSystemError):
         S('bar')
Ejemplo n.º 8
0
 def test_format_email(self):
     S = string('email', format='email')
     # No exception
     S('*****@*****.**')
     # Invalid email
     with pytest.raises(TypeSystemError, match='Not a valid email address.'):
         S('foo.net')
Ejemplo n.º 9
0
class RequiredPropsObject(Object):
    description = 'required'
    properties = {
        'foo': string('foo property', min_length=2),
        'bar': integer('an int'),
    }
    required = ['bar']
Ejemplo n.º 10
0
 def test_max_length(self):
     S = string('a string', max_length=2)
     # No exception
     S('12')
     # String too long
     with pytest.raises(TypeSystemError,
                        match='Must have no more than 2 characters'):
         S('123')
Ejemplo n.º 11
0
 def test_format_uri(self):
     S = string('uri', format='uri')
     # no exception
     S('https://doctor.com')
     # Invalid uri
     expected_msg = "'foo' is not a valid 'URI'."
     with pytest.raises(TypeSystemError, match=expected_msg):
         S('foo')
Ejemplo n.º 12
0
        class A(Array):
            description = 'Array with 2 items'
            items = string('string')

            @classmethod
            def validate(cls, value):
                if len(value) != 2:
                    raise TypeSystemError('Length must be 2')
Ejemplo n.º 13
0
 def test_items(self):
     A = array('array', items=string('string', max_length=1))
     # no exception
     A(['a', 'b'])
     # Invalid type of items
     with pytest.raises(TypeSystemError,
                        match="{0: 'Must have no more than 1 characters.'}"):
         A(['aa', 'b'])
Ejemplo n.º 14
0
 def test_format_date(self):
     S = string('date', format='date')
     # No exception
     s = S('2018-10-22')
     assert s == date(2018, 10, 22)
     # Invalid date
     expected_msg = "time data 'foo' does not match format '%Y-%m-%d'"
     with pytest.raises(TypeSystemError, match=expected_msg):
         S('foo')
Ejemplo n.º 15
0
 def test_items_multiple_types(self):
     A = array('a', items=[
         string('string', max_length=1, example='foo'),
         integer('int', maximum=1234, example=123)])
     # no exception
     A(['b', 1234])
     # Invalid type
     with pytest.raises(TypeSystemError,
                        match="{1: 'Must be less than or equal to 1234.'}"):
         A(['b', 1235])
Ejemplo n.º 16
0
    def test_format_date_time(self):
        S = string('date-time', format='date-time')
        # No exception
        s = S('2018-10-22T11:12:00')
        assert s == datetime(2018, 10, 22, 11, 12, 0)

        # Invalid datetime
        expected_msg = ("ISO 8601 time designator 'T' missing. Unable to parse "
                        "datetime string 'foo'")
        with pytest.raises(TypeSystemError, match=expected_msg):
            S('foo')
Ejemplo n.º 17
0
    def test_format_time(self):
        S = string('time', format='time')
        # no exception
        s = S('13:10:00')
        assert 13 == s.hour
        assert 10 == s.minute
        assert 0 == s.second

        # invalid
        expected_msg = "time data 'foo' does not match format '%H:%M:%S"
        with pytest.raises(TypeSystemError, match=expected_msg):
            S('foo')
    def test_parse_form_and_query_params_with_custom_parser_not_callable(self):
        """
        This test verifies if a parser is provided that isn't callable that
        we warn the user and fallback to the default parser.
        """
        A = string('str', parser='foo')

        def f(a: A):
            pass

        sig = inspect.signature(f)
        query_params = {'a': 'a'}
        with pytest.warns(UserWarning, match='Parser `foo` is not callable'):
            actual = parse_form_and_query_params(query_params, sig.parameters)
        assert {'a': 'a'} == actual
Ejemplo n.º 19
0
    def test_native_type(self):
        B = boolean('A bool.')
        S = string('A string.')

        class Item(UnionType):
            description = 'B or S.'
            types = [B, S]

        # Should be the first native_type in the types attribute.
        assert Item.native_type == bool

        # After instantiating with a value, it should update the native_type
        # to match the value.
        assert 'S' == Item('S')
        assert Item.native_type == str
        assert Item(True)
        assert Item.native_type == bool
Ejemplo n.º 20
0
 def test_type(self):
     S = string('string')
     assert type(S('string')) is str
Ejemplo n.º 21
0
def test_new_type_allows_custom_description():
    S = string('A string', example='Foo')
    N = new_type(S, description='A different description')
    assert 'A different description' == N.description
Ejemplo n.º 22
0
def test_new_type_copies_and_overrides_attrs():
    S1 = string('A string', pattern=r'^s')
    S2 = new_type(S1, description='new', max_length=10)
    expected = dict(S1.__dict__, description='new', max_length=10)
    assert expected == dict(S2.__dict__)
Ejemplo n.º 23
0
def test_new_type_copies_all_attrs():
    S1 = string('A string', pattern=r'^s')
    S2 = new_type(S1)
    assert S1.__dict__ == S2.__dict__
Ejemplo n.º 24
0
def test_new_type_uses_parent_description():
    S = string('A string', example='Foo')
    N = new_type(S, nullable=True)
    assert 'A string' == N.description
    assert S.nullable is False
    assert N.nullable is True
Ejemplo n.º 25
0
 def test_trim_whitespace(self):
     S = string('a string', trim_whitespace=True)
     actual = S(' foo ')
     assert 'foo' == actual
Ejemplo n.º 26
0
class FooObject(Object):
    additional_properties = True
    description = 'A Foo'
    properties = {'foo': string('foo property', min_length=2)}
Ejemplo n.º 27
0
 def test_type_nullable(self):
     S = string('string', nullable=True)
     assert S(None) is None
Ejemplo n.º 28
0
 def test_nullable(self):
     A = array('array', items=string('string', max_length=1), nullable=True)
     # Just tests that this does not raise an exception.
     A(None)
Ejemplo n.º 29
0
# Note that this file contains some inline comments starting with # --, used to
# generate documentation from this file. You're probably better served reading
# the actual documentation (see Using in Flask in the docs).

from flask import Flask
from flask_restful import Api
from doctor.errors import NotFoundError
from doctor.flask import create_routes
from doctor.routing import Route, get, post, put, delete
# -- mark-types
from doctor import types

# doctor provides helper functions to easily define simple types.
Body = types.string('Note body', example='body')
Done = types.boolean('Marks if a note is done or not.', example=False)
NoteId = types.integer('Note ID', example=1)
Status = types.string('API status')
NoteType = types.enum('The type of note',
                      enum=['quick', 'detailed'],
                      example='quick')


# You can also inherit from type classes to create more complex types.
class Note(types.Object):
    description = 'A note object'
    additional_properties = False
    properties = {
        'note_id': NoteId,
        'body': Body,
        'done': Done,
    }
Ejemplo n.º 30
0
"""
This module contains custom types used by tests.
"""
from doctor.types import (array, boolean, enum, integer, new_type, number,
                          string, Object, UnionType)


def parse_comma_separated_str(value):
    return value.split(',')


Age = integer('age', minimum=1, maximum=120, example=34)
Auth = string('auth token', example='testtoken')
Color = enum('Color',
             enum=['blue', 'green'],
             example='blue',
             case_insensitive=True)
Colors = array('colors', items=Color, example=['green'])
ExampleArray = array('ex description e', items=Auth, example=['ex', 'array'])
TwoItems = array('two items', items=[Age, Color])


class ExampleObject(Object):
    description = 'ex description f'
    properties = {'str': Auth}
    additional_properties = False
    example = {'str': 'ex str'}


ExampleObjects = array('ex objects',
                       items=ExampleObject,