panda-pytest-assertions 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. panda_pytest_assertions/__init__.py +0 -0
  2. panda_pytest_assertions/assert_context/__init__.py +15 -0
  3. panda_pytest_assertions/assert_context/_assert_context.py +128 -0
  4. panda_pytest_assertions/assert_object/__init__.py +41 -0
  5. panda_pytest_assertions/assert_object/_assert_object.py +36 -0
  6. panda_pytest_assertions/assert_object/_asserter_factories/__init__.py +8 -0
  7. panda_pytest_assertions/assert_object/_asserter_factories/asserter_factory.py +66 -0
  8. panda_pytest_assertions/assert_object/_asserter_factories/built_in_asserter_factory.py +29 -0
  9. panda_pytest_assertions/assert_object/_converters/__init__.py +10 -0
  10. panda_pytest_assertions/assert_object/_converters/expectation_from_yaml.py +114 -0
  11. panda_pytest_assertions/assert_object/_converters/expectation_to_yaml.py +78 -0
  12. panda_pytest_assertions/assert_object/_expectation_modificators/__init__.py +15 -0
  13. panda_pytest_assertions/assert_object/_expectation_modificators/mapping_subset.py +15 -0
  14. panda_pytest_assertions/assert_object/_expectation_modificators/object_attibutes.py +15 -0
  15. panda_pytest_assertions/assert_object/_expectation_modificators/stringified.py +11 -0
  16. panda_pytest_assertions/assert_object/_expectation_modificators/unordered.py +18 -0
  17. panda_pytest_assertions/assert_object/_expectation_modificators/with_type.py +135 -0
  18. panda_pytest_assertions/assert_object/_objects_asserters/__init__.py +36 -0
  19. panda_pytest_assertions/assert_object/_objects_asserters/asserter.py +35 -0
  20. panda_pytest_assertions/assert_object/_objects_asserters/equality_asserter.py +33 -0
  21. panda_pytest_assertions/assert_object/_objects_asserters/mapping_asserter.py +55 -0
  22. panda_pytest_assertions/assert_object/_objects_asserters/mapping_subset_asserter.py +53 -0
  23. panda_pytest_assertions/assert_object/_objects_asserters/object_attributes_asserter.py +52 -0
  24. panda_pytest_assertions/assert_object/_objects_asserters/ordered_elements_asserter.py +55 -0
  25. panda_pytest_assertions/assert_object/_objects_asserters/stringified_asserter.py +36 -0
  26. panda_pytest_assertions/assert_object/_objects_asserters/unordered_elements_asserter.py +77 -0
  27. panda_pytest_assertions/assert_object/_objects_asserters/with_type_asserter.py +57 -0
  28. panda_pytest_assertions/assert_object/_protocols.py +93 -0
  29. panda_pytest_assertions/assert_object/generators/__init__.py +41 -0
  30. panda_pytest_assertions/assert_object/generators/_expectation_definitions/__init__.py +30 -0
  31. panda_pytest_assertions/assert_object/generators/_expectation_definitions/equality.py +6 -0
  32. panda_pytest_assertions/assert_object/generators/_expectation_definitions/mapping.py +14 -0
  33. panda_pytest_assertions/assert_object/generators/_expectation_definitions/mapping_subset.py +14 -0
  34. panda_pytest_assertions/assert_object/generators/_expectation_definitions/object_attributes.py +12 -0
  35. panda_pytest_assertions/assert_object/generators/_expectation_definitions/of_type.py +13 -0
  36. panda_pytest_assertions/assert_object/generators/_expectation_definitions/stringified.py +4 -0
  37. panda_pytest_assertions/assert_object/generators/_expectation_definitions/uniform_mapping.py +13 -0
  38. panda_pytest_assertions/assert_object/generators/_expectation_definitions/uniform_mapping_subset.py +13 -0
  39. panda_pytest_assertions/assert_object/generators/_expectation_definitions/uniform_ordered.py +39 -0
  40. panda_pytest_assertions/assert_object/generators/_expectation_definitions/uniform_unordered.py +11 -0
  41. panda_pytest_assertions/assert_object/generators/_expectation_definitions/union.py +13 -0
  42. panda_pytest_assertions/assert_object/generators/_expectation_definitions/with_type.py +30 -0
  43. panda_pytest_assertions/assert_object/generators/_generate_expectation.py +23 -0
  44. panda_pytest_assertions/assert_object/generators/_generator_factories/__init__.py +8 -0
  45. panda_pytest_assertions/assert_object/generators/_generator_factories/built_in_generator_factory.py +39 -0
  46. panda_pytest_assertions/assert_object/generators/_generator_factories/generator_factory.py +66 -0
  47. panda_pytest_assertions/assert_object/generators/_generators/__init__.py +34 -0
  48. panda_pytest_assertions/assert_object/generators/_generators/equality_generator.py +35 -0
  49. panda_pytest_assertions/assert_object/generators/_generators/equality_key_mapping_generator.py +54 -0
  50. panda_pytest_assertions/assert_object/generators/_generators/exceptions.py +1 -0
  51. panda_pytest_assertions/assert_object/generators/_generators/generator.py +35 -0
  52. panda_pytest_assertions/assert_object/generators/_generators/mapping_generator.py +60 -0
  53. panda_pytest_assertions/assert_object/generators/_generators/mapping_subset_generator.py +57 -0
  54. panda_pytest_assertions/assert_object/generators/_generators/object_attributes_generator.py +53 -0
  55. panda_pytest_assertions/assert_object/generators/_generators/of_type_generator.py +47 -0
  56. panda_pytest_assertions/assert_object/generators/_generators/ordered_generator.py +55 -0
  57. panda_pytest_assertions/assert_object/generators/_generators/stringified_generator.py +35 -0
  58. panda_pytest_assertions/assert_object/generators/_generators/uniform_mapping_generator.py +50 -0
  59. panda_pytest_assertions/assert_object/generators/_generators/uniform_mapping_subset_generator.py +52 -0
  60. panda_pytest_assertions/assert_object/generators/_generators/uniform_ordered_generator.py +49 -0
  61. panda_pytest_assertions/assert_object/generators/_generators/union_generator.py +51 -0
  62. panda_pytest_assertions/assert_object/generators/_generators/unordered_generator.py +46 -0
  63. panda_pytest_assertions/assert_object/generators/_generators/with_type_generator.py +46 -0
  64. panda_pytest_assertions/py.typed +0 -0
  65. panda_pytest_assertions-0.1.0.dist-info/LICENSE +201 -0
  66. panda_pytest_assertions-0.1.0.dist-info/METADATA +32 -0
  67. panda_pytest_assertions-0.1.0.dist-info/RECORD +68 -0
  68. panda_pytest_assertions-0.1.0.dist-info/WHEEL +4 -0
