diff --git a/CHANGELOG.md b/CHANGELOG.md index 20aaa183..9434822d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,8 +33,8 @@ HEAD > > ```c++ > DynamicJsonObject obj; -> bool success = deserializeJson(obj, json); -> if (success) { +> JsonError error = deserializeJson(obj, json); +> if (error) { > > } > ``` diff --git a/examples/JsonConfigFile/JsonConfigFile.ino b/examples/JsonConfigFile/JsonConfigFile.ino index 442a8651..ebf03738 100644 --- a/examples/JsonConfigFile/JsonConfigFile.ino +++ b/examples/JsonConfigFile/JsonConfigFile.ino @@ -35,9 +35,9 @@ void loadConfiguration(const char *filename, Config &config) { StaticJsonObject<512> root; // Parse the root object - bool success = deserializeJson(root, file); + JsonError error = deserializeJson(root, file); - if (!success) + if (error) Serial.println(F("Failed to read file, using default configuration")); // Copy values from the JsonObject to the Config diff --git a/examples/JsonHttpClient/JsonHttpClient.ino b/examples/JsonHttpClient/JsonHttpClient.ino index 8ce57a7f..aeae598a 100644 --- a/examples/JsonHttpClient/JsonHttpClient.ino +++ b/examples/JsonHttpClient/JsonHttpClient.ino @@ -76,8 +76,8 @@ void setup() { DynamicJsonObject root(capacity); // Parse JSON object - bool success = deserializeJson(root, client); - if (!root.success()) { + JsonError error = deserializeJson(root, client); + if (error) { Serial.println(F("Parsing failed!")); return; } diff --git a/examples/JsonParserExample/JsonParserExample.ino b/examples/JsonParserExample/JsonParserExample.ino index 6c8063a5..1f9cb306 100644 --- a/examples/JsonParserExample/JsonParserExample.ino +++ b/examples/JsonParserExample/JsonParserExample.ino @@ -36,10 +36,10 @@ void setup() { // It's a reference to the JsonObject, the actual bytes are inside the // JsonBuffer with all the other nodes of the object tree. // Memory is freed when jsonBuffer goes out of scope. - bool success = deserializeJson(root, json); + JsonError error = deserializeJson(root, json); // Test if parsing succeeds. - if (!success) { + if (error) { Serial.println("parseObject() failed"); return; } diff --git a/fuzzing/fuzzer.cpp b/fuzzing/fuzzer.cpp index 24b2f191..358273c3 100644 --- a/fuzzing/fuzzer.cpp +++ b/fuzzing/fuzzer.cpp @@ -16,10 +16,11 @@ class memstream : public std::istream { }; extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - DynamicJsonBuffer jsonBuffer; + DynamicJsonVariant variant; memstream json(data, size); + JsonError error = deserializeJson(variant, json); JsonVariant variant = jsonBuffer.parse(json); - if (variant.success()) { + if (!error) { variant.as(); // <- serialize to JSON } return 0; diff --git a/src/ArduinoJson/Deserialization/JsonParser.hpp b/src/ArduinoJson/Deserialization/JsonParser.hpp index b30abddc..3c132448 100644 --- a/src/ArduinoJson/Deserialization/JsonParser.hpp +++ b/src/ArduinoJson/Deserialization/JsonParser.hpp @@ -5,6 +5,7 @@ #pragma once #include "../JsonBuffer.hpp" +#include "../JsonError.hpp" #include "../JsonVariant.hpp" #include "../TypeTraits/IsConst.hpp" #include "StringWriter.hpp" @@ -24,9 +25,9 @@ class JsonParser { _reader(reader), _writer(writer), _nestingLimit(nestingLimit) {} - bool parse(JsonArray &destination); - bool parse(JsonObject &destination); - bool parse(JsonVariant &destination); + JsonError parse(JsonArray &destination); + JsonError parse(JsonObject &destination); + JsonError parse(JsonVariant &destination); private: JsonParser &operator=(const JsonParser &); // non-copiable @@ -37,12 +38,12 @@ class JsonParser { } const char *parseString(); - bool parseAnythingTo(JsonVariant *destination); - FORCE_INLINE bool parseAnythingToUnsafe(JsonVariant *destination); + JsonError parseAnythingTo(JsonVariant *destination); + FORCE_INLINE JsonError parseAnythingToUnsafe(JsonVariant *destination); - inline bool parseArrayTo(JsonVariant *destination); - inline bool parseObjectTo(JsonVariant *destination); - inline bool parseStringTo(JsonVariant *destination); + inline JsonError parseArrayTo(JsonVariant *destination); + inline JsonError parseObjectTo(JsonVariant *destination); + inline JsonError parseStringTo(JsonVariant *destination); static inline bool isBetween(char c, char min, char max) { return min <= c && c <= max; diff --git a/src/ArduinoJson/Deserialization/JsonParserImpl.hpp b/src/ArduinoJson/Deserialization/JsonParserImpl.hpp index 3543d870..3e767a2a 100644 --- a/src/ArduinoJson/Deserialization/JsonParserImpl.hpp +++ b/src/ArduinoJson/Deserialization/JsonParserImpl.hpp @@ -18,18 +18,18 @@ inline bool ArduinoJson::Internals::JsonParser::eat( } template -inline bool +inline ArduinoJson::JsonError ArduinoJson::Internals::JsonParser::parseAnythingTo( JsonVariant *destination) { - if (_nestingLimit == 0) return false; + if (_nestingLimit == 0) return JsonError::TooDeep; _nestingLimit--; - bool success = parseAnythingToUnsafe(destination); + JsonError error = parseAnythingToUnsafe(destination); _nestingLimit++; - return success; + return error; } template -inline bool +inline ArduinoJson::JsonError ArduinoJson::Internals::JsonParser::parseAnythingToUnsafe( JsonVariant *destination) { skipSpacesAndComments(_reader); @@ -47,92 +47,76 @@ ArduinoJson::Internals::JsonParser::parseAnythingToUnsafe( } template -inline bool ArduinoJson::Internals::JsonParser::parse( - JsonArray &array) { +inline ArduinoJson::JsonError +ArduinoJson::Internals::JsonParser::parse(JsonArray &array) { // Check opening braket - if (!eat('[')) goto ERROR_MISSING_BRACKET; - if (eat(']')) goto SUCCESS_EMPTY_ARRAY; + if (!eat('[')) return JsonError::OpeningBracketExpected; + if (eat(']')) return JsonError::Ok; // Read each value for (;;) { // 1 - Parse value JsonVariant value; - if (!parseAnythingTo(&value)) goto ERROR_INVALID_VALUE; - if (!array.add(value)) goto ERROR_NO_MEMORY; + JsonError error = parseAnythingTo(&value); + if (error != JsonError::Ok) return error; + if (!array.add(value)) return JsonError::NoMemory; // 2 - More values? - if (eat(']')) goto SUCCES_NON_EMPTY_ARRAY; - if (!eat(',')) goto ERROR_MISSING_COMMA; + if (eat(']')) return JsonError::Ok; + if (!eat(',')) return JsonError::ClosingBracketExpected; } - -SUCCESS_EMPTY_ARRAY: -SUCCES_NON_EMPTY_ARRAY: - return true; - -ERROR_INVALID_VALUE: -ERROR_MISSING_BRACKET: -ERROR_MISSING_COMMA: -ERROR_NO_MEMORY: - return false; } template -inline bool ArduinoJson::Internals::JsonParser::parse( +inline ArduinoJson::JsonError +ArduinoJson::Internals::JsonParser::parse( JsonObject &object) { // Check opening brace - if (!eat('{')) goto ERROR_MISSING_BRACE; - if (eat('}')) goto SUCCESS_EMPTY_OBJECT; + if (!eat('{')) return JsonError::OpeningBraceExpected; + if (eat('}')) return JsonError::Ok; // Read each key value pair for (;;) { // 1 - Parse key const char *key = parseString(); - if (!key) goto ERROR_INVALID_KEY; - if (!eat(':')) goto ERROR_MISSING_COLON; + if (!key) return JsonError::NoMemory; + if (!eat(':')) return JsonError::ColonExpected; // 2 - Parse value JsonVariant value; - if (!parseAnythingTo(&value)) goto ERROR_INVALID_VALUE; - if (!object.set(key, value)) goto ERROR_NO_MEMORY; + JsonError error = parseAnythingTo(&value); + if (error != JsonError::Ok) return error; + if (!object.set(key, value)) return JsonError::NoMemory; // 3 - More keys/values? - if (eat('}')) goto SUCCESS_NON_EMPTY_OBJECT; - if (!eat(',')) goto ERROR_MISSING_COMMA; + if (eat('}')) return JsonError::Ok; + if (!eat(',')) return JsonError::ClosingBraceExpected; } - -SUCCESS_EMPTY_OBJECT: -SUCCESS_NON_EMPTY_OBJECT: - return true; - -ERROR_INVALID_KEY: -ERROR_INVALID_VALUE: -ERROR_MISSING_BRACE: -ERROR_MISSING_COLON: -ERROR_MISSING_COMMA: -ERROR_NO_MEMORY: - return false; } template -inline bool ArduinoJson::Internals::JsonParser::parse( +inline ArduinoJson::JsonError +ArduinoJson::Internals::JsonParser::parse( JsonVariant &variant) { return parseAnythingTo(&variant); } template -inline bool ArduinoJson::Internals::JsonParser::parseArrayTo( +inline ArduinoJson::JsonError +ArduinoJson::Internals::JsonParser::parseArrayTo( JsonVariant *destination) { JsonArray *array = new (_buffer) JsonArray(_buffer); - if (!array) return false; + if (!array) return JsonError::NoMemory; *destination = array; return parse(*array); } template -inline bool ArduinoJson::Internals::JsonParser::parseObjectTo( +inline ArduinoJson::JsonError +ArduinoJson::Internals::JsonParser::parseObjectTo( JsonVariant *destination) { JsonObject *object = new (_buffer) JsonObject(_buffer); - if (!object) return false; + if (!object) return JsonError::NoMemory; *destination = object; return parse(*object); } @@ -177,15 +161,16 @@ ArduinoJson::Internals::JsonParser::parseString() { } template -inline bool ArduinoJson::Internals::JsonParser::parseStringTo( +inline ArduinoJson::JsonError +ArduinoJson::Internals::JsonParser::parseStringTo( JsonVariant *destination) { bool hasQuotes = isQuote(_reader.current()); const char *value = parseString(); - if (value == NULL) return false; + if (value == NULL) return JsonError::NoMemory; if (hasQuotes) { *destination = value; } else { *destination = RawJson(value); } - return true; + return JsonError::Ok; } diff --git a/src/ArduinoJson/JsonError.hpp b/src/ArduinoJson/JsonError.hpp new file mode 100644 index 00000000..e62dae6f --- /dev/null +++ b/src/ArduinoJson/JsonError.hpp @@ -0,0 +1,83 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +namespace ArduinoJson { + +class JsonError { + public: + enum Code { + Ok, + OpeningBraceExpected, + ClosingBraceExpected, + OpeningBracketExpected, + ClosingBracketExpected, + ColonExpected, + TooDeep, + NoMemory + }; + + JsonError(Code code) : _code(code) {} + + bool operator==(Code code) const { + return _code == code; + } + + bool operator!=(Code code) const { + return _code != code; + } + + operator bool() const { + return _code != Ok; + } + + const char* c_str() const { + return to_string(_code); + } + + friend const char* to_string(const JsonError err) { + return to_string(err._code); + } + + friend const char* to_string(JsonError::Code code) { + switch (code) { + case Ok: + return "Ok"; + case OpeningBraceExpected: + return "OpeningBraceExpected"; + case ClosingBraceExpected: + return "ClosingBraceExpected"; + case OpeningBracketExpected: + return "OpeningBracketExpected"; + case ClosingBracketExpected: + return "ClosingBracketExpected"; + case ColonExpected: + return "ColonExpected"; + case TooDeep: + return "TooDeep"; + case NoMemory: + return "NoMemory"; + default: + return "???"; + } + } + + private: + Code _code; +}; + +#if ARDUINOJSON_ENABLE_STD_STREAM +inline std::ostream& operator<<(std::ostream& s, const JsonError& e) { + s << to_string(e); + return s; +} + +inline std::ostream& operator<<(std::ostream& s, JsonError::Code e) { + s << to_string(e); + return s; +} +#endif + +} // namespace ArduinoJson diff --git a/src/ArduinoJson/deserializeJson.hpp b/src/ArduinoJson/deserializeJson.hpp index c192c32b..4593529f 100644 --- a/src/ArduinoJson/deserializeJson.hpp +++ b/src/ArduinoJson/deserializeJson.hpp @@ -7,33 +7,36 @@ #include "Deserialization/JsonParser.hpp" namespace ArduinoJson { -// bool deserializeJson(TDestination& destination, TString json); +// JsonError deserializeJson(TDestination& destination, TString json); // TDestination = JsonArray, JsonObject, JsonVariant // TString = const std::string&, const String& template -typename Internals::EnableIf::value, bool>::type +typename Internals::EnableIf::value, + JsonError>::type deserializeJson(TDestination &destination, const TString &json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { return Internals::makeParser(&destination.buffer(), json, nestingLimit) .parse(destination); } // -// bool deserializeJson(TDestination& destination, TString json); +// JsonError deserializeJson(TDestination& destination, TString json); // TDestination = JsonArray, JsonObject, JsonVariant // TString = const char*, const char[N], const FlashStringHelper* template -bool deserializeJson(TDestination &destination, TString *json, - uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { +JsonError deserializeJson( + TDestination &destination, TString *json, + uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { return Internals::makeParser(&destination.buffer(), json, nestingLimit) .parse(destination); } // -// bool deserializeJson(TDestination& destination, TString json); +// JsonError deserializeJson(TDestination& destination, TString json); // TDestination = JsonArray, JsonObject, JsonVariant // TString = std::istream&, Stream& template -bool deserializeJson(TDestination &destination, TString &json, - uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { +JsonError deserializeJson( + TDestination &destination, TString &json, + uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { return Internals::makeParser(&destination.buffer(), json, nestingLimit) .parse(destination); } diff --git a/test/DynamicJsonBuffer/no_memory.cpp b/test/DynamicJsonBuffer/no_memory.cpp index be39c04d..5587a1ce 100644 --- a/test/DynamicJsonBuffer/no_memory.cpp +++ b/test/DynamicJsonBuffer/no_memory.cpp @@ -27,9 +27,9 @@ TEST_CASE("DynamicJsonBuffer no memory") { // char json[] = "[{}]"; // DynamicJsonArray arr; - // bool success = deserializeJson(arr, json); + // JsonError err = deserializeJson(arr, json); - // REQUIRE(success == false); + // REQUIRE(err != JsonError::Ok); // } // TODO: uncomment @@ -37,9 +37,9 @@ TEST_CASE("DynamicJsonBuffer no memory") { // char json[] = "{[]}"; // DynamicJsonObject obj; - // bool success = deserializeJson(obj, json); + // JsonError err = deserializeJson(obj, json); - // REQUIRE(success == false); + // REQUIRE(err != JsonError::Ok); // } SECTION("startString()") { diff --git a/test/IntegrationTests/gbathree.cpp b/test/IntegrationTests/gbathree.cpp index 0f12dbf2..dd6b293f 100644 --- a/test/IntegrationTests/gbathree.cpp +++ b/test/IntegrationTests/gbathree.cpp @@ -8,7 +8,7 @@ TEST_CASE("Gbathree") { DynamicJsonObject _object; - bool success = deserializeJson( + JsonError error = deserializeJson( _object, "{\"protocol_name\":\"fluorescence\",\"repeats\":1,\"wait\":0," "\"averages\":1,\"measurements\":3,\"meas2_light\":15,\"meas1_" @@ -22,7 +22,7 @@ TEST_CASE("Gbathree") { "[15,15,15,15]],\"altc\":[2,2,2,2],\"altd\":[2,2,2,2]}"); SECTION("Success") { - REQUIRE(success == true); + REQUIRE(error == JsonError::Ok); } SECTION("ProtocolName") { diff --git a/test/JsonArray/copyTo.cpp b/test/JsonArray/copyTo.cpp index 3a83a461..9c31e880 100644 --- a/test/JsonArray/copyTo.cpp +++ b/test/JsonArray/copyTo.cpp @@ -10,8 +10,8 @@ TEST_CASE("JsonArray::copyTo()") { SECTION("BiggerOneDimensionIntegerArray") { char json[] = "[1,2,3]"; - bool success = deserializeJson(array, json); - REQUIRE(success == true); + JsonError err = deserializeJson(array, json); + REQUIRE(err == JsonError::Ok); int destination[4] = {0}; size_t result = array.copyTo(destination); @@ -25,8 +25,8 @@ TEST_CASE("JsonArray::copyTo()") { SECTION("SmallerOneDimensionIntegerArray") { char json[] = "[1,2,3]"; - bool success = deserializeJson(array, json); - REQUIRE(success == true); + JsonError err = deserializeJson(array, json); + REQUIRE(err == JsonError::Ok); int destination[2] = {0}; size_t result = array.copyTo(destination); @@ -39,8 +39,8 @@ TEST_CASE("JsonArray::copyTo()") { SECTION("TwoOneDimensionIntegerArray") { char json[] = "[[1,2],[3],[4]]"; - bool success = deserializeJson(array, json); - REQUIRE(success == true); + JsonError err = deserializeJson(array, json); + REQUIRE(err == JsonError::Ok); int destination[3][2] = {{0}}; array.copyTo(destination); diff --git a/test/JsonParser/CMakeLists.txt b/test/JsonParser/CMakeLists.txt index fa5ec203..19381c40 100644 --- a/test/JsonParser/CMakeLists.txt +++ b/test/JsonParser/CMakeLists.txt @@ -4,6 +4,7 @@ add_executable(JsonParserTests JsonArray.cpp + JsonError.cpp JsonObject.cpp JsonVariant.cpp nestingLimit.cpp diff --git a/test/JsonParser/JsonArray.cpp b/test/JsonParser/JsonArray.cpp index af12c548..5a9a6b14 100644 --- a/test/JsonParser/JsonArray.cpp +++ b/test/JsonParser/JsonArray.cpp @@ -8,339 +8,346 @@ TEST_CASE("deserializeJson(JsonArray&)") { DynamicJsonArray arr; - SECTION("EmptyArray") { - bool success = deserializeJson(arr, "[]"); + SECTION("An empty array") { + JsonError err = deserializeJson(arr, "[]"); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); REQUIRE(0 == arr.size()); } - SECTION("MissingOpeningBracket") { - bool success = deserializeJson(arr, "]"); - REQUIRE_FALSE(success == true); + SECTION("Spaces") { + SECTION("Before the opening bracket") { + JsonError err = deserializeJson(arr, " []"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(0 == arr.size()); + } + + SECTION("Before first value") { + JsonError err = deserializeJson(arr, "[ \t\r\n42]"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == 42); + } + + SECTION("After first value") { + JsonError err = deserializeJson(arr, "[42 \t\r\n]"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == 42); + } } - SECTION("ArrayWithNoEnd") { - bool success = deserializeJson(arr, "["); - REQUIRE_FALSE(success == true); + SECTION("Values types") { + SECTION("On integer") { + JsonError err = deserializeJson(arr, "[42]"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == 42); + } + + SECTION("Two integers") { + JsonError err = deserializeJson(arr, "[42,84]"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == 42); + REQUIRE(arr[1] == 84); + } + + SECTION("Double") { + JsonError err = deserializeJson(arr, "[4.2,1e2]"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == 4.2); + REQUIRE(arr[1] == 1e2); + } + + SECTION("Unsigned long") { + JsonError err = deserializeJson(arr, "[4294967295]"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == 4294967295UL); + } + + SECTION("Boolean") { + JsonError err = deserializeJson(arr, "[true,false]"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == true); + REQUIRE(arr[1] == false); + } + + SECTION("Null") { + JsonError err = deserializeJson(arr, "[null,null]"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0].as() == 0); + REQUIRE(arr[1].as() == 0); + } } - SECTION("EmptyArrayWithLeadingSpaces") { - bool success = deserializeJson(arr, " []"); + SECTION("Quotes") { + SECTION("Double quotes") { + JsonError err = deserializeJson(arr, "[ \"hello\" , \"world\" ]"); - REQUIRE(success == true); - REQUIRE(0 == arr.size()); + REQUIRE(err == JsonError::Ok); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == "hello"); + REQUIRE(arr[1] == "world"); + } + + SECTION("Single quotes") { + JsonError err = deserializeJson(arr, "[ 'hello' , 'world' ]"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == "hello"); + REQUIRE(arr[1] == "world"); + } + + SECTION("No quotes") { + JsonError err = deserializeJson(arr, "[ hello , world ]"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == "hello"); + REQUIRE(arr[1] == "world"); + } + + SECTION("Double quotes (empty strings)") { + JsonError err = deserializeJson(arr, "[\"\",\"\"]"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == ""); + REQUIRE(arr[1] == ""); + } + + SECTION("Single quotes (empty strings)") { + JsonError err = deserializeJson(arr, "[\'\',\'\']"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == ""); + REQUIRE(arr[1] == ""); + } + + SECTION("No quotes (empty strings)") { + JsonError err = deserializeJson(arr, "[,]"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == ""); + REQUIRE(arr[1] == ""); + } + + SECTION("Closing single quotes missing") { + JsonError err = deserializeJson(arr, "[\"]"); + + REQUIRE(err != JsonError::Ok); + } + + SECTION("Closing double quotes missing") { + JsonError err = deserializeJson(arr, "[\']"); + + REQUIRE(err != JsonError::Ok); + } } - SECTION("Garbage") { - bool success = deserializeJson(arr, "%*$£¤"); + SECTION("Block comments") { + SECTION("Before opening bracket") { + JsonError err = deserializeJson(arr, "/*COMMENT*/ [\"hello\"]"); - REQUIRE_FALSE(success == true); + REQUIRE(err == JsonError::Ok); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == "hello"); + } + + SECTION("After opening bracket") { + JsonError err = deserializeJson(arr, "[/*COMMENT*/ \"hello\"]"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == "hello"); + } + + SECTION("Before closing bracket") { + JsonError err = deserializeJson(arr, "[\"hello\"/*COMMENT*/]"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == "hello"); + } + + SECTION("After closing bracket") { + JsonError err = deserializeJson(arr, "[\"hello\"]/*COMMENT*/"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == "hello"); + } + + SECTION("Before comma") { + JsonError err = deserializeJson(arr, "[\"hello\"/*COMMENT*/,\"world\"]"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == "hello"); + REQUIRE(arr[1] == "world"); + } + + SECTION("After comma") { + JsonError err = deserializeJson(arr, "[\"hello\",/*COMMENT*/ \"world\"]"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == "hello"); + REQUIRE(arr[1] == "world"); + } + + SECTION("/*/") { + JsonError err = deserializeJson(arr, "[/*/\n]"); + REQUIRE(err != JsonError::Ok); + } + + SECTION("Unfinished comment") { + JsonError err = deserializeJson(arr, "[/*COMMENT]"); + REQUIRE(err != JsonError::Ok); + } + + SECTION("Final slash missing") { + JsonError err = deserializeJson(arr, "[/*COMMENT*]"); + REQUIRE(err != JsonError::Ok); + } } - SECTION("OneInteger") { - bool success = deserializeJson(arr, "[42]"); + SECTION("Line comments") { + SECTION("Before opening bracket") { + JsonError err = deserializeJson(arr, "//COMMENT\n\t[\"hello\"]"); - REQUIRE(success == true); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == 42); + REQUIRE(err == JsonError::Ok); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == "hello"); + } + + SECTION("After opening bracket") { + JsonError err = deserializeJson(arr, "[//COMMENT\n\"hello\"]"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == "hello"); + } + + SECTION("Before closing bracket") { + JsonError err = deserializeJson(arr, "[\"hello\"//COMMENT\r\n]"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == "hello"); + } + + SECTION("After closing bracket") { + JsonError err = deserializeJson(arr, "[\"hello\"]//COMMENT\n"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == "hello"); + } + + SECTION("Before comma") { + JsonError err = deserializeJson(arr, "[\"hello\"//COMMENT\n,\"world\"]"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == "hello"); + REQUIRE(arr[1] == "world"); + } + + SECTION("After comma") { + JsonError err = deserializeJson(arr, "[\"hello\",//COMMENT\n\"world\"]"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == "hello"); + REQUIRE(arr[1] == "world"); + } + + SECTION("Invalid comment") { + JsonError err = deserializeJson(arr, "[/COMMENT\n]"); + REQUIRE(err != JsonError::Ok); + } + + SECTION("End document with comment") { + JsonError err = deserializeJson(arr, "[//COMMENT"); + REQUIRE(err != JsonError::Ok); + } } - SECTION("OneIntegerWithSpacesBefore") { - bool success = deserializeJson(arr, "[ \t\r\n42]"); + SECTION("Misc") { + SECTION("Garbage") { + JsonError err = deserializeJson(arr, "%*$£¤"); - REQUIRE(success == true); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == 42); - } + REQUIRE(err != JsonError::Ok); + } - SECTION("OneIntegerWithSpaceAfter") { - bool success = deserializeJson(arr, "[42 \t\r\n]"); + SECTION("The opening bracket is missing") { + JsonError err = deserializeJson(arr, "]"); - REQUIRE(success == true); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == 42); - } + REQUIRE(err != JsonError::Ok); // TODO + } - SECTION("TwoIntegers") { - bool success = deserializeJson(arr, "[42,84]"); + SECTION("The closing bracket is missing") { + JsonError err = deserializeJson(arr, "["); + REQUIRE(err != JsonError::Ok); // TODO + } - REQUIRE(success == true); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == 42); - REQUIRE(arr[1] == 84); - } + SECTION("Escape sequences") { + JsonError err = + deserializeJson(arr, "[\"1\\\"2\\\\3\\/4\\b5\\f6\\n7\\r8\\t9\"]"); - SECTION("TwoDoubles") { - bool success = deserializeJson(arr, "[4.2,1e2]"); + REQUIRE(err == JsonError::Ok); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == "1\"2\\3/4\b5\f6\n7\r8\t9"); + } - REQUIRE(success == true); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == 4.2); - REQUIRE(arr[1] == 1e2); - } + SECTION("Unterminated escape sequence") { + JsonError err = deserializeJson(arr, "\"\\\0\"", 4); + REQUIRE(err != JsonError::Ok); + } - SECTION("UnsignedLong") { - bool success = deserializeJson(arr, "[4294967295]"); + SECTION("Nested objects") { + char jsonString[] = + " [ { \"a\" : 1 , \"b\" : 2 } , { \"c\" : 3 , \"d\" : 4 } ] "; - REQUIRE(success == true); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == 4294967295UL); - } + JsonError err = deserializeJson(arr, jsonString); - SECTION("TwoBooleans") { - bool success = deserializeJson(arr, "[true,false]"); + JsonObject &object1 = arr[0]; + const JsonObject &object2 = arr[1]; + JsonObject &object3 = arr[2]; - REQUIRE(success == true); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == true); - REQUIRE(arr[1] == false); - } + REQUIRE(err == JsonError::Ok); - SECTION("TwoNulls") { - bool success = deserializeJson(arr, "[null,null]"); + REQUIRE(true == object1.success()); + REQUIRE(true == object2.success()); + REQUIRE(false == object3.success()); - REQUIRE(success == true); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0].as() == 0); - REQUIRE(arr[1].as() == 0); - } + REQUIRE(2 == object1.size()); + REQUIRE(2 == object2.size()); + REQUIRE(0 == object3.size()); - SECTION("TwoStringsDoubleQuotes") { - bool success = deserializeJson(arr, "[ \"hello\" , \"world\" ]"); - - REQUIRE(success == true); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == "hello"); - REQUIRE(arr[1] == "world"); - } - - SECTION("TwoStringsSingleQuotes") { - bool success = deserializeJson(arr, "[ 'hello' , 'world' ]"); - - REQUIRE(success == true); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == "hello"); - REQUIRE(arr[1] == "world"); - } - - SECTION("TwoStringsNoQuotes") { - bool success = deserializeJson(arr, "[ hello , world ]"); - - REQUIRE(success == true); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == "hello"); - REQUIRE(arr[1] == "world"); - } - - SECTION("EmptyStringsDoubleQuotes") { - bool success = deserializeJson(arr, "[\"\",\"\"]"); - - REQUIRE(success == true); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == ""); - REQUIRE(arr[1] == ""); - } - - SECTION("EmptyStringSingleQuotes") { - bool success = deserializeJson(arr, "[\'\',\'\']"); - - REQUIRE(success == true); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == ""); - REQUIRE(arr[1] == ""); - } - - SECTION("EmptyStringNoQuotes") { - bool success = deserializeJson(arr, "[,]"); - - REQUIRE(success == true); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == ""); - REQUIRE(arr[1] == ""); - } - - SECTION("ClosingDoubleQuoteMissing") { - bool success = deserializeJson(arr, "[\"]"); - - REQUIRE_FALSE(success == true); - } - - SECTION("ClosingSignleQuoteMissing") { - bool success = deserializeJson(arr, "[\']"); - - REQUIRE_FALSE(success == true); - } - - SECTION("StringWithEscapedChars") { - bool success = - deserializeJson(arr, "[\"1\\\"2\\\\3\\/4\\b5\\f6\\n7\\r8\\t9\"]"); - - REQUIRE(success == true); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == "1\"2\\3/4\b5\f6\n7\r8\t9"); - } - - SECTION("StringWithUnterminatedEscapeSequence") { - bool success = deserializeJson(arr, "\"\\\0\"", 4); - REQUIRE_FALSE(success == true); - } - - SECTION("CCommentBeforeOpeningBracket") { - bool success = deserializeJson(arr, "/*COMMENT*/ [\"hello\"]"); - - REQUIRE(success == true); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == "hello"); - } - - SECTION("CCommentAfterOpeningBracket") { - bool success = deserializeJson(arr, "[/*COMMENT*/ \"hello\"]"); - - REQUIRE(success == true); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == "hello"); - } - - SECTION("CCommentBeforeClosingBracket") { - bool success = deserializeJson(arr, "[\"hello\"/*COMMENT*/]"); - - REQUIRE(success == true); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == "hello"); - } - - SECTION("CCommentAfterClosingBracket") { - bool success = deserializeJson(arr, "[\"hello\"]/*COMMENT*/"); - - REQUIRE(success == true); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == "hello"); - } - - SECTION("CCommentBeforeComma") { - bool success = deserializeJson(arr, "[\"hello\"/*COMMENT*/,\"world\"]"); - - REQUIRE(success == true); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == "hello"); - REQUIRE(arr[1] == "world"); - } - - SECTION("CCommentAfterComma") { - bool success = deserializeJson(arr, "[\"hello\",/*COMMENT*/ \"world\"]"); - - REQUIRE(success == true); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == "hello"); - REQUIRE(arr[1] == "world"); - } - - SECTION("CppCommentBeforeOpeningBracket") { - bool success = deserializeJson(arr, "//COMMENT\n\t[\"hello\"]"); - - REQUIRE(success == true); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == "hello"); - } - - SECTION("CppCommentAfterOpeningBracket") { - bool success = deserializeJson(arr, "[//COMMENT\n\"hello\"]"); - - REQUIRE(success == true); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == "hello"); - } - - SECTION("CppCommentBeforeClosingBracket") { - bool success = deserializeJson(arr, "[\"hello\"//COMMENT\r\n]"); - - REQUIRE(success == true); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == "hello"); - } - - SECTION("CppCommentAfterClosingBracket") { - bool success = deserializeJson(arr, "[\"hello\"]//COMMENT\n"); - - REQUIRE(success == true); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == "hello"); - } - - SECTION("CppCommentBeforeComma") { - bool success = deserializeJson(arr, "[\"hello\"//COMMENT\n,\"world\"]"); - - REQUIRE(success == true); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == "hello"); - REQUIRE(arr[1] == "world"); - } - - SECTION("CppCommentAfterComma") { - bool success = deserializeJson(arr, "[\"hello\",//COMMENT\n\"world\"]"); - - REQUIRE(success == true); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == "hello"); - REQUIRE(arr[1] == "world"); - } - - SECTION("InvalidCppComment") { - bool success = deserializeJson(arr, "[/COMMENT\n]"); - REQUIRE_FALSE(success == true); - } - - SECTION("InvalidComment") { - bool success = deserializeJson(arr, "[/*/\n]"); - REQUIRE_FALSE(success == true); - } - - SECTION("UnfinishedCComment") { - bool success = deserializeJson(arr, "[/*COMMENT]"); - REQUIRE_FALSE(success == true); - } - - SECTION("EndsInCppComment") { - bool success = deserializeJson(arr, "[//COMMENT"); - REQUIRE_FALSE(success == true); - } - - SECTION("AfterClosingStar") { - bool success = deserializeJson(arr, "[/*COMMENT*"); - REQUIRE_FALSE(success == true); - } - - SECTION("DeeplyNested") { - bool success = deserializeJson( - arr, "[[[[[[[[[[[[[[[[[[[\"Not too deep\"]]]]]]]]]]]]]]]]]]]"); - REQUIRE(success == true); - } - - SECTION("ObjectNestedInArray") { - char jsonString[] = - " [ { \"a\" : 1 , \"b\" : 2 } , { \"c\" : 3 , \"d\" : 4 } ] "; - - bool success = deserializeJson(arr, jsonString); - - JsonObject &object1 = arr[0]; - const JsonObject &object2 = arr[1]; - JsonObject &object3 = arr[2]; - - REQUIRE(true == success); - - REQUIRE(true == object1.success()); - REQUIRE(true == object2.success()); - REQUIRE(false == object3.success()); - - REQUIRE(2 == object1.size()); - REQUIRE(2 == object2.size()); - REQUIRE(0 == object3.size()); - - REQUIRE(1 == object1["a"].as()); - REQUIRE(2 == object1["b"].as()); - REQUIRE(3 == object2["c"].as()); - REQUIRE(4 == object2["d"].as()); - REQUIRE(0 == object3["e"].as()); + REQUIRE(1 == object1["a"].as()); + REQUIRE(2 == object1["b"].as()); + REQUIRE(3 == object2["c"].as()); + REQUIRE(4 == object2["d"].as()); + REQUIRE(0 == object3["e"].as()); + } } } diff --git a/test/JsonParser/JsonError.cpp b/test/JsonParser/JsonError.cpp new file mode 100644 index 00000000..21714ba0 --- /dev/null +++ b/test/JsonParser/JsonError.cpp @@ -0,0 +1,44 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +void testStringification(JsonError error, std::string expected) { + REQUIRE(error.c_str() == expected); +} + +void testBoolification(JsonError error, bool expected) { + CHECK(error == expected); +} + +#define TEST_STRINGIFICATION(symbol) \ + testStringification(JsonError::symbol, #symbol) + +#define TEST_BOOLIFICATION(symbol, expected) \ + testBoolification(JsonError::symbol, expected) + +TEST_CASE("JsonError") { + SECTION("c_str()") { + TEST_STRINGIFICATION(Ok); + TEST_STRINGIFICATION(OpeningBraceExpected); + TEST_STRINGIFICATION(ClosingBraceExpected); + TEST_STRINGIFICATION(OpeningBracketExpected); + TEST_STRINGIFICATION(ClosingBracketExpected); + TEST_STRINGIFICATION(ColonExpected); + TEST_STRINGIFICATION(TooDeep); + TEST_STRINGIFICATION(NoMemory); + } + + SECTION("as boolean") { + TEST_BOOLIFICATION(Ok, false); + TEST_BOOLIFICATION(OpeningBraceExpected, true); + TEST_BOOLIFICATION(ClosingBraceExpected, true); + TEST_BOOLIFICATION(OpeningBracketExpected, true); + TEST_BOOLIFICATION(ClosingBracketExpected, true); + TEST_BOOLIFICATION(ColonExpected, true); + TEST_BOOLIFICATION(TooDeep, true); + TEST_BOOLIFICATION(NoMemory, true); + } +} diff --git a/test/JsonParser/JsonObject.cpp b/test/JsonParser/JsonObject.cpp index 41bc3e5f..87200bf7 100644 --- a/test/JsonParser/JsonObject.cpp +++ b/test/JsonParser/JsonObject.cpp @@ -9,36 +9,36 @@ TEST_CASE("deserializeJson(JsonObject&)") { DynamicJsonObject obj; SECTION("An empty object") { - bool success = deserializeJson(obj, "{}"); - REQUIRE(success == true); + JsonError err = deserializeJson(obj, "{}"); + REQUIRE(err == JsonError::Ok); REQUIRE(obj.size() == 0); } SECTION("Quotes") { SECTION("Double quotes") { - bool success = deserializeJson(obj, "{\"key\":\"value\"}"); - REQUIRE(success == true); + JsonError err = deserializeJson(obj, "{\"key\":\"value\"}"); + REQUIRE(err == JsonError::Ok); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("Single quotes") { - bool success = deserializeJson(obj, "{'key':'value'}"); - REQUIRE(success == true); + JsonError err = deserializeJson(obj, "{'key':'value'}"); + REQUIRE(err == JsonError::Ok); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("No quotes") { - bool success = deserializeJson(obj, "{key:value}"); - REQUIRE(success == true); + JsonError err = deserializeJson(obj, "{key:value}"); + REQUIRE(err == JsonError::Ok); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("No quotes, allow underscore in key") { - bool success = deserializeJson(obj, "{_k_e_y_:42}"); - REQUIRE(success == true); + JsonError err = deserializeJson(obj, "{_k_e_y_:42}"); + REQUIRE(err == JsonError::Ok); REQUIRE(obj.size() == 1); REQUIRE(obj["_k_e_y_"] == 42); } @@ -46,46 +46,46 @@ TEST_CASE("deserializeJson(JsonObject&)") { SECTION("Spaces") { SECTION("Before the key") { - bool success = deserializeJson(obj, "{ \"key\":\"value\"}"); - REQUIRE(success == true); + JsonError err = deserializeJson(obj, "{ \"key\":\"value\"}"); + REQUIRE(err == JsonError::Ok); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("After the key") { - bool success = deserializeJson(obj, "{\"key\" :\"value\"}"); - REQUIRE(success == true); + JsonError err = deserializeJson(obj, "{\"key\" :\"value\"}"); + REQUIRE(err == JsonError::Ok); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("Before the value") { - bool success = deserializeJson(obj, "{\"key\": \"value\"}"); - REQUIRE(success == true); + JsonError err = deserializeJson(obj, "{\"key\": \"value\"}"); + REQUIRE(err == JsonError::Ok); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("After the value") { - bool success = deserializeJson(obj, "{\"key\":\"value\" }"); - REQUIRE(success == true); + JsonError err = deserializeJson(obj, "{\"key\":\"value\" }"); + REQUIRE(err == JsonError::Ok); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("Before the colon") { - bool success = + JsonError err = deserializeJson(obj, "{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); REQUIRE(obj.size() == 2); REQUIRE(obj["key1"] == "value1"); REQUIRE(obj["key2"] == "value2"); } SECTION("After the colon") { - bool success = + JsonError err = deserializeJson(obj, "{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); REQUIRE(obj.size() == 2); REQUIRE(obj["key1"] == "value1"); REQUIRE(obj["key2"] == "value2"); @@ -94,41 +94,41 @@ TEST_CASE("deserializeJson(JsonObject&)") { SECTION("Values types") { SECTION("String") { - bool success = + JsonError err = deserializeJson(obj, "{\"key1\":\"value1\",\"key2\":\"value2\"}"); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); REQUIRE(obj.size() == 2); REQUIRE(obj["key1"] == "value1"); REQUIRE(obj["key2"] == "value2"); } SECTION("Integer") { - bool success = deserializeJson(obj, "{\"key1\":42,\"key2\":-42}"); - REQUIRE(success == true); + JsonError err = deserializeJson(obj, "{\"key1\":42,\"key2\":-42}"); + REQUIRE(err == JsonError::Ok); REQUIRE(obj.size() == 2); REQUIRE(obj["key1"] == 42); REQUIRE(obj["key2"] == -42); } SECTION("Double") { - bool success = deserializeJson(obj, "{\"key1\":12.345,\"key2\":-7E89}"); - REQUIRE(success == true); + JsonError err = deserializeJson(obj, "{\"key1\":12.345,\"key2\":-7E89}"); + REQUIRE(err == JsonError::Ok); REQUIRE(obj.size() == 2); REQUIRE(obj["key1"] == 12.345); REQUIRE(obj["key2"] == -7E89); } SECTION("Booleans") { - bool success = deserializeJson(obj, "{\"key1\":true,\"key2\":false}"); - REQUIRE(success == true); + JsonError err = deserializeJson(obj, "{\"key1\":true,\"key2\":false}"); + REQUIRE(err == JsonError::Ok); REQUIRE(obj.size() == 2); REQUIRE(obj["key1"] == true); REQUIRE(obj["key2"] == false); } SECTION("Null") { - bool success = deserializeJson(obj, "{\"key1\":null,\"key2\":null}"); - REQUIRE(success == true); + JsonError err = deserializeJson(obj, "{\"key1\":null,\"key2\":null}"); + REQUIRE(err == JsonError::Ok); REQUIRE(obj.size() == 2); REQUIRE(obj["key1"].as() == 0); REQUIRE(obj["key2"].as() == 0); @@ -137,13 +137,13 @@ TEST_CASE("deserializeJson(JsonObject&)") { SECTION("Array") { char jsonString[] = " { \"ab\" : [ 1 , 2 ] , \"cd\" : [ 3 , 4 ] } "; - bool success = deserializeJson(obj, jsonString); + JsonError err = deserializeJson(obj, jsonString); JsonArray &array1 = obj["ab"]; const JsonArray &array2 = obj["cd"]; JsonArray &array3 = obj["ef"]; - REQUIRE(true == success); + REQUIRE(err == JsonError::Ok); REQUIRE(true == array1.success()); REQUIRE(true == array2.success()); @@ -165,33 +165,33 @@ TEST_CASE("deserializeJson(JsonObject&)") { SECTION("Misc") { SECTION("The opening brace is missing") { - bool success = deserializeJson(obj, "}"); - REQUIRE(success == false); + JsonError err = deserializeJson(obj, "}"); + REQUIRE(err == JsonError::OpeningBraceExpected); } SECTION("The closing brace is missing") { - bool success = deserializeJson(obj, "{"); - REQUIRE(success == false); + JsonError err = deserializeJson(obj, "{\"hello\":\"world\""); + REQUIRE(err == JsonError::ClosingBraceExpected); } SECTION("A quoted key without value") { - bool success = deserializeJson(obj, "{\"key\"}"); - REQUIRE(success == false); + JsonError err = deserializeJson(obj, "{\"key\"}"); + REQUIRE(err == JsonError::ColonExpected); } SECTION("A non-quoted key without value") { - bool success = deserializeJson(obj, "{key}"); - REQUIRE(success == false); + JsonError err = deserializeJson(obj, "{key}"); + REQUIRE(err == JsonError::ColonExpected); } SECTION("A dangling comma") { - bool success = deserializeJson(obj, "{\"key1\":\"value1\",}"); - REQUIRE(success == false); + JsonError err = deserializeJson(obj, "{\"key1\":\"value1\",}"); + REQUIRE(err == JsonError::ColonExpected); } SECTION("null as a key") { - bool success = deserializeJson(obj, "null:\"value\"}"); - REQUIRE(success == false); + JsonError err = deserializeJson(obj, "{null:\"value\"}"); + REQUIRE(err == JsonError::Ok); } } } diff --git a/test/JsonParser/JsonVariant.cpp b/test/JsonParser/JsonVariant.cpp index 9141c2d4..f1b5c38a 100644 --- a/test/JsonParser/JsonVariant.cpp +++ b/test/JsonParser/JsonVariant.cpp @@ -11,79 +11,79 @@ TEST_CASE("deserializeJson(JsonVariant&)") { DynamicJsonVariant variant; SECTION("EmptyObject") { - bool success = deserializeJson(variant, "{}"); + JsonError err = deserializeJson(variant, "{}"); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); REQUIRE(variant.is()); } SECTION("EmptyArray") { - bool success = deserializeJson(variant, "[]"); + JsonError err = deserializeJson(variant, "[]"); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); REQUIRE(variant.is()); } SECTION("Integer") { - bool success = deserializeJson(variant, "-42"); + JsonError err = deserializeJson(variant, "-42"); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); REQUIRE(variant.is()); REQUIRE_FALSE(variant.is()); REQUIRE(variant == -42); } SECTION("Double") { - bool success = deserializeJson(variant, "-1.23e+4"); + JsonError err = deserializeJson(variant, "-1.23e+4"); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); REQUIRE_FALSE(variant.is()); REQUIRE(variant.is()); REQUIRE(variant.as() == Approx(-1.23e+4)); } SECTION("Double quoted string") { - bool success = deserializeJson(variant, "\"hello world\""); + JsonError err = deserializeJson(variant, "\"hello world\""); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); REQUIRE(variant.is()); REQUIRE_THAT(variant.as(), Equals("hello world")); } SECTION("Single quoted string") { - bool success = deserializeJson(variant, "\'hello world\'"); + JsonError err = deserializeJson(variant, "\'hello world\'"); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); REQUIRE(variant.is()); REQUIRE_THAT(variant.as(), Equals("hello world")); } SECTION("True") { - bool success = deserializeJson(variant, "true"); + JsonError err = deserializeJson(variant, "true"); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); REQUIRE(variant.is()); REQUIRE(variant == true); } SECTION("False") { - bool success = deserializeJson(variant, "false"); + JsonError err = deserializeJson(variant, "false"); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); REQUIRE(variant.is()); REQUIRE(variant == false); } SECTION("OpenBrace") { - bool success = deserializeJson(variant, "{"); + JsonError err = deserializeJson(variant, "{"); - REQUIRE(success == false); + REQUIRE(err != JsonError::Ok); } SECTION("Incomplete string") { - bool success = deserializeJson(variant, "\"hello"); + JsonError err = deserializeJson(variant, "\"hello"); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); REQUIRE(variant.is()); REQUIRE_THAT(variant.as(), Equals("hello")); } diff --git a/test/JsonParser/StaticJsonArray.cpp b/test/JsonParser/StaticJsonArray.cpp index 0775fc02..6cc5208d 100644 --- a/test/JsonParser/StaticJsonArray.cpp +++ b/test/JsonParser/StaticJsonArray.cpp @@ -10,61 +10,61 @@ TEST_CASE("deserializeJson(StaticJsonArray&)") { StaticJsonArray arr; char input[] = "[]"; - bool success = deserializeJson(arr, input); + JsonError err = deserializeJson(arr, input); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); } SECTION("TooSmallBufferForArrayWithOneValue") { StaticJsonArray arr; char input[] = "[1]"; - bool success = deserializeJson(arr, input); + JsonError err = deserializeJson(arr, input); - REQUIRE(success == false); + REQUIRE(err != JsonError::Ok); } SECTION("BufferOfTheRightSizeForArrayWithOneValue") { StaticJsonArray arr; char input[] = "[1]"; - bool success = deserializeJson(arr, input); + JsonError err = deserializeJson(arr, input); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); } SECTION("TooSmallBufferForArrayWithNestedObject") { StaticJsonArray arr; char input[] = "[{}]"; - bool success = deserializeJson(arr, input); + JsonError err = deserializeJson(arr, input); - REQUIRE(success == false); + REQUIRE(err != JsonError::Ok); } SECTION("BufferOfTheRightSizeForArrayWithNestedObject") { StaticJsonArray arr; char input[] = "[{}]"; - bool success = deserializeJson(arr, input); + JsonError err = deserializeJson(arr, input); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); } SECTION("CharPtrNull") { StaticJsonArray<100> arr; - bool success = deserializeJson(arr, static_cast(0)); + JsonError err = deserializeJson(arr, static_cast(0)); - REQUIRE(success == false); + REQUIRE(err != JsonError::Ok); } SECTION("ConstCharPtrNull") { StaticJsonArray<100> arr; - bool success = deserializeJson(arr, static_cast(0)); + JsonError err = deserializeJson(arr, static_cast(0)); - REQUIRE(success == false); + REQUIRE(err != JsonError::Ok); } SECTION("CopyStringNotSpaces") { diff --git a/test/JsonParser/StaticJsonObject.cpp b/test/JsonParser/StaticJsonObject.cpp index a738e49e..ffed607f 100644 --- a/test/JsonParser/StaticJsonObject.cpp +++ b/test/JsonParser/StaticJsonObject.cpp @@ -10,60 +10,60 @@ TEST_CASE("deserializeJson(StaticJsonObject&)") { StaticJsonObject obj; char input[] = "{}"; - bool success = deserializeJson(obj, input); + JsonError err = deserializeJson(obj, input); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); } SECTION("TooSmallBufferForObjectWithOneValue") { StaticJsonObject obj; char input[] = "{\"a\":1}"; - bool success = deserializeJson(obj, input); + JsonError err = deserializeJson(obj, input); - REQUIRE(success == false); + REQUIRE(err != JsonError::Ok); } SECTION("BufferOfTheRightSizeForObjectWithOneValue") { StaticJsonObject obj; char input[] = "{\"a\":1}"; - bool success = deserializeJson(obj, input); + JsonError err = deserializeJson(obj, input); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); } SECTION("TooSmallBufferForObjectWithNestedObject") { StaticJsonObject obj; char input[] = "{\"a\":[]}"; - bool success = deserializeJson(obj, input); + JsonError err = deserializeJson(obj, input); - REQUIRE(success == false); + REQUIRE(err != JsonError::Ok); } SECTION("BufferOfTheRightSizeForObjectWithNestedObject") { StaticJsonObject obj; char input[] = "{\"a\":[]}"; - bool success = deserializeJson(obj, input); + JsonError err = deserializeJson(obj, input); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); } SECTION("CharPtrNull") { StaticJsonObject<100> obj; - bool success = deserializeJson(obj, static_cast(0)); + JsonError err = deserializeJson(obj, static_cast(0)); - REQUIRE(success == false); + REQUIRE(err != JsonError::Ok); } SECTION("ConstCharPtrNull") { StaticJsonObject<100> obj; - bool success = deserializeJson(obj, static_cast(0)); + JsonError err = deserializeJson(obj, static_cast(0)); - REQUIRE(success == false); + REQUIRE(err != JsonError::Ok); } } diff --git a/test/JsonParser/nestingLimit.cpp b/test/JsonParser/nestingLimit.cpp index 290dae67..710a9fb5 100644 --- a/test/JsonParser/nestingLimit.cpp +++ b/test/JsonParser/nestingLimit.cpp @@ -5,44 +5,45 @@ #include #include -bool tryParseArray(const char *json, uint8_t nestingLimit) { +JsonError tryParseArray(const char *json, uint8_t nestingLimit) { DynamicJsonArray array; return deserializeJson(array, json, nestingLimit); } -bool tryParseObject(const char *json, uint8_t nestingLimit) { +JsonError tryParseObject(const char *json, uint8_t nestingLimit) { DynamicJsonObject obj; return deserializeJson(obj, json, nestingLimit); } TEST_CASE("JsonParser nestingLimit") { SECTION("ParseArrayWithNestingLimit0") { - REQUIRE(true == tryParseArray("[]", 0)); - REQUIRE(false == tryParseArray("[[]]", 0)); + REQUIRE(tryParseArray("[]", 0) == JsonError::Ok); + REQUIRE(tryParseArray("[[]]", 0) == JsonError::TooDeep); } SECTION("ParseArrayWithNestingLimit1") { - REQUIRE(true == tryParseArray("[[]]", 1)); - REQUIRE(false == tryParseArray("[[[]]]", 1)); + REQUIRE(tryParseArray("[[]]", 1) == JsonError::Ok); + REQUIRE(tryParseArray("[[[]]]", 1) == JsonError::TooDeep); } SECTION("ParseArrayWithNestingLimit2") { - REQUIRE(true == tryParseArray("[[[]]]", 2)); - REQUIRE(false == tryParseArray("[[[[]]]]", 2)); + REQUIRE(tryParseArray("[[[]]]", 2) == JsonError::Ok); + REQUIRE(tryParseArray("[[[[]]]]", 2) == JsonError::TooDeep); } SECTION("ParseObjectWithNestingLimit0") { - REQUIRE(true == tryParseObject("{}", 0)); - REQUIRE(false == tryParseObject("{\"key\":{}}", 0)); + REQUIRE(tryParseObject("{}", 0) == JsonError::Ok); + REQUIRE(tryParseObject("{\"key\":{}}", 0) == JsonError::TooDeep); } SECTION("ParseObjectWithNestingLimit1") { - REQUIRE(true == tryParseObject("{\"key\":{}}", 1)); - REQUIRE(false == tryParseObject("{\"key\":{\"key\":{}}}", 1)); + REQUIRE(tryParseObject("{\"key\":{}}", 1) == JsonError::Ok); + REQUIRE(tryParseObject("{\"key\":{\"key\":{}}}", 1) == JsonError::TooDeep); } SECTION("ParseObjectWithNestingLimit2") { - REQUIRE(true == tryParseObject("{\"key\":{\"key\":{}}}", 2)); - REQUIRE(false == tryParseObject("{\"key\":{\"key\":{\"key\":{}}}}", 2)); + REQUIRE(tryParseObject("{\"key\":{\"key\":{}}}", 2) == JsonError::Ok); + REQUIRE(tryParseObject("{\"key\":{\"key\":{\"key\":{}}}}", 2) == + JsonError::TooDeep); } } diff --git a/test/Misc/std_stream.cpp b/test/Misc/std_stream.cpp index 9af55894..b2b171a3 100644 --- a/test/Misc/std_stream.cpp +++ b/test/Misc/std_stream.cpp @@ -56,9 +56,9 @@ TEST_CASE("std::stream") { SECTION("ParseArray") { std::istringstream json(" [ 42 /* comment */ ] "); DynamicJsonArray arr; - bool success = deserializeJson(arr, json); + JsonError err = deserializeJson(arr, json); - REQUIRE(true == success); + REQUIRE(err == JsonError::Ok); REQUIRE(1 == arr.size()); REQUIRE(42 == arr[0]); } @@ -66,9 +66,9 @@ TEST_CASE("std::stream") { SECTION("ParseObject") { std::istringstream json(" { hello : world // comment\n }"); DynamicJsonObject obj; - bool success = deserializeJson(obj, json); + JsonError err = deserializeJson(obj, json); - REQUIRE(true == success); + REQUIRE(err == JsonError::Ok); REQUIRE(1 == obj.size()); REQUIRE(std::string("world") == obj["hello"]); } diff --git a/test/Misc/std_string.cpp b/test/Misc/std_string.cpp index ea11cb35..9e58e0f1 100644 --- a/test/Misc/std_string.cpp +++ b/test/Misc/std_string.cpp @@ -19,10 +19,10 @@ TEST_CASE("std::string") { SECTION("deserializeJson") { std::string json("[\"hello\"]"); - bool success = deserializeJson(array, json); + JsonError err = deserializeJson(array, json); eraseString(json); - REQUIRE(true == success); + REQUIRE(err == JsonError::Ok); REQUIRE(std::string("hello") == array[0]); } @@ -72,10 +72,10 @@ TEST_CASE("std::string") { SECTION("deserializeJson()") { std::string json("{\"hello\":\"world\"}"); - bool success = deserializeJson(object, json); + JsonError err = deserializeJson(object, json); eraseString(json); - REQUIRE(true == success); + REQUIRE(err == JsonError::Ok); REQUIRE(std::string("world") == object["hello"]); } diff --git a/test/Misc/unsigned_char.cpp b/test/Misc/unsigned_char.cpp index 146a936c..23752b9e 100644 --- a/test/Misc/unsigned_char.cpp +++ b/test/Misc/unsigned_char.cpp @@ -14,18 +14,18 @@ TEST_CASE("unsigned char string") { unsigned char json[] = "[42]"; StaticJsonArray arr; - bool success = deserializeJson(arr, json); + JsonError err = deserializeJson(arr, json); - REQUIRE(true == success); + REQUIRE(err == JsonError::Ok); } SECTION("JsonBuffer::parseObject") { unsigned char json[] = "{\"a\":42}"; StaticJsonObject obj; - bool success = deserializeJson(obj, json); + JsonError err = deserializeJson(obj, json); - REQUIRE(true == success); + REQUIRE(err == JsonError::Ok); } SECTION("JsonVariant constructor") { diff --git a/test/Misc/vla.cpp b/test/Misc/vla.cpp index 9c16f510..98a110d3 100644 --- a/test/Misc/vla.cpp +++ b/test/Misc/vla.cpp @@ -23,9 +23,9 @@ TEST_CASE("Variable Length Array") { strcpy(vla, "[42]"); StaticJsonArray arr; - bool success = deserializeJson(arr, vla); + JsonError err = deserializeJson(arr, vla); - REQUIRE(true == success); + REQUIRE(err == JsonError::Ok); } SECTION("ParseObject") {