Exemple #1
0
def test_dict_scheme_with_schema():
    _validate({
        False: "string",
        1: True,
        "integer": 10,
        4.4: 44.4,
    },
              DictScheme({
                  False: String(),
                  1: Bool(),
                  "integer": Integer(),
                  3.3: Float(optional=True),
                  4.4: Float(optional=True),
              }))
Exemple #2
0
def test_dict_key_value():
    _validate({
        "one": 1.0,
        "two": 2.0,
    }, Dict(String(), Float()))
Exemple #3
0
def test_float_max_invalid(value, max_value):
    with pytest.raises(InvalidValueError):
        _validate(value, Float(max=max_value))
Exemple #4
0
class Car(MutableMapping):
    __slots__ = ("_object", )
    __scheme__ = {
        "ownerName":
        OrdinaryString(),
        "serialNumber":
        Integer32(),
        "modelYear":
        Integer32(),
        # "serialNumber": Integer64(),
        # "modelYear": Integer64(),
        "code":
        OrdinaryString(),
        "vehicleCode":
        OrdinaryString(),
        "engine":
        DictScheme({
            "capacity": Integer16(),
            "numCylinders": Integer8(),
            "maxRpm": Integer16(),
            "manufacturerCode": Char(),
        }),
        "fuelFigures":
        DictScheme({
            "speed": Integer16(),
            "mpg": Float(),
            "usageDescription": OrdinaryString(),
        }),
        "performanceFigures":
        DictScheme({
            "octaneRating":
            Integer16(),
            "acceleration":
            DictScheme({
                "mph": Integer16(),
                "seconds": Float(),
            }),
        }),
        "manufacturer":
        OrdinaryString(),
        "model":
        OrdinaryString(),
        "activationCode":
        OrdinaryString(),
    }

    __database__ = "soldcars"
    __collection__ = "cars"
    __write_majority__ = WriteConcern(w="majority", wtimeout=5000)

    @classmethod
    def get_scheme(cls):
        """Return Car scheme."""

        return cls.__scheme__

    @classmethod
    def validate(cls, data):
        """Validate Car document and return the instance."""

        return cls(validate("Car", data, DictScheme(cls.__scheme__)))

    @classmethod
    def database(cls):
        """Return database instance."""

        return Motor().default()[cls.__database__]

    @classmethod
    def collection(cls, stale_ok=False, majority=False):
        """Return collection instance."""

        kwargs = {}
        if stale_ok:
            kwargs["read_preference"] = ReadPreference.SECONDARY_PREFERRED
        elif majority:
            kwargs["write_concern"] = cls.__write_majority__

        return aiomotor.AsyncIOMotorCollection(cls.database(),
                                               cls.__collection__, **kwargs)

    @classmethod
    async def ensure_index(cls):
        """Ensure collection index."""

        await cls.collection().create_index(
            [("serialNumber", pymongo.ASCENDING)], unique=True)

    @classmethod
    async def one(cls,
                  serial,
                  add_query=None,
                  fields=None,
                  required=True,
                  stale_ok=False):
        """Return a one Car document."""

        query = {"serialNumber": serial}
        if add_query:
            query.update(add_query)

        car = await cls.collection(stale_ok=stale_ok
                                   ).find_one(query, projection=fields)

        if not car and required:
            raise CarNotFound(serial)

        if car:
            car.pop("_id")
        return cls(car)

    @classmethod
    def get_mocked(cls, override=None):
        """Mock a one Car document.

        Attention: use only in tests and cli tools to fake documents!
        """
        def randstr(length):
            letters = string.ascii_lowercase
            return ''.join(random.choice(letters) for i in range(length))

        def _mock(part):
            d = {}
            for key, value in part.items():
                # NOTE: using mangled attributes is not a good way
                #       but object_validator library was not intend to
                #       convert or generate new data by the scheme.
                if isinstance(value, DictScheme):
                    d[key] = _mock(value._DictScheme__scheme)
                elif isinstance(value, Integer):
                    d[key] = random.randint(value._BasicNumber__min or 0,
                                            value._BasicNumber__max or 100)
                elif isinstance(value, Float):
                    d[key] = random.uniform(value._BasicNumber__min or 0,
                                            value._BasicNumber__max or 100)
                    d[key] = round(d[key], 2)
                elif isinstance(value, String):
                    d[key] = randstr(
                        random.randint(value._String__min_length,
                                       value._String__max_length))
            return d

        mocked = _mock(cls.get_scheme())
        mocked.update(override or {})
        return cls(mocked)

    def __init__(self, data):
        self._object = data or {}

    def __getitem__(self, key):
        return self._object[key]

    def __setitem__(self, key, value):
        self._object[key] = value

    def __delitem__(self, key):
        self._object.pop(key)

    def __iter__(self):
        return iter(self._object)

    def __len__(self):
        return len(self._object)

    def asdict(self):
        """Return Car document as dictionary."""

        return copy.deepcopy(self._object)

    def asjson(self):
        """Return Car document as JSON."""

        return json.dumps(self._object)

    async def insert(self, majority=True):
        """Insert Car document in collection."""

        try:
            document_id = self["_id"] = \
                await self.collection(majority=majority).insert_one(self)
        except pymongo.errors.WTimeoutError:
            # FIXME: add retry on write timeout
            raise
        except pymongo.errors.DuplicateKeyError:
            raise CarAlreadyExists(self["serialNumber"])

        return document_id
Exemple #5
0
def test_float_min_invalid(value, min_value):
    with pytest.raises(InvalidValueError):
        _validate(value, Float(min=min_value))
Exemple #6
0
def test_float_min_max_valid():
    _validate(7.0, Float(min=7, max=7))
    _validate(7.0, Float(min=6.9, max=7.1))
    _validate(7.5, Float(min=6, max=8))
    _validate(7.5, Float(min=6.0, max=8.0))
Exemple #7
0
def test_float_invalid_type():
    error = pytest.raises(InvalidTypeError,
                          lambda: _validate(1, Float())).value

    assert error.object_name == ""
    assert error.object_type == int
Exemple #8
0
def test_float():
    _validate(0.1, Float())
Exemple #9
0
}, {
    "id": 2,
    "name": "two",
    "value": 2.0,
    "zero": False,
    "dividers": [1, 2],
    "dividers_map": {
        1: 1.0,
        2: 2.0,
    },
}]

SCHEME = List(DictScheme({
    "id": Integer(choices=(0, 2)),
    "name": String(),
    "value": Float(),
    "zero": Bool(),
    "dividers": List(Integer()),
    "dividers_map": Dict(Integer(), Float()),
}))


def test_validate():
    _validate("items", copy.deepcopy(ITEMS), SCHEME)


def test_validate_invalid_type():
    items = copy.deepcopy(ITEMS)
    items[1]["id"] = "string"

    error = pytest.raises(InvalidTypeError, lambda: