| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- 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");
- fifo.unblock();
-
- // 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/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;
- fifo.unblock();
- 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());
- });
- }
|