File: test_field.py

package info (click to toggle)
python-odmantic 1.0.2-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, trixie
  • size: 1,640 kB
  • sloc: python: 8,547; sh: 37; makefile: 34; xml: 13; javascript: 3
file content (113 lines) | stat: -rw-r--r-- 3,034 bytes parent folder | download | duplicates (2)
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
from datetime import datetime
from typing import Optional

import pytest

import odmantic
from odmantic.field import Field
from odmantic.model import EmbeddedModel, Model
from odmantic.reference import Reference


def test_field_defined_as_primary_key_and_custom_name():
    with pytest.raises(
        ValueError, match="cannot specify a primary field with a custom key_name"
    ):
        Field(primary_field=True, key_name="not _id")


def test_field_defined_as_primary_key_default_name():
    f = Field(primary_field=True)
    assert f.key_name == "_id"


def test_field_define_key_as__id_without_setting_as_primary():
    with pytest.raises(
        ValueError,
        match="cannot specify key_name='_id' without defining the field as primary",
    ):
        Field(key_name="_id")


def test_pos_key_name():
    class M(Model):
        field: int = Field(key_name="alternate_name")

    assert +M.field == "alternate_name"
    assert ++M.field == "$alternate_name"


def test_unknown_attr_embedded_model():
    class E(EmbeddedModel): ...

    class M(Model):
        field: E

    with pytest.raises(AttributeError):
        M.field.unknown_attr  # type: ignore


@pytest.mark.parametrize("operator_name", ("lt", "lte", "gt", "gte", "match"))
def test_reference_field_operator_not_allowed(operator_name: str):
    class E(Model): ...

    class M(Model):
        field: E = Reference()

    with pytest.raises(
        AttributeError,
        match=f"operator {operator_name} not allowed for ODMReference fields",
    ):
        getattr(M.field, operator_name)


def test_field_required_in_doc_without_default():
    class M(Model):
        field: str

    assert M.__odm_fields__["field"].is_required_in_doc()


def test_field_required_in_doc_with_default():
    class M(Model):
        field: str = Field("hi")

    assert not M.__odm_fields__["field"].is_required_in_doc()


def test_field_required_in_doc_default_factory_disabled():
    class M(Model):
        field: str = Field(default_factory=lambda: "hi")  # pragma: no cover

    assert M.__odm_fields__["field"].is_required_in_doc()


def test_field_required_in_doc_default_factory_enabled():
    class M(Model):
        field: str = Field(default_factory=lambda: "hi")  # pragma: no cover

        model_config = {
            "parse_doc_with_default_factories": True,
        }

    assert not M.__odm_fields__["field"].is_required_in_doc()


def test_multiple_optional_fields():
    class M(Model):
        field: str = Field(default_factory=lambda: "hi")  # pragma: no cover
        optionalBoolField: Optional[bool] = None
        optionalDatetimeField: Optional[datetime] = None

    assert (
        M.__odm_fields__["optionalBoolField"].pydantic_field.annotation
        == Optional[bool]
    )
    assert (
        M.__odm_fields__["optionalDatetimeField"].pydantic_field.annotation
        == Optional[odmantic.bson._datetime]
    )

    instance = M(field="Hi")
    # This should work and never throw a value error
    instance.optionalBoolField = True