Skip to content

Expectation Definitions#

An expectation definition describes the desired structure of an expectation that will be generated from a values object. It can be any class, as long as there is an expectation generator registered for it in the used generator factory.

Out-of-the-Box Expectations#

The module comes with several generic expectation generators that support the following expectation definition types:

  1. Built-in Classes:

    • Mapping (from collections.abc)
    • list or tuple
  2. Special Expectation Classes (importable from panda_pytest_assertions.assert_object.generators):

    • EqualityDef
    • StringifiedDef
    • IsTypeDef
    • MappingDef
    • MappingSubsetDef
    • UniformMappingDef
    • UniformMappingSubsetDef
    • UniformUnorderedDef
    • UniformOrderedDef
    • ObjectAttributesDef
    • OfTypeDef
    • WithTypeDef
    • UnionDef

EqualityDef#

The simplest expectation definition is EqualityDef. While not very useful by itself, it becomes valuable when building complex definitions. It means that the object will be used as an expectation as is.

Example usage:

Python
1
2
3
4
5
object_ = {
    1: {'color': 'brown', 'legs': 4},
    2: {'fur': False, 'env': 'water'},
}
definition = EqualityDef
Generated expectation
1
2
3
4
5
6
1:
  color: brown
  legs: 4
2:
  env: water
  fur: false

Notes:

  • It can be used as a class or as an instance of the class.

StringifiedDef#

Another trivial definition, mostly used as a nested one, is StringifiedDef. It generates a Stringified expectation with the value equal to the stringified object.

Example usage:

Python
1
2
3
4
5
object_ = {
    1: {'color': 'brown', 'legs': 4},
    2: {'fur': False, 'env': 'water'},
}
definition = StringifiedDef
Generated expectation
!Stringified '{1: {''color'': ''brown'', ''legs'': 4}, 2: {''fur'': False, ''env'': ''water''}}'

Notes:

  • It can be used as a class or as an instance of the class.

IsTypeDef#

The IsTypeDef definition generates a IsType expectation. The constructor includes a keyword-only parameter that determines whether the values object module shall be included in the expectation (defaulting to True).

Example usage:

Python
1
2
3
4
5
6
object_ = Munch(
    xyz={'color': 'brown', 'legs': 4},
)
definition = IsTypeDef(
    include_module=True,
)
Generated expectation
1
2
3
!IsType
expected_type_module: munch
expected_type_name: Munch

Notes:

  • The values object can be of any type.
  • If include_module is set to False, the expected module name will be set to None.

Mapping#

Any Mapping can be used as an expectation definition. The definition is a mapping between keys from the object and definitions that will be used for respective values. It is used to generate an expectation that is also a mapping.

Example usage:

Python
1
2
3
4
5
6
7
8
object_ = {
    1: {'color': 'brown', 'legs': 4},
    2: {'fur': False, 'env': 'water'},
}
definition = {
    2: StringifiedDef,
    1: EqualityDef,
}
Generated expectation
1
2
3
4
1:
  color: brown
  legs: 4
2: !Stringified '{''fur'': False, ''env'': ''water''}'

Notes:

  • Values object must be an instance of collections.abc.Mapping.
  • Values object must contain the exact same keys as the definition (no more, no less).
  • Although dictionaries in Python are ordered, the order of keys in mappings does not matter for this type of definition.
  • Any supported expectation definition can be used as the value in the definition.
  • Keys of the definition and values object are extracted for comparison using .keys().
  • Keys and values are extracted from the definition using .items().
  • Values are extracted from the object using object_[key_from_definition].
  • Keys in the expectation will be used as-is without any modification.

MappingDef#

MappingDef is a slight modification of using a simple mapping. It is also used to generate a mapping expectation, but the difference is that keys of the values object are not copied to the expectation as is; instead, they are processed through a custom definition (one for all keys).

Example usage:

Python
object_ = {
    1: {'color': 'brown', 'legs': 4},
    2: {'fur': False, 'env': 'water'},
}
definition = MappingDef(
    StringifiedDef,
    {
        2: StringifiedDef,
        1: EqualityDef,
    },
)
Generated expectation
1
2
3
4
!Stringified '2': !Stringified '{''fur'': False, ''env'': ''water''}'
!Stringified '1':
  color: brown
  legs: 4

