Skip to content

Commit ddf273a

Browse files
author
Sylvain MARIE
committed
Updated tests to cover the latest changes
1 parent 0902040 commit ddf273a

5 files changed

Lines changed: 156 additions & 7 deletions

File tree

autoclass/tests/doc/test_readme_index.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,23 @@
1414
from autoclass import autoargs, autoprops, setter_override, autoclass
1515

1616

17+
def test_readme_index_pyfields():
18+
""" """
19+
from pyfields import field
20+
21+
@autoclass
22+
class House(object):
23+
name = field(check_type=True, type_hint=str, doc="the name of your house")
24+
nb_floors = field(default=100, check_type=True, type_hint=int, doc="the nb floors",
25+
validators={"should be positive": lambda x: x >= 0,
26+
"should be a multiple of 100": lambda x: x % 100 == 0})
27+
28+
h = House(name="mine")
29+
with pytest.raises(ValueError):
30+
h.nb_floors = 101
31+
assert str(h) == "House(name='mine', nb_floors=100)"
32+
33+
1734
def test_readme_index_basic():
1835
""" First basic example in the doc """
1936

@@ -23,7 +40,7 @@ def __init__(self, name, nb_floors=1):
2340
pass
2441

2542
a = House('my_house', 3)
26-
assert str(a) == "House({'name': 'my_house', 'nb_floors': 3})"
43+
assert str(a) == "House(name='my_house', nb_floors=3)"
2744
assert [att for att in a.keys()] == ['name', 'nb_floors']
2845
assert {a, a} == {a}
2946
assert a == {'name': 'my_house', 'nb_floors': 3}

autoclass/tests/doc/test_readme_usage.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,29 @@ def __init__(self,
120120
'_D__class_private': 't'} # notice the name
121121

122122

123+
def test_readme_usage_autodict_4():
124+
125+
@autodict(only_constructor_args=False, only_public_fields=False)
126+
@autoprops
127+
class D(object):
128+
@autoargs
129+
def __init__(self,
130+
a, # type: str
131+
b # type: List[str]
132+
):
133+
self.non_constructor_arg = 'b'
134+
self._private = 1
135+
self.__class_private = 't'
136+
137+
o = D(1, 'r')
138+
# o behaves like a read-only dict, all fields are now visible
139+
assert o == dict(o)
140+
assert o == {'a': 1, 'b': 'r',
141+
'non_constructor_arg': 'b',
142+
'_private': 1,
143+
'_D__class_private': 't'} # notice the name
144+
145+
123146
def test_readme_usage_autohash_1():
124147
@autohash
125148
class A(object):

autoclass/tests/features/test_autoclass.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def __init__(self, bar, foo1, foo2=0):
5050
assert list(a.keys()) == ['bar', 'foo1', 'foo2']
5151

5252
# order in prints is same than in init
53-
assert str(a) == "Bar({'bar': 2, 'foo1': 'th', 'foo2': 0})"
53+
assert str(a) == "Bar(bar=2, foo1='th', foo2=0)"
5454

5555

5656
def test_autoclass_pickle_inheritance():
@@ -66,7 +66,7 @@ def test_autoclass_pickle_inheritance():
6666
assert list(a.keys()) == ['bar', 'foo1', 'foo2']
6767

6868
# order in prints is fixed
69-
assert str(a) == "Bar({'bar': 2, 'foo1': 'th', 'foo2': 0})"
69+
assert str(a) == "Bar(bar=2, foo1='th', foo2=0)"
7070

7171
# pickle
7272
pik = pickle.dumps(a)
@@ -99,7 +99,7 @@ def __init__(self, bar, foo1, foo2=0):
9999
assert list(a.keys()) == ['bar', 'foo1', 'foo2']
100100

101101
# order in prints is fixed
102-
assert str(a) == "Bar({'bar': 2, 'foo1': 'th', 'foo2': 0})"
102+
assert str(a) == "Bar(bar=2, foo1='th', foo2=0)"
103103

104104

105105
def test_autoclass_pyfields():
@@ -126,4 +126,4 @@ class Bar(Foo):
126126
assert list(a.keys()) == ['foo1', 'foo2', 'bar']
127127

128128
# order in prints is the same than in init
129-
assert str(a) == "Bar({'foo1': 'th', 'foo2': 0, 'bar': 2})"
129+
assert str(a) == "Bar(foo1='th', foo2=0, bar=2)"

autoclass/tests/features/test_autodict.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ class Foo(object):
145145
foo1 = field()
146146
foo2 = field(default=0)
147147

148-
@autodict
148+
@autodict(legacy_str_repr=True)
149149
class Bar(Foo):
150150
bar = field()
151151

@@ -163,5 +163,5 @@ class Bar(Foo):
163163
# iteration order is correct
164164
assert list(a.keys()) == ['foo1', 'foo2', 'bar']
165165

