Coverage for test_archery.py: 99%
168 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-04-08 21:58 +0200
« prev ^ index » next coverage.py v7.8.0, created at 2025-04-08 21:58 +0200
1#/usr/bin/env python
2import os
3import sys
5import warnings
6import unittest
7from archery.bow import Hankyu, Daikyu, sdict, vdict, mdict, edict
8from archery.barrack import bowyer, Path, make_from_path, paired_row_iter
10from math import sqrt, cos, pi, sin, acos
12class TestDeprecation(unittest.TestCase):
13 def test_deprec_edict(self):
14 """ edict (ExpDict is becoming searchable """
15 with warnings.catch_warnings(record=True) as w:
16 warnings.simplefilter('always')
17 edict(x=1)
18 self.assertTrue(
19 issubclass(w[-1].category, DeprecationWarning),
20 )
22class TestKyleExpectation(unittest.TestCase):
24 def test_commutativity(self):
25 a = mdict({"a": 1, "y": {"b": 4, "c": [5]}})
26 b= mdict({"a": 1, "x": 5, "y": {"b": 6, "c": [12]}})
27 expected_ab = {"a": 2, "x": 5, "y": {"b": 10, "c": [5, 12]}}
28 expected_ba = {"a": 2, "x": 5, "y": {"b": 10, "c": [12, 5]}}
29 self.assertEqual(a + b, expected_ab)
30 a = mdict({"a": 1, "y": mdict({"b": 4, "c": [5]})})
31 b= mdict({"a": 1, "x": 5, "y": mdict({"b": 6, "c": [12]})})
32 self.assertEqual(b + a, expected_ba)
33 a = mdict({"a": 1, "y": mdict({"b": 4, "c": [5]})})
34 b= mdict({"a": 1, "x": 5, "y": mdict({"b": 6, "c": [12]})})
35 a += b
36 self.assertEqual(a, expected_ab)
39 def test_bug_iadd(self):
40 a = mdict({"a": 1, "y": mdict({"b": 4, "c": [5]})})
41 c = mdict({"a": 1, "y": mdict({"b": 4, "c": 5})})
42 b= mdict({"a": 1, "x": 5, "y": mdict({"b": 6, "c": [12]})})
43 expected_ab = {"a": 2, "x": 5, "y": {"b": 10, "c": [5, 12]}}
44 expected_ba = {"a": 2, "x": 5, "y": {"b": 10, "c": [12, 5]}}
45 self.assertEqual(a + b, expected_ab)
46 self.assertEqual(b + a, expected_ba)
47 a += b
48 c+=1
49 d=c.copy()
50 e=4
51 e+=c
52 self.assertEqual(c, d)
53 self.assertEqual(a, expected_ab)
56class TestVectorDict(unittest.TestCase):
57 """test a dict with Vector properies (cos, dot, abs)"""
59 def setUp(self):
60 self.point = vdict( x=3, y=3, z=0)
61 self.point2 = vdict( x=1, y=1, z=1)
63 def testNorm(self):
64 self.assertAlmostEqual(
65 abs(self.point),
66 sqrt(3*3+3*3)
67 )
68 def testCos(self):
69 self.assertAlmostEqual(
70 vdict(x=1,y=0).cos(vdict(x=1,y=1)),
71 cos(pi/4)
72 )
74class TestBarrack(unittest.TestCase):
75 def test_path(self):
76 self.assertEqual(
77 Path(("a","b",1)).key(),
78 ("a","b")
79 )
80 self.assertFalse(
81 Path(("a","b",1)).contains("a","b","c")
82 )
83 self.assertEqual(
84 Path(("a","b",1)).value(),
85 1
86 )
87 self.assertTrue(Path(("x", "y", 1)).startswith("x"))
88 self.assertTrue(Path(("s", "x", "y", 1)).contains("x","y"))
90 def test_paired_row_iter(self):
91 self.assertEqual(set(paired_row_iter(dict(x=1, a=dict(b=dict(c=1))))),
92 { (("x",),1), (("a","b","c"), 1)}
93 )
96class TestBugWeired(unittest.TestCase):
98 def test_stay_same(self):
100 class Matrix(mdict):
101 def __call__(self, other):
102 other = other.copy()
103 res= vdict()
104 for (src, dst), functor in self.items():
105 res += mdict({ dst: functor(other[src])})
106 return res
109 theta = pi/6
111 u = mdict(x=1, y=2)
112 v = mdict(x=1, y=0)
113 alien = vdict(x=u, y=v)
115 def rotation_maker(theta):
116 """"Matrix takes as key (SRC, DST) (which is the opposite of "actual notation")
117 """
118 return Matrix({
119 ("x", "x") : lambda v:1.0 * v * cos(theta),
120 ("y", "x") : lambda v:1.0 * -v * sin(theta),
121 ("x", "y") : lambda v:1.0 * v * sin(theta),
122 ("y", "y") : lambda v:1.0 * v * cos(theta)
123 })
125 rotation = rotation_maker(pi/6)
126 self.assertAlmostEqual(
127 rotation(u),
128 {'x': -0.13397459621556118, 'y': 2.232050807568877}
129 )
130# OUT:{'x': 1, 'y': 0}
131 self.assertAlmostEqual(rotation(v),
132 {'x': 0.8660254037844387, 'y': 0.49999999999999994}
133 )
134 self.assertAlmostEqual(
135 acos(vdict(u).cos(vdict(rotation(u))))/2 / pi * 360,
136 29.999999999999993
137 )
138 self.assertEqual(u, dict(x=1, y=2))
139 self.assertAlmostEqual(acos(vdict(v).cos(vdict(rotation_maker(pi/3)(v))))/2 / pi * 360,
14060.0)
141 self.assertAlmostEqual(
142 acos(vdict(v).cos(vdict(rotation_maker(pi/5)(v))))/2 / pi * 360,
143 36.0
144 )
145 self.assertEqual(
146 alien,
147 {'x': {'x': 1, 'y': 2}, 'y': {'x': 1, 'y': 0}}
148 )
149 """
150 undefined behaviour until I can make a sense of this
154 self.assertAlmostEqual(
155 rotation_maker(pi/4)(alien),
156 {
157 'x': {'x': 1.1102230246251565e-16, 'y': 1.4142135623730951},
158 'y': {'x': -1.1102230246251565e-16, 'y': 1.414213562373095}
159 }
160 )
161 self.assertAlmostEqual(
162 acos(alien.cos(rotation_maker(pi/4)(alien)))/2 / pi * 360,
163 54.73561031724534
164 )
166 self.assertAlmostEqual(rotation_maker(pi/4)(alien),
167 {'x':
168 {'x': 1.1102230246251565e-16, 'y': 1.4142135623730951},
169 'y': {'x': -1.1102230246251565e-16, 'y': 1.414213562373095}})
170 """
173class TestSearchableDict(unittest.TestCase):
174 def setUp(self):
175 self.easy = vdict( x=1, y=1, z=0)
177 self.tree = sdict(
178 a = 1,
179 b = dict(
180 c = 3.0,
181 d = dict(e=True)
182 ),
183 point = self.easy
184 )
186 def test_rec_type(self):
187 """test that if created with another mutale mapping
188 does not converts it on the fly to himself"""
189 self.assertNotEqual(
190 type(self.tree["point"]),
191 sdict
192 )
194 def test_search(self):
195 self.assertEqual(
196 set([ x for x in self.tree.search(
197 lambda x : Path(x).contains("point","x")
198 or Path(x).endswith(3.0)
199 )
200 ]),
201 set([('b', 'c', 3.0), ('point', 'x', 1)])
202 )
203 self.assertEqual(
204 set([ x for x in self.tree.search(
205 lambda x : Path(x).startswith("a")
206 )
207 ]),
208 set([('a', 1)])
209 )
211 def test_leaf_search(self):
212 self.assertEqual(
213 [ i for i in self.tree.leaf_search(lambda x : type(x) is float)],
214 [ 3.0 ]
215 )
216 self.assertEqual(
217 [ i for i in self.tree.leaf_search(lambda x : type(x) is bool)],
218 [ True ]
219 )
225class TestHankyu(unittest.TestCase):
226 def setUp(self):
227 self.easy = Hankyu( x=1, y=1, z=0)
228 self.easy_too = Hankyu( x=0, y=-2, o=0)
230 self.a_tree = dict(
231 a = 1,
232 b = dict(
233 c = 3.0,
234 d = dict(e=True)
235 ),
236 point = self.easy
237 )
238 self.cplx = bowyer(Hankyu,self.a_tree)
240 def test_convert(self):
241 self.assertEqual(
242 bowyer(Hankyu, {'a': {'b': 1}}),
243 Hankyu( {'a': Hankyu(b=1)})
244 )
247 def test_add_not_exists(self):
248 self.easy += dict(a=1)
249 self.assertEqual(self.easy['a'], 1)
250 self.assertEqual(
251 self.easy + self.easy_too,
252 sum([ self.easy_too, self.easy])
253 )
255 def test_add_exists(self):
256 self.easy += dict(x=1)
257 self.assertEqual(self.easy['x'] , 2)
259 def test_number_inc(self):
260 self.easy += 1
261 self.assertEqual(self.easy['x'] , 2)
264 def test_bug_convert_empty_mapping(self):
265 """bug #8 : empty mapping intialisation dont work"""
266 bug = bowyer( Hankyu,dict( a={}))
267 expected = Hankyu( {'a': {}})
268 self.assertEqual(
269 expected,
270 bug
271 )
273class TestDaikyu(unittest.TestCase):
274 def setUp(self):
275 self.easy = Daikyu( x=1, y=1, z=0)
276 self.easy_too = Daikyu( x=0, y=-2, o=0)
278 self.a_tree = dict(
279 a = 1,
280 b = dict(
281 c = 3.0,
282 d = dict(e=True)
283 ),
284 point = self.easy
285 )
286 self.cplx = bowyer(Daikyu,self.a_tree)
289 def test_bug_1(self):
290 """bug #1 : * returns a copy where a reference is needed"""
291 pt = self.easy
292 pt *= -1
293 self.assertEqual(
294 self.easy,
295 pt
296 )
297 def test_bug_2(self):
298 """bug #2 : self * other without affectation should not modify self.
299 """
300 self.easy *= -1
301 a_copy = self.easy.copy()
302 self.easy * a_copy
303 self.assertEqual(
304 self.easy,
305 a_copy
306 )
309 def test_bug_4(self):
310 """bug #4 : self / other without affectation should not modify self.
311 """
312 del(self.easy['z'])
313 self.easy /= -1
314 a_copy = self.easy.copy()
315 self.easy / a_copy
316 self.assertEqual(
317 self.easy,
318 a_copy
319 )
321 def test_bug_5(self):
322 """bug #5 : int * dict without affectation should not modify self.
323 """
324 a_copy = self.easy.copy()
325 2 * self.easy
326 self.assertEqual(
327 self.easy,
328 a_copy
329 )
331 def test_bug_6(self):
332 """bug #6 : int / dict without affectation should not modify self.
333 """
334 del(self.easy['z'])
335 a_copy = self.easy.copy()
336 2.0 / self.easy
337 self.assertEqual(
338 self.easy,
339 a_copy
340 )
343 def test_for_fun(self):
344 """just for fun """
345 a = self.easy
346 b = self.easy_too
347 aa = a.copy()
348 bb = b.copy()
349 self.assertEqual(
350 (a - b) * (a + b),
351 aa * aa - bb * bb
352 )
355 def test_for_fun2(self):
356 """just for fun """
357 a = self.easy
358 b = self.easy_too
359 aa = a.copy()
360 bb = b.copy()
361 self.assertEqual(
362 -(a + b) * (a + b),
363 -1 * ((aa * aa) + 2 * aa * bb + (bb * bb))
364 )
366 def test_dyslexia_bug4(self):
367 """counfonding right & left in all r(div/add/sub/mul) operator """
368 a = self.easy
369 self.assertEqual(
370 2/Daikyu({'a':1}),
371 {'a' : 2}
372 )
373 self.assertEqual(
374 2-a,
375 -(a-2)
376 )
377 def test_inplace_bug5(self):
378 """a/b in place"""
379 a = self.easy*4
380 self.assertEqual(
381 a/{'x':2},
382 {'x' : 2}
383 )
385if __name__ == '__main__':
386 unittest.main(verbosity=4)