Skip to content

Commit 525dda7

Browse files
committed
tests and fixes for field
1 parent a544dfc commit 525dda7

File tree

3 files changed

+172
-9
lines changed

3 files changed

+172
-9
lines changed

aiorethink/field.py

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
class Field:
99
"""Field instances are attached to FieldContainer classes as class attributes.
1010
11-
Field implements __get__ and __set__ for attribute access on FieldContainer
12-
instances. This way, Field instances store values in a FieldContainer
13-
instance.
11+
Field is a data descriptor, i.e. it implements __get__ and __set__ for
12+
attribute access on FieldContainer instances. This way, Field instances
13+
store values in a FieldContainer instance.
1414
1515
A Field instance has an associated ValueType instance, which takes care of
1616
DB<->Python world value conversion and value validation.
@@ -49,11 +49,7 @@ def __init__(self, val_type = None, **kwargs):
4949
validate_default_now = True
5050
del kwargs["default"]
5151

52-
# now that we popped all our args off kwargs, we call parent's
53-
# constructor
54-
super().__init__(**kwargs)
55-
56-
# finally, validate the default value if we have to
52+
# validate the default value if we have to
5753
if validate_default_now:
5854
try:
5955
self.validate(self._default)
@@ -102,7 +98,7 @@ def __repr__(self):
10298

10399

104100
###########################################################################
105-
# value access
101+
# value access (data descriptor protocol ++)
106102
###########################################################################
107103

108104
def __get__(self, obj, cls):

aiorethink/values_and_valuetypes/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
from .simple_types import *
33
from .simple_containers import *
44
from .lazy import *
5+
from .field_container import *
56
from .reference import *

tests/a_unit/test_30_field.py

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
import asyncio
2+
3+
import pytest
4+
import rethinkdb as r
5+
6+
import aiorethink as ar
7+
8+
9+
###############################################################################
10+
# Field and FieldAlias in isolation (i.e. not as class attribute in a
11+
# FieldContainer)
12+
###############################################################################
13+
14+
def test_basic_field():
15+
f = ar.Field()
16+
17+
assert isinstance(f.val_type, ar.AnyValueType)
18+
19+
assert f.name == None
20+
assert f.dbname == None # this is never the case when the field is inside a FieldContainer
21+
f.name = "f" # because this is done by FieldContainer
22+
assert f.name == "f"
23+
assert f.dbname == "f"
24+
25+
assert not f.indexed
26+
assert not f.required
27+
assert not f.primary_key
28+
assert f.default == None
29+
30+
assert f.validate(None) == f
31+
assert f.validate(1) == f
32+
assert f.validate("hello") == f
33+
34+
35+
def test_field_with_type():
36+
f = ar.Field(ar.IntValueType())
37+
38+
assert f.validate(1) == f
39+
with pytest.raises(ar.ValidationError):
40+
f.validate("hello")
41+
42+
43+
def test_field_with_type_and_default():
44+
with pytest.raises(ar.IllegalSpecError):
45+
f = ar.Field(ar.IntValueType(), default = "hello")
46+
47+
f = ar.Field(ar.StringValueType(), default = "hello")
48+
49+
50+
def test_field_properties():
51+
f = ar.Field(default = "hello")
52+
assert f.default == "hello"
53+
54+
f = ar.Field(indexed = True)
55+
assert f.indexed == True
56+
57+
f = ar.Field(required = True)
58+
with pytest.raises(ar.ValidationError):
59+
f.validate(None)
60+
assert f.validate(10) == f
61+
62+
f = ar.Field(primary_key = True)
63+
assert f.primary_key == True
64+
65+
with pytest.raises(ar.IllegalSpecError):
66+
f = ar.Field(indexed = True, primary_key = True)
67+
68+
f = ar.Field(name = "dbf")
69+
assert f.dbname == "dbf"
70+
f.name = "f" # this is what FieldContainer does
71+
assert f.name == "f"
72+
assert f.dbname == "dbf"
73+
74+
75+
def test_repr():
76+
f = ar.Field()
77+
assert "dbname" in repr(f)
78+
79+
80+
def test_fieldalias():
81+
f = ar.Field(ar.IntValueType())
82+
f.name = "f"
83+
fa = ar.FieldAlias(f)
84+
85+
for attr in ["name", "dbname", "indexed", "required", "default", "validate"]:
86+
assert getattr(fa, attr) == getattr(f, attr)
87+
88+
assert "fld_name=f" in repr(fa)
89+
90+
91+
###############################################################################
92+
# Field and FieldAlias inside FieldContainer
93+
###############################################################################
94+
95+
def test_simple_field_inside_container():
96+
class FC(ar.FieldContainer):
97+
f = ar.Field()
98+
fa = ar.FieldAlias(f)
99+
100+
assert FC.f.name == "f"
101+
assert FC.fa.name == "f"
102+
103+
104+
def test_simple_get_set_delete():
105+
class FC(ar.FieldContainer):
106+
f1 = ar.Field()
107+
f1a = ar.FieldAlias(f1)
108+
fc = FC()
109+
110+
assert fc.f1 == None
111+
assert fc.f1a == None
112+
fc.f1 = 1
113+
assert fc.f1 == 1
114+
assert fc.f1a == 1
115+
fc.f1a = 2
116+
assert fc.f1 == 2
117+
assert fc.f1a == 2
118+
del fc.f1
119+
assert fc.f1 == None
120+
assert fc.f1a == None
121+
del fc.f1a
122+
assert fc.f1 == None
123+
assert fc.f1a == None
124+
fc.f1a = 1
125+
assert fc.f1 == 1
126+
assert fc.f1a == 1
127+
del fc.f1a
128+
assert fc.f1 == None
129+
assert fc.f1a == None
130+
131+
132+
def test_default_value():
133+
class FC(ar.FieldContainer):
134+
f = ar.Field(default = 10)
135+
fc = FC()
136+
137+
assert fc.f == 10
138+
fc.f = 1
139+
assert fc.f == 1
140+
del fc.f
141+
assert fc.f == 10
142+
del fc.f
143+
assert fc.f == 10
144+
145+
146+
def test_field_to_doc():
147+
class FC(ar.FieldContainer):
148+
f1 = ar.Field()
149+
fc = FC()
150+
151+
e = fc.to_doc()
152+
assert e["f1"] == None
153+
154+
fc.f1 = 1
155+
e = fc.to_doc()
156+
assert e["f1"] == 1
157+
158+
159+
def test_field_from_doc():
160+
class FC(ar.FieldContainer):
161+
f1 = ar.Field()
162+
163+
doc = { "f1": "hello" }
164+
fc = FC.from_doc(doc)
165+
166+
assert fc.f1 == "hello"

0 commit comments

Comments
 (0)