diff --git a/.gitignore b/.gitignore index 97d869a..49f0c5b 100644 --- a/.gitignore +++ b/.gitignore @@ -270,3 +270,7 @@ CPack* _CPack* .cache/ *.deb + +# test files +test/lib/googletest/googletest/generated/ +jsonlogic_test diff --git a/src/operations/data/missing.cpp b/src/operations/data/missing.cpp index ba1ab2e..eca203d 100644 --- a/src/operations/data/missing.cpp +++ b/src/operations/data/missing.cpp @@ -1,7 +1,8 @@ #include "json_logic.h" -#include #include +#include +#include #include "nlohmann/json.hpp" @@ -17,7 +18,8 @@ namespace json_logic "Expected 1 or more arguments, but received " + std::to_string(values.size()) ); - std::set missing_keys{}; + std::vector missing_keys{}; + std::unordered_set seen{}; for (const auto& value : values) { @@ -34,7 +36,11 @@ namespace json_logic } catch (...) { - missing_keys.insert(key); + const auto [_, inserted] = seen.insert(key); + if (inserted) + { + missing_keys.push_back(key); + } } } diff --git a/src/operations/data/missing_some.cpp b/src/operations/data/missing_some.cpp index 01ef464..2b43826 100644 --- a/src/operations/data/missing_some.cpp +++ b/src/operations/data/missing_some.cpp @@ -1,7 +1,8 @@ #include "json_logic.h" -#include #include +#include +#include #include "nlohmann/json.hpp" @@ -23,8 +24,9 @@ namespace json_logic if (!search_values.is_array()) throw JsonLogicException(__FUNCTION__, "Second argument must be an array"); - std::set found_keys{}; - std::set missing_keys{}; + std::vector missing_keys{}; + std::unordered_set found_keys{}; + std::unordered_set seen_missing{}; for (const auto& value : search_values) { @@ -43,7 +45,11 @@ namespace json_logic } catch (...) { - missing_keys.insert(key); + const auto [_, inserted] = seen_missing.insert(key); + if (inserted) + { + missing_keys.push_back(key); + } } } diff --git a/test/operations/data/missing.cpp b/test/operations/data/missing.cpp index 658fadf..1e19409 100644 --- a/test/operations/data/missing.cpp +++ b/test/operations/data/missing.cpp @@ -1,4 +1,4 @@ -#include +#include #include "gtest/gtest.h" @@ -29,7 +29,7 @@ TEST_F(OperationDataMissing, SimpleKeys) const auto result = json_logic_->Apply(logic, data); - std::set expected_result{"b", "d"}; + std::vector expected_result{"b", "d"}; EXPECT_EQ(result, expected_result); } @@ -52,7 +52,7 @@ TEST_F(OperationDataMissing, SimpleKeysAllPresent) const auto result = json_logic_->Apply(logic, data); - std::set expected_result{}; + std::vector expected_result{}; EXPECT_EQ(result, expected_result); } @@ -73,7 +73,7 @@ TEST_F(OperationDataMissing, SimpleKeysRepeatedKeys) const auto result = json_logic_->Apply(logic, data); - std::set expected_result{"b", "d"}; + std::vector expected_result{"b", "d"}; EXPECT_EQ(result, expected_result); } @@ -100,6 +100,48 @@ TEST_F(OperationDataMissing, NestedKeys) const auto result = json_logic_->Apply(logic, data); - std::set expected_result{"a.y", "b.z"}; + std::vector expected_result{"a.y", "b.z"}; + EXPECT_EQ(result, expected_result); +} + +TEST_F(OperationDataMissing, OrderPreservationNonAlphabetic) +{ + const auto logic = R"( + { + "missing": ["zebra", "apple", "banana", "dog", "cat"] + } + )"_json; + + const auto data = R"( + { + "apple": 1, + "dog": 4 + } + )"_json; + + const auto result = json_logic_->Apply(logic, data); + + std::vector expected_result{"zebra", "banana", "cat"}; + EXPECT_EQ(result, expected_result); +} + +TEST_F(OperationDataMissing, OrderPreservationReversedKeys) +{ + const auto logic = R"( + { + "missing": ["z", "y", "x", "w", "v"] + } + )"_json; + + const auto data = R"( + { + "y": 2, + "w": 4 + } + )"_json; + + const auto result = json_logic_->Apply(logic, data); + + std::vector expected_result{"z", "x", "v"}; EXPECT_EQ(result, expected_result); } diff --git a/test/operations/data/missing_some.cpp b/test/operations/data/missing_some.cpp index 9773ca0..b81f292 100644 --- a/test/operations/data/missing_some.cpp +++ b/test/operations/data/missing_some.cpp @@ -1,4 +1,4 @@ -#include +#include #include "gtest/gtest.h" @@ -29,7 +29,7 @@ TEST_F(OperationDataMissingSome, SimpleKeysFoundMinimum) const auto result = json_logic_->Apply(logic, data); - std::set expected_result{}; + std::vector expected_result{}; EXPECT_EQ(result, expected_result); } @@ -50,7 +50,7 @@ TEST_F(OperationDataMissingSome, SimpleKeysNotFoundMinimum) const auto result = json_logic_->Apply(logic, data); - std::set expected_result{"b", "d"}; + std::vector expected_result{"b", "d"}; EXPECT_EQ(result, expected_result); } @@ -71,7 +71,7 @@ TEST_F(OperationDataMissingSome, SimpleRepeatedKeysFoundMinimum) const auto result = json_logic_->Apply(logic, data); - std::set expected_result{}; + std::vector expected_result{}; EXPECT_EQ(result, expected_result); } @@ -92,7 +92,7 @@ TEST_F(OperationDataMissingSome, SimpleRepeatedKeysNotFoundMinimum) const auto result = json_logic_->Apply(logic, data); - std::set expected_result{"b", "d"}; + std::vector expected_result{"b", "d"}; EXPECT_EQ(result, expected_result); } @@ -119,7 +119,7 @@ TEST_F(OperationDataMissingSome, NestedKeysFoundMinimum) const auto result = json_logic_->Apply(logic, data); - std::set expected_result{}; + std::vector expected_result{}; EXPECT_EQ(result, expected_result); } @@ -146,6 +146,48 @@ TEST_F(OperationDataMissingSome, NestedKeysNotFoundMinimum) const auto result = json_logic_->Apply(logic, data); - std::set expected_result{"a.y", "b.z"}; + std::vector expected_result{"a.y", "b.z"}; + EXPECT_EQ(result, expected_result); +} + +TEST_F(OperationDataMissingSome, OrderPreservationNonAlphabetic) +{ + const auto logic = R"( + { + "missing_some": [3, ["zebra", "dog", "apple", "banana", "cat"]] + } + )"_json; + + const auto data = R"( + { + "dog": 4, + "apple": 1 + } + )"_json; + + const auto result = json_logic_->Apply(logic, data); + + std::vector expected_result{"zebra", "banana", "cat"}; + EXPECT_EQ(result, expected_result); +} + +TEST_F(OperationDataMissingSome, OrderPreservationReversedKeys) +{ + const auto logic = R"( + { + "missing_some": [3, ["z", "y", "x", "w", "v"]] + } + )"_json; + + const auto data = R"( + { + "y": 2, + "w": 4 + } + )"_json; + + const auto result = json_logic_->Apply(logic, data); + + std::vector expected_result{"z", "x", "v"}; EXPECT_EQ(result, expected_result); }