diff --git a/extras/tests/JsonDeserializer/CMakeLists.txt b/extras/tests/JsonDeserializer/CMakeLists.txt index 0bc39054..15c84721 100644 --- a/extras/tests/JsonDeserializer/CMakeLists.txt +++ b/extras/tests/JsonDeserializer/CMakeLists.txt @@ -5,10 +5,9 @@ add_executable(JsonDeserializerTests array.cpp DeserializationError.cpp + errors.cpp filter.cpp - incomplete_input.cpp input_types.cpp - invalid_input.cpp misc.cpp nestingLimit.cpp number.cpp diff --git a/extras/tests/JsonDeserializer/errors.cpp b/extras/tests/JsonDeserializer/errors.cpp new file mode 100644 index 00000000..9bd5681c --- /dev/null +++ b/extras/tests/JsonDeserializer/errors.cpp @@ -0,0 +1,103 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2023, Benoit BLANCHON +// MIT License + +#define ARDUINOJSON_DECODE_UNICODE 1 +#include +#include + +TEST_CASE("deserializeJson() returns IncompleteInput") { + const char* testCases[] = { + // strings + "\"\\", + "\"hello", + "\'hello", + // unicode + "'\\u", + "'\\u00", + "'\\u000", + // false + "f", + "fa", + "fal", + "fals", + // true + "t", + "tr", + "tru", + // null + "n", + "nu", + "nul", + // object + "{", + "{a", + "{a:", + "{a:1", + "{a:1,", + "{a:1,b", + "{a:1,b:", + }; + + for (auto input : testCases) { + SECTION(input) { + JsonDocument doc; + REQUIRE(deserializeJson(doc, input) == + DeserializationError::IncompleteInput); + } + } +} + +TEST_CASE("deserializeJson() returns InvalidInput") { + const char* testCases[] = { + // unicode + "'\\u'", "'\\u000g'", "'\\u000'", "'\\u000G'", "'\\u000/'", "\\x1234", + // numbers + "6a9", "1,", "2]", "3}", + // constants + "nulL", "tru3", "fals3", + // garbage + "%*$£¤"}; + + for (auto input : testCases) { + SECTION(input) { + JsonDocument doc; + REQUIRE(deserializeJson(doc, input) == + DeserializationError::InvalidInput); + } + } +} + +TEST_CASE("deserializeJson() oversees some edge cases") { + const char* testCases[] = { + "'\\ud83d'", // leading surrogate without a trailing surrogate + "'\\udda4'", // trailing surrogate without a leading surrogate + "'\\ud83d\\ud83d'", // two leading surrogates + }; + + for (auto input : testCases) { + SECTION(input) { + JsonDocument doc; + REQUIRE(deserializeJson(doc, input) == DeserializationError::Ok); + } + } +} + +TEST_CASE("deserializeJson() returns EmptyInput") { + JsonDocument doc; + + SECTION("null") { + auto err = deserializeJson(doc, static_cast(0)); + REQUIRE(err == DeserializationError::EmptyInput); + } + + SECTION("Empty string") { + auto err = deserializeJson(doc, ""); + REQUIRE(err == DeserializationError::EmptyInput); + } + + SECTION("Only spaces") { + auto err = deserializeJson(doc, " \t\n\r"); + REQUIRE(err == DeserializationError::EmptyInput); + } +} diff --git a/extras/tests/JsonDeserializer/incomplete_input.cpp b/extras/tests/JsonDeserializer/incomplete_input.cpp deleted file mode 100644 index 13a0bde1..00000000 --- a/extras/tests/JsonDeserializer/incomplete_input.cpp +++ /dev/null @@ -1,50 +0,0 @@ -// ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON -// MIT License - -#define ARDUINOJSON_DECODE_UNICODE 1 -#include -#include - -TEST_CASE("Truncated JSON input") { - const char* testCases[] = { - // strings - "\"\\", - "\"hello", - "\'hello", - // unicode - "'\\u", - "'\\u00", - "'\\u000", - // false - "f", - "fa", - "fal", - "fals", - // true - "t", - "tr", - "tru", - // null - "n", - "nu", - "nul", - // object - "{", - "{a", - "{a:", - "{a:1", - "{a:1,", - "{a:1,", - }; - const size_t testCount = sizeof(testCases) / sizeof(testCases[0]); - - JsonDocument doc; - - for (size_t i = 0; i < testCount; i++) { - const char* input = testCases[i]; - CAPTURE(input); - REQUIRE(deserializeJson(doc, input) == - DeserializationError::IncompleteInput); - } -} diff --git a/extras/tests/JsonDeserializer/invalid_input.cpp b/extras/tests/JsonDeserializer/invalid_input.cpp deleted file mode 100644 index 1e12a8b2..00000000 --- a/extras/tests/JsonDeserializer/invalid_input.cpp +++ /dev/null @@ -1,40 +0,0 @@ -// ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON -// MIT License - -#define ARDUINOJSON_DECODE_UNICODE 1 -#include -#include - -TEST_CASE("Invalid JSON input") { - const char* testCases[] = {"'\\u'", "'\\u000g'", "'\\u000'", "'\\u000G'", - "'\\u000/'", "\\x1234", "6a9", "1,", - "nulL", "tru3", "fals3", "2]", - "3}"}; - const size_t testCount = sizeof(testCases) / sizeof(testCases[0]); - - JsonDocument doc; - - for (size_t i = 0; i < testCount; i++) { - const char* input = testCases[i]; - CAPTURE(input); - REQUIRE(deserializeJson(doc, input) == DeserializationError::InvalidInput); - } -} - -TEST_CASE("Invalid JSON input that should pass") { - const char* testCases[] = { - "'\\ud83d'", // leading surrogate without a trailing surrogate - "'\\udda4'", // trailing surrogate without a leading surrogate - "'\\ud83d\\ud83d'", // two leading surrogates - }; - const size_t testCount = sizeof(testCases) / sizeof(testCases[0]); - - JsonDocument doc; - - for (size_t i = 0; i < testCount; i++) { - const char* input = testCases[i]; - CAPTURE(input); - REQUIRE(deserializeJson(doc, input) == DeserializationError::Ok); - } -} diff --git a/extras/tests/JsonDeserializer/misc.cpp b/extras/tests/JsonDeserializer/misc.cpp index a7ff5a93..41407550 100644 --- a/extras/tests/JsonDeserializer/misc.cpp +++ b/extras/tests/JsonDeserializer/misc.cpp @@ -7,69 +7,30 @@ #include "Allocators.hpp" -using namespace Catch::Matchers; - -using ArduinoJson::detail::sizeofObject; - -TEST_CASE("deserializeJson(JsonDocument&)") { +TEST_CASE("deserializeJson() misc cases") { SpyingAllocator spy; JsonDocument doc(&spy); - SECTION("Edge cases") { - SECTION("null char*") { - DeserializationError err = deserializeJson(doc, static_cast(0)); - - REQUIRE(err != DeserializationError::Ok); - } - - SECTION("null const char*") { - DeserializationError err = - deserializeJson(doc, static_cast(0)); - - REQUIRE(err != DeserializationError::Ok); - } - - SECTION("Empty input") { - DeserializationError err = deserializeJson(doc, ""); - - REQUIRE(err == DeserializationError::EmptyInput); - } - - SECTION("Only spaces") { - DeserializationError err = deserializeJson(doc, " \t\n\r"); - - REQUIRE(err == DeserializationError::EmptyInput); - } - - SECTION("issue #628") { - DeserializationError err = deserializeJson(doc, "null"); - REQUIRE(err == DeserializationError::Ok); - REQUIRE(doc.is() == false); - } - - SECTION("Garbage") { - DeserializationError err = deserializeJson(doc, "%*$£¤"); - - REQUIRE(err == DeserializationError::InvalidInput); - } + SECTION("null") { + DeserializationError err = deserializeJson(doc, "null"); + REQUIRE(err == DeserializationError::Ok); + REQUIRE(doc.is() == false); } - SECTION("Booleans") { - SECTION("True") { - DeserializationError err = deserializeJson(doc, "true"); + SECTION("true") { + DeserializationError err = deserializeJson(doc, "true"); - REQUIRE(err == DeserializationError::Ok); - REQUIRE(doc.is()); - REQUIRE(doc.as() == true); - } + REQUIRE(err == DeserializationError::Ok); + REQUIRE(doc.is()); + REQUIRE(doc.as() == true); + } - SECTION("False") { - DeserializationError err = deserializeJson(doc, "false"); + SECTION("false") { + DeserializationError err = deserializeJson(doc, "false"); - REQUIRE(err == DeserializationError::Ok); - REQUIRE(doc.is()); - REQUIRE(doc.as() == false); - } + REQUIRE(err == DeserializationError::Ok); + REQUIRE(doc.is()); + REQUIRE(doc.as() == false); } SECTION("Should clear the JsonVariant") {