소스 검색

fix(series): decrement n_items on node removal

The item counter was not being decremented when nodes were deleted
from the Series data structure, causing incorrect item counts.

Also add Catalogue integration tests to the test suite.
Billy Barrow 4 주 전
부모
커밋
51b9e6a249
4개의 변경된 파일336개의 추가작업 그리고 0개의 파일을 삭제
  1. 1 0
      src/lib/DataStructures/Series.vala
  2. 333 0
      src/tests/Integration/Catalogue.vala
  3. 1 0
      src/tests/TestRunner.vala
  4. 1 0
      src/tests/meson.build

+ 1 - 0
src/lib/DataStructures/Series.vala

@@ -161,6 +161,7 @@ namespace Invercargill.DataStructures {
                             previous->next = node->next;
                             previous->next = node->next;
                         }
                         }
                         delete node;
                         delete node;
+                        n_items--;
                         if(first_only) {
                         if(first_only) {
                             break;
                             break;
                         }
                         }

+ 333 - 0
src/tests/Integration/Catalogue.vala

@@ -0,0 +1,333 @@
+using Invercargill;
+using Invercargill.DataStructures;
+
+
+void catalogue_tests() {
+
+    Test.add_func("/invercargill/catalogue/add_single", () => {
+        var catalogue = new Catalogue<string, int>();
+        catalogue.add("even", 2);
+        catalogue.add("even", 4);
+        catalogue.add("odd", 1);
+        catalogue.add("odd", 3);
+
+        assert(catalogue.length == 4);
+        assert(catalogue.has("even"));
+        assert(catalogue.has("odd"));
+        assert(!catalogue.has("prime"));
+    });
+
+    Test.add_func("/invercargill/catalogue/try_get", () => {
+        var catalogue = new Catalogue<string, int>();
+        catalogue.add("even", 2);
+        catalogue.add("even", 4);
+        catalogue.add("odd", 1);
+
+        Grouping<string, int> even_group;
+        assert(catalogue.try_get("even", out even_group));
+        assert(even_group.count() == 2);
+        
+        assert(even_group.contains(2));
+        assert(even_group.contains(4));
+
+        Grouping<string, int> prime_group;
+        assert(!catalogue.try_get("prime", out prime_group));
+        assert(prime_group == null);
+    });
+
+    Test.add_func("/invercargill/catalogue/try_get_any", () => {
+        var catalogue = new Catalogue<string, int>();
+        catalogue.add("even", 2);
+        catalogue.add("even", 4);
+
+        int value;
+        assert(catalogue.try_get_any("even", out value));
+        assert(value == 2 || value == 4);
+
+        int missing_value;
+        assert(!catalogue.try_get_any("odd", out missing_value));
+        assert(missing_value == 0);
+    });
+
+    Test.add_func("/invercargill/catalogue/keys", () => {
+        var catalogue = new Catalogue<string, int>();
+        catalogue.add("a", 1);
+        catalogue.add("b", 2);
+        catalogue.add("c", 3);
+
+        var keys = catalogue.keys.to_array();
+        assert(keys.length == 3);
+        assert(catalogue.keys.contains("a"));
+        assert(catalogue.keys.contains("b"));
+        assert(catalogue.keys.contains("c"));
+    });
+
+    Test.add_func("/invercargill/catalogue/values", () => {
+        var catalogue = new Catalogue<string, int>();
+        catalogue.add("group1", 1);
+        catalogue.add("group1", 2);
+        catalogue.add("group2", 3);
+
+        assert(catalogue.values.count() == 3);
+        assert(catalogue.values.contains(1));
+        assert(catalogue.values.contains(2));
+        assert(catalogue.values.contains(3));
+    });
+
+    Test.add_func("/invercargill/catalogue/set", () => {
+        var catalogue = new Catalogue<string, int>();
+        catalogue.add("group", 1);
+        catalogue.add("group", 2);
+        
+        assert(catalogue.length == 2);
+
+        catalogue.set("group", Wrap.array(new int[] { 10, 20, 30 }));
+        assert(catalogue.length == 3);
+
+        Grouping<string, int> group;
+        assert(catalogue.try_get("group", out group));
+        assert(group.count() == 3);
+    });
+
+    Test.add_func("/invercargill/catalogue/set_replace", () => {
+        var catalogue = new Catalogue<string, int>();
+        catalogue.add("group", 1);
+        catalogue.add("group", 2);
+        catalogue.add("other", 5);
+        
+        assert(catalogue.length == 3);
+
+        catalogue.set("group", Wrap.array(new int[] { 10, 20 }));
+        assert(catalogue.length == 3); // 2 from new group + 1 from other
+
+        Grouping<string, int> group;
+        assert(catalogue.try_get("group", out group));
+        assert(group.count() == 2);
+        assert(group.contains(10));
+        assert(group.contains(20));
+    });
+
+    Test.add_func("/invercargill/catalogue/add_all", () => {
+        var catalogue = new Catalogue<string, int>();
+        catalogue.add_all("numbers", Wrap.array(new int[] { 1, 2, 3 }));
+        
+        assert(catalogue.length == 3);
+
+        catalogue.add_all("numbers", Wrap.array(new int[] { 4, 5 }));
+        assert(catalogue.length == 5);
+
+        Grouping<string, int> group;
+        assert(catalogue.try_get("numbers", out group));
+        assert(group.count() == 5);
+    });
+
+    Test.add_func("/invercargill/catalogue/remove_from", () => {
+        var catalogue = new Catalogue<string, int>();
+        catalogue.add_all("numbers", Wrap.array(new int[] { 1, 2, 3, 4, 5 }));
+        
+        assert(catalogue.length == 5);
+
+        catalogue.remove_from("numbers", 3);
+        assert(catalogue.length == 4);
+
+        Grouping<string, int> group;
+        assert(catalogue.try_get("numbers", out group));
+        assert(!group.contains(3));
+        assert(group.count() == 4);
+    });
+
+    Test.add_func("/invercargill/catalogue/remove_from_last_item", () => {
+        var catalogue = new Catalogue<string, int>();
+        catalogue.add("single", 42);
+        
+        assert(catalogue.length == 1);
+        assert(catalogue.has("single"));
+
+        catalogue.remove_from("single", 42);
+        assert(catalogue.length == 0);
+        assert(!catalogue.has("single")); // Key should be removed when empty
+    });
+
+    Test.add_func("/invercargill/catalogue/remove_all_from", () => {
+        var catalogue = new Catalogue<string, int>();
+        catalogue.add_all("numbers", Wrap.array(new int[] { 1, 2, 3, 4, 5 }));
+        
+        assert(catalogue.length == 5);
+
+        catalogue.remove_all_from("numbers", Wrap.array(new int[] { 2, 4 }));
+        assert(catalogue.length == 3);
+
+        Grouping<string, int> group;
+        assert(catalogue.try_get("numbers", out group));
+        assert(!group.contains(2));
+        assert(!group.contains(4));
+        assert(group.contains(1));
+        assert(group.contains(3));
+        assert(group.contains(5));
+    });
+
+    Test.add_func("/invercargill/catalogue/remove", () => {
+        var catalogue = new Catalogue<string, int>();
+        catalogue.add("a", 1);
+        catalogue.add("a", 2);
+        catalogue.add("b", 2);
+        catalogue.add("b", 3);
+        catalogue.add("c", 2);
+        
+        assert(catalogue.length == 5);
+
+        catalogue.remove(2);
+        assert(catalogue.length == 2);
+
+        // Value 2 should be removed from all groups
+        assert(!catalogue.values.contains(2));
+        assert(catalogue.values.contains(1));
+        assert(catalogue.values.contains(3));
+    });
+
+    Test.add_func("/invercargill/catalogue/remove_all", () => {
+        var catalogue = new Catalogue<string, int>();
+        catalogue.add("a", 1);
+        catalogue.add("a", 2);
+        catalogue.add("b", 2);
+        catalogue.add("b", 3);
+        catalogue.add("c", 4);
+        
+        assert(catalogue.length == 5);
+
+        catalogue.remove_all(Wrap.array(new int[] { 2, 3 }));
+        assert(catalogue.length == 2);
+
+        assert(!catalogue.values.contains(2));
+        assert(!catalogue.values.contains(3));
+        assert(catalogue.values.contains(1));
+        assert(catalogue.values.contains(4));
+    });
+
+    Test.add_func("/invercargill/catalogue/clear_key", () => {
+        var catalogue = new Catalogue<string, int>();
+        catalogue.add("a", 1);
+        catalogue.add("b", 2);
+        catalogue.add("c", 3);
+        
+        assert(catalogue.length == 3);
+
+        assert(catalogue.clear_key("b"));
+        assert(catalogue.length == 2);
+        assert(!catalogue.has("b"));
+        assert(catalogue.has("a"));
+        assert(catalogue.has("c"));
+
+        assert(!catalogue.clear_key("nonexistent"));
+    });
+
+    Test.add_func("/invercargill/catalogue/clear", () => {
+        var catalogue = new Catalogue<string, int>();
+        catalogue.add("a", 1);
+        catalogue.add("b", 2);
+        catalogue.add("c", 3);
+        
+        assert(catalogue.length == 3);
+
+        catalogue.clear();
+        assert(catalogue.length == 0);
+        assert(!catalogue.has("a"));
+        assert(!catalogue.has("b"));
+        assert(!catalogue.has("c"));
+    });
+
+    Test.add_func("/invercargill/catalogue/iteration", () => {
+        var catalogue = new Catalogue<string, int>();
+        catalogue.add("even", 2);
+        catalogue.add("even", 4);
+        catalogue.add("odd", 1);
+        catalogue.add("odd", 3);
+
+        var group_count = 0;
+        var total_values = 0;
+        
+        foreach (var grouping in catalogue) {
+            group_count++;
+            foreach (var value in grouping) {
+                total_values++;
+            }
+        }
+
+        assert(group_count == 2);
+        assert(total_values == 4);
+    });
+
+    Test.add_func("/invercargill/catalogue/int_keys", () => {
+        var catalogue = new Catalogue<int, string>();
+        catalogue.add(1, "one");
+        catalogue.add(2, "two");
+        catalogue.add(1, "uno");
+
+        assert(catalogue.length == 3);
+        assert(catalogue.has(1));
+        assert(catalogue.has(2));
+
+        Grouping<int, string> group;
+        assert(catalogue.try_get(1, out group));
+        assert(group.count() == 2);
+    });
+
+    Test.add_func("/invercargill/catalogue/custom_hash", () => {
+        // Test with custom hash and equality functions
+        var catalogue = new Catalogue<string, int>(
+            (key) => key.hash(),
+            (a, b) => a == b
+        );
+        
+        catalogue.add("key1", 1);
+        catalogue.add("KEY1", 2); // Different key (case-sensitive)
+        catalogue.add("key1", 3);
+
+        assert(catalogue.length == 3);
+        assert(catalogue.has("key1"));
+        assert(catalogue.has("KEY1"));
+
+        Grouping<string, int> group;
+        assert(catalogue.try_get("key1", out group));
+        assert(group.count() == 2); // "key1" has 2 values
+    });
+
+    Test.add_func("/invercargill/catalogue/empty", () => {
+        var catalogue = new Catalogue<string, int>();
+        
+        assert(catalogue.length == 0);
+        assert(!catalogue.has("any"));
+        
+        Grouping<string, int> group;
+        assert(!catalogue.try_get("nonexistent", out group));
+        
+        int value;
+        assert(!catalogue.try_get_any("nonexistent", out value));
+    });
+
+    Test.add_func("/invercargill/catalogue/peek_count", () => {
+        var catalogue = new Catalogue<string, int>();
+        catalogue.add("a", 1);
+        catalogue.add("b", 2);
+        
+        var count = catalogue.peek_count();
+        assert(count == 2);
+    });
+
+    Test.add_func("/invercargill/catalogue/complex_objects", () => {
+        var catalogue = new Catalogue<string, string>();
+        catalogue.add("names", "Alice");
+        catalogue.add("names", "Bob");
+        catalogue.add("cities", "Auckland");
+        catalogue.add("cities", "Wellington");
+
+        assert(catalogue.length == 4);
+
+        Grouping<string, string> names;
+        assert(catalogue.try_get("names", out names));
+        
+        assert(names.contains("Alice"));
+        assert(names.contains("Bob"));
+    });
+
+}

+ 1 - 0
src/tests/TestRunner.vala

@@ -25,6 +25,7 @@ public static int main(string[] args) {
     promotion_tests();
     promotion_tests();
     numbers_test();
     numbers_test();
     dictionary_tests();
     dictionary_tests();
+    catalogue_tests();
     property_mapper_tests();
     property_mapper_tests();
     cache_tests();
     cache_tests();
     sorted_vector_tests();
     sorted_vector_tests();

+ 1 - 0
src/tests/meson.build

@@ -16,6 +16,7 @@ sources += files('Integration/Arrays.vala')
 sources += files('Integration/Promotion.vala')
 sources += files('Integration/Promotion.vala')
 sources += files('Integration/Numbers.vala')
 sources += files('Integration/Numbers.vala')
 sources += files('Integration/Dictionary.vala')
 sources += files('Integration/Dictionary.vala')
+sources += files('Integration/Catalogue.vala')
 sources += files('Integration/PropertyMapper.vala')
 sources += files('Integration/PropertyMapper.vala')
 sources += files('Integration/Cache.vala')
 sources += files('Integration/Cache.vala')
 sources += files('Integration/SortedVector.vala')
 sources += files('Integration/SortedVector.vala')