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()