forked from pytest-dev/pytest-factoryboy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
test_postgen_dependencies.py
142 lines (93 loc) · 3.09 KB
/
test_postgen_dependencies.py
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
"""Test post-generation dependencies."""
from __future__ import annotations
from dataclasses import dataclass, field
from typing import TYPE_CHECKING
import factory
import pytest
from pytest_factoryboy import register
if TYPE_CHECKING:
from typing import Any
from pytest_factoryboy.plugin import Request
@dataclass
class Foo:
value: int
expected: int
bar: Bar | None = None
# NOTE: following attributes are used internally only for assertions
_create: bool | None = None
_postgeneration_results: dict[str, Any] = field(default_factory=dict)
@dataclass
class Bar:
foo: Foo
@dataclass
class Baz:
foo: Foo
@register
class BazFactory(factory.Factory):
class Meta:
model = Baz
foo = None
@register
class FooFactory(factory.Factory):
"""Foo factory."""
class Meta:
model = Foo
value = 0
expected = 0
"""Value that is expected at the constructor."""
@factory.post_generation
def set1(foo: Foo, create: bool, value: Any, **kwargs: Any) -> str:
foo.value = 1
return "set to 1"
baz = factory.RelatedFactory(BazFactory, "foo")
@classmethod
def _after_postgeneration(cls, obj: Foo, create: bool, results: dict[str, Any] | None = None) -> None:
obj._postgeneration_results = results or {}
obj._create = create
class BarFactory(factory.Factory):
"""Bar factory."""
foo = factory.SubFactory(FooFactory)
@classmethod
def _create(cls, model_class: type[Bar], foo: Foo) -> Bar:
assert foo.value == foo.expected
bar = super()._create(model_class, foo=foo)
foo.bar = bar
return bar
class Meta:
model = Bar
def test_postgen_invoked(foo: Foo):
"""Test that post-generation hooks are done and the value is 2."""
assert foo.value == 1
register(BarFactory)
@pytest.mark.parametrize("foo__value", [3])
@pytest.mark.parametrize("foo__expected", [1])
def test_depends_on(bar: Bar):
"""Test that post-generation hooks are done and the value is 1."""
assert bar.foo.value == 1
def test_getfixturevalue(request, factoryboy_request: Request):
"""Test post-generation declarations via the getfixturevalue."""
foo = request.getfixturevalue("foo")
assert not factoryboy_request.deferred
assert foo.value == 1
def test_after_postgeneration(foo: Foo):
"""Test _after_postgeneration is called."""
assert foo._create is True
foo._postgeneration_results["set1"] == "set to 1"
foo._postgeneration_results["baz"].foo is foo
assert len(foo._postgeneration_results) == 2
@dataclass
class Ordered:
value: str | None = None
@register
class OrderedFactory(factory.Factory):
class Meta:
model = Ordered
@factory.post_generation
def zzz(obj: Ordered, create: bool, val: Any, **kwargs: Any) -> None:
obj.value = "zzz"
@factory.post_generation
def aaa(obj: Ordered, create: bool, val: Any, **kwargs: Any) -> None:
obj.value = "aaa"
def test_ordered(ordered: Ordered):
"""Test post generation are ordered by creation counter."""
assert ordered.value == "aaa"