Selaa lähdekoodia

Better fifo tests

Billy Barrow 1 viikko sitten
vanhempi
sitoutus
d961b4859f
1 muutettua tiedostoa jossa 237 lisäystä ja 0 poistoa
  1. 237 0
      src/tests/Integration/Fifo.vala

+ 237 - 0
src/tests/Integration/Fifo.vala

@@ -0,0 +1,237 @@
+using Invercargill;
+using Invercargill.DataStructures;
+
+void fifo_tests() {
+
+    Test.add_func("/invercargill/fifo/basic_push_pop", () => {
+        var fifo = new Fifo<string>();
+        
+        // Push items
+        fifo.push("first");
+        fifo.push("second");
+        fifo.push("third");
+        
+        // Pop in insertion order (FIFO)
+        var first = fifo.pop();
+        var second = fifo.pop();
+        var third = fifo.pop();
+        
+        assert_cmpstr("first", CompareOperator.EQ, first);
+        assert_cmpstr("second", CompareOperator.EQ, second);
+        assert_cmpstr("third", CompareOperator.EQ, third);
+    });
+
+    Test.add_func("/invercargill/fifo/peek functionality", () => {
+        var fifo = new Fifo<int>();
+        
+        fifo.push(1);
+        fifo.push(2);
+        fifo.push(3);
+        
+        // Peek should return front item without removing
+        var front = fifo.peek();
+        assert_cmpint(1, CompareOperator.EQ, front);
+        
+        // Pop should still return 1
+        var popped = fifo.pop();
+        assert_cmpint(1, CompareOperator.EQ, popped);
+        
+        // Peek now should return 2
+        var new_front = fifo.peek();
+        assert_cmpint(2, CompareOperator.EQ, new_front);
+    });
+
+    Test.add_func("/invercargill/fifo/empty_fifo_behavior", () => {
+        // Test peek on empty fifo
+        var fifo1 = new Fifo<string>();
+        try {
+            fifo1.peek();
+            assert_not_reached();
+        }
+        catch (SequenceError e) {
+            assert_cmpstr("No elements in queue", CompareOperator.EQ, e.message);
+        }
+        
+        // Test pop on empty fifo - need to unblock first
+        var fifo2 = new Fifo<string>();
+        fifo2.unblock();
+        try {
+            fifo2.pop();
+            assert_not_reached();
+        }
+        catch (SequenceError e) {
+            assert_cmpstr("No elements in unblocked queue to pop", CompareOperator.EQ, e.message);
+        }
+    });
+
+    Test.add_func("/invercargill/fifo/push_all", () => {
+        var fifo = new Fifo<int>();
+        var items = new Series<int>();
+        items.add(1);
+        items.add(2);
+        items.add(3);
+        
+        // Push all items
+        fifo.push_all(items);
+        
+        // Should pop in insertion order
+        assert_cmpint(1, CompareOperator.EQ, fifo.pop());
+        assert_cmpint(2, CompareOperator.EQ, fifo.pop());
+        assert_cmpint(3, CompareOperator.EQ, fifo.pop());
+    });
+
+    Test.add_func("/invercargill/fifo/enumerable_behavior", () => {
+        var fifo = new Fifo<string>();
+        
+        fifo.push("first");
+        fifo.push("second");
+        fifo.push("third");
+        
+        // Iteration should return items in FIFO order
+        var tracker = fifo.get_tracker();
+        var items = new string[3];
+        var index = 0;
+        
+        while (tracker.has_next()) {
+            items[index++] = tracker.get_next();
+        }
+        
+        assert_cmpstr("first", CompareOperator.EQ, items[0]);
+        assert_cmpstr("second", CompareOperator.EQ, items[1]);
+        assert_cmpstr("third", CompareOperator.EQ, items[2]);
+    });
+
+    Test.add_func("/invercargill/fifo/count_and_iteration", () => {
+        var fifo = new Fifo<int>();
+        
+        // Empty fifo
+        assert_cmpint(0, CompareOperator.EQ, fifo.count());
+        
+        // Add items
+        fifo.push(1);
+        fifo.push(2);
+        fifo.push(3);
+        
+        assert_cmpint(3, CompareOperator.EQ, fifo.count());
+        
+        // Pop items
+        fifo.pop();
+        assert_cmpint(2, CompareOperator.EQ, fifo.count());
+        
+        fifo.pop();
+        assert_cmpint(1, CompareOperator.EQ, fifo.count());
+        
+        fifo.pop();
+        assert_cmpint(0, CompareOperator.EQ, fifo.count());
+        
+        // Unblock to prevent blocking on any future operations
+        fifo.unblock();
+    });
+
+    Test.add_func("/invercargill/fifo/blocking_behavior", () => {
+        var fifo = new Fifo<string>();
+        bool thread_started = false;
+        bool thread_finished = false;
+        
+        // Start a thread that will wait for an item
+        Thread<void*> thread = new Thread<void*>("test-thread", () => {
+            thread_started = true;
+            var item = fifo.pop();
+            assert_cmpstr("test_item", CompareOperator.EQ, item);
+            thread_finished = true;
+            return null;
+        });
+        
+        // Wait for thread to start and block
+        while (!thread_started) {
+            Thread.usleep(1000); // 1ms
+        }
+        // Give additional time for thread to block on pop()
+        Thread.usleep(50000); // 50ms
+        
+        // Push an item to unblock the thread
+        fifo.push("test_item");
+        
+        // Wait for thread to finish
+        thread.join();
+        assert_true(thread_finished);
+    });
+
+    Test.add_func("/invercargill/fifo/unblock_behavior", () => {
+        var fifo = new Fifo<int>();
+        bool thread_started = false;
+        bool exception_thrown = false;
+        
+        // Start a thread that will wait for an item
+        Thread<void*> thread = new Thread<void*>("test-thread", () => {
+            thread_started = true;
+            try {
+                var item = fifo.pop(); // This should throw after unblock
+                assert_not_reached();
+            }
+            catch (SequenceError e) {
+                assert_cmpstr("No elements in unblocked queue to pop", CompareOperator.EQ, e.message);
+                exception_thrown = true;
+            }
+            return null;
+        });
+        
+        // Wait for thread to start and block
+        while (!thread_started) {
+            Thread.usleep(1000); // 1ms
+        }
+        // Give additional time for thread to block on pop()
+        Thread.usleep(50000); // 50ms
+        
+        // Unblock the fifo
+        fifo.unblock();
+        
+        // Wait for thread to finish
+        thread.join();
+        assert_true(exception_thrown);
+    });
+
+    Test.add_func("/invercargill/fifo/try_peek_and_try_pop", () => {
+        var fifo = new Fifo<string>();
+        
+        // Try operations on empty fifo
+        string item;
+        assert_false(fifo.try_peek(out item));
+        assert_null(item);
+        
+        string popped;
+        assert_false(fifo.try_pop(out popped));
+        assert_null(popped);
+        
+        // Add an item
+        fifo.push("test");
+        
+        // Try operations should now succeed
+        assert_true(fifo.try_peek(out item));
+        assert_cmpstr("test", CompareOperator.EQ, item);
+        
+        assert_true(fifo.try_pop(out popped));
+        assert_cmpstr("test", CompareOperator.EQ, popped);
+        
+        // Should be empty again
+        assert_false(fifo.try_pop(out popped));
+        assert_null(popped);
+    });
+
+    Test.add_func("/invercargill/fifo/push_start", () => {
+        var fifo = new Fifo<string>();
+        
+        // Add items normally
+        fifo.push("first");
+        fifo.push("second");
+        
+        // Add item to start
+        fifo.push_start("zero");
+        
+        // Should pop: zero, first, second
+        assert_cmpstr("zero", CompareOperator.EQ, fifo.pop());
+        assert_cmpstr("first", CompareOperator.EQ, fifo.pop());
+        assert_cmpstr("second", CompareOperator.EQ, fifo.pop());
+    });
+
+}