import unittest from utils.algo_context import AlgoContext from utils.algo_int import Int from utils.algo_array import Array class TestArray(unittest.TestCase): def setUp(self): self.ctx = AlgoContext() # ------------------------------------------------------------------ # Erzeugung # ------------------------------------------------------------------ def test_from_list(self): z = Array([3, 1, 4, 1, 5], self.ctx) self.assertEqual(len(z), 5) self.assertEqual(z[0].value, 3) self.assertEqual(z[4].value, 5) def test_random(self): z = Array.random(20, 0, 99, self.ctx) self.assertEqual(len(z), 20) for cell in z: self.assertGreaterEqual(cell.value, 0) self.assertLessEqual(cell.value, 99) def test_sorted(self): z = Array.sorted(5, self.ctx) values = [z[i].value for i in range(5)] self.assertEqual(values, [0, 1, 2, 3, 4]) def test_from_file(self): z = Array.from_file("data/seq0.txt", self.ctx) self.assertGreater(len(z), 0) def test_random_uses_no_write_counts(self): """Fabrikmethoden sollen keine Schreibzugriffe verzeichnen.""" z = Array.random(10, 0, 9, self.ctx) self.assertEqual(self.ctx.writes, 0) # ------------------------------------------------------------------ # Zugriff # ------------------------------------------------------------------ def test_getitem_returns_int_cell(self): z = Array([10, 20], self.ctx) cell = z[0] self.assertIsInstance(cell, Int) self.assertEqual(cell.value, 10) def test_getitem_with_int_index(self): z = Array([10, 20, 30], self.ctx) i = Int(2, self.ctx) self.assertEqual(z[i].value, 30) def test_getitem_no_read_count(self): """Array-Zugriff allein soll keinen read-Zähler erhöhen.""" z = Array([5, 6, 7], self.ctx) _ = z[0] self.assertEqual(self.ctx.reads, 0) def test_setitem_plain_int(self): z = Array([1, 2, 3], self.ctx) z[0] = 99 self.assertEqual(z[0].value, 99) self.assertEqual(self.ctx.writes, 1) self.assertEqual(self.ctx.reads, 0) def test_setitem_int_object(self): z = Array([1, 2, 3], self.ctx) v = Int(42, self.ctx) z[1] = v self.assertEqual(z[1].value, 42) self.assertEqual(self.ctx.writes, 1) self.assertEqual(self.ctx.reads, 1) def test_setitem_cell_to_cell(self): """z[i] = z[j] kopiert den Wert (keine Alias-Referenz).""" z = Array([10, 20], self.ctx) z[0] = z[1] self.assertEqual(z[0].value, 20) # Wert ändern – z[1] darf sich nicht mitändern z[0] = 99 self.assertEqual(z[1].value, 20) # ------------------------------------------------------------------ # Swap # ------------------------------------------------------------------ def test_swap_exchanges_values(self): z = Array([1, 2, 3, 4, 5], self.ctx) z.swap(0, 4) self.assertEqual(z[0].value, 5) self.assertEqual(z[4].value, 1) def test_swap_counts_reads_and_writes(self): z = Array([1, 2], self.ctx) z.swap(0, 1) self.assertEqual(self.ctx.reads, 2) self.assertEqual(self.ctx.writes, 2) def test_swap_with_int_indices(self): z = Array([10, 20, 30], self.ctx) i = Int(0, self.ctx) j = Int(2, self.ctx) z.swap(i, j) self.assertEqual(z[0].value, 30) self.assertEqual(z[2].value, 10) # ------------------------------------------------------------------ # Vergleich über Array-Zellen (zählt beim Int, nicht beim Array) # ------------------------------------------------------------------ def test_cell_comparison_counts_in_ctx(self): z = Array([5, 3], self.ctx) result = z[0] > z[1] self.assertTrue(result) self.assertEqual(self.ctx.comparisons, 1) self.assertEqual(self.ctx.reads, 2) # ------------------------------------------------------------------ # Iteration # ------------------------------------------------------------------ def test_iteration(self): z = Array([1, 2, 3], self.ctx) values = [c.value for c in z] self.assertEqual(values, [1, 2, 3]) # ------------------------------------------------------------------ # Länge # ------------------------------------------------------------------ def test_len(self): z = Array([1, 2, 3, 4], self.ctx) self.assertEqual(len(z), 4) def test_length_returns_int(self): z = Array([1, 2, 3], self.ctx) n = z.length() self.assertIsInstance(n, Int) self.assertEqual(n.value, 3) class TestArrayIntegration(unittest.TestCase): """Bubble Sort als Integrationstest für das gesamte Framework.""" def test_bubble_sort_produces_correct_result(self): import sys, os sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../vorlesung/L02_elementares_sortieren')) from bubble_sorting import bubble_sort ctx = AlgoContext() z = Array([5, 3, 1, 4, 2], ctx) bubble_sort(z, ctx) values = [z[i].value for i in range(len(z))] self.assertEqual(values, [1, 2, 3, 4, 5]) def test_bubble_sort_counts_comparisons(self): import sys, os sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../vorlesung/L02_elementares_sortieren')) from bubble_sorting import bubble_sort ctx = AlgoContext() z = Array([5, 4, 3, 2, 1], ctx) # worst case bubble_sort(z, ctx) # n=5: maximal n*(n-1)/2 = 10 Vergleiche self.assertGreater(ctx.comparisons, 0) self.assertLessEqual(ctx.comparisons, 10) if __name__ == "__main__": unittest.main()