ucon 0.3.3rc2__py3-none-any.whl → 0.3.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,237 @@
1
+
2
+
3
+ import math
4
+ from unittest import TestCase
5
+
6
+ from ucon.algebra import Exponent, Vector
7
+
8
+
9
+ class TestVector(TestCase):
10
+
11
+ def test_vector_iteration_and_length(self):
12
+ v = Vector(1, 0, 0, 0, 0, 0, 0)
13
+ self.assertEqual(tuple(v), (1, 0, 0, 0, 0, 0, 0))
14
+ self.assertEqual(len(v), 7) # always 7 components
15
+
16
+ def test_vector_addition(self):
17
+ v1 = Vector(1, 0, 0, 0, 0, 0, 0)
18
+ v2 = Vector(0, 2, 0, 0, 0, 0, 0)
19
+ result = v1 + v2
20
+ self.assertEqual(result, Vector(1, 2, 0, 0, 0, 0, 0))
21
+
22
+ def test_vector_subtraction(self):
23
+ v1 = Vector(2, 1, 0, 0, 0, 0, 0)
24
+ v2 = Vector(1, 1, 0, 0, 0, 0, 0)
25
+ self.assertEqual(v1 - v2, Vector(1, 0, 0, 0, 0, 0, 0))
26
+
27
+ def test_vector_scalar_multiplication_by_integer(self):
28
+ v = Vector(1, -2, 0, 0, 0, 0, 3)
29
+ scaled = v * 2
30
+ self.assertEqual(scaled, Vector(2, -4, 0, 0, 0, 0, 6))
31
+ self.assertEqual(v, Vector(1, -2, 0, 0, 0, 0, 3)) # original unchanged
32
+
33
+ def test_vector_scalar_multiplication_by_float(self):
34
+ v = Vector(0, 1, 0, 0, 0, 0, 0)
35
+ scaled = v * 0.5
36
+ self.assertEqual(scaled, Vector(0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0))
37
+
38
+ def test_vector_scalar_multiplication_by_zero(self):
39
+ v = Vector(1, 2, 3, 4, 5, 6, 7)
40
+ zeroed = v * 0
41
+ self.assertEqual(zeroed, Vector(0, 0, 0, 0, 0, 0, 0))
42
+
43
+ def test_vector_equality_and_hash(self):
44
+ v1 = Vector(1, 0, 0, 0, 0, 0, 0)
45
+ v2 = Vector(1, 0, 0, 0, 0, 0, 0)
46
+ v3 = Vector(0, 1, 0, 0, 0, 0, 0)
47
+ self.assertTrue(v1 == v2)
48
+ self.assertFalse(v1 == v3)
49
+ self.assertEqual(hash(v1), hash(v2))
50
+ self.assertNotEqual(hash(v1), hash(v3))
51
+
52
+
53
+ class TestVectorEdgeCases(TestCase):
54
+
55
+ def test_zero_vector_equality_and_additivity(self):
56
+ zero = Vector()
57
+ self.assertEqual(zero, Vector(0, 0, 0, 0, 0, 0, 0))
58
+ # Adding or subtracting zero should yield same vector
59
+ v = Vector(1, 2, 3, 4, 5, 6, 7)
60
+ self.assertEqual(v + zero, v)
61
+ self.assertEqual(v - zero, v)
62
+
63
+ def test_vector_with_negative_exponents(self):
64
+ v1 = Vector(1, -2, 3, 0, 0, 0, 0)
65
+ v2 = Vector(-1, 2, -3, 0, 0, 0, 0)
66
+ result = v1 + v2
67
+ self.assertEqual(result, Vector(0, 0, 0, 0, 0, 0, 0))
68
+ self.assertEqual(v1 - v1, Vector()) # perfect cancellation
69
+
70
+ def test_vector_equality_with_non_vector(self):
71
+ v = Vector()
72
+ with self.assertRaises(AssertionError):
73
+ v == "not a vector"
74
+ with self.assertRaises(AssertionError):
75
+ v == None
76
+
77
+ def test_hash_consistency_for_equal_vectors(self):
78
+ v1 = Vector(1, 0, 0, 0, 0, 0, 0)
79
+ v2 = Vector(1, 0, 0, 0, 0, 0, 0)
80
+ self.assertEqual(hash(v1), hash(v2))
81
+ self.assertEqual(len({v1, v2}), 1)
82
+
83
+ def test_iter_length_order_consistency(self):
84
+ v = Vector(1, 2, 3, 4, 5, 6, 7)
85
+ components = list(v)
86
+ self.assertEqual(len(components), len(v))
87
+ # Ensure order of iteration is fixed (T→L→M→I→Θ→J→N)
88
+ self.assertEqual(components, [1, 2, 3, 4, 5, 6, 7])
89
+
90
+ def test_vector_arithmetic_does_not_mutate_operands(self):
91
+ v1 = Vector(1, 0, 0, 0, 0, 0, 0)
92
+ v2 = Vector(0, 1, 0, 0, 0, 0, 0)
93
+ _ = v1 + v2
94
+ self.assertEqual(v1, Vector(1, 0, 0, 0, 0, 0, 0))
95
+ self.assertEqual(v2, Vector(0, 1, 0, 0, 0, 0, 0))
96
+
97
+ def test_invalid_addition_type_raises(self):
98
+ v = Vector(1, 0, 0, 0, 0, 0, 0)
99
+ with self.assertRaises(TypeError):
100
+ _ = v + "length"
101
+ with self.assertRaises(TypeError):
102
+ _ = v - 5
103
+
104
+
105
+ class TestExponent(TestCase):
106
+
107
+ thousand = Exponent(10, 3)
108
+ thousandth = Exponent(10, -3)
109
+ kibibyte = Exponent(2, 10)
110
+ mebibyte = Exponent(2, 20)
111
+
112
+ def test___init__(self):
113
+ with self.assertRaises(ValueError):
114
+ Exponent(5, 3) # no support for base 5 logarithms
115
+
116
+ def test_parts(self):
117
+ self.assertEqual((10, 3), self.thousand.parts())
118
+ self.assertEqual((10, -3), self.thousandth.parts())
119
+
120
+ def test_evaluated_property(self):
121
+ self.assertEqual(1000, self.thousand.evaluated)
122
+ self.assertAlmostEqual(0.001, self.thousandth.evaluated)
123
+ self.assertEqual(1024, self.kibibyte.evaluated)
124
+ self.assertEqual(1048576, self.mebibyte.evaluated)
125
+
126
+ def test___truediv__(self):
127
+ # same base returns a new Exponent
128
+ ratio = self.thousand / self.thousandth
129
+ self.assertIsInstance(ratio, Exponent)
130
+ self.assertEqual(ratio.base, 10)
131
+ self.assertEqual(ratio.power, 6)
132
+ self.assertEqual(ratio.evaluated, 1_000_000)
133
+
134
+ # different base returns numeric float
135
+ val = self.thousand / self.kibibyte
136
+ self.assertIsInstance(val, float)
137
+ self.assertAlmostEqual(1000 / 1024, val)
138
+
139
+ def test___mul__(self):
140
+ product = self.kibibyte * self.mebibyte
141
+ self.assertIsInstance(product, Exponent)
142
+ self.assertEqual(product.base, 2)
143
+ self.assertEqual(product.power, 30)
144
+ self.assertEqual(product.evaluated, 2**30)
145
+
146
+ # cross-base multiplication returns numeric
147
+ val = self.kibibyte * self.thousand
148
+ self.assertIsInstance(val, float)
149
+ self.assertAlmostEqual(1024 * 1000, val)
150
+
151
+ def test___hash__(self):
152
+ a = Exponent(10, 3)
153
+ b = Exponent(10, 3)
154
+ self.assertEqual(hash(a), hash(b))
155
+ self.assertEqual(len({a, b}), 1) # both should hash to same value
156
+
157
+ def test___float__(self):
158
+ self.assertEqual(float(self.thousand), 1000.0)
159
+
160
+ def test___int__(self):
161
+ self.assertEqual(int(self.thousand), 1000)
162
+
163
+ def test_comparisons(self):
164
+ self.assertTrue(self.thousand > self.thousandth)
165
+ self.assertTrue(self.thousandth < self.thousand)
166
+ self.assertTrue(self.kibibyte < self.mebibyte)
167
+ self.assertTrue(self.kibibyte == Exponent(2, 10))
168
+
169
+ with self.assertRaises(TypeError):
170
+ _ = self.thousand == 1000 # comparison to non-Exponent
171
+
172
+ def test___repr__(self):
173
+ self.assertIn("Exponent", repr(Exponent(10, -3)))
174
+
175
+ def test___str__(self):
176
+ self.assertEqual(str(self.thousand), '10^3')
177
+ self.assertEqual(str(self.thousandth), '10^-3')
178
+
179
+ def test_to_base(self):
180
+ e = Exponent(2, 10)
181
+ converted = e.to_base(10)
182
+ self.assertIsInstance(converted, Exponent)
183
+ self.assertEqual(converted.base, 10)
184
+ self.assertAlmostEqual(converted.power, math.log10(1024), places=10)
185
+
186
+ with self.assertRaises(ValueError):
187
+ e.to_base(5)
188
+
189
+
190
+ class TestExponentEdgeCases(TestCase):
191
+
192
+ def test_extreme_powers(self):
193
+ e = Exponent(10, 308)
194
+ self.assertTrue(math.isfinite(e.evaluated))
195
+ e_small = Exponent(10, -308)
196
+ self.assertGreater(e.evaluated, e_small.evaluated)
197
+
198
+ def test_precision_rounding_in_hash(self):
199
+ a = Exponent(10, 6)
200
+ b = Exponent(10, 6 + 1e-16)
201
+ # rounding in hash avoids floating drift
202
+ self.assertEqual(hash(a), hash(b))
203
+
204
+ def test_negative_and_zero_power(self):
205
+ e0 = Exponent(10, 0)
206
+ e_neg = Exponent(10, -1)
207
+ self.assertEqual(e0.evaluated, 1.0)
208
+ self.assertEqual(e_neg.evaluated, 0.1)
209
+ self.assertLess(e_neg, e0)
210
+
211
+ def test_valid_exponent_evaluates_correctly(self):
212
+ base, power = 10, 3
213
+ e = Exponent(base, power)
214
+ self.assertEqual(e.evaluated, 1000)
215
+ self.assertEqual(e.parts(), (base, power))
216
+ self.assertEqual(f'{base}^{power}', str(e))
217
+ self.assertEqual(f'Exponent(base={base}, power={power})', repr(e))
218
+
219
+ def test_invalid_base_raises_value_error(self):
220
+ with self.assertRaises(ValueError):
221
+ Exponent(5, 2)
222
+
223
+ def test_exponent_comparisons(self):
224
+ e1 = Exponent(10, 2)
225
+ e2 = Exponent(10, 3)
226
+ self.assertTrue(e1 < e2)
227
+ self.assertTrue(e2 > e1)
228
+ self.assertFalse(e1 == e2)
229
+
230
+ def test_division_returns_exponent(self):
231
+ e1 = Exponent(10, 3)
232
+ e2 = Exponent(10, 2)
233
+ self.assertEqual(e1 / e2, Exponent(10, 1))
234
+
235
+ def test_equality_with_different_type(self):
236
+ with self.assertRaises(TypeError):
237
+ Exponent(10, 2) == "10^2"