194 lines
6.1 KiB
Python
194 lines
6.1 KiB
Python
import unittest
|
||
from utils.algo_context import AlgoContext
|
||
from utils.algo_int import Int
|
||
|
||
|
||
class TestInt(unittest.TestCase):
|
||
|
||
def setUp(self):
|
||
self.ctx = AlgoContext()
|
||
|
||
def _int(self, v):
|
||
return Int(v, self.ctx)
|
||
|
||
# ------------------------------------------------------------------
|
||
# Vergleiche
|
||
# ------------------------------------------------------------------
|
||
|
||
def test_comparison_counts_reads_and_compare(self):
|
||
a, b = self._int(5), self._int(3)
|
||
result = a > b
|
||
self.assertTrue(result)
|
||
self.assertEqual(self.ctx.comparisons, 1)
|
||
self.assertEqual(self.ctx.reads, 2)
|
||
|
||
def test_all_comparison_operators(self):
|
||
a, b = self._int(4), self._int(4)
|
||
self.assertTrue(a == b)
|
||
self.assertFalse(a != b)
|
||
self.assertTrue(a <= b)
|
||
self.assertTrue(a >= b)
|
||
self.assertFalse(a < b)
|
||
self.assertFalse(a > b)
|
||
self.assertEqual(self.ctx.comparisons, 6)
|
||
self.assertEqual(self.ctx.reads, 12)
|
||
|
||
def test_comparison_with_plain_int(self):
|
||
a = self._int(5)
|
||
result = a > 3 # 3 wird auto-gewrappt, kein extra Zähler
|
||
self.assertTrue(result)
|
||
self.assertEqual(self.ctx.comparisons, 1)
|
||
self.assertEqual(self.ctx.reads, 2)
|
||
|
||
def test_eq_with_none_returns_false(self):
|
||
a = self._int(1)
|
||
self.assertFalse(a == None) # noqa: E711
|
||
self.assertEqual(self.ctx.comparisons, 0) # keine Zählung
|
||
|
||
# ------------------------------------------------------------------
|
||
# Arithmetik (binär)
|
||
# ------------------------------------------------------------------
|
||
|
||
def test_addition_returns_new_int(self):
|
||
a, b = self._int(3), self._int(4)
|
||
c = a + b
|
||
self.assertIsInstance(c, Int)
|
||
self.assertEqual(c.value, 7)
|
||
self.assertEqual(self.ctx.additions, 1)
|
||
self.assertEqual(self.ctx.reads, 2)
|
||
self.assertEqual(self.ctx.writes, 0)
|
||
|
||
def test_subtraction(self):
|
||
a, b = self._int(10), self._int(4)
|
||
c = a - b
|
||
self.assertEqual(c.value, 6)
|
||
self.assertEqual(self.ctx.subtractions, 1)
|
||
|
||
def test_multiplication(self):
|
||
a, b = self._int(3), self._int(4)
|
||
c = a * b
|
||
self.assertEqual(c.value, 12)
|
||
self.assertEqual(self.ctx.multiplications, 1)
|
||
|
||
def test_floordiv(self):
|
||
a, b = self._int(10), self._int(3)
|
||
c = a // b
|
||
self.assertEqual(c.value, 3)
|
||
self.assertEqual(self.ctx.divisions, 1)
|
||
|
||
def test_mod(self):
|
||
a, b = self._int(10), self._int(3)
|
||
c = a % b
|
||
self.assertEqual(c.value, 1)
|
||
self.assertEqual(self.ctx.divisions, 1)
|
||
|
||
def test_arithmetic_with_plain_int(self):
|
||
a = self._int(5)
|
||
c = a + 3
|
||
self.assertEqual(c.value, 8)
|
||
self.assertEqual(self.ctx.additions, 1)
|
||
|
||
def test_result_shares_context(self):
|
||
a = self._int(5)
|
||
b = self._int(3)
|
||
c = a + b # c hat denselben ctx
|
||
_ = c > self._int(0) # Vergleich auf c zählt im selben ctx
|
||
self.assertEqual(self.ctx.comparisons, 1)
|
||
|
||
# ------------------------------------------------------------------
|
||
# Augmented assignment
|
||
# ------------------------------------------------------------------
|
||
|
||
def test_iadd_counts_read_add_write(self):
|
||
a, b = self._int(5), self._int(3)
|
||
a += b
|
||
self.assertEqual(a.value, 8)
|
||
self.assertEqual(self.ctx.reads, 2)
|
||
self.assertEqual(self.ctx.additions, 1)
|
||
self.assertEqual(self.ctx.writes, 1)
|
||
|
||
def test_isub(self):
|
||
a, b = self._int(10), self._int(4)
|
||
a -= b
|
||
self.assertEqual(a.value, 6)
|
||
self.assertEqual(self.ctx.subtractions, 1)
|
||
self.assertEqual(self.ctx.writes, 1)
|
||
|
||
def test_imul(self):
|
||
a, b = self._int(3), self._int(4)
|
||
a *= b
|
||
self.assertEqual(a.value, 12)
|
||
self.assertEqual(self.ctx.multiplications, 1)
|
||
self.assertEqual(self.ctx.writes, 1)
|
||
|
||
def test_iadd_with_plain_int(self):
|
||
a = self._int(5)
|
||
a += 1
|
||
self.assertEqual(a.value, 6)
|
||
self.assertEqual(self.ctx.writes, 1)
|
||
|
||
# ------------------------------------------------------------------
|
||
# set()
|
||
# ------------------------------------------------------------------
|
||
|
||
def test_set_plain_counts_one_write(self):
|
||
a = self._int(0)
|
||
a.set(42)
|
||
self.assertEqual(a.value, 42)
|
||
self.assertEqual(self.ctx.writes, 1)
|
||
self.assertEqual(self.ctx.reads, 0)
|
||
|
||
def test_set_int_counts_write_and_read(self):
|
||
a = self._int(0)
|
||
b = self._int(7)
|
||
a.set(b)
|
||
self.assertEqual(a.value, 7)
|
||
self.assertEqual(self.ctx.writes, 1)
|
||
self.assertEqual(self.ctx.reads, 1)
|
||
|
||
# ------------------------------------------------------------------
|
||
# Typkonvertierung
|
||
# ------------------------------------------------------------------
|
||
|
||
def test_int_conversion(self):
|
||
a = self._int(5)
|
||
self.assertEqual(int(a), 5)
|
||
|
||
def test_index_usage(self):
|
||
a = self._int(2)
|
||
lst = [10, 20, 30]
|
||
self.assertEqual(lst[a], 30) # __index__
|
||
|
||
def test_hash(self):
|
||
a = self._int(5)
|
||
self.assertEqual(hash(a), hash(5))
|
||
|
||
# ------------------------------------------------------------------
|
||
# AlgoContext.reset()
|
||
# ------------------------------------------------------------------
|
||
|
||
def test_context_reset(self):
|
||
a, b = self._int(3), self._int(4)
|
||
_ = a > b
|
||
self.ctx.reset()
|
||
self.assertEqual(self.ctx.comparisons, 0)
|
||
self.assertEqual(self.ctx.reads, 0)
|
||
|
||
|
||
class TestIntNullCtx(unittest.TestCase):
|
||
"""Int ohne expliziten ctx (irange-Verwendung) – keine Zählung."""
|
||
|
||
def test_arithmetic_without_ctx_produces_no_counts(self):
|
||
from utils.algo_context import NULL_CTX
|
||
a = Int(5) # uses NULL_CTX by default
|
||
b = Int(3)
|
||
_ = a + b
|
||
_ = a > b
|
||
# NULL_CTX hat feste 0-Attribute – keine Ausnahme, keine Zählung
|
||
self.assertEqual(NULL_CTX.additions, 0)
|
||
self.assertEqual(NULL_CTX.comparisons, 0)
|
||
|
||
|
||
if __name__ == "__main__":
|
||
unittest.main()
|