File: test_data_parsing.py

package info (click to toggle)
python-polyfactory 2.22.2-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,892 kB
  • sloc: python: 11,338; makefile: 103; sh: 37
file content (152 lines) | stat: -rw-r--r-- 4,154 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
from datetime import date
from enum import Enum
from typing import Callable, Literal, Optional

import pytest

from pydantic import AmqpDsn, AnyHttpUrl, AnyUrl, BaseConfig, BaseModel, HttpUrl, KafkaDsn, PostgresDsn, RedisDsn

from polyfactory.exceptions import ParameterException
from polyfactory.factories.pydantic_factory import ModelFactory
from tests.models import Person, PersonFactoryWithDefaults, Pet


def test_enum_parsing() -> None:
    class MyStrEnum(str, Enum):
        FIRST_NAME = "Moishe Zuchmir"
        SECOND_NAME = "Hannah Arendt"

    class MyIntEnum(Enum):
        ONE_HUNDRED = 100
        TWO_HUNDRED = 200

    class MyModel(BaseModel):
        name: MyStrEnum
        worth: MyIntEnum

    class MyFactory(ModelFactory):
        __model__ = MyModel

    result = MyFactory.build()

    assert isinstance(result.name, MyStrEnum)
    assert isinstance(result.worth, MyIntEnum)


def test_callback_parsing() -> None:
    today = date.today()

    class MyModel(BaseModel):
        name: str
        birthday: date
        secret: Callable

    class MyFactory(ModelFactory):
        __model__ = MyModel

        name = lambda: "moishe zuchmir"  # noqa: E731
        birthday = lambda: today  # noqa: E731

    result = MyFactory.build()

    assert result.name == "moishe zuchmir"
    assert result.birthday == today
    assert callable(result.secret)


def test_literal_parsing() -> None:
    class MyModel(BaseModel):
        literal_field: "Literal['yoyos']"
        multi_literal_field: "Literal['nolos', 'zozos', 'kokos']"

    class MyFactory(ModelFactory):
        __model__ = MyModel

    assert MyFactory.build().literal_field == "yoyos"
    batch = MyFactory.batch(30)
    values = {v.multi_literal_field for v in batch}
    assert values == {"nolos", "zozos", "kokos"}


def test_embedded_models_parsing() -> None:
    class MyModel(BaseModel):
        pet: Pet

    class MyFactory(ModelFactory):
        __model__ = MyModel

    result = MyFactory.build()
    assert isinstance(result.pet, Pet)


def test_embedded_factories_parsing() -> None:
    class MyModel(BaseModel):
        person: Person

    class MyFactory(ModelFactory):
        __model__ = MyModel
        person = PersonFactoryWithDefaults

    result = MyFactory.build()
    assert isinstance(result.person, Person)


def test_class_parsing() -> None:
    class TestClassWithoutKwargs:
        def __init__(self) -> None:
            self.flag = "123"

    class MyModel(BaseModel):
        class Config(BaseConfig):
            arbitrary_types_allowed = True

        class_field: TestClassWithoutKwargs
        # just a few select exceptions, to verify this works
        exception_field: Exception
        type_error_field: TypeError
        attribute_error_field: AttributeError
        runtime_error_field: RuntimeError

    class MyFactory(ModelFactory):
        __model__ = MyModel

    result = MyFactory.build()

    assert isinstance(result.class_field, TestClassWithoutKwargs)
    assert result.class_field.flag == "123"
    assert isinstance(result.exception_field, Exception)
    assert isinstance(result.type_error_field, TypeError)
    assert isinstance(result.attribute_error_field, AttributeError)
    assert isinstance(result.runtime_error_field, RuntimeError)

    class TestClassWithKwargs:
        def __init__(self, _: str) -> None:
            self.flag = str

    class MyNewModel(BaseModel):
        class Config(BaseConfig):
            arbitrary_types_allowed = True

        class_field: TestClassWithKwargs

    class MySecondFactory(ModelFactory):
        __model__ = MyNewModel

    with pytest.raises(ParameterException):
        MySecondFactory.build()


@pytest.mark.parametrize(
    "type_",
    [AnyUrl, HttpUrl, KafkaDsn, PostgresDsn, RedisDsn, AmqpDsn, AnyHttpUrl],
)
def test_optional_url_field_parsed_correctly(type_: type) -> None:
    class MyModel(BaseModel):
        url: Optional[type_]  # type: ignore

    class MyFactory(ModelFactory[MyModel]):
        __model__ = MyModel

    while not (url := MyFactory.build().url):
        assert not url
        assert MyModel(url=url)  # no validation error raised