Notes:

  • Values object must be an instance of collections.abc.Mapping.
  • Values object must contain the exact same keys as the definition (no more, no less).
  • Although dictionaries in Python are ordered, the order of keys in mappings does not matter for this type of definition.
  • Any supported expectation definition can be used as the value in the definition.
  • Keys of the definition and values object are extracted for comparison using .keys().
  • Keys and values are extracted from the definition using .items().
  • Values are extracted from the object using object_[key_from_definition].

MappingSubsetDef#

MappingSubsetDef is a slight modification of a MappingDef. It generates a MappingSubset expectation instead of a dictionary, and values object can have more keys than the definition, which will just be skipped.

Example usage:

Python
object_ = {
    1: {'color': 'brown', 'legs': 4},
    2: {'fur': False, 'env': 'water'},
}
definition = MappingSubsetDef(
    StringifiedDef,
    {
        2: StringifiedDef,
    },
)
Generated expectation
!MappingSubset
!Stringified '2': !Stringified '{''fur'': False, ''env'': ''water''}'

Notes:

  • Values object must be an instance of collections.abc.Mapping.
  • Values object must have at least the same keys as the definition (it can contain more).
  • Although dictionaries in Python are ordered, the order of keys in mappings does not matter for this type of definition.
  • Any supported expectation definition can be used as the value in the definition.
  • Keys and values are extracted from the definition using .items().
  • Values are extracted from the object using object_[key_from_definition].

UniformMappingDef#

UniformMappingDef is a slight modification of a MappingDef. It also generates a mapping expectation, but the difference is that it accepts a single definition that will be used for all values.

Example usage:

Python
1
2
3
4
5
6
7
8
9
object_ = {
    1: {'color': 'brown', 'legs': 4},
    2: {'fur': False, 'env': 'water'},
}

definition = UniformMappingDef(
    StringifiedDef,  # definition for keys
    StringifiedDef,  # definition for values
)
Generated expectation
!Stringified '1': !Stringified '{''color'': ''brown'', ''legs'': 4}'
!Stringified '2': !Stringified '{''fur'': False, ''env'': ''water''}'

Notes:

  • Values object must be an instance of collections.abc.Mapping.
  • Any supported expectation definition can be used as the value in the definition.
  • Keys and values are extracted from the values object using .items().

UniformMappingSubsetDef#

UniformMappingSubsetDef is a slight modification of UniformMappingDef. The difference is that it generates a MappingSubset expectation instead of a dictionary.

Example usage:

Python
1
2
3
4
5
6
7
8
9
object_ = {
    1: {'color': 'brown', 'legs': 4},
    2: {'fur': False, 'env': 'water'},
}

definition = UniformMappingSubsetDef(
    StringifiedDef,  # definition for keys
    StringifiedDef,  # definition for values
)
Generated expectation
1
2
3
!MappingSubset
!Stringified '1': !Stringified '{''color'': ''brown'', ''legs'': 4}'
!Stringified '2': !Stringified '{''fur'': False, ''env'': ''water''}'

Notes:

  • Values object must be an instance of collections.abc.Mapping.
  • Any supported expectation definition can be used as the value in the definition.
  • Keys and values are extracted from the values object using .items().

list or tuple#

Any list or tuple can be used as an expectation definition. The definition is an iterable of definitions for values object elements. It is used to generate an expectation that is also a list or a tuple.

Example usage:

Python
1
2
3
4
5
6
7
8
9
object_ = [
    {'color': 'brown', 'legs': 4},
    {'fur': False, 'env': 'water'},
]

definition = [
    StringifiedDef,
    EqualityDef,
]
Generated expectation
1
2
3
- !Stringified '{''color'': ''brown'', ''legs'': 4}'
- env: water
  fur: false

Notes:

  • Values object must be an instance of collections.abc.Iterable.
  • Values object must contain the exact number of elements as the definition.
  • Any supported expectation definition can be used as the element in the definition.
  • The order of the elements in the definition matters; the first one will be used for the first element in the values object, and so on.
  • The produced expectation will be of the same type as the definition.

UniformOrderedDef#

UniformOrderedDef is a slight modification of using a simple list or tuple. It also generates a list or tuple expectation, but the difference is that it accepts a single definition that will be used for all elements. It also has a keyword-only parameter that decides the result expectation type (defaults to list).

Example usage:

Python
1
2
3
4
5
6
object_ = [
    {'color': 'brown', 'legs': 4},
    {'fur': False, 'env': 'water'},
]

definition = UniformOrderedDef(StringifiedDef, expectation_type=list)
Generated expectation
- !Stringified '{''color'': ''brown'', ''legs'': 4}'
- !Stringified '{''fur'': False, ''env'': ''water''}'