@@ -0,0 +1,60 @@
1
+ from collections.abc import Mapping
2
+ from typing import Any
3
+
4
+ from panda_pytest_assertions.assert_object import GeneratorFactoryProtocol
5
+
6
+ from .._expectation_definitions import MappingDef # noqa: TID252
7
+ from .exceptions import ObjectNotMatchingDefinitionError
8
+ from .generator import Generator
9
+
10
+
11
+ class MappingGenerator(Generator):
12
+ """
13
+ Generates Mapping expectation.
14
+ """
15
+
16
+ @classmethod
17
+ def matches(cls, definition: Any) -> bool: # noqa: ANN401
18
+ """
19
+ Decide whether provided definiton can be handled by this generator.
20
+
21
+ This generator can handle MappingDef definition.
22
+
23
+ :param definition: definition to be tested
24
+ :return: whether definition can be handled by this generator
25
+ """
26
+ return isinstance(definition, MappingDef)
27
+
28
+ def __init__(
29
+ self,
30
+ generator_factory: type[GeneratorFactoryProtocol],
31
+ definition: MappingDef,
32
+ ) -> None:
33
+ super().__init__(generator_factory, definition)
34
+ self.keys_generator = generator_factory.create(definition.keys_definition)
35
+ self.items_generators = {
36
+ key: generator_factory.create(value) for key, value in definition.items_definitions.items()
37
+ }
38
+
39
+ def generate_expectation(self, object_: Any) -> Mapping[Any, Any]: # noqa: ANN401
40
+ """
41
+ Generate expectation from given object.
42
+
43
+ :param object_: an object to generate expectation from
44
+ :return: generated expectation
45
+ """
46
+ if not isinstance(object_, Mapping):
47
+ msg = f'Expected mapping, got {type(object_)}'
48
+ raise ObjectNotMatchingDefinitionError(msg)
49
+ if object_.keys() != self.items_generators.keys():
50
+ msg = (
51
+ f'Object has invalid keys. '
52
+ f'Expected: {set(self.items_generators.keys())}, got {set(object_.keys())}.'
53
+ )
54
+ raise ObjectNotMatchingDefinitionError(msg)
55
+ expectation = {}
56
+ for key, value_generator in self.items_generators.items():
57
+ key_expectation = self.keys_generator.generate_expectation(key)
58
+ value_expectation = value_generator.generate_expectation(object_[key])
59
+ expectation[key_expectation] = value_expectation
60
+ return expectation
@@ -0,0 +1,57 @@
1
+ from collections.abc import Mapping
2
+ from typing import Any
3
+
4
+ from panda_pytest_assertions.assert_object import GeneratorFactoryProtocol, MappingSubset
5
+
6
+ from .._expectation_definitions import MappingSubsetDef # noqa: TID252
7
+ from .exceptions import ObjectNotMatchingDefinitionError
8
+ from .generator import Generator
9
+
10
+
11
+ class MappingSubsetGenerator(Generator):
12
+ """
13
+ Generates MappingSubset expectation.
14
+ """
15
+
16
+ @classmethod
17
+ def matches(cls, definition: Any) -> bool: # noqa: ANN401
18
+ """
19
+ Decide whether provided definiton can be handled by this generator.
20
+
21
+ This generator can handle MappingSubsetDef definition.
22
+
23
+ :param definition: definition to be tested
24
+ :return: whether definition can be handled by this generator
25
+ """
26
+ return isinstance(definition, MappingSubsetDef)
27
+
28
+ def __init__(
29
+ self,
30
+ generator_factory: type[GeneratorFactoryProtocol],
31
+ definition: MappingSubsetDef,
32
+ ) -> None:
33
+ super().__init__(generator_factory, definition)
34
+ self.keys_generator = generator_factory.create(definition.keys_definition)
35
+ self.items_generators = {
36
+ key: generator_factory.create(value) for key, value in definition.items_definitions.items()
37
+ }
38
+
39
+ def generate_expectation(self, object_: Any) -> MappingSubset: # noqa: ANN401
40
+ """
41
+ Generate expectation from given object.
42
+
43
+ :param object_: an object to generate expectation from
44
+ :return: generated expectation
45
+ """
46
+ if not isinstance(object_, Mapping):
47
+ msg = f'Expected mapping, got {type(object_)}'
48
+ raise ObjectNotMatchingDefinitionError(msg)
49
+ items_expectations = {}
50
+ for key, value_generator in self.items_generators.items():
51
+ if key not in object_:
52
+ msg = f'"{object_}" does not contain a key "{key}"'
53
+ raise ObjectNotMatchingDefinitionError(msg)
54
+ key_expectation = self.keys_generator.generate_expectation(key)
55
+ value_expectation = value_generator.generate_expectation(object_[key])
56
+ items_expectations[key_expectation] = value_expectation
57
+ return MappingSubset(items_expectations)
@@ -0,0 +1,53 @@
1
+ from typing import Any
2
+
3
+ from panda_pytest_assertions.assert_object import GeneratorFactoryProtocol, ObjectAttributes
4
+
5
+ from .._expectation_definitions import ObjectAttributesDef # noqa: TID252
6
+ from .exceptions import ObjectNotMatchingDefinitionError
7
+ from .generator import Generator
8
+
9
+
10
+ class ObjectAttributesGenerator(Generator):
11
+ """
12
+ Generates ObjectAttributes expectation.
13
+ """
14
+
15
+ @classmethod
16
+ def matches(cls, definition: Any) -> bool: # noqa: ANN401
17
+ """
18
+ Decide whether provided definiton can be handled by this generator.
19
+
20
+ This generator can handle ObjectAttributesDef definition.
21
+
22
+ :param definition: definition to be tested
23
+ :return: whether definition can be handled by this generator
24
+ """
25
+ return isinstance(definition, ObjectAttributesDef)
26
+
27
+ def __init__(
28
+ self,
29
+ generator_factory: type[GeneratorFactoryProtocol],
30
+ definition: ObjectAttributesDef,
31
+ ) -> None:
32
+ super().__init__(generator_factory, definition)
33
+ self.attributes_generators = {
34
+ attr_name: generator_factory.create(attr_definition)
35
+ for attr_name, attr_definition in definition.attributes_definitions.items()
36
+ }
37
+
38
+ def generate_expectation(self, object_: Any) -> ObjectAttributes: # noqa: ANN401
39
+ """
40
+ Generate expectation from given object.
41
+
42
+ :param object_: an object to generate expectation from
43
+ :return: generated expectation
44
+ """
45
+ attributes_expectations = {}
46
+ for attr_name, attr_generator in self.attributes_generators.items():
47
+ if not hasattr(object_, attr_name):
48
+ msg = f'"{object_}" does not have an attribute names "{attr_name}"'
49
+ raise ObjectNotMatchingDefinitionError(msg)
50
+ attributes_expectations[attr_name] = attr_generator.generate_expectation(
51
+ getattr(object_, attr_name),
52
+ )
53
+ return ObjectAttributes(attributes_expectations)
@@ -0,0 +1,47 @@
1
+ from types import NoneType
2
+ from typing import Any
3
+
4
+ from panda_pytest_assertions.assert_object import GeneratorFactoryProtocol
5
+
6
+ from .._expectation_definitions import OfTypeDef # noqa: TID252
7
+ from .exceptions import ObjectNotMatchingDefinitionError
8
+ from .generator import Generator
9
+
10
+
11
+ class OfTypeGenerator(Generator):
12
+ """
13
+ Generates custom expectation, but only if the object is of a correct type.
14
+ """
15
+
16
+ @classmethod
17
+ def matches(cls, definition: Any) -> bool: # noqa: ANN401
18
+ """
19
+ Decide whether provided definiton can be handled by this generator.
20
+
21
+ This generator can handle OfTypeDef definition.
22
+
23
+ :param definition: definition to be tested
24
+ :return: whether definition can be handled by this generator
25
+ """
26
+ return isinstance(definition, OfTypeDef)
27
+
28
+ def __init__(
29
+ self,
30
+ generator_factory: type[GeneratorFactoryProtocol],
31
+ definition: OfTypeDef,
32
+ ) -> None:
33
+ super().__init__(generator_factory, definition)
34
+ self.object_generator = generator_factory.create(definition.object_definition)
35
+ self.expected_type = definition.expected_type if definition.expected_type is not None else NoneType
36
+
37
+ def generate_expectation(self, object_: Any) -> Any: # noqa: ANN401
38
+ """
39
+ Generate expectation from given object.
40
+
41
+ :param object_: an object to generate expectation from
42
+ :return: generated expectation
43
+ """
44
+ if not isinstance(object_, self.expected_type):
45
+ msg = f'Object is expected to be "{self.expected_type}" type. Got "{type(object_)}".'
46
+ raise ObjectNotMatchingDefinitionError(msg)
47
+ return self.object_generator.generate_expectation(object_)
@@ -0,0 +1,55 @@
1
+ from collections.abc import Iterable
2
+ from typing import Any
3
+
4
+ from panda_pytest_assertions.assert_object import GeneratorFactoryProtocol
5
+
6
+ from .exceptions import ObjectNotMatchingDefinitionError
7
+ from .generator import Generator
8
+
9
+
10
+ class OrderedGenerator(Generator):
11
+ """
12
+ Generates ordered collection expectation.
13
+ """
14
+
15
+ @classmethod
16
+ def matches(cls, definition: Any) -> bool: # noqa: ANN401
17
+ """
18
+ Decide whether provided definiton can be handled by this generator.
19
+
20
+ This generator can handle any list or tuple definition.
21
+
22
+ :param definition: definition to be tested
23
+ :return: whether definition can be handled by this generator
24
+ """
25
+ return isinstance(definition, list | tuple)
26
+
27
+ def __init__(
28
+ self,
29
+ generator_factory: type[GeneratorFactoryProtocol],
30
+ definition: list[Any] | tuple[Any, ...],
31
+ ) -> None:
32
+ super().__init__(generator_factory, definition)
33
+ self.elements_generators = [generator_factory.create(element) for element in definition]
34
+ self.expectation_type = type(definition)
35
+
36
+ def generate_expectation(self, object_: Any) -> list[Any] | tuple[Any, ...]: # noqa: ANN401
37
+ """
38
+ Generate expectation from given object.
39
+
40
+ :param object_: an object to generate expectation from
41
+ :return: generated expectation
42
+ """
43
+ if not isinstance(object_, Iterable):
44
+ msg = f'Expected iterale, got {type(object_)}'
45
+ raise ObjectNotMatchingDefinitionError(msg)
46
+ elements = list(object_)
47
+ if len(elements) != len(self.elements_generators):
48
+ msg = (
49
+ f'Object has incorrect lenght. Expected {len(self.elements_generators)}, got {len(elements)}.'
50
+ )
51
+ raise ObjectNotMatchingDefinitionError(msg)
52
+ return self.expectation_type(
53
+ generator.generate_expectation(element)
54
+ for element, generator in zip(elements, self.elements_generators, strict=True)
55
+ )
@@ -0,0 +1,35 @@
1
+ from typing import Any
2
+
3
+ from panda_pytest_assertions.assert_object import Stringified
4
+
5
+ from .._expectation_definitions import StringifiedDef # noqa: TID252
6
+ from .generator import Generator
7
+
8
+
9
+ class StringifiedGenerator(Generator):
10
+ """
11
+ Generates Stringified expectation from the object.
12
+ """
13
+
14
+ @classmethod
15
+ def matches(cls, definition: Any) -> bool: # noqa: ANN401
16
+ """
17
+ Decide whether provided definiton can be handled by this generator.
18
+
19
+ This generator can handle StringifiedDef definition.
20
+
21
+ :param definition: definition to be tested
22
+ :return: whether definition can be handled by this generator
23
+ """
24
+ return isinstance(definition, StringifiedDef) or (
25
+ isinstance(definition, type) and issubclass(definition, StringifiedDef)
26
+ )
27
+
28
+ def generate_expectation(self, object_: Any) -> Any: # noqa: ANN401
29
+ """
30
+ Generate Stringified expectation from given object.
31
+
32
+ :param object_: an object to generate expectation from
33
+ :return: generated expectation
34
+ """
35
+ return Stringified(str(object_))
@@ -0,0 +1,50 @@
1
+ from collections.abc import Mapping
2
+ from typing import Any
3
+
4
+ from panda_pytest_assertions.assert_object import GeneratorFactoryProtocol
5
+
6
+ from .._expectation_definitions import UniformMappingDef # noqa: TID252
7
+ from .exceptions import ObjectNotMatchingDefinitionError
8
+ from .generator import Generator
9
+
10
+
11
+ class UniformMappingGenerator(Generator):
12
+ """
13
+ Generates mapping expectation using the same definition for each value.
14
+ """
15
+
16
+ @classmethod
17
+ def matches(cls, definition: Any) -> bool: # noqa: ANN401
18
+ """
19
+ Decide whether provided definiton can be handled by this generator.
20
+
21
+ This generator can handle UniformMappingDef definition.
22
+
23
+ :param definition: definition to be tested
24
+ :return: whether definition can be handled by this generator
25
+ """
26
+ return isinstance(definition, UniformMappingDef)
27
+
28
+ def __init__(
29
+ self,
30
+ generator_factory: type[GeneratorFactoryProtocol],
31
+ definition: UniformMappingDef,
32
+ ) -> None:
33
+ super().__init__(generator_factory, definition)
34
+ self.keys_generator = generator_factory.create(definition.keys_definition)
35
+ self.values_generator = generator_factory.create(definition.values_definition)
36
+
37
+ def generate_expectation(self, object_: Any) -> Mapping[Any, Any]: # noqa: ANN401
38
+ """
39
+ Generate expectation from given object.
40
+
41
+ :param object_: an object to generate expectation from
42
+ :return: generated expectation
43
+ """
44
+ if not isinstance(object_, Mapping):
45
+ msg = f'Expected mapping, got {type(object_)}'
46
+ raise ObjectNotMatchingDefinitionError(msg)
47
+ return {
48
+ self.keys_generator.generate_expectation(key): self.values_generator.generate_expectation(value)
49
+ for key, value in object_.items()
50
+ }
@@ -0,0 +1,52 @@
1
+ from collections.abc import Mapping
2
+ from typing import Any
3
+
4
+ from panda_pytest_assertions.assert_object import GeneratorFactoryProtocol, MappingSubset
5
+
6
+ from .._expectation_definitions import UniformMappingSubsetDef # noqa: TID252
7
+ from .exceptions import ObjectNotMatchingDefinitionError
8
+ from .generator import Generator
9
+
10
+
11
+ class UniformMappingSubsetGenerator(Generator):
12
+ """
13
+ Generates MappingSubset expectation using the same definition for each value.
14
+ """
15
+
16
+ @classmethod
17
+ def matches(cls, definition: Any) -> bool: # noqa: ANN401
18
+ """
19
+ Decide whether provided definiton can be handled by this generator.
20
+
21
+ This generator can handle UniformMappingSubsetDef definition.
22
+
23
+ :param definition: definition to be tested
24
+ :return: whether definition can be handled by this generator
25
+ """
26
+ return isinstance(definition, UniformMappingSubsetDef)
27
+
28
+ def __init__(
29
+ self,
30
+ generator_factory: type[GeneratorFactoryProtocol],
31
+ definition: UniformMappingSubsetDef,
32
+ ) -> None:
33
+ super().__init__(generator_factory, definition)
34
+ self.keys_generator = generator_factory.create(definition.keys_definition)
35
+ self.values_generator = generator_factory.create(definition.values_definition)
36
+
37
+ def generate_expectation(self, object_: Any) -> MappingSubset: # noqa: ANN401
38
+ """
39
+ Generate expectation from given object.
40
+
41
+ :param object_: an object to generate expectation from
42
+ :return: generated expectation
43
+ """
44
+ if not isinstance(object_, Mapping):
45
+ msg = f'Expected mapping, got {type(object_)}'
46
+ raise ObjectNotMatchingDefinitionError(msg)
47
+ items_expectations = {}
48
+ for key, value in object_.items():
49
+ key_expectation = self.keys_generator.generate_expectation(key)
50
+ value_expectation = self.values_generator.generate_expectation(value)
51
+ items_expectations[key_expectation] = value_expectation
52
+ return MappingSubset(items_expectations)
@@ -0,0 +1,49 @@
1
+ from collections.abc import Iterable
2
+ from typing import Any
3
+
4
+ from panda_pytest_assertions.assert_object import GeneratorFactoryProtocol
5
+
6
+ from .._expectation_definitions import UniformOrderedDef # noqa: TID252
7
+ from .exceptions import ObjectNotMatchingDefinitionError
8
+ from .generator import Generator
9
+
10
+
11
+ class UniformOrderedGenerator(Generator):
12
+ """
13
+ Generates ordered collection expectation using the same definition for each element.
14
+ """
15
+
16
+ @classmethod
17
+ def matches(cls, definition: Any) -> bool: # noqa: ANN401
18
+ """
19
+ Decide whether provided definiton can be handled by this generator.
20
+
21
+ This generator can handle OrderedDef definition.
22
+
23
+ :param definition: definition to be tested
24
+ :return: whether definition can be handled by this generator
25
+ """
26
+ return isinstance(definition, UniformOrderedDef)
27
+
28
+ def __init__(
29
+ self,
30
+ generator_factory: type[GeneratorFactoryProtocol],
31
+ definition: UniformOrderedDef,
32
+ ) -> None:
33
+ super().__init__(generator_factory, definition)
34
+ self.elements_generator = generator_factory.create(definition.elements_definition)
35
+ self.expectation_type = definition.expectation_type
36
+
37
+ def generate_expectation(self, object_: Any) -> list[Any] | tuple[Any, ...]: # noqa: ANN401
38
+ """
39
+ Generate expectation from given object.
40
+
41
+ :param object_: an object to generate expectation from
42
+ :return: generated expectation
43
+ """
44
+ if not isinstance(object_, Iterable):
45
+ msg = f'Expected iterale, got {type(object_)}'
46
+ raise ObjectNotMatchingDefinitionError(msg)
47
+ return self.expectation_type(
48
+ self.elements_generator.generate_expectation(element) for element in object_
49
+ )
@@ -0,0 +1,51 @@
1
+ from typing import Any
2
+
3
+ from panda_pytest_assertions.assert_object import GeneratorFactoryProtocol
4
+
5
+ from .._expectation_definitions import UnionDef # noqa: TID252
6
+ from .exceptions import ObjectNotMatchingDefinitionError
7
+ from .generator import Generator
8
+
9
+
10
+ class UnionGenerator(Generator):
11
+ """
12
+ Generates expectation using the first definition that matches the value.
13
+ """
14
+
15
+ @classmethod
16
+ def matches(cls, definition: Any) -> bool: # noqa: ANN401
17
+ """
18
+ Decide whether provided definiton can be handled by this generator.
19
+
20
+ This generator can handle UniformMappingDef definition.
21
+
22
+ :param definition: definition to be tested
23
+ :return: whether definition can be handled by this generator
24
+ """
25
+ return isinstance(definition, UnionDef)
26
+
27
+ def __init__(
28
+ self,
29
+ generator_factory: type[GeneratorFactoryProtocol],
30
+ definition: UnionDef,
31
+ ) -> None:
32
+ super().__init__(generator_factory, definition)
33
+ self.generators = tuple(
34
+ generator_factory.create(single_definition) for single_definition in definition.definitions
35
+ )
36
+
37
+ def generate_expectation(self, object_: Any) -> Any: # noqa: ANN401
38
+ """
39
+ Generate expectation from given object.
40
+
41
+ :param object_: an object to generate expectation from
42
+ :return: generated expectation
43
+ """
44
+ exceptions = []
45
+ for generator in self.generators:
46
+ try:
47
+ return generator.generate_expectation(object_)
48
+ except ObjectNotMatchingDefinitionError as exc:
49
+ exceptions.append(exc)
50
+ msg = f'Object "{object_}" did not match any of the expectation definition. Errors: {exceptions!r}'
51
+ raise ObjectNotMatchingDefinitionError(msg)
@@ -0,0 +1,46 @@
1
+ from collections.abc import Iterable
2
+ from typing import Any
3
+
4
+ from panda_pytest_assertions.assert_object import GeneratorFactoryProtocol, Unordered
5
+
6
+ from .._expectation_definitions import UniformUnorderedDef # noqa: TID252
7
+ from .exceptions import ObjectNotMatchingDefinitionError
8
+ from .generator import Generator
9
+
10
+
11
+ class UnorderedGenerator(Generator):
12
+ """
13
+ Generates unordered collection expectation.
14
+ """
15
+
16
+ @classmethod
17
+ def matches(cls, definition: Any) -> bool: # noqa: ANN401
18
+ """
19
+ Decide whether provided definiton can be handled by this generator.
20
+
21
+ This generator can handle UniformUnorderedDef definition.
22
+
23
+ :param definition: definition to be tested
24
+ :return: whether definition can be handled by this generator
25
+ """
26
+ return isinstance(definition, UniformUnorderedDef)
27
+
28
+ def __init__(
29
+ self,
30
+ generator_factory: type[GeneratorFactoryProtocol],
31
+ definition: UniformUnorderedDef,
32
+ ) -> None:
33
+ super().__init__(generator_factory, definition)
34
+ self.elements_generator = generator_factory.create(definition.elements_definition)
35
+
36
+ def generate_expectation(self, object_: Any) -> Unordered: # noqa: ANN401
37
+ """
38
+ Generate expectation from given object.
39
+
40
+ :param object_: an object to generate expectation from
41
+ :return: generated expectation
42
+ """
43
+ if not isinstance(object_, Iterable):
44
+ msg = f'Expected iterale, got {type(object_)}'
45
+ raise ObjectNotMatchingDefinitionError(msg)
46
+ return Unordered([self.elements_generator.generate_expectation(element) for element in object_])
@@ -0,0 +1,46 @@
1
+ from typing import Any
2
+
3
+ from panda_pytest_assertions.assert_object import GeneratorFactoryProtocol, WithType
4
+
5
+ from .._expectation_definitions import WithTypeDef # noqa: TID252
6
+ from .generator import Generator
7
+
8
+
9
+ class WithTypeGenerator(Generator):
10
+ """
11
+ Generates WithType expectation.
12
+ """
13
+
14
+ @classmethod
15
+ def matches(cls, definition: Any) -> bool: # noqa: ANN401
16
+ """
17
+ Decide whether provided definiton can be handled by this generator.
18
+
19
+ This generator can handle WithTypeDef definition.
20
+
21
+ :param definition: definition to be tested
22
+ :return: whether definition can be handled by this generator
23
+ """
24
+ return isinstance(definition, WithTypeDef)
25
+
26
+ def __init__(
27
+ self,
28
+ generator_factory: type[GeneratorFactoryProtocol],
29
+ definition: WithTypeDef,
30
+ ) -> None:
31
+ super().__init__(generator_factory, definition)
32
+ self.object_generator = generator_factory.create(definition.object_definition)
33
+ self.include_module = definition.include_module
34
+
35
+ def generate_expectation(self, object_: Any) -> WithType: # noqa: ANN401
36
+ """
37
+ Generate expectation from given object.
38
+
39
+ :param object_: an object to generate expectation from
40
+ :return: generated expectation
41
+ """
42
+ return WithType(
43
+ self.object_generator.generate_expectation(object_),
44
+ object_.__class__.__name__,
45
+ object_.__class__.__module__ if self.include_module else None,
46
+ )
File without changes