diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/test_array.h | 234 | ||||
-rw-r--r-- | tests/test_dictionary.h | 367 | ||||
-rw-r--r-- | tests/test_macros.h | 1 | ||||
-rw-r--r-- | tests/test_variant.h | 211 |
4 files changed, 804 insertions, 9 deletions
diff --git a/tests/test_array.h b/tests/test_array.h index 3bd476fd27..05b4eaea2a 100644 --- a/tests/test_array.h +++ b/tests/test_array.h @@ -43,6 +43,25 @@ namespace TestArray { +static inline Array build_array() { + return Array(); +} +template <typename... Targs> +static inline Array build_array(Variant item, Targs... Fargs) { + Array a = build_array(Fargs...); + a.push_front(item); + return a; +} +static inline Dictionary build_dictionary() { + return Dictionary(); +} +template <typename... Targs> +static inline Dictionary build_dictionary(Variant key, Variant item, Targs... Fargs) { + Dictionary d = build_dictionary(Fargs...); + d[key] = item; + return d; +} + TEST_CASE("[Array] size(), clear(), and is_empty()") { Array arr; CHECK(arr.size() == 0); @@ -232,6 +251,221 @@ TEST_CASE("[Array] max() and min()") { CHECK(max == 5); CHECK(min == 2); } + +TEST_CASE("[Array] Duplicate array") { + // a = [1, [2, 2], {3: 3}] + Array a = build_array(1, build_array(2, 2), build_dictionary(3, 3)); + + // Deep copy + Array deep_a = a.duplicate(true); + CHECK_MESSAGE(deep_a.id() != a.id(), "Should create a new array"); + CHECK_MESSAGE(Array(deep_a[1]).id() != Array(a[1]).id(), "Should clone nested array"); + CHECK_MESSAGE(Dictionary(deep_a[2]).id() != Dictionary(a[2]).id(), "Should clone nested dictionary"); + CHECK_EQ(deep_a, a); + deep_a.push_back(1); + CHECK_NE(deep_a, a); + deep_a.pop_back(); + Array(deep_a[1]).push_back(1); + CHECK_NE(deep_a, a); + Array(deep_a[1]).pop_back(); + CHECK_EQ(deep_a, a); + + // Shallow copy + Array shallow_a = a.duplicate(false); + CHECK_MESSAGE(shallow_a.id() != a.id(), "Should create a new array"); + CHECK_MESSAGE(Array(shallow_a[1]).id() == Array(a[1]).id(), "Should keep nested array"); + CHECK_MESSAGE(Dictionary(shallow_a[2]).id() == Dictionary(a[2]).id(), "Should keep nested dictionary"); + CHECK_EQ(shallow_a, a); + Array(shallow_a).push_back(1); + CHECK_NE(shallow_a, a); +} + +TEST_CASE("[Array] Duplicate recursive array") { + // Self recursive + Array a; + a.push_back(a); + + Array a_shallow = a.duplicate(false); + CHECK_EQ(a, a_shallow); + + // Deep copy of recursive array endup with recursion limit and return + // an invalid result (multiple nested arrays), the point is we should + // not end up with a segfault and an error log should be printed + ERR_PRINT_OFF; + a.duplicate(true); + ERR_PRINT_ON; + + // Nested recursive + Array a1; + Array a2; + a2.push_back(a1); + a1.push_back(a2); + + Array a1_shallow = a1.duplicate(false); + CHECK_EQ(a1, a1_shallow); + + // Same deep copy issue as above + ERR_PRINT_OFF; + a1.duplicate(true); + ERR_PRINT_ON; + + // Break the recursivity otherwise Array teardown will leak memory + a.clear(); + a1.clear(); + a2.clear(); +} + +TEST_CASE("[Array] Hash array") { + // a = [1, [2, 2], {3: 3}] + Array a = build_array(1, build_array(2, 2), build_dictionary(3, 3)); + uint32_t original_hash = a.hash(); + + a.push_back(1); + CHECK_NE(a.hash(), original_hash); + + a.pop_back(); + CHECK_EQ(a.hash(), original_hash); + + Array(a[1]).push_back(1); + CHECK_NE(a.hash(), original_hash); + Array(a[1]).pop_back(); + CHECK_EQ(a.hash(), original_hash); + + (Dictionary(a[2]))[1] = 1; + CHECK_NE(a.hash(), original_hash); + Dictionary(a[2]).erase(1); + CHECK_EQ(a.hash(), original_hash); + + Array a2 = a.duplicate(true); + CHECK_EQ(a2.hash(), a.hash()); +} + +TEST_CASE("[Array] Hash recursive array") { + Array a1; + a1.push_back(a1); + + Array a2; + a2.push_back(a2); + + // Hash should reach recursion limit + ERR_PRINT_OFF; + CHECK_EQ(a1.hash(), a2.hash()); + ERR_PRINT_ON; + + // Break the recursivity otherwise Array teardown will leak memory + a1.clear(); + a2.clear(); +} + +TEST_CASE("[Array] Empty comparison") { + Array a1; + Array a2; + + // test both operator== and operator!= + CHECK_EQ(a1, a2); + CHECK_FALSE(a1 != a2); +} + +TEST_CASE("[Array] Flat comparison") { + Array a1 = build_array(1); + Array a2 = build_array(1); + Array other_a = build_array(2); + + // test both operator== and operator!= + CHECK_EQ(a1, a1); // compare self + CHECK_FALSE(a1 != a1); + CHECK_EQ(a1, a2); // different equivalent arrays + CHECK_FALSE(a1 != a2); + CHECK_NE(a1, other_a); // different arrays with different content + CHECK_FALSE(a1 == other_a); +} + +TEST_CASE("[Array] Nested array comparison") { + // a1 = [[[1], 2], 3] + Array a1 = build_array(build_array(build_array(1), 2), 3); + + Array a2 = a1.duplicate(true); + + // other_a = [[[1, 0], 2], 3] + Array other_a = build_array(build_array(build_array(1, 0), 2), 3); + + // test both operator== and operator!= + CHECK_EQ(a1, a1); // compare self + CHECK_FALSE(a1 != a1); + CHECK_EQ(a1, a2); // different equivalent arrays + CHECK_FALSE(a1 != a2); + CHECK_NE(a1, other_a); // different arrays with different content + CHECK_FALSE(a1 == other_a); +} + +TEST_CASE("[Array] Nested dictionary comparison") { + // a1 = [{1: 2}, 3] + Array a1 = build_array(build_dictionary(1, 2), 3); + + Array a2 = a1.duplicate(true); + + // other_a = [{1: 0}, 3] + Array other_a = build_array(build_dictionary(1, 0), 3); + + // test both operator== and operator!= + CHECK_EQ(a1, a1); // compare self + CHECK_FALSE(a1 != a1); + CHECK_EQ(a1, a2); // different equivalent arrays + CHECK_FALSE(a1 != a2); + CHECK_NE(a1, other_a); // different arrays with different content + CHECK_FALSE(a1 == other_a); +} + +TEST_CASE("[Array] Recursive comparison") { + Array a1; + a1.push_back(a1); + + Array a2; + a2.push_back(a2); + + // Comparison should reach recursion limit + ERR_PRINT_OFF; + CHECK_EQ(a1, a2); + CHECK_FALSE(a1 != a2); + ERR_PRINT_ON; + + a1.push_back(1); + a2.push_back(1); + + // Comparison should reach recursion limit + ERR_PRINT_OFF; + CHECK_EQ(a1, a2); + CHECK_FALSE(a1 != a2); + ERR_PRINT_ON; + + a1.push_back(1); + a2.push_back(2); + + // Comparison should reach recursion limit + ERR_PRINT_OFF; + CHECK_NE(a1, a2); + CHECK_FALSE(a1 == a2); + ERR_PRINT_ON; + + // Break the recursivity otherwise Array tearndown will leak memory + a1.clear(); + a2.clear(); +} + +TEST_CASE("[Array] Recursive self comparison") { + Array a1; + Array a2; + a2.push_back(a1); + a1.push_back(a2); + + CHECK_EQ(a1, a1); + CHECK_FALSE(a1 != a1); + + // Break the recursivity otherwise Array tearndown will leak memory + a1.clear(); + a2.clear(); +} + } // namespace TestArray #endif // TEST_ARRAY_H diff --git a/tests/test_dictionary.h b/tests/test_dictionary.h index b94cf36109..64d1d68e21 100644 --- a/tests/test_dictionary.h +++ b/tests/test_dictionary.h @@ -39,6 +39,25 @@ namespace TestDictionary { +static inline Array build_array() { + return Array(); +} +template <typename... Targs> +static inline Array build_array(Variant item, Targs... Fargs) { + Array a = build_array(Fargs...); + a.push_front(item); + return a; +} +static inline Dictionary build_dictionary() { + return Dictionary(); +} +template <typename... Targs> +static inline Dictionary build_dictionary(Variant key, Variant item, Targs... Fargs) { + Dictionary d = build_dictionary(Fargs...); + d[key] = item; + return d; +} + TEST_CASE("[Dictionary] Assignment using bracket notation ([])") { Dictionary map; map["Hello"] = 0; @@ -61,15 +80,6 @@ TEST_CASE("[Dictionary] Assignment using bracket notation ([])") { CHECK(int(map[false]) == 128); } -TEST_CASE("[Dictionary] == and != operators") { - Dictionary map1; - Dictionary map2; - CHECK(map1 != map2); - map1[1] = 3; - map2 = map1; - CHECK(map1 == map2); -} - TEST_CASE("[Dictionary] get_key_lists()") { Dictionary map; List<Variant> keys; @@ -155,5 +165,344 @@ TEST_CASE("[Dictionary] keys() and values()") { CHECK(int(keys[0]) == 1); CHECK(int(values[0]) == 3); } + +TEST_CASE("[Dictionary] Duplicate dictionary") { + // d = {1: {1: 1}, {2: 2}: [2], [3]: 3} + Dictionary k2 = build_dictionary(2, 2); + Array k3 = build_array(3); + Dictionary d = build_dictionary(1, build_dictionary(1, 1), k2, build_array(2), k3, 3); + + // Deep copy + Dictionary deep_d = d.duplicate(true); + CHECK_MESSAGE(deep_d.id() != d.id(), "Should create a new dictionary"); + CHECK_MESSAGE(Dictionary(deep_d[1]).id() != Dictionary(d[1]).id(), "Should clone nested dictionary"); + CHECK_MESSAGE(Array(deep_d[k2]).id() != Array(d[k2]).id(), "Should clone nested array"); + CHECK_EQ(deep_d, d); + deep_d[0] = 0; + CHECK_NE(deep_d, d); + deep_d.erase(0); + Dictionary(deep_d[1]).operator[](0) = 0; + CHECK_NE(deep_d, d); + Dictionary(deep_d[1]).erase(0); + CHECK_EQ(deep_d, d); + // Keys should also be copied + k2[0] = 0; + CHECK_NE(deep_d, d); + k2.erase(0); + CHECK_EQ(deep_d, d); + k3.push_back(0); + CHECK_NE(deep_d, d); + k3.pop_back(); + CHECK_EQ(deep_d, d); + + // Shallow copy + Dictionary shallow_d = d.duplicate(false); + CHECK_MESSAGE(shallow_d.id() != d.id(), "Should create a new array"); + CHECK_MESSAGE(Dictionary(shallow_d[1]).id() == Dictionary(d[1]).id(), "Should keep nested dictionary"); + CHECK_MESSAGE(Array(shallow_d[2]).id() == Array(d[2]).id(), "Should keep nested array"); + CHECK_EQ(shallow_d, d); + shallow_d[0] = 0; + CHECK_NE(shallow_d, d); + shallow_d.erase(0); +#if 0 // TODO: recursion in dict key currently is buggy + // Keys should also be shallowed + k2[0] = 0; + CHECK_EQ(shallow_d, d); + k2.erase(0); + k3.push_back(0); + CHECK_EQ(shallow_d, d); +#endif +} + +TEST_CASE("[Dictionary] Duplicate recursive dictionary") { + // Self recursive + Dictionary d; + d[1] = d; + + Dictionary d_shallow = d.duplicate(false); + CHECK_EQ(d, d_shallow); + + // Deep copy of recursive dictionary endup with recursion limit and return + // an invalid result (multiple nested dictionaries), the point is we should + // not end up with a segfault and an error log should be printed + ERR_PRINT_OFF; + d.duplicate(true); + ERR_PRINT_ON; + + // Nested recursive + Dictionary d1; + Dictionary d2; + d1[2] = d2; + d2[1] = d1; + + Dictionary d1_shallow = d1.duplicate(false); + CHECK_EQ(d1, d1_shallow); + + // Same deep copy issue as above + ERR_PRINT_OFF; + d1.duplicate(true); + ERR_PRINT_ON; + + // Break the recursivity otherwise Dictionary teardown will leak memory + d.clear(); + d1.clear(); + d2.clear(); +} + +#if 0 // TODO: duplicate recursion in dict key is currently buggy +TEST_CASE("[Dictionary] Duplicate recursive dictionary on keys") { + // Self recursive + Dictionary d; + d[d] = d; + + Dictionary d_shallow = d.duplicate(false); + CHECK_EQ(d, d_shallow); + + // Deep copy of recursive dictionary endup with recursion limit and return + // an invalid result (multiple nested dictionaries), the point is we should + // not end up with a segfault and an error log should be printed + ERR_PRINT_OFF; + d.duplicate(true); + ERR_PRINT_ON; + + // Nested recursive + Dictionary d1; + Dictionary d2; + d1[d2] = d2; + d2[d1] = d1; + + Dictionary d1_shallow = d1.duplicate(false); + CHECK_EQ(d1, d1_shallow); + + // Same deep copy issue as above + ERR_PRINT_OFF; + d1.duplicate(true); + ERR_PRINT_ON; + + // Break the recursivity otherwise Dictionary teardown will leak memory + d.clear(); + d1.clear(); + d2.clear(); +} +#endif + +TEST_CASE("[Dictionary] Hash dictionary") { + // d = {1: {1: 1}, {2: 2}: [2], [3]: 3} + Dictionary k2 = build_dictionary(2, 2); + Array k3 = build_array(3); + Dictionary d = build_dictionary(1, build_dictionary(1, 1), k2, build_array(2), k3, 3); + uint32_t original_hash = d.hash(); + + // Modify dict change the hash + d[0] = 0; + CHECK_NE(d.hash(), original_hash); + d.erase(0); + CHECK_EQ(d.hash(), original_hash); + + // Modify nested item change the hash + Dictionary(d[1]).operator[](0) = 0; + CHECK_NE(d.hash(), original_hash); + Dictionary(d[1]).erase(0); + Array(d[k2]).push_back(0); + CHECK_NE(d.hash(), original_hash); + Array(d[k2]).pop_back(); + + // Modify a key change the hash + k2[0] = 0; + CHECK_NE(d.hash(), original_hash); + k2.erase(0); + CHECK_EQ(d.hash(), original_hash); + k3.push_back(0); + CHECK_NE(d.hash(), original_hash); + k3.pop_back(); + CHECK_EQ(d.hash(), original_hash); + + // Duplication doesn't change the hash + Dictionary d2 = d.duplicate(true); + CHECK_EQ(d2.hash(), original_hash); +} + +TEST_CASE("[Dictionary] Hash recursive dictionary") { + Dictionary d; + d[1] = d; + + // Hash should reach recursion limit, we just make sure this doesn't blow up + ERR_PRINT_OFF; + d.hash(); + ERR_PRINT_ON; + + // Break the recursivity otherwise Dictionary teardown will leak memory + d.clear(); +} + +#if 0 // TODO: recursion in dict key is currently buggy +TEST_CASE("[Dictionary] Hash recursive dictionary on keys") { + Dictionary d; + d[d] = 1; + + // Hash should reach recursion limit, we just make sure this doesn't blow up + ERR_PRINT_OFF; + d.hash(); + ERR_PRINT_ON; + + // Break the recursivity otherwise Dictionary teardown will leak memory + d.clear(); +} +#endif + +TEST_CASE("[Dictionary] Empty comparison") { + Dictionary d1; + Dictionary d2; + + // test both operator== and operator!= + CHECK_EQ(d1, d2); + CHECK_FALSE(d1 != d2); +} + +TEST_CASE("[Dictionary] Flat comparison") { + Dictionary d1 = build_dictionary(1, 1); + Dictionary d2 = build_dictionary(1, 1); + Dictionary other_d = build_dictionary(2, 1); + + // test both operator== and operator!= + CHECK_EQ(d1, d1); // compare self + CHECK_FALSE(d1 != d1); + CHECK_EQ(d1, d2); // different equivalent arrays + CHECK_FALSE(d1 != d2); + CHECK_NE(d1, other_d); // different arrays with different content + CHECK_FALSE(d1 == other_d); +} + +TEST_CASE("[Dictionary] Nested dictionary comparison") { + // d1 = {1: {2: {3: 4}}} + Dictionary d1 = build_dictionary(1, build_dictionary(2, build_dictionary(3, 4))); + + Dictionary d2 = d1.duplicate(true); + + // other_d = {1: {2: {3: 0}}} + Dictionary other_d = build_dictionary(1, build_dictionary(2, build_dictionary(3, 0))); + + // test both operator== and operator!= + CHECK_EQ(d1, d1); // compare self + CHECK_FALSE(d1 != d1); + CHECK_EQ(d1, d2); // different equivalent arrays + CHECK_FALSE(d1 != d2); + CHECK_NE(d1, other_d); // different arrays with different content + CHECK_FALSE(d1 == other_d); +} + +TEST_CASE("[Dictionary] Nested array comparison") { + // d1 = {1: [2, 3]} + Dictionary d1 = build_dictionary(1, build_array(2, 3)); + + Dictionary d2 = d1.duplicate(true); + + // other_d = {1: [2, 0]} + Dictionary other_d = build_dictionary(1, build_array(2, 0)); + + // test both operator== and operator!= + CHECK_EQ(d1, d1); // compare self + CHECK_FALSE(d1 != d1); + CHECK_EQ(d1, d2); // different equivalent arrays + CHECK_FALSE(d1 != d2); + CHECK_NE(d1, other_d); // different arrays with different content + CHECK_FALSE(d1 == other_d); +} + +TEST_CASE("[Dictionary] Recursive comparison") { + Dictionary d1; + d1[1] = d1; + + Dictionary d2; + d2[1] = d2; + + // Comparison should reach recursion limit + ERR_PRINT_OFF; + CHECK_EQ(d1, d2); + CHECK_FALSE(d1 != d2); + ERR_PRINT_ON; + + d1[2] = 2; + d2[2] = 2; + + // Comparison should reach recursion limit + ERR_PRINT_OFF; + CHECK_EQ(d1, d2); + CHECK_FALSE(d1 != d2); + ERR_PRINT_ON; + + d1[3] = 3; + d2[3] = 0; + + // Comparison should reach recursion limit + ERR_PRINT_OFF; + CHECK_NE(d1, d2); + CHECK_FALSE(d1 == d2); + ERR_PRINT_ON; + + // Break the recursivity otherwise Dictionary teardown will leak memory + d1.clear(); + d2.clear(); +} + +#if 0 // TODO: recursion in dict key is currently buggy +TEST_CASE("[Dictionary] Recursive comparison on keys") { + Dictionary d1; + // Hash computation should reach recursion limit + ERR_PRINT_OFF; + d1[d1] = 1; + ERR_PRINT_ON; + + Dictionary d2; + // Hash computation should reach recursion limit + ERR_PRINT_OFF; + d2[d2] = 1; + ERR_PRINT_ON; + + // Comparison should reach recursion limit + ERR_PRINT_OFF; + CHECK_EQ(d1, d2); + CHECK_FALSE(d1 != d2); + ERR_PRINT_ON; + + d1[2] = 2; + d2[2] = 2; + + // Comparison should reach recursion limit + ERR_PRINT_OFF; + CHECK_EQ(d1, d2); + CHECK_FALSE(d1 != d2); + ERR_PRINT_ON; + + d1[3] = 3; + d2[3] = 0; + + // Comparison should reach recursion limit + ERR_PRINT_OFF; + CHECK_NE(d1, d2); + CHECK_FALSE(d1 == d2); + ERR_PRINT_ON; + + // Break the recursivity otherwise Dictionary teardown will leak memory + d1.clear(); + d2.clear(); +} +#endif + +TEST_CASE("[Dictionary] Recursive self comparison") { + Dictionary d1; + Dictionary d2; + d1[1] = d2; + d2[1] = d1; + + CHECK_EQ(d1, d1); + CHECK_FALSE(d1 != d1); + + // Break the recursivity otherwise Dictionary teardown will leak memory + d1.clear(); + d2.clear(); +} + } // namespace TestDictionary + #endif // TEST_DICTIONARY_H diff --git a/tests/test_macros.h b/tests/test_macros.h index 2f0bc6dcfa..6968f9df1f 100644 --- a/tests/test_macros.h +++ b/tests/test_macros.h @@ -33,6 +33,7 @@ #include "core/object/callable_method_pointer.h" #include "core/object/class_db.h" +#include "core/string/print_string.h" #include "core/templates/map.h" #include "core/variant/variant.h" diff --git a/tests/test_variant.h b/tests/test_variant.h index 598fe488d7..0d16fa092c 100644 --- a/tests/test_variant.h +++ b/tests/test_variant.h @@ -38,6 +38,25 @@ namespace TestVariant { +static inline Array build_array() { + return Array(); +} +template <typename... Targs> +static inline Array build_array(Variant item, Targs... Fargs) { + Array a = build_array(Fargs...); + a.push_front(item); + return a; +} +static inline Dictionary build_dictionary() { + return Dictionary(); +} +template <typename... Targs> +static inline Dictionary build_dictionary(Variant key, Variant item, Targs... Fargs) { + Dictionary d = build_dictionary(Fargs...); + d[key] = item; + return d; +} + TEST_CASE("[Variant] Writer and parser integer") { int64_t a32 = 2147483648; // 2^31, so out of bounds for 32-bit signed int [-2^31, +2^31-1]. String a32_str; @@ -700,6 +719,198 @@ TEST_CASE("[Variant] Assignment To Color from Bool,Int,Float,String,Vec2,Vec2i,V vec3i_v = col_v; CHECK(vec3i_v.get_type() == Variant::COLOR); } +TEST_CASE("[Variant] Writer and parser array") { + Array a = build_array(1, String("hello"), build_array(Variant())); + String a_str; + VariantWriter::write_to_string(a, a_str); + + CHECK_EQ(a_str, "[1, \"hello\", [null]]"); + + VariantParser::StreamString ss; + String errs; + int line; + Variant a_parsed; + + ss.s = a_str; + VariantParser::parse(&ss, a_parsed, errs, line); + + CHECK_MESSAGE(a_parsed == Variant(a), "Should parse back."); +} + +TEST_CASE("[Variant] Writer recursive array") { + // There is no way to accurately represent a recursive array, + // the only thing we can do is make sure the writer doesn't blow up + + // Self recursive + Array a; + a.push_back(a); + + // Writer should it recursion limit while visiting the array + ERR_PRINT_OFF; + String a_str; + VariantWriter::write_to_string(a, a_str); + ERR_PRINT_ON; + + // Nested recursive + Array a1; + Array a2; + a1.push_back(a2); + a2.push_back(a1); + + // Writer should it recursion limit while visiting the array + ERR_PRINT_OFF; + String a1_str; + VariantWriter::write_to_string(a1, a1_str); + ERR_PRINT_ON; + + // Break the recursivity otherwise Dictionary tearndown will leak memory + a.clear(); + a1.clear(); + a2.clear(); +} + +TEST_CASE("[Variant] Writer and parser dictionary") { + // d = {{1: 2}: 3, 4: "hello", 5: {null: []}} + Dictionary d = build_dictionary(build_dictionary(1, 2), 3, 4, String("hello"), 5, build_dictionary(Variant(), build_array())); + String d_str; + VariantWriter::write_to_string(d, d_str); + + CHECK_EQ(d_str, "{\n4: \"hello\",\n5: {\nnull: []\n},\n{\n1: 2\n}: 3\n}"); + + VariantParser::StreamString ss; + String errs; + int line; + Variant d_parsed; + + ss.s = d_str; + VariantParser::parse(&ss, d_parsed, errs, line); + + CHECK_MESSAGE(d_parsed == Variant(d), "Should parse back."); +} + +TEST_CASE("[Variant] Writer recursive dictionary") { + // There is no way to accurately represent a recursive dictionary, + // the only thing we can do is make sure the writer doesn't blow up + + // Self recursive + Dictionary d; + d[1] = d; + + // Writer should it recursion limit while visiting the dictionary + ERR_PRINT_OFF; + String d_str; + VariantWriter::write_to_string(d, d_str); + ERR_PRINT_ON; + + // Nested recursive + Dictionary d1; + Dictionary d2; + d1[2] = d2; + d2[1] = d1; + + // Writer should it recursion limit while visiting the dictionary + ERR_PRINT_OFF; + String d1_str; + VariantWriter::write_to_string(d1, d1_str); + ERR_PRINT_ON; + + // Break the recursivity otherwise Dictionary tearndown will leak memory + d.clear(); + d1.clear(); + d2.clear(); +} + +#if 0 // TODO: recursion in dict key is currently buggy +TEST_CASE("[Variant] Writer recursive dictionary on keys") { + // There is no way to accurately represent a recursive dictionary, + // the only thing we can do is make sure the writer doesn't blow up + + // Self recursive + Dictionary d; + d[d] = 1; + + // Writer should it recursion limit while visiting the dictionary + ERR_PRINT_OFF; + String d_str; + VariantWriter::write_to_string(d, d_str); + ERR_PRINT_ON; + + // Nested recursive + Dictionary d1; + Dictionary d2; + d1[d2] = 2; + d2[d1] = 1; + + // Writer should it recursion limit while visiting the dictionary + ERR_PRINT_OFF; + String d1_str; + VariantWriter::write_to_string(d1, d1_str); + ERR_PRINT_ON; + + // Break the recursivity otherwise Dictionary tearndown will leak memory + d.clear(); + d1.clear(); + d2.clear(); +} +#endif + +TEST_CASE("[Variant] Basic comparison") { + CHECK_EQ(Variant(1), Variant(1)); + CHECK_FALSE(Variant(1) != Variant(1)); + CHECK_NE(Variant(1), Variant(2)); + CHECK_EQ(Variant(String("foo")), Variant(String("foo"))); + CHECK_NE(Variant(String("foo")), Variant(String("bar"))); + // Check "empty" version of different types are not equivalents + CHECK_NE(Variant(0), Variant()); + CHECK_NE(Variant(String()), Variant()); + CHECK_NE(Variant(Array()), Variant()); + CHECK_NE(Variant(Dictionary()), Variant()); +} + +TEST_CASE("[Variant] Nested array comparison") { + Array a1 = build_array(1, build_array(2, 3)); + Array a2 = build_array(1, build_array(2, 3)); + Array a_other = build_array(1, build_array(2, 4)); + Variant v_a1 = a1; + Variant v_a1_ref2 = a1; + Variant v_a2 = a2; + Variant v_a_other = a_other; + + // test both operator== and operator!= + CHECK_EQ(v_a1, v_a1); + CHECK_FALSE(v_a1 != v_a1); + CHECK_EQ(v_a1, v_a1_ref2); + CHECK_FALSE(v_a1 != v_a1_ref2); + CHECK_EQ(v_a1, v_a2); + CHECK_FALSE(v_a1 != v_a2); + CHECK_NE(v_a1, v_a_other); + CHECK_FALSE(v_a1 == v_a_other); +} + +TEST_CASE("[Variant] Nested dictionary comparison") { + Dictionary d1 = build_dictionary(build_dictionary(1, 2), build_dictionary(3, 4)); + Dictionary d2 = build_dictionary(build_dictionary(1, 2), build_dictionary(3, 4)); + Dictionary d_other_key = build_dictionary(build_dictionary(1, 0), build_dictionary(3, 4)); + Dictionary d_other_val = build_dictionary(build_dictionary(1, 2), build_dictionary(3, 0)); + Variant v_d1 = d1; + Variant v_d1_ref2 = d1; + Variant v_d2 = d2; + Variant v_d_other_key = d_other_key; + Variant v_d_other_val = d_other_val; + + // test both operator== and operator!= + CHECK_EQ(v_d1, v_d1); + CHECK_FALSE(v_d1 != v_d1); + CHECK_EQ(v_d1, v_d1_ref2); + CHECK_FALSE(v_d1 != v_d1_ref2); + CHECK_EQ(v_d1, v_d2); + CHECK_FALSE(v_d1 != v_d2); + CHECK_NE(v_d1, v_d_other_key); + CHECK_FALSE(v_d1 == v_d_other_key); + CHECK_NE(v_d1, v_d_other_val); + CHECK_FALSE(v_d1 == v_d_other_val); +} + } // namespace TestVariant #endif // TEST_VARIANT_H |