Notes:

  • Values object must be an instance of collections.abc.Iterable.
  • Any supported expectation definition can be used in the definition.

UniformUnorderedDef#

UniformUnorderedDef is a slight modification of UniformOrderedDef. The difference is that it produces an Unordered expectation.

Example usage:

Python
1
2
3
4
5
6
object_ = [
    {'color': 'brown', 'legs': 4},
    {'fur': False, 'env': 'water'},
]

definition = UniformUnorderedDef(StringifiedDef)
Generated expectation
1
2
3
!Unordered
- !Stringified '{''color'': ''brown'', ''legs'': 4}'
- !Stringified '{''fur'': False, ''env'': ''water''}'

Notes:

  • Values object must be an instance of collections.abc.Iterable.
  • Any supported expectation definition can be used in the definition.

ObjectAttributesDef#

The ObjectAttributesDef definition is used to generate an ObjectAttributes expectation. This definition maps attribute names from the values object to definitions that will be used to create expectations for their corresponding values.

Example usage:

Python
object_ = Munch(
    xyz={'color': 'brown', 'legs': 4},
    another='anything',
    abc={'fur': False, 'env': 'water'},
)
definition = ObjectAttributesDef(
    {
        'abc': EqualityDef,
        'xyz': StringifiedDef,
    },
)
Generated expectation
1
2
3
4
5
!ObjectAttributes
abc:
  env: water
  fur: false
xyz: !Stringified '{''color'': ''brown'', ''legs'': 4}'

Notes:

  • The values object can be of any type.
  • The values object must contain at least the attributes specified in the definition (it may contain more).
  • The order of keys in mappings does not matter.
  • Any supported expectation definition can be used as the value in the definition.
  • Checking whether an attribute exists in the values object is done using the hasattr function.
  • Values from the values object are extracted using getattr(object_, key_from_definition).

WithTypeDef#

The WithTypeDef definition generates a WithType expectation. It holds a definition that will be used to create the inner expectation. The constructor includes a keyword-only parameter that determines whether the values object module shall be included in the expectation (defaulting to True).

Example usage:

Python
object_ = Munch(
    xyz={'color': 'brown', 'legs': 4},
    another='anything',
    abc={'fur': False, 'env': 'water'},
)
definition = WithTypeDef(
    ObjectAttributesDef(
        {
            'abc': EqualityDef,
            'xyz': StringifiedDef,
        },
    ),
    include_module=True,
)
Generated expectation
1
2
3
4
5
6
7
8
!WithType
expectation: !ObjectAttributes
  abc:
    env: water
    fur: false
  xyz: !Stringified '{''color'': ''brown'', ''legs'': 4}'
expected_type_module: munch
expected_type_name: Munch

Notes:

  • The values object can be of any type.
  • Any supported expectation definition can be used as the value in the definition.
  • If include_module is set to False, the expected module name will be set to None.

UnionDef#

The UnionDef is used when the value can be of different kinds, each requiring a different definition. The expectation will be created using the first definition that is applicable for the provided values object.

Example usage:

Python
object_ = [
    Munch(abc='something'),
    123,
    Munch(xyz=True),
]
definition = UniformOrderedDef(
    UnionDef(
        ObjectAttributesDef({'abc': EqualityDef}),
        ObjectAttributesDef({'xyz': StringifiedDef}),
        StringifiedDef,
    ),
)
Generated expectation
1
2
3
4
5
- !ObjectAttributes
  abc: something
- !Stringified '123'
- !ObjectAttributes
  xyz: !Stringified 'True'

Notes:

  • The values object can be of any type.
  • Any supported expectation definition can be used as values in the definition.

OfTypeDef#

The OfTypeDef is particularly useful in combination with UnionDef. It generates an expectation only if the values object is of a specific type (or its subtype). The expectation itself is generated using the provided definition.

Example usage:

Python
object_ = [
    Munch(abc='something'),
    123,
    Munch(xyz=True),
    False,
]
definition = UniformOrderedDef(
    UnionDef(
        OfTypeDef(int, StringifiedDef),
        OfTypeDef(Munch, UniformMappingDef(EqualityDef, StringifiedDef)),
    ),
)
Generated expectation
1
2
3
4
- abc: !Stringified 'something'
- !Stringified '123'
- xyz: !Stringified 'True'
- !Stringified 'False'

Notes:

  • The values object can be of any type.
  • Any supported expectation definition can be used as values in the definition.