From e2bb2cec7b260b8fed7f8a897268d2026207061a Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Fri, 10 Jun 2022 09:53:25 +0200 Subject: [PATCH] Fix comparison operators for `JsonObject` and `JsonObjectConst` --- CHANGELOG.md | 2 +- extras/tests/JsonObject/CMakeLists.txt | 3 +- extras/tests/JsonObject/compare.cpp | 512 +++++++++++++++++++++++++ src/ArduinoJson/Object/ObjectRef.hpp | 2 + 4 files changed, 517 insertions(+), 2 deletions(-) create mode 100644 extras/tests/JsonObject/compare.cpp diff --git a/CHANGELOG.md b/CHANGELOG.md index d0a143b1..375a7fb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ HEAD * Add `JsonVariant::link()` (issue #1343) * Fix `9.22337e+18 is outside the range of representable values of type 'long'` -* Fix comparison operators for `JsonArray` and `JsonArrayConst` +* Fix comparison operators for `JsonArray`, `JsonArrayConst`, `JsonObject`, and `JsonObjectConst` v6.19.4 (2022-04-05) ------- diff --git a/extras/tests/JsonObject/CMakeLists.txt b/extras/tests/JsonObject/CMakeLists.txt index 9e5ac482..033e73ea 100644 --- a/extras/tests/JsonObject/CMakeLists.txt +++ b/extras/tests/JsonObject/CMakeLists.txt @@ -2,8 +2,9 @@ # Copyright © 2014-2022, Benoit BLANCHON # MIT License -add_executable(JsonObjectTests +add_executable(JsonObjectTests clear.cpp + compare.cpp containsKey.cpp copy.cpp createNestedArray.cpp diff --git a/extras/tests/JsonObject/compare.cpp b/extras/tests/JsonObject/compare.cpp new file mode 100644 index 00000000..ffdb9aa2 --- /dev/null +++ b/extras/tests/JsonObject/compare.cpp @@ -0,0 +1,512 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2022, Benoit BLANCHON +// MIT License + +#include +#include + +TEST_CASE("Compare JsonObject with JsonObject") { + StaticJsonDocument<512> doc; + + SECTION("Compare with unbound") { + JsonObject object = doc.to(); + object["a"] = 1; + object["b"] = "hello"; + JsonObject unbound; + + CHECK(object != unbound); + CHECK_FALSE(object == unbound); + CHECK_FALSE(object <= unbound); + CHECK_FALSE(object >= unbound); + CHECK_FALSE(object > unbound); + CHECK_FALSE(object < unbound); + + CHECK(unbound != object); + CHECK_FALSE(unbound == object); + CHECK_FALSE(unbound <= object); + CHECK_FALSE(unbound >= object); + CHECK_FALSE(unbound > object); + CHECK_FALSE(unbound < object); + } + + SECTION("Compare with self") { + JsonObject object = doc.to(); + object["a"] = 1; + object["b"] = "hello"; + + CHECK(object == object); + CHECK(object <= object); + CHECK(object >= object); + CHECK_FALSE(object != object); + CHECK_FALSE(object > object); + CHECK_FALSE(object < object); + } + + SECTION("Compare with identical object") { + JsonObject object1 = doc.createNestedObject(); + object1["a"] = 1; + object1["b"] = "hello"; + object1["c"][0] = false; + + JsonObject object2 = doc.createNestedObject(); + object2["a"] = 1; + object2["b"] = "hello"; + object2["c"][0] = false; + + CHECK(object1 == object2); + CHECK(object1 <= object2); + CHECK(object1 >= object2); + CHECK_FALSE(object1 != object2); + CHECK_FALSE(object1 > object2); + CHECK_FALSE(object1 < object2); + } + + SECTION("Compare with different object") { + JsonObject object1 = doc.createNestedObject(); + object1["a"] = 1; + object1["b"] = "hello1"; + object1["c"][0] = false; + + JsonObject object2 = doc.createNestedObject(); + object2["a"] = 1; + object2["b"] = "hello2"; + object2["c"][0] = false; + + CHECK(object1 != object2); + CHECK_FALSE(object1 == object2); + CHECK_FALSE(object1 > object2); + CHECK_FALSE(object1 < object2); + CHECK_FALSE(object1 <= object2); + CHECK_FALSE(object1 >= object2); + } +} + +TEST_CASE("Compare JsonObject with JsonVariant") { + StaticJsonDocument<512> doc; + + SECTION("Compare with self") { + JsonObject object = doc.to(); + object["a"] = 1; + object["b"] = "hello"; + + JsonVariant variant = object; + + CHECK(object == variant); + CHECK(object <= variant); + CHECK(object >= variant); + CHECK_FALSE(object != variant); + CHECK_FALSE(object > variant); + CHECK_FALSE(object < variant); + + CHECK(variant == object); + CHECK(variant <= object); + CHECK(variant >= object); + CHECK_FALSE(variant != object); + CHECK_FALSE(variant > object); + CHECK_FALSE(variant < object); + } + + SECTION("Compare with identical object") { + JsonObject object = doc.createNestedObject(); + object["a"] = 1; + object["b"] = "hello"; + object["c"][0] = false; + + JsonVariant variant = doc.createNestedObject(); + variant["a"] = 1; + variant["b"] = "hello"; + variant["c"][0] = false; + + CHECK(object == variant); + CHECK(object <= variant); + CHECK(object >= variant); + CHECK_FALSE(object != variant); + CHECK_FALSE(object > variant); + CHECK_FALSE(object < variant); + + CHECK(variant == object); + CHECK(variant <= object); + CHECK(variant >= object); + CHECK_FALSE(variant != object); + CHECK_FALSE(variant > object); + CHECK_FALSE(variant < object); + } + + SECTION("Compare with different object") { + JsonObject object = doc.createNestedObject(); + object["a"] = 1; + object["b"] = "hello1"; + object["c"][0] = false; + + JsonVariant variant = doc.createNestedObject(); + variant["a"] = 1; + variant["b"] = "hello2"; + variant["c"][0] = false; + + CHECK(object != variant); + CHECK_FALSE(object == variant); + CHECK_FALSE(object > variant); + CHECK_FALSE(object < variant); + CHECK_FALSE(object <= variant); + CHECK_FALSE(object >= variant); + } +} + +TEST_CASE("Compare JsonObject with JsonVariantConst") { + StaticJsonDocument<512> doc; + + SECTION("Compare with unbound") { + JsonObject object = doc.to(); + object["a"] = 1; + object["b"] = "hello"; + JsonVariantConst unbound; + + CHECK(object != unbound); + CHECK_FALSE(object == unbound); + CHECK_FALSE(object <= unbound); + CHECK_FALSE(object >= unbound); + CHECK_FALSE(object > unbound); + CHECK_FALSE(object < unbound); + + CHECK(unbound != object); + CHECK_FALSE(unbound == object); + CHECK_FALSE(unbound <= object); + CHECK_FALSE(unbound >= object); + CHECK_FALSE(unbound > object); + CHECK_FALSE(unbound < object); + } + + SECTION("Compare with self") { + JsonObject object = doc.to(); + object["a"] = 1; + object["b"] = "hello"; + + JsonVariantConst variant = object; + + CHECK(object == variant); + CHECK(object <= variant); + CHECK(object >= variant); + CHECK_FALSE(object != variant); + CHECK_FALSE(object > variant); + CHECK_FALSE(object < variant); + + CHECK(variant == object); + CHECK(variant <= object); + CHECK(variant >= object); + CHECK_FALSE(variant != object); + CHECK_FALSE(variant > object); + CHECK_FALSE(variant < object); + } + + SECTION("Compare with identical object") { + JsonObject object = doc.createNestedObject(); + object["a"] = 1; + object["b"] = "hello"; + object["c"][0] = false; + + JsonObject object2 = doc.createNestedObject(); + object2["a"] = 1; + object2["b"] = "hello"; + object2["c"][0] = false; + JsonVariantConst variant = object2; + + CHECK(object == variant); + CHECK(object <= variant); + CHECK(object >= variant); + CHECK_FALSE(object != variant); + CHECK_FALSE(object > variant); + CHECK_FALSE(object < variant); + + CHECK(variant == object); + CHECK(variant <= object); + CHECK(variant >= object); + CHECK_FALSE(variant != object); + CHECK_FALSE(variant > object); + CHECK_FALSE(variant < object); + } + + SECTION("Compare with different object") { + JsonObject object = doc.createNestedObject(); + object["a"] = 1; + object["b"] = "hello1"; + object["c"][0] = false; + + JsonObject object2 = doc.createNestedObject(); + object2["a"] = 1; + object2["b"] = "hello2"; + object2["c"][0] = false; + JsonVariantConst variant = object2; + + CHECK(object != variant); + CHECK_FALSE(object == variant); + CHECK_FALSE(object > variant); + CHECK_FALSE(object < variant); + CHECK_FALSE(object <= variant); + CHECK_FALSE(object >= variant); + } +} + +TEST_CASE("Compare JsonObject with JsonObjectConst") { + StaticJsonDocument<512> doc; + + SECTION("Compare with unbound") { + JsonObject object = doc.to(); + object["a"] = 1; + object["b"] = "hello"; + JsonObjectConst unbound; + + CHECK(object != unbound); + CHECK_FALSE(object == unbound); + CHECK_FALSE(object <= unbound); + CHECK_FALSE(object >= unbound); + CHECK_FALSE(object > unbound); + CHECK_FALSE(object < unbound); + + CHECK(unbound != object); + CHECK_FALSE(unbound == object); + CHECK_FALSE(unbound <= object); + CHECK_FALSE(unbound >= object); + CHECK_FALSE(unbound > object); + CHECK_FALSE(unbound < object); + } + + SECTION("Compare with self") { + JsonObject object = doc.to(); + object["a"] = 1; + object["b"] = "hello"; + JsonObjectConst cobject = object; + + CHECK(object == cobject); + CHECK(object <= cobject); + CHECK(object >= cobject); + CHECK_FALSE(object != cobject); + CHECK_FALSE(object > cobject); + CHECK_FALSE(object < cobject); + + CHECK(cobject == object); + CHECK(cobject <= object); + CHECK(cobject >= object); + CHECK_FALSE(cobject != object); + CHECK_FALSE(cobject > object); + CHECK_FALSE(cobject < object); + } + + SECTION("Compare with identical object") { + JsonObject object1 = doc.createNestedObject(); + object1["a"] = 1; + object1["b"] = "hello"; + object1["c"][0] = false; + + JsonObject object2 = doc.createNestedObject(); + object2["a"] = 1; + object2["b"] = "hello"; + object2["c"][0] = false; + JsonObjectConst carray2 = object2; + + CHECK(object1 == carray2); + CHECK(object1 <= carray2); + CHECK(object1 >= carray2); + CHECK_FALSE(object1 != carray2); + CHECK_FALSE(object1 > carray2); + CHECK_FALSE(object1 < carray2); + + CHECK(carray2 == object1); + CHECK(carray2 <= object1); + CHECK(carray2 >= object1); + CHECK_FALSE(carray2 != object1); + CHECK_FALSE(carray2 > object1); + CHECK_FALSE(carray2 < object1); + } + + SECTION("Compare with different object") { + JsonObject object1 = doc.createNestedObject(); + object1["a"] = 1; + object1["b"] = "hello1"; + object1["c"][0] = false; + + JsonObject object2 = doc.createNestedObject(); + object2["a"] = 1; + object2["b"] = "hello2"; + object2["c"][0] = false; + JsonObjectConst carray2 = object2; + + CHECK(object1 != carray2); + CHECK_FALSE(object1 == carray2); + CHECK_FALSE(object1 > carray2); + CHECK_FALSE(object1 < carray2); + CHECK_FALSE(object1 <= carray2); + CHECK_FALSE(object1 >= carray2); + + CHECK(carray2 != object1); + CHECK_FALSE(carray2 == object1); + CHECK_FALSE(carray2 > object1); + CHECK_FALSE(carray2 < object1); + CHECK_FALSE(carray2 <= object1); + CHECK_FALSE(carray2 >= object1); + } +} + +TEST_CASE("Compare JsonObjectConst with JsonObjectConst") { + StaticJsonDocument<512> doc; + + SECTION("Compare with unbound") { + JsonObject object = doc.to(); + object["a"] = 1; + object["b"] = "hello"; + + JsonObjectConst cobject = object; + JsonObjectConst unbound; + + CHECK(cobject != unbound); + CHECK_FALSE(cobject == unbound); + CHECK_FALSE(cobject <= unbound); + CHECK_FALSE(cobject >= unbound); + CHECK_FALSE(cobject > unbound); + CHECK_FALSE(cobject < unbound); + + CHECK(unbound != cobject); + CHECK_FALSE(unbound == cobject); + CHECK_FALSE(unbound <= cobject); + CHECK_FALSE(unbound >= cobject); + CHECK_FALSE(unbound > cobject); + CHECK_FALSE(unbound < cobject); + } + + SECTION("Compare with self") { + JsonObject object = doc.to(); + object["a"] = 1; + object["b"] = "hello"; + JsonObjectConst cobject = object; + + CHECK(cobject == cobject); + CHECK(cobject <= cobject); + CHECK(cobject >= cobject); + CHECK_FALSE(cobject != cobject); + CHECK_FALSE(cobject > cobject); + CHECK_FALSE(cobject < cobject); + } + + SECTION("Compare with identical object") { + JsonObject object1 = doc.createNestedObject(); + object1["a"] = 1; + object1["b"] = "hello"; + object1["c"][0] = false; + JsonObjectConst carray1 = object1; + + JsonObject object2 = doc.createNestedObject(); + object2["a"] = 1; + object2["b"] = "hello"; + object2["c"][0] = false; + JsonObjectConst carray2 = object2; + + CHECK(carray1 == carray2); + CHECK(carray1 <= carray2); + CHECK(carray1 >= carray2); + CHECK_FALSE(carray1 != carray2); + CHECK_FALSE(carray1 > carray2); + CHECK_FALSE(carray1 < carray2); + } + + SECTION("Compare with different object") { + JsonObject object1 = doc.createNestedObject(); + object1["a"] = 1; + object1["b"] = "hello1"; + object1["c"][0] = false; + JsonObjectConst carray1 = object1; + + JsonObject object2 = doc.createNestedObject(); + object2["a"] = 1; + object2["b"] = "hello2"; + object2["c"][0] = false; + JsonObjectConst carray2 = object2; + + CHECK(carray1 != carray2); + CHECK_FALSE(carray1 == carray2); + CHECK_FALSE(carray1 > carray2); + CHECK_FALSE(carray1 < carray2); + CHECK_FALSE(carray1 <= carray2); + CHECK_FALSE(carray1 >= carray2); + } +} + +TEST_CASE("Compare JsonObjectConst with JsonVariant") { + StaticJsonDocument<512> doc; + + SECTION("Compare with self") { + JsonObject object = doc.to(); + object["a"] = 1; + object["b"] = "hello"; + JsonObjectConst cobject = object; + JsonVariant variant = object; + + CHECK(cobject == variant); + CHECK(cobject <= variant); + CHECK(cobject >= variant); + CHECK_FALSE(cobject != variant); + CHECK_FALSE(cobject > variant); + CHECK_FALSE(cobject < variant); + + CHECK(variant == cobject); + CHECK(variant <= cobject); + CHECK(variant >= cobject); + CHECK_FALSE(variant != cobject); + CHECK_FALSE(variant > cobject); + CHECK_FALSE(variant < cobject); + } + + SECTION("Compare with identical object") { + JsonObject object1 = doc.createNestedObject(); + object1["a"] = 1; + object1["b"] = "hello"; + object1["c"][0] = false; + JsonObjectConst carray1 = object1; + + JsonObject object2 = doc.createNestedObject(); + object2["a"] = 1; + object2["b"] = "hello"; + object2["c"][0] = false; + JsonVariant variant2 = object2; + + CHECK(carray1 == variant2); + CHECK(carray1 <= variant2); + CHECK(carray1 >= variant2); + CHECK_FALSE(carray1 != variant2); + CHECK_FALSE(carray1 > variant2); + CHECK_FALSE(carray1 < variant2); + + CHECK(variant2 == carray1); + CHECK(variant2 <= carray1); + CHECK(variant2 >= carray1); + CHECK_FALSE(variant2 != carray1); + CHECK_FALSE(variant2 > carray1); + CHECK_FALSE(variant2 < carray1); + } + + SECTION("Compare with different object") { + JsonObject object1 = doc.createNestedObject(); + object1["a"] = 1; + object1["b"] = "hello1"; + object1["c"][0] = false; + JsonObjectConst carray1 = object1; + + JsonObject object2 = doc.createNestedObject(); + object2["a"] = 1; + object2["b"] = "hello2"; + object2["c"][0] = false; + JsonVariant variant2 = object2; + + CHECK(carray1 != variant2); + CHECK_FALSE(carray1 == variant2); + CHECK_FALSE(carray1 > variant2); + CHECK_FALSE(carray1 < variant2); + CHECK_FALSE(carray1 <= variant2); + CHECK_FALSE(carray1 >= variant2); + + CHECK(variant2 != carray1); + CHECK_FALSE(variant2 == carray1); + CHECK_FALSE(variant2 > carray1); + CHECK_FALSE(variant2 < carray1); + CHECK_FALSE(variant2 <= carray1); + CHECK_FALSE(variant2 >= carray1); + } +} diff --git a/src/ArduinoJson/Object/ObjectRef.hpp b/src/ArduinoJson/Object/ObjectRef.hpp index 3ef65c87..f7a19f6e 100644 --- a/src/ArduinoJson/Object/ObjectRef.hpp +++ b/src/ArduinoJson/Object/ObjectRef.hpp @@ -57,6 +57,7 @@ class ObjectRefBase { }; class ObjectConstRef : public ObjectRefBase, + public VariantOperators, public Visitable { friend class ObjectRef; typedef ObjectRefBase base_type; @@ -147,6 +148,7 @@ class ObjectConstRef : public ObjectRefBase, class ObjectRef : public ObjectRefBase, public ObjectShortcuts, + public VariantOperators, public Visitable { typedef ObjectRefBase base_type;