166-
# order in prints is correct
166+
# order in prints is correct in legacy str mode
167167
assert str(a) == "Bar({'foo1': 'th', 'foo2': 0, 'bar': 2})"
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# Authors: Sylvain Marie <sylvain.marie@se.com>
2+
#
3+
# Copyright (c) Schneider Electric Industries, 2019. All right reserved.
4+
import sys
5+
6+
import pytest
7+
8+
from autoclass import autorepr
9+
10+
11+
@pytest.mark.skipif(sys.version_info < (3, 6), reason="class vars order is not preserved")
12+
@pytest.mark.parametrize('only_public_fields', [True, False], ids=lambda x: 'only_public' if x else 'including class-private dunder fields')
13+
@pytest.mark.parametrize('only_known_fields', [True, False], ids=lambda x: 'only_constructor_args' if x else 'all_obj_fields')
14+
@pytest.mark.parametrize("curly_mode", [False, True], ids="curly_mode={}".format)
15+
def test_autorepr(only_known_fields, only_public_fields, curly_mode):
16+
""" @autorepr functionality with various customization options for only_constructor_args/only_public_fields """
17+
18+
if curly_mode:
19+
def format_pairs(cls, pairs):
20+
return "%s(**{%s})" % (cls.__name__, ", ".join(["%r: %r" % pair for pair in pairs]))
21+
else:
22+
def format_pairs(cls, pairs):
23+
return "%s(%s)" % (cls.__name__, ", ".join(["%s=%r" % pair for pair in pairs]))
24+
25+
@autorepr(only_known_fields=only_known_fields, only_public_fields=only_public_fields, curly_string_repr=curly_mode)
26+
class FooConfigA(object):
27+
28+
dummy_class_field = 'just to be sure it does not appear'
29+
30+
def __init__(self,
31+
a, # type: str,
32+
b # type: List[str]
33+
):
34+
self.a = a
35+
self.b = b
36+
self.c = 't'
37+
self._weak_private = 'r'
38+
self.__class_private = 't'
39+
40+
def dummy_func(self):
41+
""" we create this just to be sure the function is not in the dict view """
42+
pass
43+
44+
t = FooConfigA('rhubarb', ['pie', 'pie2'])
45+
t.new_field = 0
46+
t._new_field_weak_private = 1
47+
t.__new_field_class_private_incorrect = 0
48+
49+
class Dummy:
50+
t.__new_field_class_private = 1
51+
52+
# check the str/repr
53+
assert str(t) == repr(t)
54+
55+
if only_known_fields:
56+
pairs = [('a', 'rhubarb'), # only the two constructor fields appear
57+
('b', ['pie', 'pie2'])]
58+
elif only_public_fields:
59+
pairs = [('a', 'rhubarb'),
60+
('b', ['pie', 'pie2']),
61+
('c', 't'),
62+
# _FooConfigA__class_private should not appear
63+
('new_field', 0)
64+
#'_weak_private': 'r',
65+
#'_new_field_weak_private': 1,
66+
# private fields defined out of the objects class are still visible
67+
#'__new_field_class_private_incorrect': 0,
68+
#'_Dummy__new_field_class_private': 1
69+
]
70+
else:
71+
pairs = [('a', 'rhubarb'),
72+
('b', ['pie', 'pie2']),
73+
('c', 't'),
74+
('_weak_private', 'r'),
75+
('_FooConfigA__class_private', 't'), # <= this is the one private field that appears now
76+
('new_field', 0),
77+
('_new_field_weak_private', 1),
78+
# private fields defined out of the objects class are still visible
79+
('__new_field_class_private_incorrect', 0),
80+
('_Dummy__new_field_class_private', 1)]
81+
82+
assert str(t) == format_pairs(FooConfigA, pairs)
83+
84+
85+
@pytest.mark.parametrize("curly_mode", [False, True], ids="curly_mode={}".format)
86+
def test_autorepr_pyfields(curly_mode):
87+
"""tests that @autorepr works with pyfields"""
88+
89+
from pyfields import field
90+
91+
@autorepr
92+
class Foo(object):
93+
foo1 = field()
94+
foo2 = field(default=0)
95+
96+
@autorepr(curly_string_repr=curly_mode)
97+
class Bar(Foo):
98+
bar = field()
99+
100+
# create an object manually
101+
a = Bar()
102+
a.bar = 2
103+
a.foo1 = 'th'
104+
105+
# order in prints is correct in legacy str mode
106+
if curly_mode:
107+
assert str(a) == "Bar(**{'foo1': 'th', 'foo2': 0, 'bar': 2})"
108+
else:
109+
assert str(a) == "Bar(foo1='th', foo2=0, bar=2)"

0 commit comments

Comments
 (0)