-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Expand file tree
/
Copy pathtest_filter_models.py
More file actions
160 lines (140 loc) · 5.08 KB
/
Copy pathtest_filter_models.py
File metadata and controls
160 lines (140 loc) · 5.08 KB
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
153
154
155
156
157
158
159
160
import pytest
from pydantic import ValidationError
from feast.filter_models import (
ComparisonFilter,
CompoundFilter,
convert_dict_to_filter,
)
class TestComparisonFilter:
@pytest.mark.parametrize("op", ["eq", "ne", "gt", "gte", "lt", "lte", "in", "nin"])
def test_valid_operators(self, op):
f = ComparisonFilter(type=op, key="field", value="x")
assert f.type == op
assert f.key == "field"
def test_rejects_invalid_operator(self):
with pytest.raises(ValidationError):
ComparisonFilter(type="like", key="field", value="x")
def test_accepts_string_value(self):
f = ComparisonFilter(type="eq", key="city", value="LA")
assert f.value == "LA"
def test_accepts_int_value(self):
f = ComparisonFilter(type="gt", key="age", value=25)
assert f.value == 25
def test_accepts_float_value(self):
f = ComparisonFilter(type="lte", key="score", value=0.95)
assert f.value == 0.95
def test_accepts_bool_value(self):
f = ComparisonFilter(type="eq", key="active", value=True)
assert f.value is True
def test_accepts_list_value(self):
f = ComparisonFilter(type="in", key="status", value=["a", "b"])
assert f.value == ["a", "b"]
class TestCompoundFilter:
def test_and_filter(self):
f = CompoundFilter(
type="and",
filters=[
ComparisonFilter(type="eq", key="a", value=1),
ComparisonFilter(type="gt", key="b", value=2),
],
)
assert f.type == "and"
assert len(f.filters) == 2
def test_or_filter(self):
f = CompoundFilter(
type="or",
filters=[
ComparisonFilter(type="eq", key="a", value=1),
ComparisonFilter(type="eq", key="b", value=2),
],
)
assert f.type == "or"
assert len(f.filters) == 2
def test_rejects_invalid_type(self):
with pytest.raises(ValidationError):
CompoundFilter(
type="xor",
filters=[ComparisonFilter(type="eq", key="a", value=1)],
)
def test_nested_compound(self):
f = CompoundFilter(
type="and",
filters=[
ComparisonFilter(type="eq", key="x", value=1),
CompoundFilter(
type="or",
filters=[
ComparisonFilter(type="gt", key="y", value=5),
ComparisonFilter(type="lt", key="z", value=10),
],
),
],
)
assert f.type == "and"
assert len(f.filters) == 2
inner = f.filters[1]
assert isinstance(inner, CompoundFilter)
assert inner.type == "or"
assert len(inner.filters) == 2
class TestConvertDictToFilter:
def test_comparison_dict(self):
result = convert_dict_to_filter({"type": "eq", "key": "city", "value": "LA"})
assert isinstance(result, ComparisonFilter)
assert result.type == "eq"
assert result.key == "city"
assert result.value == "LA"
def test_compound_dict(self):
result = convert_dict_to_filter(
{
"type": "and",
"filters": [
{"type": "eq", "key": "a", "value": 1},
{"type": "gt", "key": "b", "value": 2},
],
}
)
assert isinstance(result, CompoundFilter)
assert result.type == "and"
assert len(result.filters) == 2
assert all(isinstance(f, ComparisonFilter) for f in result.filters)
def test_nested_compound_dict(self):
result = convert_dict_to_filter(
{
"type": "or",
"filters": [
{"type": "eq", "key": "x", "value": "a"},
{
"type": "and",
"filters": [
{"type": "gt", "key": "y", "value": 5},
{"type": "lt", "key": "z", "value": 10},
],
},
],
}
)
assert isinstance(result, CompoundFilter)
assert result.type == "or"
inner = result.filters[1]
assert isinstance(inner, CompoundFilter)
assert inner.type == "and"
assert len(inner.filters) == 2
def test_or_compound_dict(self):
result = convert_dict_to_filter(
{
"type": "or",
"filters": [
{"type": "eq", "key": "a", "value": 1},
{"type": "eq", "key": "b", "value": 2},
],
}
)
assert isinstance(result, CompoundFilter)
assert result.type == "or"
def test_in_operator_dict(self):
result = convert_dict_to_filter(
{"type": "in", "key": "status", "value": ["active", "pending"]}
)
assert isinstance(result, ComparisonFilter)
assert result.type == "in"
assert result.value == ["active", "pending"]