From 1feb92679da887955e3a6b2994c6c25cdaf6039e Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Tue, 17 Apr 2018 21:27:45 +0200 Subject: [PATCH] Added StaticJsonDocument and DynamicJsonDocument. Removed StaticJsonArray and DynamicJsonArray. Removed StaticJsonObject and DynamicJsonObject. Removed StaticJsonVariant and DynamicJsonVariant. --- CHANGELOG.md | 14 +- README.md | 11 +- examples/JsonConfigFile/JsonConfigFile.ino | 29 ++- .../JsonGeneratorExample.ino | 19 +- examples/JsonHttpClient/JsonHttpClient.ino | 10 +- .../JsonParserExample/JsonParserExample.ino | 22 +- examples/JsonServer/JsonServer.ino | 7 +- examples/JsonUdpBeacon/JsonUdpBeacon.ino | 7 +- examples/MsgPackParser/MsgPackParser.ino | 18 +- examples/ProgmemExample/ProgmemExample.ino | 17 +- examples/StringExample/StringExample.ino | 25 +- fuzzing/fuzzer.cpp | 8 +- keywords.txt | 10 +- src/ArduinoJson.hpp | 12 +- src/ArduinoJson/DynamicJsonArray.hpp | 32 --- src/ArduinoJson/DynamicJsonDocument.hpp | 83 +++++++ src/ArduinoJson/DynamicJsonObject.hpp | 32 --- src/ArduinoJson/DynamicJsonVariant.hpp | 45 ---- .../Json/Deserialization/JsonDeserializer.hpp | 218 ++++++++++++++++++ .../Json/Deserialization/JsonParser.hpp | 95 -------- .../Json/Deserialization/JsonParserImpl.hpp | 166 ------------- .../Json/Serialization/JsonSerializer.hpp | 53 +++-- .../Json/Serialization/JsonSerializerImpl.hpp | 69 ------ src/ArduinoJson/JsonArray.hpp | 5 + src/ArduinoJson/JsonArraySubscript.hpp | 5 + src/ArduinoJson/JsonError.hpp | 28 +-- src/ArduinoJson/JsonObject.hpp | 5 + src/ArduinoJson/JsonObjectSubscript.hpp | 5 + src/ArduinoJson/Memory/DynamicJsonBuffer.hpp | 12 +- src/ArduinoJson/Memory/StaticJsonBuffer.hpp | 2 +- .../MsgPack/MsgPackDeserializer.hpp | 34 --- src/ArduinoJson/MsgPack/MsgPackError.hpp | 11 +- src/ArduinoJson/StaticJsonArray.hpp | 32 --- src/ArduinoJson/StaticJsonDocument.hpp | 80 +++++++ src/ArduinoJson/StaticJsonObject.hpp | 32 --- src/ArduinoJson/StaticJsonVariant.hpp | 43 ---- src/ArduinoJson/TypeTraits/Max.hpp | 2 + src/ArduinoJson/deserializeJson.hpp | 41 ++-- src/ArduinoJson/deserializeMsgPack.hpp | 42 ++-- test/CMakeLists.txt | 2 +- test/DynamicJsonBuffer/alloc.cpp | 3 +- test/DynamicJsonBuffer/no_memory.cpp | 14 +- test/DynamicJsonBuffer/size.cpp | 4 +- test/DynamicJsonBuffer/startString.cpp | 4 +- test/IntegrationTests/CMakeLists.txt | 2 +- test/IntegrationTests/gbathree.cpp | 49 ++-- test/IntegrationTests/round_trip.cpp | 10 +- test/JsonArray/add.cpp | 25 +- test/JsonArray/basics.cpp | 3 +- test/JsonArray/copyFrom.cpp | 12 +- test/JsonArray/copyTo.cpp | 11 +- test/JsonArray/iterator.cpp | 3 +- test/JsonArray/remove.cpp | 3 +- test/JsonArray/set.cpp | 21 +- test/JsonArray/size.cpp | 3 +- test/JsonArray/subscript.cpp | 21 +- test/JsonDeserializer/CMakeLists.txt | 16 ++ .../JsonError.cpp | 18 +- .../deserializeJsonArray.cpp} | 161 +++++++------ .../deserializeJsonArrayStatic.cpp | 105 +++++++++ .../deserializeJsonObject.cpp} | 134 ++++++++--- .../deserializeJsonObjectStatic.cpp} | 40 ++-- .../JsonDeserializer/deserializeJsonValue.cpp | 103 +++++++++ test/JsonDeserializer/nestingLimit.cpp | 32 +++ test/JsonObject/basics.cpp | 9 +- test/JsonObject/containsKey.cpp | 17 +- test/JsonObject/get.cpp | 3 +- test/JsonObject/iterator.cpp | 3 +- test/JsonObject/remove.cpp | 7 +- test/JsonObject/set.cpp | 111 ++++----- test/JsonObject/size.cpp | 17 +- test/JsonObject/subscript.cpp | 140 +++++------ test/JsonParser/CMakeLists.txt | 17 -- test/JsonParser/DynamicJsonVariant.cpp | 98 -------- test/JsonParser/StaticJsonArray.cpp | 90 -------- test/JsonParser/StaticJsonVariant.cpp | 35 --- test/JsonParser/nestingLimit.cpp | 70 ------ test/JsonSerializer/JsonArray.cpp | 3 +- test/JsonSerializer/JsonArrayPretty.cpp | 3 +- test/JsonSerializer/JsonObject.cpp | 18 +- test/JsonSerializer/JsonObjectPretty.cpp | 3 +- test/JsonVariant/as.cpp | 12 +- test/JsonVariant/compare.cpp | 26 ++- test/JsonVariant/copy.cpp | 8 +- test/JsonVariant/is.cpp | 5 +- test/JsonVariant/set_get.cpp | 3 +- test/JsonVariant/subscript.cpp | 20 +- test/JsonVariant/success.cpp | 6 +- test/Misc/std_stream.cpp | 26 ++- test/Misc/std_string.cpp | 149 +++++++----- test/Misc/unsigned_char.cpp | 85 ++++--- test/Misc/vla.cpp | 87 ++++--- test/MsgPack/MsgPackError.cpp | 10 +- test/MsgPack/deserializationErrors.cpp | 2 +- test/MsgPack/deserializeArray.cpp | 28 ++- test/MsgPack/deserializeObject.cpp | 60 ++--- test/MsgPack/deserializeStaticVariant.cpp | 32 +-- test/MsgPack/deserializeVariant.cpp | 149 +----------- test/StaticJsonBuffer/alloc.cpp | 4 +- test/StaticJsonBuffer/size.cpp | 4 +- 100 files changed, 1696 insertions(+), 1844 deletions(-) delete mode 100644 src/ArduinoJson/DynamicJsonArray.hpp create mode 100644 src/ArduinoJson/DynamicJsonDocument.hpp delete mode 100644 src/ArduinoJson/DynamicJsonObject.hpp delete mode 100644 src/ArduinoJson/DynamicJsonVariant.hpp create mode 100644 src/ArduinoJson/Json/Deserialization/JsonDeserializer.hpp delete mode 100644 src/ArduinoJson/Json/Deserialization/JsonParser.hpp delete mode 100644 src/ArduinoJson/Json/Deserialization/JsonParserImpl.hpp delete mode 100644 src/ArduinoJson/Json/Serialization/JsonSerializerImpl.hpp delete mode 100644 src/ArduinoJson/StaticJsonArray.hpp create mode 100644 src/ArduinoJson/StaticJsonDocument.hpp delete mode 100644 src/ArduinoJson/StaticJsonObject.hpp delete mode 100644 src/ArduinoJson/StaticJsonVariant.hpp create mode 100644 test/JsonDeserializer/CMakeLists.txt rename test/{JsonParser => JsonDeserializer}/JsonError.cpp (62%) rename test/{JsonParser/DynamicJsonArray.cpp => JsonDeserializer/deserializeJsonArray.cpp} (56%) create mode 100644 test/JsonDeserializer/deserializeJsonArrayStatic.cpp rename test/{JsonParser/DynamicJsonObject.cpp => JsonDeserializer/deserializeJsonObject.cpp} (52%) rename test/{JsonParser/StaticJsonObject.cpp => JsonDeserializer/deserializeJsonObjectStatic.cpp} (50%) create mode 100644 test/JsonDeserializer/deserializeJsonValue.cpp create mode 100644 test/JsonDeserializer/nestingLimit.cpp delete mode 100644 test/JsonParser/CMakeLists.txt delete mode 100644 test/JsonParser/DynamicJsonVariant.cpp delete mode 100644 test/JsonParser/StaticJsonArray.cpp delete mode 100644 test/JsonParser/StaticJsonVariant.cpp delete mode 100644 test/JsonParser/nestingLimit.cpp diff --git a/CHANGELOG.md b/CHANGELOG.md index e4de8075..e03c7e07 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,9 +6,7 @@ HEAD * Fixed `JsonBuffer::parse()` not respecting nesting limit correctly (issue #693) * Fixed inconsistencies in nesting level counting (PR #695 from Zhenyu Wu) -* Added `DynamicJsonArray` and `StaticJsonArray` -* Added `DynamicJsonObject` and `StaticJsonObject` -* Added `DynamicJsonVariant` and `StaticJsonVariant` +* Added `DynamicJsonDocument` and `StaticJsonDocument` * Added `deserializeJson()` * Added `serializeJson()` and `serializeJsonPretty()` * Added `measureJson()` and `measureJsonPretty()` @@ -37,11 +35,12 @@ HEAD > New code: > > ```c++ -> DynamicJsonObject obj; -> JsonError error = deserializeJson(obj, json); +> DynamicJsonDocument doc; +> JsonError error = deserializeJson(doc, json); > if (error) { > > } +> JsonObject& obj = doc.as(); > ``` > > #### Serialization @@ -58,9 +57,10 @@ HEAD > New code: > > ```c++ -> DynamicJsonObject obj; +> DynamicJsonDocument obj; +> JsonObject& obj = doc.to(); > obj["key"] = "value"; -> serializeJson(obj, Serial); +> serializeJson(doc, Serial); > ``` v5.13.1 diff --git a/README.md b/README.md index 31fc6266..9434e775 100644 --- a/README.md +++ b/README.md @@ -59,9 +59,10 @@ Here is a program that parses a JSON document with ArduinoJson. ```c++ char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}"; -DynamicJsonObject root; -deserializeJson(root, json); +DynamicJsonDocument doc; +deserializeJson(doc, json); +JsonObject& root = doc.as(); const char* sensor = root["sensor"]; long time = root["time"]; double latitude = root["data"][0]; @@ -75,7 +76,9 @@ See the [tutorial on arduinojson.org](https://arduinojson.org/doc/decoding/?utm_ Here is a program that generates a JSON document with ArduinoJson: ```c++ -DynamicJsonObject root; +DynamicJsonDocument doc; + +JsonObject& root = doc.to(); root["sensor"] = "gps"; root["time"] = 1351824120; @@ -83,7 +86,7 @@ JsonArray& data = root.createNestedArray("data"); data.add(48.756080); data.add(2.302038); -serializeJson(root, Serial); +serializeJson(doc, Serial); // This prints: // {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]} ``` diff --git a/examples/JsonConfigFile/JsonConfigFile.ino b/examples/JsonConfigFile/JsonConfigFile.ino index ebf03738..6134f587 100644 --- a/examples/JsonConfigFile/JsonConfigFile.ino +++ b/examples/JsonConfigFile/JsonConfigFile.ino @@ -29,17 +29,19 @@ void loadConfiguration(const char *filename, Config &config) { // Open file for reading File file = SD.open(filename); - // Allocate the memory pool on the stack. - // Don't forget to change the capacity to match your JSON document. + // Allocate the document on the stack. + // Don't forget to change the capacity to match your requirements. // Use arduinojson.org/assistant to compute the capacity. - StaticJsonObject<512> root; - - // Parse the root object - JsonError error = deserializeJson(root, file); + StaticJsonDocument<512> doc; + // Deserialize the JSON document + JsonError error = deserializeJson(doc, file); if (error) Serial.println(F("Failed to read file, using default configuration")); + // Get the root object in the document + JsonObject &root = doc.as(); + // Copy values from the JsonObject to the Config config.port = root["port"] | 2731; strlcpy(config.hostname, // <- destination @@ -62,17 +64,20 @@ void saveConfiguration(const char *filename, const Config &config) { return; } - // Allocate the memory pool on the stack - // Don't forget to change the capacity to match your JSON document. - // Use https://arduinojson.org/assistant/ to compute the capacity. - StaticJsonObject<256> root; + // Allocate the document on the stack. + // Don't forget to change the capacity to match your requirements. + // Use arduinojson.org/assistant to compute the capacity. + StaticJsonDocument<256> doc; - // Set the values + // Make our document contain an object + JsonObject &root = doc.to(); + + // Set the values in the object root["hostname"] = config.hostname; root["port"] = config.port; // Serialize JSON to file - if (serializeJson(root, file) == 0) { + if (serializeJson(doc, file) == 0) { Serial.println(F("Failed to write to file")); } diff --git a/examples/JsonGeneratorExample/JsonGeneratorExample.ino b/examples/JsonGeneratorExample/JsonGeneratorExample.ino index ee22fe71..b74e2c0d 100644 --- a/examples/JsonGeneratorExample/JsonGeneratorExample.ino +++ b/examples/JsonGeneratorExample/JsonGeneratorExample.ino @@ -11,17 +11,20 @@ void setup() { Serial.begin(9600); while (!Serial) continue; - // Root JSON object + // The JSON document // - // Inside the brackets, 200 is the size of the memory pool in bytes. - // Don't forget to change this value to match your JSON document. + // Inside the brackets, 200 is the RAM allocated to this document. + // Don't forget to change this value to match your requirement. // Use arduinojson.org/assistant to compute the capacity. - StaticJsonObject<200> root; + StaticJsonDocument<200> doc; // StaticJsonObject allocates memory on the stack, it can be - // replaced by DynamicJsonObject which allocates in the heap. + // replaced by DynamicJsonDocument which allocates in the heap. // - // DynamicJsonObject root(200); + // DynamicJsonDocument doc(200); + + // Make our document be an object + JsonObject& root = doc.to(); // Add values in the object // @@ -30,10 +33,8 @@ void setup() { root["sensor"] = "gps"; root["time"] = 1351824120; - // Add a nested array. + // Add an array. // - // It's also possible to create the array separately and add it to the - // JsonObject but it's less efficient. JsonArray& data = root.createNestedArray("data"); data.add(48.756080); data.add(2.302038); diff --git a/examples/JsonHttpClient/JsonHttpClient.ino b/examples/JsonHttpClient/JsonHttpClient.ino index aeae598a..41b130ef 100644 --- a/examples/JsonHttpClient/JsonHttpClient.ino +++ b/examples/JsonHttpClient/JsonHttpClient.ino @@ -70,19 +70,21 @@ void setup() { return; } - // Allocate JsonBuffer + // Allocate the JSON document // Use arduinojson.org/assistant to compute the capacity. const size_t capacity = JSON_OBJECT_SIZE(3) + JSON_ARRAY_SIZE(2) + 60; - DynamicJsonObject root(capacity); + DynamicJsonDocument doc(capacity); // Parse JSON object - JsonError error = deserializeJson(root, client); + JsonError error = deserializeJson(doc, client); if (error) { - Serial.println(F("Parsing failed!")); + Serial.print(F("deserializeJson() failed: ")); + Serial.println(error.c_str()); return; } // Extract values + JsonObject& root = doc.as(); Serial.println(F("Response:")); Serial.println(root["sensor"].as()); Serial.println(root["time"].as()); diff --git a/examples/JsonParserExample/JsonParserExample.ino b/examples/JsonParserExample/JsonParserExample.ino index 72bc6e85..d7926cf9 100644 --- a/examples/JsonParserExample/JsonParserExample.ino +++ b/examples/JsonParserExample/JsonParserExample.ino @@ -16,12 +16,12 @@ void setup() { // Inside the brackets, 200 is the size of the memory pool in bytes. // Don't forget to change this value to match your JSON document. // Use arduinojson.org/assistant to compute the capacity. - StaticJsonObject<200> root; + StaticJsonDocument<200> doc; - // StaticJsonObject allocates memory on the stack, it can be + // StaticJsonDocument allocates memory on the stack, it can be // replaced by DynamicJsonObject which allocates in the heap. // - // DynamicJsonObject root(200); + // DynamicJsonObject doc(200); // JSON input string. // @@ -31,23 +31,23 @@ void setup() { char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}"; - // Root of the object tree. - // - // 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. - JsonError error = deserializeJson(root, json); + // Deserialize the JSON document + JsonError error = deserializeJson(doc, json); // Test if parsing succeeds. if (error) { - Serial.println("deserializeJson() failed"); + Serial.print(F("deserializeJson() failed: ")); + Serial.println(error.c_str()); return; } + // Get the root object in the document + JsonObject& root = doc.as(); + // Fetch values. // // Most of the time, you can rely on the implicit casts. - // In other case, you can do root["time"].as(); + // In other case, you can do doc["time"].as(); const char* sensor = root["sensor"]; long time = root["time"]; double latitude = root["data"][0]; diff --git a/examples/JsonServer/JsonServer.ino b/examples/JsonServer/JsonServer.ino index 677d5039..92dcc790 100644 --- a/examples/JsonServer/JsonServer.ino +++ b/examples/JsonServer/JsonServer.ino @@ -51,9 +51,12 @@ void loop() { // Read the request (we ignore the content in this example) while (client.available()) client.read(); - // Allocate the root JsonObject + // Allocate the JSON document // Use arduinojson.org/assistant to compute the capacity. - StaticJsonObject<500> root; + StaticJsonDocument<500> doc; + + // Make our document represent an object + JsonObject& root = doc.to(); // Create the "analog" array JsonArray& analogValues = root.createNestedArray("analog"); diff --git a/examples/JsonUdpBeacon/JsonUdpBeacon.ino b/examples/JsonUdpBeacon/JsonUdpBeacon.ino index 82c8b8ff..1af13d9a 100644 --- a/examples/JsonUdpBeacon/JsonUdpBeacon.ino +++ b/examples/JsonUdpBeacon/JsonUdpBeacon.ino @@ -43,9 +43,12 @@ void setup() { } void loop() { - // Allocate the root JsonObject + // Allocate the JSON document // Use arduinojson.org/assistant to compute the capacity. - StaticJsonObject<500> root; + StaticJsonDocument<500> doc; + + // Make our document represent an object + JsonObject& root = doc.to(); // Create the "analog" array JsonArray& analogValues = root.createNestedArray("analog"); diff --git a/examples/MsgPackParser/MsgPackParser.ino b/examples/MsgPackParser/MsgPackParser.ino index deb2d546..381fffd1 100644 --- a/examples/MsgPackParser/MsgPackParser.ino +++ b/examples/MsgPackParser/MsgPackParser.ino @@ -12,17 +12,17 @@ void setup() { Serial.begin(9600); while (!Serial) continue; - // Root JSON object + // Allocate the JSON document // // Inside the brackets, 200 is the size of the memory pool in bytes. // Don't forget to change this value to match your JSON document. // Use arduinojson.org/assistant to compute the capacity. - StaticJsonObject<200> root; + StaticJsonDocument<200> doc; // StaticJsonObject allocates memory on the stack, it can be // replaced by DynamicJsonObject which allocates in the heap. // - // DynamicJsonObject root(200); + // DynamicJsonObject doc(200); // MessagePack input string. // @@ -40,23 +40,27 @@ void setup() { // "data": [48.75608, 2.302038] // } - // Root of the object tree. + // doc of the object tree. // // 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. - MsgPackError error = deserializeMsgPack(root, input); + MsgPackError error = deserializeMsgPack(doc, input); // Test if parsing succeeds. if (error) { - Serial.println("deserializeMsgPack() failed"); + Serial.print("deserializeMsgPack() failed: "); + Serial.println(error.c_str()); return; } + // Get the root object in the document + JsonObject& root = doc.as(); + // Fetch values. // // Most of the time, you can rely on the implicit casts. - // In other case, you can do root["time"].as(); + // In other case, you can do doc["time"].as(); const char* sensor = root["sensor"]; long time = root["time"]; double latitude = root["data"][0]; diff --git a/examples/ProgmemExample/ProgmemExample.ino b/examples/ProgmemExample/ProgmemExample.ino index 87740bb4..3302fc2d 100644 --- a/examples/ProgmemExample/ProgmemExample.ino +++ b/examples/ProgmemExample/ProgmemExample.ino @@ -14,33 +14,34 @@ void setup() { #ifdef PROGMEM // <- check that Flash strings are supported - DynamicJsonObject root; + DynamicJsonDocument doc; // You can use a Flash String as your JSON input. // WARNING: the content of the Flash String will be duplicated in the // JsonBuffer. - deserializeJson(root, F("{\"sensor\":\"gps\",\"time\":1351824120," - "\"data\":[48.756080,2.302038]}")); + deserializeJson(doc, F("{\"sensor\":\"gps\",\"time\":1351824120," + "\"data\":[48.756080,2.302038]}")); + JsonObject& obj = doc.as(); // You can use a Flash String to get an element of a JsonObject // No duplication is done. - long time = root[F("time")]; + long time = obj[F("time")]; // You can use a Flash String to set an element of a JsonObject // WARNING: the content of the Flash String will be duplicated in the // JsonBuffer. - root[F("time")] = time; + obj[F("time")] = time; // You can set a Flash String to a JsonObject or JsonArray: // WARNING: the content of the Flash String will be duplicated in the // JsonBuffer. - root["sensor"] = F("gps"); + obj["sensor"] = F("gps"); // It works with RawJson too: - root["sensor"] = RawJson(F("\"gps\"")); + obj["sensor"] = RawJson(F("\"gps\"")); // You can compare the content of a JsonVariant to a Flash String - if (root["sensor"] == F("gps")) { + if (obj["sensor"] == F("gps")) { // ... } diff --git a/examples/StringExample/StringExample.ino b/examples/StringExample/StringExample.ino index a497651a..d888e620 100644 --- a/examples/StringExample/StringExample.ino +++ b/examples/StringExample/StringExample.ino @@ -11,50 +11,51 @@ #include void setup() { - DynamicJsonObject root; + DynamicJsonDocument doc; // You can use a String as your JSON input. // WARNING: the content of the String will be duplicated in the JsonBuffer. String input = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}"; - deserializeJson(root, input); + deserializeJson(doc, input); + JsonObject& obj = doc.as(); // You can use a String to get an element of a JsonObject // No duplication is done. - long time = root[String("time")]; + long time = obj[String("time")]; // You can use a String to set an element of a JsonObject // WARNING: the content of the String will be duplicated in the JsonBuffer. - root[String("time")] = time; + obj[String("time")] = time; // You can get a String from a JsonObject or JsonArray: // No duplication is done, at least not in the JsonBuffer. - String sensor = root["sensor"]; + String sensor = obj["sensor"]; // Unfortunately, the following doesn't work (issue #118): - // sensor = root["sensor"]; // <- error "ambiguous overload for 'operator='" + // sensor = obj["sensor"]; // <- error "ambiguous overload for 'operator='" // As a workaround, you need to replace by: - sensor = root["sensor"].as(); + sensor = obj["sensor"].as(); // You can set a String to a JsonObject or JsonArray: // WARNING: the content of the String will be duplicated in the JsonBuffer. - root["sensor"] = sensor; + obj["sensor"] = sensor; // It works with RawJson too: - root["sensor"] = RawJson(sensor); + obj["sensor"] = RawJson(sensor); // You can also concatenate strings // WARNING: the content of the String will be duplicated in the JsonBuffer. - root[String("sen") + "sor"] = String("gp") + "s"; + obj[String("sen") + "sor"] = String("gp") + "s"; // You can compare the content of a JsonObject with a String - if (root["sensor"] == sensor) { + if (obj["sensor"] == sensor) { // ... } // Lastly, you can print the resulting JSON to a String String output; - serializeJson(root, output); + serializeJson(doc, output); } void loop() { diff --git a/fuzzing/fuzzer.cpp b/fuzzing/fuzzer.cpp index 358273c3..0c5a19af 100644 --- a/fuzzing/fuzzer.cpp +++ b/fuzzing/fuzzer.cpp @@ -16,11 +16,11 @@ class memstream : public std::istream { }; extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - DynamicJsonVariant variant; + DynamicJsonDocument doc; memstream json(data, size); - JsonError error = deserializeJson(variant, json); - JsonVariant variant = jsonBuffer.parse(json); - if (!error) { + JsonError error = deserializeJson(doc, json); + if (error == JsonError::Ok) { + JsonVariant variant = doc.as(); variant.as(); // <- serialize to JSON } return 0; diff --git a/keywords.txt b/keywords.txt index ae31a74c..647ae987 100644 --- a/keywords.txt +++ b/keywords.txt @@ -3,9 +3,8 @@ as KEYWORD2 createNestedArray KEYWORD2 createNestedObject KEYWORD2 deserializeJson KEYWORD2 -DynamicJsonArray KEYWORD1 -DynamicJsonObject KEYWORD1 -DynamicJsonVariant KEYWORD1 +deserializeMsgPack KEYWORD2 +DynamicJsonDocument KEYWORD1 get KEYWORD2 JsonArray KEYWORD1 JsonObject KEYWORD1 @@ -13,6 +12,5 @@ JsonVariant KEYWORD1 serializeJson KEYWORD2 serializeJsonPretty KEYWORD2 set KEYWORD2 -StaticJsonArray KEYWORD1 -StaticJsonObject KEYWORD1 -StaticJsonVariant KEYWORD1 +StaticJsonDocument KEYWORD1 +to KEYWORD2 diff --git a/src/ArduinoJson.hpp b/src/ArduinoJson.hpp index 2830ce26..71bc18e1 100644 --- a/src/ArduinoJson.hpp +++ b/src/ArduinoJson.hpp @@ -4,18 +4,14 @@ #pragma once -#include "ArduinoJson/DynamicJsonArray.hpp" -#include "ArduinoJson/DynamicJsonObject.hpp" -#include "ArduinoJson/DynamicJsonVariant.hpp" +#include "ArduinoJson/DynamicJsonDocument.hpp" #include "ArduinoJson/MsgPack/MsgPackDeserializer.hpp" -#include "ArduinoJson/StaticJsonArray.hpp" -#include "ArduinoJson/StaticJsonObject.hpp" -#include "ArduinoJson/StaticJsonVariant.hpp" +#include "ArduinoJson/StaticJsonDocument.hpp" #include "ArduinoJson/deserializeJson.hpp" #include "ArduinoJson/deserializeMsgPack.hpp" -#include "ArduinoJson/Json/Deserialization/JsonParserImpl.hpp" -#include "ArduinoJson/Json/Serialization/JsonSerializerImpl.hpp" +#include "ArduinoJson/Json/Deserialization/JsonDeserializer.hpp" +#include "ArduinoJson/Json/Serialization/JsonSerializer.hpp" #include "ArduinoJson/JsonArrayImpl.hpp" #include "ArduinoJson/JsonObjectImpl.hpp" #include "ArduinoJson/JsonVariantImpl.hpp" diff --git a/src/ArduinoJson/DynamicJsonArray.hpp b/src/ArduinoJson/DynamicJsonArray.hpp deleted file mode 100644 index 6b82c6e2..00000000 --- a/src/ArduinoJson/DynamicJsonArray.hpp +++ /dev/null @@ -1,32 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#pragma once - -#include "JsonArray.hpp" -#include "Memory/DynamicJsonBuffer.hpp" - -namespace ArduinoJson { -class DynamicJsonArray : public JsonArray { - DynamicJsonBuffer _buffer; - - public: - DynamicJsonArray() : JsonArray(&_buffer) {} - DynamicJsonArray(size_t capacity) - : JsonArray(&_buffer), _buffer(capacity - sizeof(JsonArray)) {} - - void clear() { - Internals::List::clear(); - _buffer.clear(); - } - - size_t memoryUsage() const { - return _buffer.size() + sizeof(JsonArray); - } - - DynamicJsonBuffer& buffer() { - return _buffer; - } -}; -} // namespace ArduinoJson diff --git a/src/ArduinoJson/DynamicJsonDocument.hpp b/src/ArduinoJson/DynamicJsonDocument.hpp new file mode 100644 index 00000000..9cbda37f --- /dev/null +++ b/src/ArduinoJson/DynamicJsonDocument.hpp @@ -0,0 +1,83 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +#include "JsonArray.hpp" +#include "JsonObject.hpp" +#include "JsonVariant.hpp" +#include "Memory/DynamicJsonBuffer.hpp" + +namespace ArduinoJson { + +class DynamicJsonDocument { + Internals::DynamicJsonBuffer _buffer; + JsonVariant _root; + + public: + DynamicJsonDocument() {} + DynamicJsonDocument(size_t capacity) : _buffer(capacity) {} + + template + bool is() const { + return _root.is(); + } + + template + typename Internals::JsonVariantAs::type as() const { + return _root.as(); + } + + // JsonObject& to() + template + typename Internals::EnableIf::value, + JsonObject&>::type + to() { + clear(); + JsonObject* object = new (&_buffer) JsonObject(&_buffer); + if (!object) return JsonObject::invalid(); + _root = object; + return *object; + } + + // JsonArray& to() + template + typename Internals::EnableIf::value, + JsonArray&>::type + to() { + clear(); + JsonArray* array = new (&_buffer) JsonArray(&_buffer); + if (!array) return JsonArray::invalid(); + _root = array; + return *array; + } + + // JsonVariant& to() + template + typename Internals::EnableIf::value, + T&>::type + to() { + clear(); + return _root; + } + + Internals::DynamicJsonBuffer& buffer() { + return _buffer; + } + + void clear() { + _buffer.clear(); + _root = JsonVariant(); + } + + size_t memoryUsage() const { + return _buffer.size(); + } + + template + void visit(Visitor visitor) const { + return _root.visit(visitor); + } +}; +} // namespace ArduinoJson diff --git a/src/ArduinoJson/DynamicJsonObject.hpp b/src/ArduinoJson/DynamicJsonObject.hpp deleted file mode 100644 index c442377c..00000000 --- a/src/ArduinoJson/DynamicJsonObject.hpp +++ /dev/null @@ -1,32 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#pragma once - -#include "JsonObject.hpp" -#include "Memory/DynamicJsonBuffer.hpp" - -namespace ArduinoJson { -class DynamicJsonObject : public JsonObject { - DynamicJsonBuffer _buffer; - - public: - DynamicJsonObject() : JsonObject(&_buffer) {} - DynamicJsonObject(size_t capacity) - : JsonObject(&_buffer), _buffer(capacity - sizeof(JsonObject)) {} - - DynamicJsonBuffer& buffer() { - return _buffer; - } - - void clear() { - Internals::List::clear(); - _buffer.clear(); - } - - size_t memoryUsage() const { - return _buffer.size() + sizeof(JsonObject); - } -}; -} // namespace ArduinoJson diff --git a/src/ArduinoJson/DynamicJsonVariant.hpp b/src/ArduinoJson/DynamicJsonVariant.hpp deleted file mode 100644 index 3f67ec42..00000000 --- a/src/ArduinoJson/DynamicJsonVariant.hpp +++ /dev/null @@ -1,45 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#pragma once - -#include "JsonVariant.hpp" -#include "Memory/DynamicJsonBuffer.hpp" - -namespace ArduinoJson { - -class DynamicJsonVariant : public JsonVariant { - DynamicJsonBuffer _buffer; - - public: - DynamicJsonVariant() : JsonVariant() {} - DynamicJsonVariant(size_t capacity) : JsonVariant(), _buffer(capacity) {} - - template - DynamicJsonVariant& operator=(const T& value) { - _buffer.clear(); - JsonVariant::operator=(value); - return *this; - } - - template - DynamicJsonVariant& operator=(const T* value) { - _buffer.clear(); - JsonVariant::operator=(value); - return *this; - } - - DynamicJsonBuffer& buffer() { - return _buffer; - } - - void clear() { - _buffer.clear(); - } - - size_t memoryUsage() const { - return _buffer.size(); - } -}; -} // namespace ArduinoJson diff --git a/src/ArduinoJson/Json/Deserialization/JsonDeserializer.hpp b/src/ArduinoJson/Json/Deserialization/JsonDeserializer.hpp new file mode 100644 index 00000000..c8db8ffd --- /dev/null +++ b/src/ArduinoJson/Json/Deserialization/JsonDeserializer.hpp @@ -0,0 +1,218 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +#include "../../JsonError.hpp" +#include "../../JsonVariant.hpp" +#include "../../Memory/JsonBuffer.hpp" +#include "../../Strings/StringWriter.hpp" +#include "../../TypeTraits/IsConst.hpp" +#include "../Encoding.hpp" +#include "./Comments.hpp" + +namespace ArduinoJson { +namespace Internals { + +template +class JsonDeserializer { + public: + JsonDeserializer(JsonBuffer *buffer, TReader reader, TWriter writer, + uint8_t nestingLimit) + : _buffer(buffer), + _reader(reader), + _writer(writer), + _nestingLimit(nestingLimit) {} + JsonError parse(JsonVariant &variant) { + skipSpacesAndComments(_reader); + + switch (_reader.current()) { + case '[': + return parseArray(variant); + + case '{': + return parseObject(variant); + + default: + return parseValue(variant); + } + } + + private: + JsonDeserializer &operator=(const JsonDeserializer &); // non-copiable + + static bool eat(TReader &reader, char charToSkip) { + skipSpacesAndComments(reader); + if (reader.current() != charToSkip) return false; + reader.move(); + return true; + } + + FORCE_INLINE bool eat(char charToSkip) { + return eat(_reader, charToSkip); + } + + JsonError parseArray(JsonVariant &variant) { + if (_nestingLimit == 0) return JsonError::TooDeep; + + JsonArray *array = new (_buffer) JsonArray(_buffer); + if (!array) return JsonError::NoMemory; + variant = array; + + // Check opening braket + if (!eat('[')) return JsonError::InvalidInput; + if (eat(']')) return JsonError::Ok; + + // Read each value + for (;;) { + // 1 - Parse value + JsonVariant value; + _nestingLimit--; + JsonError error = parse(value); + _nestingLimit++; + if (error != JsonError::Ok) return error; + if (!array->add(value)) return JsonError::NoMemory; + + // 2 - More values? + if (eat(']')) return JsonError::Ok; + if (!eat(',')) return JsonError::InvalidInput; + } + } + + JsonError parseObject(JsonVariant &variant) { + if (_nestingLimit == 0) return JsonError::TooDeep; + + JsonObject *object = new (_buffer) JsonObject(_buffer); + if (!object) return JsonError::NoMemory; + variant = object; + + // Check opening brace + if (!eat('{')) return JsonError::InvalidInput; + if (eat('}')) return JsonError::Ok; + + // Read each key value pair + for (;;) { + // 1 - Parse key + const char *key; + JsonError error = parseString(&key); + if (error) return error; + if (!eat(':')) return JsonError::InvalidInput; + + // 2 - Parse value + JsonVariant value; + _nestingLimit--; + error = parse(value); + _nestingLimit++; + if (error != JsonError::Ok) return error; + if (!object->set(key, value)) return JsonError::NoMemory; + + // 3 - More keys/values? + if (eat('}')) return JsonError::Ok; + if (!eat(',')) return JsonError::InvalidInput; + } + } + JsonError parseValue(JsonVariant &variant) { + bool hasQuotes = isQuote(_reader.current()); + const char *value; + JsonError error = parseString(&value); + if (error) return error; + if (hasQuotes) { + variant = value; + } else { + variant = RawJson(value); + } + return JsonError::Ok; + } + + JsonError parseString(const char **result) { + typename RemoveReference::type::String str = _writer.startString(); + + skipSpacesAndComments(_reader); + char c = _reader.current(); + + if (isQuote(c)) { // quotes + _reader.move(); + char stopChar = c; + for (;;) { + c = _reader.current(); + if (c == '\0') break; + _reader.move(); + + if (c == stopChar) break; + + if (c == '\\') { + // replace char + c = Encoding::unescapeChar(_reader.current()); + if (c == '\0') return JsonError::InvalidInput; + _reader.move(); + } + + str.append(c); + } + } else if (canBeInNonQuotedString(c)) { // no quotes + do { + _reader.move(); + str.append(c); + c = _reader.current(); + } while (canBeInNonQuotedString(c)); + } else { + return JsonError::InvalidInput; + } + + *result = str.c_str(); + if (*result == NULL) return JsonError::NoMemory; + return JsonError::Ok; + } + + static inline bool isBetween(char c, char min, char max) { + return min <= c && c <= max; + } + + static inline bool canBeInNonQuotedString(char c) { + return isBetween(c, '0', '9') || isBetween(c, '_', 'z') || + isBetween(c, 'A', 'Z') || c == '+' || c == '-' || c == '.'; + } + + static inline bool isQuote(char c) { + return c == '\'' || c == '\"'; + } + + JsonBuffer *_buffer; + TReader _reader; + TWriter _writer; + uint8_t _nestingLimit; +}; + +template +struct JsonParserBuilder { + typedef typename StringTraits::Reader InputReader; + typedef JsonDeserializer TParser; + + static TParser makeParser(TJsonBuffer *buffer, TString &json, + uint8_t nestingLimit) { + return TParser(buffer, InputReader(json), *buffer, nestingLimit); + } +}; + +template +struct JsonParserBuilder::value>::type> { + typedef typename StringTraits::Reader TReader; + typedef StringWriter TWriter; + typedef JsonDeserializer TParser; + + static TParser makeParser(TJsonBuffer *buffer, TChar *json, + uint8_t nestingLimit) { + return TParser(buffer, TReader(json), TWriter(json), nestingLimit); + } +}; + +template +inline typename JsonParserBuilder::TParser makeParser( + TJsonBuffer *buffer, TString &json, uint8_t nestingLimit) { + return JsonParserBuilder::makeParser(buffer, json, + nestingLimit); +} +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/Json/Deserialization/JsonParser.hpp b/src/ArduinoJson/Json/Deserialization/JsonParser.hpp deleted file mode 100644 index c1a34a70..00000000 --- a/src/ArduinoJson/Json/Deserialization/JsonParser.hpp +++ /dev/null @@ -1,95 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#pragma once - -#include "../../JsonError.hpp" -#include "../../JsonVariant.hpp" -#include "../../Memory/JsonBuffer.hpp" -#include "../../Strings/StringWriter.hpp" -#include "../../TypeTraits/IsConst.hpp" - -namespace ArduinoJson { -namespace Internals { - -// Parse JSON string to create JsonArrays and JsonObjects -// This internal class is not indended to be used directly. -// Instead, use JsonBuffer.parseArray() or .parseObject() -template -class JsonParser { - public: - JsonParser(JsonBuffer *buffer, TReader reader, TWriter writer, - uint8_t nestingLimit) - : _buffer(buffer), - _reader(reader), - _writer(writer), - _nestingLimit(nestingLimit) {} - JsonError parse(JsonArray &destination); - JsonError parse(JsonObject &destination); - JsonError parse(JsonVariant &destination); - - private: - JsonParser &operator=(const JsonParser &); // non-copiable - - static bool eat(TReader &, char charToSkip); - FORCE_INLINE bool eat(char charToSkip) { - return eat(_reader, charToSkip); - } - - const char *parseString(); - JsonError parseArray(JsonVariant &variant); - JsonError parseObject(JsonVariant &variant); - JsonError parseValue(JsonVariant &variant); - - static inline bool isBetween(char c, char min, char max) { - return min <= c && c <= max; - } - - static inline bool canBeInNonQuotedString(char c) { - return isBetween(c, '0', '9') || isBetween(c, '_', 'z') || - isBetween(c, 'A', 'Z') || c == '+' || c == '-' || c == '.'; - } - - static inline bool isQuote(char c) { - return c == '\'' || c == '\"'; - } - - JsonBuffer *_buffer; - TReader _reader; - TWriter _writer; - uint8_t _nestingLimit; -}; - -template -struct JsonParserBuilder { - typedef typename StringTraits::Reader InputReader; - typedef JsonParser TParser; - - static TParser makeParser(TJsonBuffer *buffer, TString &json, - uint8_t nestingLimit) { - return TParser(buffer, InputReader(json), *buffer, nestingLimit); - } -}; - -template -struct JsonParserBuilder::value>::type> { - typedef typename StringTraits::Reader TReader; - typedef StringWriter TWriter; - typedef JsonParser TParser; - - static TParser makeParser(TJsonBuffer *buffer, TChar *json, - uint8_t nestingLimit) { - return TParser(buffer, TReader(json), TWriter(json), nestingLimit); - } -}; - -template -inline typename JsonParserBuilder::TParser makeParser( - TJsonBuffer *buffer, TString &json, uint8_t nestingLimit) { - return JsonParserBuilder::makeParser(buffer, json, - nestingLimit); -} -} // namespace Internals -} // namespace ArduinoJson diff --git a/src/ArduinoJson/Json/Deserialization/JsonParserImpl.hpp b/src/ArduinoJson/Json/Deserialization/JsonParserImpl.hpp deleted file mode 100644 index dd43c0ca..00000000 --- a/src/ArduinoJson/Json/Deserialization/JsonParserImpl.hpp +++ /dev/null @@ -1,166 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#pragma once - -#include "../Encoding.hpp" -#include "Comments.hpp" -#include "JsonParser.hpp" - -template -inline bool ArduinoJson::Internals::JsonParser::eat( - TReader &reader, char charToSkip) { - skipSpacesAndComments(reader); - if (reader.current() != charToSkip) return false; - reader.move(); - return true; -} - -template -inline ArduinoJson::JsonError -ArduinoJson::Internals::JsonParser::parse(JsonArray &array) { - if (_nestingLimit == 0) return JsonError::TooDeep; - - // Check opening braket - if (!eat('[')) return JsonError::OpeningBracketExpected; - if (eat(']')) return JsonError::Ok; - - // Read each value - for (;;) { - // 1 - Parse value - JsonVariant value; - _nestingLimit--; - JsonError error = parse(value); - _nestingLimit++; - if (error != JsonError::Ok) return error; - if (!array.add(value)) return JsonError::NoMemory; - - // 2 - More values? - if (eat(']')) return JsonError::Ok; - if (!eat(',')) return JsonError::ClosingBracketExpected; - } -} - -template -inline ArduinoJson::JsonError -ArduinoJson::Internals::JsonParser::parse( - JsonObject &object) { - if (_nestingLimit == 0) return JsonError::TooDeep; - - // Check opening brace - 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) return JsonError::NoMemory; - if (!eat(':')) return JsonError::ColonExpected; - - // 2 - Parse value - JsonVariant value; - _nestingLimit--; - JsonError error = parse(value); - _nestingLimit++; - if (error != JsonError::Ok) return error; - if (!object.set(key, value)) return JsonError::NoMemory; - - // 3 - More keys/values? - if (eat('}')) return JsonError::Ok; - if (!eat(',')) return JsonError::ClosingBraceExpected; - } -} - -template -inline ArduinoJson::JsonError -ArduinoJson::Internals::JsonParser::parse( - JsonVariant &variant) { - skipSpacesAndComments(_reader); - - switch (_reader.current()) { - case '[': - return parseArray(variant); - - case '{': - return parseObject(variant); - - default: - return parseValue(variant); - } -} - -template -inline ArduinoJson::JsonError -ArduinoJson::Internals::JsonParser::parseArray( - JsonVariant &variant) { - JsonArray *array = new (_buffer) JsonArray(_buffer); - if (!array) return JsonError::NoMemory; - variant = array; - return parse(*array); -} - -template -inline ArduinoJson::JsonError -ArduinoJson::Internals::JsonParser::parseObject( - JsonVariant &variant) { - JsonObject *object = new (_buffer) JsonObject(_buffer); - if (!object) return JsonError::NoMemory; - variant = object; - return parse(*object); -} - -template -inline ArduinoJson::JsonError -ArduinoJson::Internals::JsonParser::parseValue( - JsonVariant &variant) { - bool hasQuotes = isQuote(_reader.current()); - const char *value = parseString(); - if (value == NULL) return JsonError::NoMemory; - if (hasQuotes) { - variant = value; - } else { - variant = RawJson(value); - } - return JsonError::Ok; -} - -template -inline const char * -ArduinoJson::Internals::JsonParser::parseString() { - typename RemoveReference::type::String str = _writer.startString(); - - skipSpacesAndComments(_reader); - char c = _reader.current(); - - if (isQuote(c)) { // quotes - _reader.move(); - char stopChar = c; - for (;;) { - c = _reader.current(); - if (c == '\0') break; - _reader.move(); - - if (c == stopChar) break; - - if (c == '\\') { - // replace char - c = Encoding::unescapeChar(_reader.current()); - if (c == '\0') break; - _reader.move(); - } - - str.append(c); - } - } else { // no quotes - for (;;) { - if (!canBeInNonQuotedString(c)) break; - _reader.move(); - str.append(c); - c = _reader.current(); - } - } - - return str.c_str(); -} diff --git a/src/ArduinoJson/Json/Serialization/JsonSerializer.hpp b/src/ArduinoJson/Json/Serialization/JsonSerializer.hpp index a8c6e328..cae6ac84 100644 --- a/src/ArduinoJson/Json/Serialization/JsonSerializer.hpp +++ b/src/ArduinoJson/Json/Serialization/JsonSerializer.hpp @@ -16,26 +16,15 @@ #endif namespace ArduinoJson { - -class JsonArray; -class JsonObject; -class JsonVariant; - namespace Internals { -class JsonArraySubscript; -template -class JsonObjectSubscript; - template class JsonSerializer { public: - static void serialize(const JsonArray &, Writer &); - static void serialize(const JsonArraySubscript &, Writer &); - static void serialize(const JsonObject &, Writer &); - template - static void serialize(const JsonObjectSubscript &, Writer &); - static void serialize(const JsonVariant &, Writer &); + template + static void serialize(const TSource &source, Writer &writer) { + source.visit(Visitor(&writer)); + } struct Visitor { Visitor(Writer *writer) : _writer(writer) {} @@ -44,12 +33,38 @@ class JsonSerializer { _writer->writeFloat(value); } - void acceptArray(const JsonArray &value) { - serialize(value, *_writer); + void acceptArray(const JsonArray &array) { + _writer->beginArray(); + + JsonArray::const_iterator it = array.begin(); + while (it != array.end()) { + it->visit(*this); + + ++it; + if (it == array.end()) break; + + _writer->writeComma(); + } + + _writer->endArray(); } - void acceptObject(const JsonObject &value) { - serialize(value, *_writer); + void acceptObject(const JsonObject &object) { + _writer->beginObject(); + + JsonObject::const_iterator it = object.begin(); + while (it != object.end()) { + _writer->writeString(it->key); + _writer->writeColon(); + it->value.visit(*this); + + ++it; + if (it == object.end()) break; + + _writer->writeComma(); + } + + _writer->endObject(); } void acceptString(const char *value) { diff --git a/src/ArduinoJson/Json/Serialization/JsonSerializerImpl.hpp b/src/ArduinoJson/Json/Serialization/JsonSerializerImpl.hpp deleted file mode 100644 index 2060cae5..00000000 --- a/src/ArduinoJson/Json/Serialization/JsonSerializerImpl.hpp +++ /dev/null @@ -1,69 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#pragma once - -#include "../../JsonArray.hpp" -#include "../../JsonArraySubscript.hpp" -#include "../../JsonObject.hpp" -#include "../../JsonObjectSubscript.hpp" -#include "../../JsonVariant.hpp" -#include "JsonSerializer.hpp" - -template -inline void ArduinoJson::Internals::JsonSerializer::serialize( - const JsonArray& array, Writer& writer) { - writer.beginArray(); - - JsonArray::const_iterator it = array.begin(); - while (it != array.end()) { - serialize(*it, writer); - - ++it; - if (it == array.end()) break; - - writer.writeComma(); - } - - writer.endArray(); -} - -template -inline void ArduinoJson::Internals::JsonSerializer::serialize( - const JsonArraySubscript& arraySubscript, Writer& writer) { - serialize(arraySubscript.as(), writer); -} - -template -inline void ArduinoJson::Internals::JsonSerializer::serialize( - const JsonObject& object, Writer& writer) { - writer.beginObject(); - - JsonObject::const_iterator it = object.begin(); - while (it != object.end()) { - writer.writeString(it->key); - writer.writeColon(); - serialize(it->value, writer); - - ++it; - if (it == object.end()) break; - - writer.writeComma(); - } - - writer.endObject(); -} - -template -template -inline void ArduinoJson::Internals::JsonSerializer::serialize( - const JsonObjectSubscript& objectSubscript, Writer& writer) { - serialize(objectSubscript.template as(), writer); -} - -template -inline void ArduinoJson::Internals::JsonSerializer::serialize( - const JsonVariant& variant, Writer& writer) { - variant.visit(Visitor(&writer)); -} diff --git a/src/ArduinoJson/JsonArray.hpp b/src/ArduinoJson/JsonArray.hpp index 51757f20..d52430fd 100644 --- a/src/ArduinoJson/JsonArray.hpp +++ b/src/ArduinoJson/JsonArray.hpp @@ -180,6 +180,11 @@ class JsonArray : public Internals::ReferenceType, } } + template + void visit(Visitor visitor) const { + return visitor.acceptArray(*this); + } + private: template bool set_impl(size_t index, TValueRef value) { diff --git a/src/ArduinoJson/JsonArraySubscript.hpp b/src/ArduinoJson/JsonArraySubscript.hpp index a9633991..839182ff 100644 --- a/src/ArduinoJson/JsonArraySubscript.hpp +++ b/src/ArduinoJson/JsonArraySubscript.hpp @@ -74,6 +74,11 @@ class JsonArraySubscript : public JsonVariantBase { return _array.set(_index, value); } + template + void visit(Visitor visitor) const { + return _array.get(_index).visit(visitor); + } + private: JsonArray& _array; const size_t _index; diff --git a/src/ArduinoJson/JsonError.hpp b/src/ArduinoJson/JsonError.hpp index d7f4c903..44060415 100644 --- a/src/ArduinoJson/JsonError.hpp +++ b/src/ArduinoJson/JsonError.hpp @@ -8,16 +8,7 @@ namespace ArduinoJson { class JsonError { public: - enum Code { - Ok, - OpeningBraceExpected, - ClosingBraceExpected, - OpeningBracketExpected, - ClosingBracketExpected, - ColonExpected, - TooDeep, - NoMemory - }; + enum Code { Ok, TooDeep, NoMemory, InvalidInput }; JsonError(Code code) : _code(code) {} @@ -45,20 +36,12 @@ class JsonError { 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"; + case InvalidInput: + return "InvalidInput"; default: return "???"; } @@ -73,6 +56,11 @@ inline std::ostream& operator<<(std::ostream& s, const JsonError& e) { s << e.c_str(); return s; } + +inline std::ostream& operator<<(std::ostream& s, JsonError::Code c) { + s << JsonError(c).c_str(); + return s; +} #endif } // namespace ArduinoJson diff --git a/src/ArduinoJson/JsonObject.hpp b/src/ArduinoJson/JsonObject.hpp index 43e39ec7..def89b95 100644 --- a/src/ArduinoJson/JsonObject.hpp +++ b/src/ArduinoJson/JsonObject.hpp @@ -229,6 +229,11 @@ class JsonObject : public Internals::ReferenceType, return instance; } + template + void visit(Visitor visitor) const { + return visitor.acceptObject(*this); + } + private: // Returns the list node that matches the specified key. template diff --git a/src/ArduinoJson/JsonObjectSubscript.hpp b/src/ArduinoJson/JsonObjectSubscript.hpp index 832d0ca9..f323fb32 100644 --- a/src/ArduinoJson/JsonObjectSubscript.hpp +++ b/src/ArduinoJson/JsonObjectSubscript.hpp @@ -82,6 +82,11 @@ class JsonObjectSubscript return _object.set(_key, value); } + template + void visit(Visitor visitor) const { + return _object.get(_key).visit(visitor); + } + private: JsonObject& _object; TStringRef _key; diff --git a/src/ArduinoJson/Memory/DynamicJsonBuffer.hpp b/src/ArduinoJson/Memory/DynamicJsonBuffer.hpp index 9570e489..3b67deea 100644 --- a/src/ArduinoJson/Memory/DynamicJsonBuffer.hpp +++ b/src/ArduinoJson/Memory/DynamicJsonBuffer.hpp @@ -151,6 +151,12 @@ class DynamicJsonBufferBase : public JsonBuffer { Block* _head; size_t _nextBlockCapacity; }; + +// Implements a JsonBuffer with dynamic memory allocation. +// You are strongly encouraged to consider using StaticJsonBuffer which is much +// more suitable for embedded systems. +typedef Internals::DynamicJsonBufferBase + DynamicJsonBuffer; } // namespace Internals #if defined(__clang__) @@ -160,10 +166,4 @@ class DynamicJsonBufferBase : public JsonBuffer { #pragma GCC diagnostic pop #endif #endif - -// Implements a JsonBuffer with dynamic memory allocation. -// You are strongly encouraged to consider using StaticJsonBuffer which is much -// more suitable for embedded systems. -typedef Internals::DynamicJsonBufferBase - DynamicJsonBuffer; } // namespace ArduinoJson diff --git a/src/ArduinoJson/Memory/StaticJsonBuffer.hpp b/src/ArduinoJson/Memory/StaticJsonBuffer.hpp index 237221d4..eb4fc36e 100644 --- a/src/ArduinoJson/Memory/StaticJsonBuffer.hpp +++ b/src/ArduinoJson/Memory/StaticJsonBuffer.hpp @@ -92,7 +92,6 @@ class StaticJsonBufferBase : public JsonBuffer { size_t _capacity; size_t _size; }; -} // namespace Internals #if defined(__clang__) #pragma clang diagnostic push @@ -118,6 +117,7 @@ class StaticJsonBuffer : public Internals::StaticJsonBufferBase { private: char _buffer[ACTUAL_CAPACITY]; }; +} // namespace Internals } // namespace ArduinoJson #if defined(__clang__) diff --git a/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp b/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp index 0cf05c56..e1a923b7 100644 --- a/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp +++ b/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp @@ -28,40 +28,6 @@ class MsgPackDeserializer { _writer(writer), _nestingLimit(nestingLimit) {} - MsgPackError parse(JsonArray &array) { - uint8_t c = readOne(); - size_t n; - - if ((c & 0xF0) == 0x90) { - n = c & 0x0F; - } else if (c == 0xdc) { - n = readInteger(); - } else if (c == 0xdd) { - n = readInteger(); - } else { - return MsgPackError::NotAnArray; - } - - return readArray(array, n); - } - - MsgPackError parse(JsonObject &object) { - uint8_t c = readOne(); - size_t n; - - if ((c & 0xf0) == 0x80) { - n = c & 0x0f; - } else if (c == 0xde) { - n = readInteger(); - } else if (c == 0xdf) { - n = readInteger(); - } else { - return MsgPackError::NotAnObject; - } - - return readObject(object, n); - } - MsgPackError parse(JsonVariant &variant) { uint8_t c = readOne(); diff --git a/src/ArduinoJson/MsgPack/MsgPackError.hpp b/src/ArduinoJson/MsgPack/MsgPackError.hpp index 0162aac6..0134a723 100644 --- a/src/ArduinoJson/MsgPack/MsgPackError.hpp +++ b/src/ArduinoJson/MsgPack/MsgPackError.hpp @@ -8,7 +8,7 @@ namespace ArduinoJson { class MsgPackError { public: - enum Code { Ok, NotSupported, NoMemory, NotAnArray, NotAnObject, TooDeep }; + enum Code { Ok, NotSupported, NoMemory, TooDeep }; MsgPackError() {} @@ -42,10 +42,6 @@ class MsgPackError { return "NotSupported"; case NoMemory: return "NoMemory"; - case NotAnArray: - return "NotAnArray"; - case NotAnObject: - return "NotAnObject"; case TooDeep: return "TooDeep"; default: @@ -62,6 +58,11 @@ inline std::ostream& operator<<(std::ostream& os, const MsgPackError& err) { os << err.c_str(); return os; } + +inline std::ostream& operator<<(std::ostream& os, MsgPackError::Code code) { + os << MsgPackError(code).c_str(); + return os; +} #endif } // namespace ArduinoJson diff --git a/src/ArduinoJson/StaticJsonArray.hpp b/src/ArduinoJson/StaticJsonArray.hpp deleted file mode 100644 index 21b3a220..00000000 --- a/src/ArduinoJson/StaticJsonArray.hpp +++ /dev/null @@ -1,32 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#pragma once - -#include "JsonArray.hpp" -#include "Memory/StaticJsonBuffer.hpp" - -namespace ArduinoJson { - -template -class StaticJsonArray : public JsonArray { - StaticJsonBuffer _buffer; - - public: - StaticJsonArray() : JsonArray(&_buffer) {} - - void clear() { - Internals::List::clear(); - _buffer.clear(); - } - - size_t memoryUsage() const { - return _buffer.size() + sizeof(JsonArray); - } - - Internals::StaticJsonBufferBase& buffer() { - return _buffer; - } -}; -} // namespace ArduinoJson diff --git a/src/ArduinoJson/StaticJsonDocument.hpp b/src/ArduinoJson/StaticJsonDocument.hpp new file mode 100644 index 00000000..a1821ca3 --- /dev/null +++ b/src/ArduinoJson/StaticJsonDocument.hpp @@ -0,0 +1,80 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +#include "JsonVariant.hpp" +#include "Memory/StaticJsonBuffer.hpp" + +namespace ArduinoJson { + +template +class StaticJsonDocument { + Internals::StaticJsonBuffer _buffer; + JsonVariant _root; + + public: + Internals::StaticJsonBufferBase& buffer() { + return _buffer; + } + + template + bool is() const { + return _root.is(); + } + + template + typename Internals::JsonVariantAs::type as() const { + return _root.as(); + } + + // JsonObject& to() + template + typename Internals::EnableIf::value, + JsonObject&>::type + to() { + clear(); + JsonObject* object = new (&_buffer) JsonObject(&_buffer); + if (!object) return JsonObject::invalid(); + _root = object; + return *object; + } + + // JsonArray& to() + template + typename Internals::EnableIf::value, + JsonArray&>::type + to() { + clear(); + JsonArray* array = new (&_buffer) JsonArray(&_buffer); + if (!array) return JsonArray::invalid(); + _root = array; + return *array; + } + + // JsonVariant to() + template + typename Internals::EnableIf::value, + T&>::type + to() { + clear(); + return _root; + } + + void clear() { + _buffer.clear(); + _root = JsonVariant(); + } + + size_t memoryUsage() const { + return _buffer.size(); + } + + template + void visit(Visitor visitor) const { + return _root.visit(visitor); + } +}; + +} // namespace ArduinoJson diff --git a/src/ArduinoJson/StaticJsonObject.hpp b/src/ArduinoJson/StaticJsonObject.hpp deleted file mode 100644 index 0b5912a8..00000000 --- a/src/ArduinoJson/StaticJsonObject.hpp +++ /dev/null @@ -1,32 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#pragma once - -#include "JsonObject.hpp" -#include "Memory/StaticJsonBuffer.hpp" - -namespace ArduinoJson { - -template -class StaticJsonObject : public JsonObject { - StaticJsonBuffer _buffer; - - public: - StaticJsonObject() : JsonObject(&_buffer) {} - - void clear() { - Internals::List::clear(); - _buffer.clear(); - } - - size_t memoryUsage() const { - return _buffer.size() + sizeof(JsonObject); - } - - Internals::StaticJsonBufferBase& buffer() { - return _buffer; - } -}; -} // namespace ArduinoJson diff --git a/src/ArduinoJson/StaticJsonVariant.hpp b/src/ArduinoJson/StaticJsonVariant.hpp deleted file mode 100644 index 250e1754..00000000 --- a/src/ArduinoJson/StaticJsonVariant.hpp +++ /dev/null @@ -1,43 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#pragma once - -#include "JsonVariant.hpp" -#include "Memory/StaticJsonBuffer.hpp" - -namespace ArduinoJson { - -template -class StaticJsonVariant : public JsonVariant { - StaticJsonBuffer _buffer; - - public: - template - StaticJsonVariant& operator=(const T& value) { - _buffer.clear(); - JsonVariant::operator=(value); - return *this; - } - - template - StaticJsonVariant& operator=(const T* value) { - _buffer.clear(); - JsonVariant::operator=(value); - return *this; - } - - Internals::StaticJsonBufferBase& buffer() { - return _buffer; - } - - void clear() { - _buffer.clear(); - } - - size_t memoryUsage() const { - return _buffer.size(); - } -}; -} // namespace ArduinoJson diff --git a/src/ArduinoJson/TypeTraits/Max.hpp b/src/ArduinoJson/TypeTraits/Max.hpp index e046910d..13d65371 100644 --- a/src/ArduinoJson/TypeTraits/Max.hpp +++ b/src/ArduinoJson/TypeTraits/Max.hpp @@ -4,6 +4,8 @@ #pragma once +#include // for size_t + namespace ArduinoJson { namespace Internals { diff --git a/src/ArduinoJson/deserializeJson.hpp b/src/ArduinoJson/deserializeJson.hpp index d0932a99..46ffbfff 100644 --- a/src/ArduinoJson/deserializeJson.hpp +++ b/src/ArduinoJson/deserializeJson.hpp @@ -4,43 +4,40 @@ #pragma once -#include "Json/Deserialization/JsonParser.hpp" +#include "Json/Deserialization/JsonDeserializer.hpp" namespace ArduinoJson { -// JsonError deserializeJson(TDestination& destination, TString json); -// TDestination = JsonArray, JsonObject, JsonVariant +// JsonError deserializeJson(TDocument& doc, TString json); +// TDocument = DynamicJsonDocument, StaticJsonDocument // TString = const std::string&, const String& -template +template typename Internals::EnableIf::value, JsonError>::type -deserializeJson(TDestination &destination, const TString &json, +deserializeJson(TDocument &doc, const TString &json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { - destination.clear(); - return Internals::makeParser(&destination.buffer(), json, nestingLimit) - .parse(destination); + return Internals::makeParser(&doc.buffer(), json, nestingLimit) + .parse(doc.template to()); } // -// JsonError deserializeJson(TDestination& destination, TString json); -// TDestination = JsonArray, JsonObject, JsonVariant +// JsonError deserializeJson(TDocument& doc, TString json); +// TDocument = DynamicJsonDocument, StaticJsonDocument // TString = const char*, const char[N], const FlashStringHelper* -template +template JsonError deserializeJson( - TDestination &destination, TString *json, + TDocument &doc, TString *json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { - destination.clear(); - return Internals::makeParser(&destination.buffer(), json, nestingLimit) - .parse(destination); + return Internals::makeParser(&doc.buffer(), json, nestingLimit) + .parse(doc.template to()); } // -// JsonError deserializeJson(TDestination& destination, TString json); -// TDestination = JsonArray, JsonObject, JsonVariant +// JsonError deserializeJson(TDocument& doc, TString json); +// TDocument = DynamicJsonDocument, StaticJsonDocument // TString = std::istream&, Stream& -template +template JsonError deserializeJson( - TDestination &destination, TString &json, + TDocument &doc, TString &json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { - destination.clear(); - return Internals::makeParser(&destination.buffer(), json, nestingLimit) - .parse(destination); + return Internals::makeParser(&doc.buffer(), json, nestingLimit) + .parse(doc.template to()); } } // namespace ArduinoJson diff --git a/src/ArduinoJson/deserializeMsgPack.hpp b/src/ArduinoJson/deserializeMsgPack.hpp index d55a7e77..60493d35 100644 --- a/src/ArduinoJson/deserializeMsgPack.hpp +++ b/src/ArduinoJson/deserializeMsgPack.hpp @@ -7,43 +7,37 @@ #include "MsgPack/MsgPackDeserializer.hpp" namespace ArduinoJson { -// MsgPackError deserializeMsgPack(TDestination& destination, TString json); -// TDestination = JsonArray, JsonObject, JsonVariant +// MsgPackError deserializeMsgPack(TDocument& doc, TString json); +// TDocument = DynamicJsonArray | StaticJsonArray // TString = const std::string&, const String& -template +template typename Internals::EnableIf::value, MsgPackError>::type -deserializeMsgPack(TDestination &destination, const TString &json, +deserializeMsgPack(TDocument &doc, const TString &json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { - destination.clear(); - return Internals::makeMsgPackDeserializer(&destination.buffer(), json, - nestingLimit) - .parse(destination); + return Internals::makeMsgPackDeserializer(&doc.buffer(), json, nestingLimit) + .parse(doc.template to()); } // -// MsgPackError deserializeMsgPack(TDestination& destination, TString json); -// TDestination = JsonArray, JsonObject, JsonVariant +// MsgPackError deserializeMsgPack(TDocument& doc, TString json); +// TDocument = DynamicJsonArray | StaticJsonArray // TString = const char*, const char[N], const FlashStringHelper* -template +template MsgPackError deserializeMsgPack( - TDestination &destination, TString *json, + TDocument &doc, TString *json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { - destination.clear(); - return Internals::makeMsgPackDeserializer(&destination.buffer(), json, - nestingLimit) - .parse(destination); + return Internals::makeMsgPackDeserializer(&doc.buffer(), json, nestingLimit) + .parse(doc.template to()); } // -// MsgPackError deserializeMsgPack(TDestination& destination, TString json); -// TDestination = JsonArray, JsonObject, JsonVariant +// MsgPackError deserializeMsgPack(TDocument& doc, TString json); +// TDocument = DynamicJsonArray | StaticJsonArray // TString = std::istream&, Stream& -template +template MsgPackError deserializeMsgPack( - TDestination &destination, TString &json, + TDocument &doc, TString &json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { - destination.clear(); - return Internals::makeMsgPackDeserializer(&destination.buffer(), json, - nestingLimit) - .parse(destination); + return Internals::makeMsgPackDeserializer(&doc.buffer(), json, nestingLimit) + .parse(doc.template to()); } } // namespace ArduinoJson diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b33dfbb4..d255347f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -68,7 +68,7 @@ add_subdirectory(DynamicJsonBuffer) add_subdirectory(IntegrationTests) add_subdirectory(JsonArray) add_subdirectory(JsonObject) -add_subdirectory(JsonParser) +add_subdirectory(JsonDeserializer) add_subdirectory(JsonSerializer) add_subdirectory(JsonVariant) add_subdirectory(JsonWriter) diff --git a/test/DynamicJsonBuffer/alloc.cpp b/test/DynamicJsonBuffer/alloc.cpp index 0d1994f6..c45e6866 100644 --- a/test/DynamicJsonBuffer/alloc.cpp +++ b/test/DynamicJsonBuffer/alloc.cpp @@ -18,8 +18,7 @@ std::stringstream allocatorLog; struct SpyingAllocator : DefaultAllocator { void* allocate(size_t n) { - allocatorLog << static_cast("A") - << (n - DynamicJsonBuffer::EmptyBlockSize); + allocatorLog << "A" << (n - DynamicJsonBuffer::EmptyBlockSize); return DefaultAllocator::allocate(n); } void deallocate(void* p) { diff --git a/test/DynamicJsonBuffer/no_memory.cpp b/test/DynamicJsonBuffer/no_memory.cpp index 5587a1ce..ecb82b8c 100644 --- a/test/DynamicJsonBuffer/no_memory.cpp +++ b/test/DynamicJsonBuffer/no_memory.cpp @@ -23,19 +23,9 @@ TEST_CASE("DynamicJsonBuffer no memory") { } // TODO: uncomment - // SECTION("parseArray()") { - // char json[] = "[{}]"; - // DynamicJsonArray arr; - - // JsonError err = deserializeJson(arr, json); - - // REQUIRE(err != JsonError::Ok); - // } - - // TODO: uncomment - // SECTION("parseObject()") { + // SECTION("deserializeJson()") { // char json[] = "{[]}"; - // DynamicJsonObject obj; + // DynamicJsonDocument obj; // JsonError err = deserializeJson(obj, json); diff --git a/test/DynamicJsonBuffer/size.cpp b/test/DynamicJsonBuffer/size.cpp index 8ebba424..06b187d5 100644 --- a/test/DynamicJsonBuffer/size.cpp +++ b/test/DynamicJsonBuffer/size.cpp @@ -2,9 +2,11 @@ // Copyright Benoit Blanchon 2014-2018 // MIT License -#include +#include #include +using namespace ArduinoJson::Internals; + TEST_CASE("DynamicJsonBuffer::size()") { DynamicJsonBuffer buffer; diff --git a/test/DynamicJsonBuffer/startString.cpp b/test/DynamicJsonBuffer/startString.cpp index 2e5bef7f..3253f1ad 100644 --- a/test/DynamicJsonBuffer/startString.cpp +++ b/test/DynamicJsonBuffer/startString.cpp @@ -2,9 +2,11 @@ // Copyright Benoit Blanchon 2014-2018 // MIT License -#include +#include #include +using namespace ArduinoJson::Internals; + TEST_CASE("DynamicJsonBuffer::startString()") { SECTION("WorksWhenBufferIsBigEnough") { DynamicJsonBuffer jsonBuffer(6); diff --git a/test/IntegrationTests/CMakeLists.txt b/test/IntegrationTests/CMakeLists.txt index 9294bbbf..c158367e 100644 --- a/test/IntegrationTests/CMakeLists.txt +++ b/test/IntegrationTests/CMakeLists.txt @@ -2,7 +2,7 @@ # Copyright Benoit Blanchon 2014-2018 # MIT License -add_executable(IntegrationTests +add_executable(IntegrationTests gbathree.cpp round_trip.cpp ) diff --git a/test/IntegrationTests/gbathree.cpp b/test/IntegrationTests/gbathree.cpp index dd6b293f..965022ae 100644 --- a/test/IntegrationTests/gbathree.cpp +++ b/test/IntegrationTests/gbathree.cpp @@ -6,10 +6,10 @@ #include TEST_CASE("Gbathree") { - DynamicJsonObject _object; + DynamicJsonDocument doc; JsonError error = deserializeJson( - _object, + doc, "{\"protocol_name\":\"fluorescence\",\"repeats\":1,\"wait\":0," "\"averages\":1,\"measurements\":3,\"meas2_light\":15,\"meas1_" "baseline\":0,\"act_light\":20,\"pulsesize\":25,\"pulsedistance\":" @@ -20,67 +20,68 @@ TEST_CASE("Gbathree") { "\"measlights\":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15," "15,15]],\"measlights2\":[[15,15,15,15],[15,15,15,15],[15,15,15,15]," "[15,15,15,15]],\"altc\":[2,2,2,2],\"altd\":[2,2,2,2]}"); + JsonObject& root = doc.as(); SECTION("Success") { REQUIRE(error == JsonError::Ok); } SECTION("ProtocolName") { - REQUIRE("fluorescence" == _object["protocol_name"]); + REQUIRE("fluorescence" == root["protocol_name"]); } SECTION("Repeats") { - REQUIRE(1 == _object["repeats"]); + REQUIRE(1 == root["repeats"]); } SECTION("Wait") { - REQUIRE(0 == _object["wait"]); + REQUIRE(0 == root["wait"]); } SECTION("Measurements") { - REQUIRE(3 == _object["measurements"]); + REQUIRE(3 == root["measurements"]); } SECTION("Meas2_Light") { - REQUIRE(15 == _object["meas2_light"]); + REQUIRE(15 == root["meas2_light"]); } SECTION("Meas1_Baseline") { - REQUIRE(0 == _object["meas1_baseline"]); + REQUIRE(0 == root["meas1_baseline"]); } SECTION("Act_Light") { - REQUIRE(20 == _object["act_light"]); + REQUIRE(20 == root["act_light"]); } SECTION("Pulsesize") { - REQUIRE(25 == _object["pulsesize"]); + REQUIRE(25 == root["pulsesize"]); } SECTION("Pulsedistance") { - REQUIRE(10000 == _object["pulsedistance"]); + REQUIRE(10000 == root["pulsedistance"]); } SECTION("Actintensity1") { - REQUIRE(50 == _object["actintensity1"]); + REQUIRE(50 == root["actintensity1"]); } SECTION("Actintensity2") { - REQUIRE(255 == _object["actintensity2"]); + REQUIRE(255 == root["actintensity2"]); } SECTION("Measintensity") { - REQUIRE(255 == _object["measintensity"]); + REQUIRE(255 == root["measintensity"]); } SECTION("Calintensity") { - REQUIRE(255 == _object["calintensity"]); + REQUIRE(255 == root["calintensity"]); } SECTION("Pulses") { // "pulses":[50,50,50] - JsonArray& array = _object["pulses"]; + JsonArray& array = root["pulses"]; REQUIRE(array.success()); REQUIRE(3 == array.size()); @@ -93,7 +94,7 @@ TEST_CASE("Gbathree") { SECTION("Act") { // "act":[2,1,2,2] - JsonArray& array = _object["act"]; + JsonArray& array = root["act"]; REQUIRE(array.success()); REQUIRE(4 == array.size()); @@ -106,7 +107,7 @@ TEST_CASE("Gbathree") { SECTION("Detectors") { // "detectors":[[34,34,34,34],[34,34,34,34],[34,34,34,34],[34,34,34,34]] - JsonArray& array = _object["detectors"]; + JsonArray& array = root["detectors"]; REQUIRE(array.success()); REQUIRE(4 == array.size()); @@ -123,7 +124,7 @@ TEST_CASE("Gbathree") { SECTION("Alta") { // alta:[2,2,2,2] - JsonArray& array = _object["alta"]; + JsonArray& array = root["alta"]; REQUIRE(array.success()); REQUIRE(4 == array.size()); @@ -136,7 +137,7 @@ TEST_CASE("Gbathree") { SECTION("Altb") { // altb:[2,2,2,2] - JsonArray& array = _object["altb"]; + JsonArray& array = root["altb"]; REQUIRE(array.success()); REQUIRE(4 == array.size()); @@ -149,7 +150,7 @@ TEST_CASE("Gbathree") { SECTION("Measlights") { // "measlights":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15,15,15]] - JsonArray& array = _object["measlights"]; + JsonArray& array = root["measlights"]; REQUIRE(array.success()); REQUIRE(4 == array.size()); @@ -167,7 +168,7 @@ TEST_CASE("Gbathree") { SECTION("Measlights2") { // "measlights2":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15,15,15]] - JsonArray& array = _object["measlights2"]; + JsonArray& array = root["measlights2"]; REQUIRE(array.success()); REQUIRE(4 == array.size()); @@ -184,7 +185,7 @@ TEST_CASE("Gbathree") { SECTION("Altc") { // altc:[2,2,2,2] - JsonArray& array = _object["altc"]; + JsonArray& array = root["altc"]; REQUIRE(array.success()); REQUIRE(4 == array.size()); @@ -197,7 +198,7 @@ TEST_CASE("Gbathree") { SECTION("Altd") { // altd:[2,2,2,2] - JsonArray& array = _object["altd"]; + JsonArray& array = root["altd"]; REQUIRE(array.success()); REQUIRE(4 == array.size()); diff --git a/test/IntegrationTests/round_trip.cpp b/test/IntegrationTests/round_trip.cpp index 487dbb74..ac221835 100644 --- a/test/IntegrationTests/round_trip.cpp +++ b/test/IntegrationTests/round_trip.cpp @@ -6,15 +6,15 @@ #include void check(std::string originalJson) { - DynamicJsonObject obj; + DynamicJsonDocument doc; std::string prettyJson; - deserializeJson(obj, originalJson); - serializeJsonPretty(obj, prettyJson); + deserializeJson(doc, originalJson); + serializeJsonPretty(doc, prettyJson); std::string finalJson; - deserializeJson(obj, originalJson); - serializeJson(obj, finalJson); + deserializeJson(doc, originalJson); + serializeJson(doc, finalJson); REQUIRE(originalJson == finalJson); } diff --git a/test/JsonArray/add.cpp b/test/JsonArray/add.cpp index 61f6ec6f..b2d6034d 100644 --- a/test/JsonArray/add.cpp +++ b/test/JsonArray/add.cpp @@ -6,7 +6,8 @@ #include TEST_CASE("JsonArray::add()") { - DynamicJsonArray _array; + DynamicJsonDocument doc; + JsonArray& _array = doc.to(); SECTION("int") { _array.add(123); @@ -38,7 +39,8 @@ TEST_CASE("JsonArray::add()") { } SECTION("nested array") { - DynamicJsonArray arr; + DynamicJsonDocument doc2; + JsonArray& arr = doc2.to(); _array.add(arr); @@ -48,7 +50,8 @@ TEST_CASE("JsonArray::add()") { } SECTION("nested object") { - DynamicJsonObject obj; + DynamicJsonDocument doc2; + JsonObject& obj = doc2.to(); _array.add(obj); @@ -59,7 +62,8 @@ TEST_CASE("JsonArray::add()") { SECTION("array subscript") { const char* str = "hello"; - DynamicJsonArray arr; + DynamicJsonDocument doc2; + JsonArray& arr = doc2.to(); arr.add(str); _array.add(arr[0]); @@ -69,7 +73,8 @@ TEST_CASE("JsonArray::add()") { SECTION("object subscript") { const char* str = "hello"; - DynamicJsonObject obj; + DynamicJsonDocument doc2; + JsonObject& obj = doc2.to(); obj["x"] = str; _array.add(obj["x"]); @@ -80,30 +85,30 @@ TEST_CASE("JsonArray::add()") { SECTION("should not duplicate const char*") { _array.add("world"); const size_t expectedSize = JSON_ARRAY_SIZE(1); - REQUIRE(expectedSize == _array.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should duplicate char*") { _array.add(const_cast("world")); const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; - REQUIRE(expectedSize == _array.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should duplicate std::string") { _array.add(std::string("world")); const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; - REQUIRE(expectedSize == _array.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should not duplicate RawJson(const char*)") { _array.add(RawJson("{}")); const size_t expectedSize = JSON_ARRAY_SIZE(1); - REQUIRE(expectedSize == _array.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should duplicate RawJson(char*)") { _array.add(RawJson(const_cast("{}"))); const size_t expectedSize = JSON_ARRAY_SIZE(1) + 3; - REQUIRE(expectedSize == _array.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } } diff --git a/test/JsonArray/basics.cpp b/test/JsonArray/basics.cpp index 0e9d0617..9c0b727d 100644 --- a/test/JsonArray/basics.cpp +++ b/test/JsonArray/basics.cpp @@ -6,7 +6,8 @@ #include TEST_CASE("JsonArray basics") { - DynamicJsonArray array; + DynamicJsonDocument doc; + JsonArray& array = doc.to(); SECTION("SuccessIsTrue") { REQUIRE(array.success()); diff --git a/test/JsonArray/copyFrom.cpp b/test/JsonArray/copyFrom.cpp index fa2045bc..60ba95ea 100644 --- a/test/JsonArray/copyFrom.cpp +++ b/test/JsonArray/copyFrom.cpp @@ -7,7 +7,8 @@ TEST_CASE("JsonArray::copyFrom()") { SECTION("OneDimension") { - DynamicJsonArray array; + DynamicJsonDocument doc; + JsonArray& array = doc.to(); char json[32]; int source[] = {1, 2, 3}; @@ -20,7 +21,8 @@ TEST_CASE("JsonArray::copyFrom()") { SECTION("OneDimension_JsonBufferTooSmall") { const size_t SIZE = JSON_ARRAY_SIZE(2); - StaticJsonArray array; + StaticJsonDocument doc; + JsonArray& array = doc.to(); char json[32]; int source[] = {1, 2, 3}; @@ -32,7 +34,8 @@ TEST_CASE("JsonArray::copyFrom()") { } SECTION("TwoDimensions") { - DynamicJsonArray array; + DynamicJsonDocument doc; + JsonArray& array = doc.to(); char json[32]; int source[][3] = {{1, 2, 3}, {4, 5, 6}}; @@ -46,7 +49,8 @@ TEST_CASE("JsonArray::copyFrom()") { SECTION("TwoDimensions_JsonBufferTooSmall") { const size_t SIZE = JSON_ARRAY_SIZE(2) + JSON_ARRAY_SIZE(3) + JSON_ARRAY_SIZE(2); - StaticJsonArray array; + StaticJsonDocument doc; + JsonArray& array = doc.to(); char json[32]; int source[][3] = {{1, 2, 3}, {4, 5, 6}}; diff --git a/test/JsonArray/copyTo.cpp b/test/JsonArray/copyTo.cpp index 9c31e880..87c9801e 100644 --- a/test/JsonArray/copyTo.cpp +++ b/test/JsonArray/copyTo.cpp @@ -6,12 +6,13 @@ #include TEST_CASE("JsonArray::copyTo()") { - DynamicJsonArray array; + DynamicJsonDocument doc; SECTION("BiggerOneDimensionIntegerArray") { char json[] = "[1,2,3]"; - JsonError err = deserializeJson(array, json); + JsonError err = deserializeJson(doc, json); REQUIRE(err == JsonError::Ok); + JsonArray& array = doc.as(); int destination[4] = {0}; size_t result = array.copyTo(destination); @@ -25,8 +26,9 @@ TEST_CASE("JsonArray::copyTo()") { SECTION("SmallerOneDimensionIntegerArray") { char json[] = "[1,2,3]"; - JsonError err = deserializeJson(array, json); + JsonError err = deserializeJson(doc, json); REQUIRE(err == JsonError::Ok); + JsonArray& array = doc.as(); int destination[2] = {0}; size_t result = array.copyTo(destination); @@ -39,8 +41,9 @@ TEST_CASE("JsonArray::copyTo()") { SECTION("TwoOneDimensionIntegerArray") { char json[] = "[[1,2],[3],[4]]"; - JsonError err = deserializeJson(array, json); + JsonError err = deserializeJson(doc, json); REQUIRE(err == JsonError::Ok); + JsonArray& array = doc.as(); int destination[3][2] = {{0}}; array.copyTo(destination); diff --git a/test/JsonArray/iterator.cpp b/test/JsonArray/iterator.cpp index ef0c7785..91efc243 100644 --- a/test/JsonArray/iterator.cpp +++ b/test/JsonArray/iterator.cpp @@ -7,7 +7,8 @@ template static void run_iterator_test() { - StaticJsonArray array; + StaticJsonDocument doc; + JsonArray& array = doc.to(); array.add(12); array.add(34); diff --git a/test/JsonArray/remove.cpp b/test/JsonArray/remove.cpp index 61ea011d..27f149ac 100644 --- a/test/JsonArray/remove.cpp +++ b/test/JsonArray/remove.cpp @@ -6,7 +6,8 @@ #include TEST_CASE("JsonArray::remove()") { - DynamicJsonArray _array; + DynamicJsonDocument doc; + JsonArray& _array = doc.to(); _array.add(1); _array.add(2); _array.add(3); diff --git a/test/JsonArray/set.cpp b/test/JsonArray/set.cpp index f0f55016..498b2668 100644 --- a/test/JsonArray/set.cpp +++ b/test/JsonArray/set.cpp @@ -8,7 +8,8 @@ using namespace Catch::Matchers; TEST_CASE("JsonArray::set()") { - DynamicJsonArray _array; + DynamicJsonDocument doc; + JsonArray& _array = doc.to(); _array.add(0); SECTION("int") { @@ -40,7 +41,8 @@ TEST_CASE("JsonArray::set()") { } SECTION("nested array") { - DynamicJsonArray arr; + DynamicJsonDocument doc2; + JsonArray& arr = doc2.to(); _array.set(0, arr); @@ -50,7 +52,8 @@ TEST_CASE("JsonArray::set()") { } SECTION("nested object") { - DynamicJsonObject obj; + DynamicJsonDocument doc2; + JsonObject& obj = doc2.to(); _array.set(0, obj); @@ -60,7 +63,8 @@ TEST_CASE("JsonArray::set()") { } SECTION("array subscript") { - DynamicJsonArray arr; + DynamicJsonDocument doc2; + JsonArray& arr = doc2.to(); arr.add("hello"); _array.set(0, arr[0]); @@ -69,7 +73,8 @@ TEST_CASE("JsonArray::set()") { } SECTION("object subscript") { - DynamicJsonObject obj; + DynamicJsonDocument doc2; + JsonObject& obj = doc2.to(); obj["x"] = "hello"; _array.set(0, obj["x"]); @@ -80,18 +85,18 @@ TEST_CASE("JsonArray::set()") { SECTION("should not duplicate const char*") { _array.set(0, "world"); const size_t expectedSize = JSON_ARRAY_SIZE(1); - REQUIRE(expectedSize == _array.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should duplicate char*") { _array.set(0, const_cast("world")); const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; - REQUIRE(expectedSize == _array.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should duplicate std::string") { _array.set(0, std::string("world")); const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; - REQUIRE(expectedSize == _array.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } } diff --git a/test/JsonArray/size.cpp b/test/JsonArray/size.cpp index de409a79..48edee07 100644 --- a/test/JsonArray/size.cpp +++ b/test/JsonArray/size.cpp @@ -6,7 +6,8 @@ #include TEST_CASE("JsonArray::size()") { - DynamicJsonArray _array; + DynamicJsonDocument doc; + JsonArray& _array = doc.to(); SECTION("increases after add()") { _array.add("hello"); diff --git a/test/JsonArray/subscript.cpp b/test/JsonArray/subscript.cpp index 17f3e7a4..d763e4b1 100644 --- a/test/JsonArray/subscript.cpp +++ b/test/JsonArray/subscript.cpp @@ -7,7 +7,8 @@ #include TEST_CASE("JsonArray::operator[]") { - DynamicJsonArray _array; + DynamicJsonDocument doc; + JsonArray& _array = doc.to(); _array.add(0); SECTION("int") { @@ -51,7 +52,8 @@ TEST_CASE("JsonArray::operator[]") { } SECTION("nested array") { - DynamicJsonArray arr; + DynamicJsonDocument doc2; + JsonArray& arr = doc2.to(); _array[0] = arr; @@ -64,7 +66,8 @@ TEST_CASE("JsonArray::operator[]") { } SECTION("nested object") { - DynamicJsonObject obj; + DynamicJsonDocument doc2; + JsonObject& obj = doc2.to(); _array[0] = obj; @@ -77,7 +80,8 @@ TEST_CASE("JsonArray::operator[]") { } SECTION("array subscript") { - DynamicJsonArray arr; + DynamicJsonDocument doc2; + JsonArray& arr = doc2.to(); const char* str = "hello"; arr.add(str); @@ -88,8 +92,9 @@ TEST_CASE("JsonArray::operator[]") { } SECTION("object subscript") { - DynamicJsonObject obj; const char* str = "hello"; + DynamicJsonDocument doc2; + JsonObject& obj = doc2.to(); obj["x"] = str; @@ -101,18 +106,18 @@ TEST_CASE("JsonArray::operator[]") { SECTION("should not duplicate const char*") { _array[0] = "world"; const size_t expectedSize = JSON_ARRAY_SIZE(1); - REQUIRE(expectedSize == _array.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should duplicate char*") { _array[0] = const_cast("world"); const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; - REQUIRE(expectedSize == _array.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should duplicate std::string") { _array[0] = std::string("world"); const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; - REQUIRE(expectedSize == _array.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } } diff --git a/test/JsonDeserializer/CMakeLists.txt b/test/JsonDeserializer/CMakeLists.txt new file mode 100644 index 00000000..6201ea70 --- /dev/null +++ b/test/JsonDeserializer/CMakeLists.txt @@ -0,0 +1,16 @@ +# ArduinoJson - arduinojson.org +# Copyright Benoit Blanchon 2014-2018 +# MIT License + +add_executable(JsonDeserializerTests + deserializeJsonArray.cpp + deserializeJsonArrayStatic.cpp + deserializeJsonObject.cpp + deserializeJsonObjectStatic.cpp + deserializeJsonValue.cpp + JsonError.cpp + nestingLimit.cpp +) + +target_link_libraries(JsonDeserializerTests catch) +add_test(JsonDeserializer JsonDeserializerTests) diff --git a/test/JsonParser/JsonError.cpp b/test/JsonDeserializer/JsonError.cpp similarity index 62% rename from test/JsonParser/JsonError.cpp rename to test/JsonDeserializer/JsonError.cpp index 21714ba0..edcad063 100644 --- a/test/JsonParser/JsonError.cpp +++ b/test/JsonDeserializer/JsonError.cpp @@ -22,23 +22,21 @@ void testBoolification(JsonError error, bool 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); + TEST_STRINGIFICATION(InvalidInput); } 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); + TEST_BOOLIFICATION(InvalidInput, true); + } + + SECTION("ostream") { + std::stringstream s; + s << JsonError::InvalidInput; + REQUIRE(s.str() == "InvalidInput"); } } diff --git a/test/JsonParser/DynamicJsonArray.cpp b/test/JsonDeserializer/deserializeJsonArray.cpp similarity index 56% rename from test/JsonParser/DynamicJsonArray.cpp rename to test/JsonDeserializer/deserializeJsonArray.cpp index cfb498f7..54dcc2d5 100644 --- a/test/JsonParser/DynamicJsonArray.cpp +++ b/test/JsonDeserializer/deserializeJsonArray.cpp @@ -5,11 +5,12 @@ #include #include -TEST_CASE("deserializeJson(DynamicJsonArray&)") { - DynamicJsonArray arr; +TEST_CASE("deserialize JSON array") { + DynamicJsonDocument doc; SECTION("An empty array") { - JsonError err = deserializeJson(arr, "[]"); + JsonError err = deserializeJson(doc, "[]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(0 == arr.size()); @@ -17,14 +18,16 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { SECTION("Spaces") { SECTION("Before the opening bracket") { - JsonError err = deserializeJson(arr, " []"); + JsonError err = deserializeJson(doc, " []"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(0 == arr.size()); } SECTION("Before first value") { - JsonError err = deserializeJson(arr, "[ \t\r\n42]"); + JsonError err = deserializeJson(doc, "[ \t\r\n42]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(1 == arr.size()); @@ -32,7 +35,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("After first value") { - JsonError err = deserializeJson(arr, "[42 \t\r\n]"); + JsonError err = deserializeJson(doc, "[42 \t\r\n]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(1 == arr.size()); @@ -42,7 +46,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { SECTION("Values types") { SECTION("On integer") { - JsonError err = deserializeJson(arr, "[42]"); + JsonError err = deserializeJson(doc, "[42]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(1 == arr.size()); @@ -50,7 +55,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("Two integers") { - JsonError err = deserializeJson(arr, "[42,84]"); + JsonError err = deserializeJson(doc, "[42,84]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(2 == arr.size()); @@ -59,7 +65,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("Double") { - JsonError err = deserializeJson(arr, "[4.2,1e2]"); + JsonError err = deserializeJson(doc, "[4.2,1e2]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(2 == arr.size()); @@ -68,7 +75,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("Unsigned long") { - JsonError err = deserializeJson(arr, "[4294967295]"); + JsonError err = deserializeJson(doc, "[4294967295]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(1 == arr.size()); @@ -76,7 +84,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("Boolean") { - JsonError err = deserializeJson(arr, "[true,false]"); + JsonError err = deserializeJson(doc, "[true,false]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(2 == arr.size()); @@ -85,18 +94,20 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("Null") { - JsonError err = deserializeJson(arr, "[null,null]"); + JsonError err = deserializeJson(doc, "[null,null]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(2 == arr.size()); - REQUIRE(arr[0].as() == 0); - REQUIRE(arr[1].as() == 0); + REQUIRE(arr[0].as() == 0); + REQUIRE(arr[1].as() == 0); } } SECTION("Quotes") { SECTION("Double quotes") { - JsonError err = deserializeJson(arr, "[ \"hello\" , \"world\" ]"); + JsonError err = deserializeJson(doc, "[ \"hello\" , \"world\" ]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(2 == arr.size()); @@ -105,7 +116,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("Single quotes") { - JsonError err = deserializeJson(arr, "[ 'hello' , 'world' ]"); + JsonError err = deserializeJson(doc, "[ 'hello' , 'world' ]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(2 == arr.size()); @@ -114,7 +126,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("No quotes") { - JsonError err = deserializeJson(arr, "[ hello , world ]"); + JsonError err = deserializeJson(doc, "[ hello , world ]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(2 == arr.size()); @@ -123,7 +136,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("Double quotes (empty strings)") { - JsonError err = deserializeJson(arr, "[\"\",\"\"]"); + JsonError err = deserializeJson(doc, "[\"\",\"\"]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(2 == arr.size()); @@ -132,7 +146,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("Single quotes (empty strings)") { - JsonError err = deserializeJson(arr, "[\'\',\'\']"); + JsonError err = deserializeJson(doc, "[\'\',\'\']"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(2 == arr.size()); @@ -141,30 +156,28 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("No quotes (empty strings)") { - JsonError err = deserializeJson(arr, "[,]"); + JsonError err = deserializeJson(doc, "[,]"); - REQUIRE(err == JsonError::Ok); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == ""); - REQUIRE(arr[1] == ""); + REQUIRE(err == JsonError::InvalidInput); } SECTION("Closing single quotes missing") { - JsonError err = deserializeJson(arr, "[\"]"); + JsonError err = deserializeJson(doc, "[\"]"); - REQUIRE(err != JsonError::Ok); + REQUIRE(err == JsonError::InvalidInput); } SECTION("Closing double quotes missing") { - JsonError err = deserializeJson(arr, "[\']"); + JsonError err = deserializeJson(doc, "[\']"); - REQUIRE(err != JsonError::Ok); + REQUIRE(err == JsonError::InvalidInput); } } SECTION("Block comments") { SECTION("Before opening bracket") { - JsonError err = deserializeJson(arr, "/*COMMENT*/ [\"hello\"]"); + JsonError err = deserializeJson(doc, "/*COMMENT*/ [\"hello\"]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(1 == arr.size()); @@ -172,7 +185,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("After opening bracket") { - JsonError err = deserializeJson(arr, "[/*COMMENT*/ \"hello\"]"); + JsonError err = deserializeJson(doc, "[/*COMMENT*/ \"hello\"]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(1 == arr.size()); @@ -180,7 +194,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("Before closing bracket") { - JsonError err = deserializeJson(arr, "[\"hello\"/*COMMENT*/]"); + JsonError err = deserializeJson(doc, "[\"hello\"/*COMMENT*/]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(1 == arr.size()); @@ -188,7 +203,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("After closing bracket") { - JsonError err = deserializeJson(arr, "[\"hello\"]/*COMMENT*/"); + JsonError err = deserializeJson(doc, "[\"hello\"]/*COMMENT*/"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(1 == arr.size()); @@ -196,7 +212,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("Before comma") { - JsonError err = deserializeJson(arr, "[\"hello\"/*COMMENT*/,\"world\"]"); + JsonError err = deserializeJson(doc, "[\"hello\"/*COMMENT*/,\"world\"]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(2 == arr.size()); @@ -205,7 +222,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("After comma") { - JsonError err = deserializeJson(arr, "[\"hello\",/*COMMENT*/ \"world\"]"); + JsonError err = deserializeJson(doc, "[\"hello\",/*COMMENT*/ \"world\"]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(2 == arr.size()); @@ -214,24 +232,25 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("/*/") { - JsonError err = deserializeJson(arr, "[/*/\n]"); - REQUIRE(err != JsonError::Ok); + JsonError err = deserializeJson(doc, "[/*/\n]"); + REQUIRE(err == JsonError::InvalidInput); } SECTION("Unfinished comment") { - JsonError err = deserializeJson(arr, "[/*COMMENT]"); - REQUIRE(err != JsonError::Ok); + JsonError err = deserializeJson(doc, "[/*COMMENT]"); + REQUIRE(err == JsonError::InvalidInput); } SECTION("Final slash missing") { - JsonError err = deserializeJson(arr, "[/*COMMENT*]"); - REQUIRE(err != JsonError::Ok); + JsonError err = deserializeJson(doc, "[/*COMMENT*]"); + REQUIRE(err == JsonError::InvalidInput); } } SECTION("Line comments") { SECTION("Before opening bracket") { - JsonError err = deserializeJson(arr, "//COMMENT\n\t[\"hello\"]"); + JsonError err = deserializeJson(doc, "//COMMENT\n\t[\"hello\"]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(1 == arr.size()); @@ -239,7 +258,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("After opening bracket") { - JsonError err = deserializeJson(arr, "[//COMMENT\n\"hello\"]"); + JsonError err = deserializeJson(doc, "[//COMMENT\n\"hello\"]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(1 == arr.size()); @@ -247,7 +267,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("Before closing bracket") { - JsonError err = deserializeJson(arr, "[\"hello\"//COMMENT\r\n]"); + JsonError err = deserializeJson(doc, "[\"hello\"//COMMENT\r\n]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(1 == arr.size()); @@ -255,7 +276,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("After closing bracket") { - JsonError err = deserializeJson(arr, "[\"hello\"]//COMMENT\n"); + JsonError err = deserializeJson(doc, "[\"hello\"]//COMMENT\n"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(1 == arr.size()); @@ -263,7 +285,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("Before comma") { - JsonError err = deserializeJson(arr, "[\"hello\"//COMMENT\n,\"world\"]"); + JsonError err = deserializeJson(doc, "[\"hello\"//COMMENT\n,\"world\"]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(2 == arr.size()); @@ -272,7 +295,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("After comma") { - JsonError err = deserializeJson(arr, "[\"hello\",//COMMENT\n\"world\"]"); + JsonError err = deserializeJson(doc, "[\"hello\",//COMMENT\n\"world\"]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(2 == arr.size()); @@ -281,57 +305,55 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("Invalid comment") { - JsonError err = deserializeJson(arr, "[/COMMENT\n]"); - REQUIRE(err != JsonError::Ok); + JsonError err = deserializeJson(doc, "[/COMMENT\n]"); + REQUIRE(err == JsonError::InvalidInput); } SECTION("End document with comment") { - JsonError err = deserializeJson(arr, "[//COMMENT"); - REQUIRE(err != JsonError::Ok); + JsonError err = deserializeJson(doc, "[//COMMENT"); + REQUIRE(err == JsonError::InvalidInput); } } SECTION("Misc") { SECTION("Garbage") { - JsonError err = deserializeJson(arr, "%*$£¤"); + JsonError err = deserializeJson(doc, "%*$£¤"); - REQUIRE(err != JsonError::Ok); + REQUIRE(err == JsonError::InvalidInput); } SECTION("The opening bracket is missing") { - JsonError err = deserializeJson(arr, "]"); + JsonError err = deserializeJson(doc, "]"); - REQUIRE(err != JsonError::Ok); // TODO + REQUIRE(err == JsonError::InvalidInput); } SECTION("The closing bracket is missing") { - JsonError err = deserializeJson(arr, "["); - REQUIRE(err != JsonError::Ok); // TODO + JsonError err = deserializeJson(doc, "["); + + REQUIRE(err == JsonError::InvalidInput); } SECTION("Escape sequences") { JsonError err = - deserializeJson(arr, "[\"1\\\"2\\\\3\\/4\\b5\\f6\\n7\\r8\\t9\"]"); + deserializeJson(doc, "[\"1\\\"2\\\\3\\/4\\b5\\f6\\n7\\r8\\t9\"]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(1 == arr.size()); REQUIRE(arr[0] == "1\"2\\3/4\b5\f6\n7\r8\t9"); } - SECTION("Unterminated escape sequence") { - JsonError err = deserializeJson(arr, "\"\\\0\"", 4); - REQUIRE(err != JsonError::Ok); - } - SECTION("Nested objects") { char jsonString[] = " [ { \"a\" : 1 , \"b\" : 2 } , { \"c\" : 3 , \"d\" : 4 } ] "; - JsonError err = deserializeJson(arr, jsonString); + JsonError err = deserializeJson(doc, jsonString); + JsonArray& arr = doc.as(); - JsonObject &object1 = arr[0]; - const JsonObject &object2 = arr[1]; - JsonObject &object3 = arr[2]; + JsonObject& object1 = arr[0]; + const JsonObject& object2 = arr[1]; + JsonObject& object3 = arr[2]; REQUIRE(err == JsonError::Ok); @@ -352,10 +374,11 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("Should clear the JsonArray") { - deserializeJson(arr, "[1,2,3,4]"); - deserializeJson(arr, "[]"); + deserializeJson(doc, "[1,2,3,4]"); + deserializeJson(doc, "[]"); + JsonArray& arr = doc.as(); REQUIRE(arr.size() == 0); - REQUIRE(arr.memoryUsage() == JSON_ARRAY_SIZE(0)); + REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(0)); } } diff --git a/test/JsonDeserializer/deserializeJsonArrayStatic.cpp b/test/JsonDeserializer/deserializeJsonArrayStatic.cpp new file mode 100644 index 00000000..45da9c03 --- /dev/null +++ b/test/JsonDeserializer/deserializeJsonArrayStatic.cpp @@ -0,0 +1,105 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +TEST_CASE("deserialize JSON array with a StaticJsonDocument") { + SECTION("BufferOfTheRightSizeForEmptyArray") { + StaticJsonDocument doc; + char input[] = "[]"; + + JsonError err = deserializeJson(doc, input); + + REQUIRE(err == JsonError::Ok); + } + + SECTION("TooSmallBufferForArrayWithOneValue") { + StaticJsonDocument doc; + char input[] = "[1]"; + + JsonError err = deserializeJson(doc, input); + + REQUIRE(err != JsonError::Ok); + } + + SECTION("BufferOfTheRightSizeForArrayWithOneValue") { + StaticJsonDocument doc; + char input[] = "[1]"; + + JsonError err = deserializeJson(doc, input); + + REQUIRE(err == JsonError::Ok); + } + + SECTION("TooSmallBufferForArrayWithNestedObject") { + StaticJsonDocument doc; + char input[] = "[{}]"; + + JsonError err = deserializeJson(doc, input); + + REQUIRE(err != JsonError::Ok); + } + + SECTION("BufferOfTheRightSizeForArrayWithNestedObject") { + StaticJsonDocument doc; + char input[] = "[{}]"; + + JsonError err = deserializeJson(doc, input); + + REQUIRE(err == JsonError::Ok); + } + + SECTION("CharPtrNull") { + StaticJsonDocument<100> doc; + + JsonError err = deserializeJson(doc, static_cast(0)); + + REQUIRE(err != JsonError::Ok); + } + + SECTION("ConstCharPtrNull") { + StaticJsonDocument<100> doc; + + JsonError err = deserializeJson(doc, static_cast(0)); + + REQUIRE(err != JsonError::Ok); + } + + SECTION("CopyStringNotSpaces") { + StaticJsonDocument<100> doc; + + deserializeJson(doc, " [ \"1234567\" ] "); + + REQUIRE(JSON_ARRAY_SIZE(1) + sizeof("1234567") == doc.memoryUsage()); + // note: we use a string of 8 bytes to be sure that the StaticJsonBuffer + // will not insert bytes to enforce alignement + } + + SECTION("Should clear the JsonArray") { + StaticJsonDocument doc; + char input[] = "[1,2,3,4]"; + + deserializeJson(doc, input); + deserializeJson(doc, "[]"); + + JsonArray& arr = doc.as(); + REQUIRE(arr.size() == 0); + REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(0)); + } + + SECTION("Array") { + StaticJsonDocument doc; + char input[] = "[1,2]"; + + JsonError err = deserializeJson(doc, input); + JsonArray& arr = doc.as(); + + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); + REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(2)); + REQUIRE(arr[0] == 1); + REQUIRE(arr[1] == 2); + } +} diff --git a/test/JsonParser/DynamicJsonObject.cpp b/test/JsonDeserializer/deserializeJsonObject.cpp similarity index 52% rename from test/JsonParser/DynamicJsonObject.cpp rename to test/JsonDeserializer/deserializeJsonObject.cpp index 72e6d2c5..f44a8e05 100644 --- a/test/JsonParser/DynamicJsonObject.cpp +++ b/test/JsonDeserializer/deserializeJsonObject.cpp @@ -5,40 +5,55 @@ #include #include -TEST_CASE("deserializeJson(DynamicJsonObject&)") { - DynamicJsonObject obj; +TEST_CASE("deserialize JSON object") { + DynamicJsonDocument doc; SECTION("An empty object") { - JsonError err = deserializeJson(obj, "{}"); + JsonError err = deserializeJson(doc, "{}"); + JsonObject& obj = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); REQUIRE(obj.size() == 0); } SECTION("Quotes") { SECTION("Double quotes") { - JsonError err = deserializeJson(obj, "{\"key\":\"value\"}"); + JsonError err = deserializeJson(doc, "{\"key\":\"value\"}"); + JsonObject& obj = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("Single quotes") { - JsonError err = deserializeJson(obj, "{'key':'value'}"); + JsonError err = deserializeJson(doc, "{'key':'value'}"); + JsonObject& obj = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("No quotes") { - JsonError err = deserializeJson(obj, "{key:value}"); + JsonError err = deserializeJson(doc, "{key:value}"); + JsonObject& obj = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("No quotes, allow underscore in key") { - JsonError err = deserializeJson(obj, "{_k_e_y_:42}"); + JsonError err = deserializeJson(doc, "{_k_e_y_:42}"); + JsonObject& obj = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); REQUIRE(obj.size() == 1); REQUIRE(obj["_k_e_y_"] == 42); } @@ -46,37 +61,52 @@ TEST_CASE("deserializeJson(DynamicJsonObject&)") { SECTION("Spaces") { SECTION("Before the key") { - JsonError err = deserializeJson(obj, "{ \"key\":\"value\"}"); + JsonError err = deserializeJson(doc, "{ \"key\":\"value\"}"); + JsonObject& obj = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("After the key") { - JsonError err = deserializeJson(obj, "{\"key\" :\"value\"}"); + JsonError err = deserializeJson(doc, "{\"key\" :\"value\"}"); + JsonObject& obj = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("Before the value") { - JsonError err = deserializeJson(obj, "{\"key\": \"value\"}"); + JsonError err = deserializeJson(doc, "{\"key\": \"value\"}"); + JsonObject& obj = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("After the value") { - JsonError err = deserializeJson(obj, "{\"key\":\"value\" }"); + JsonError err = deserializeJson(doc, "{\"key\":\"value\" }"); + JsonObject& obj = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("Before the colon") { JsonError err = - deserializeJson(obj, "{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); + deserializeJson(doc, "{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); + JsonObject& obj = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); REQUIRE(obj.size() == 2); REQUIRE(obj["key1"] == "value1"); REQUIRE(obj["key2"] == "value2"); @@ -84,8 +114,11 @@ TEST_CASE("deserializeJson(DynamicJsonObject&)") { SECTION("After the colon") { JsonError err = - deserializeJson(obj, "{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); + deserializeJson(doc, "{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); + JsonObject& obj = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); REQUIRE(obj.size() == 2); REQUIRE(obj["key1"] == "value1"); REQUIRE(obj["key2"] == "value2"); @@ -95,53 +128,69 @@ TEST_CASE("deserializeJson(DynamicJsonObject&)") { SECTION("Values types") { SECTION("String") { JsonError err = - deserializeJson(obj, "{\"key1\":\"value1\",\"key2\":\"value2\"}"); + deserializeJson(doc, "{\"key1\":\"value1\",\"key2\":\"value2\"}"); + JsonObject& obj = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); REQUIRE(obj.size() == 2); REQUIRE(obj["key1"] == "value1"); REQUIRE(obj["key2"] == "value2"); } SECTION("Integer") { - JsonError err = deserializeJson(obj, "{\"key1\":42,\"key2\":-42}"); + JsonError err = deserializeJson(doc, "{\"key1\":42,\"key2\":-42}"); + JsonObject& obj = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); REQUIRE(obj.size() == 2); REQUIRE(obj["key1"] == 42); REQUIRE(obj["key2"] == -42); } SECTION("Double") { - JsonError err = deserializeJson(obj, "{\"key1\":12.345,\"key2\":-7E89}"); + JsonError err = deserializeJson(doc, "{\"key1\":12.345,\"key2\":-7E89}"); + JsonObject& obj = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); REQUIRE(obj.size() == 2); REQUIRE(obj["key1"] == 12.345); REQUIRE(obj["key2"] == -7E89); } SECTION("Booleans") { - JsonError err = deserializeJson(obj, "{\"key1\":true,\"key2\":false}"); + JsonError err = deserializeJson(doc, "{\"key1\":true,\"key2\":false}"); + JsonObject& obj = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); REQUIRE(obj.size() == 2); REQUIRE(obj["key1"] == true); REQUIRE(obj["key2"] == false); } SECTION("Null") { - JsonError err = deserializeJson(obj, "{\"key1\":null,\"key2\":null}"); + JsonError err = deserializeJson(doc, "{\"key1\":null,\"key2\":null}"); + JsonObject& obj = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); REQUIRE(obj.size() == 2); - REQUIRE(obj["key1"].as() == 0); - REQUIRE(obj["key2"].as() == 0); + REQUIRE(obj["key1"].as() == 0); + REQUIRE(obj["key2"].as() == 0); } SECTION("Array") { char jsonString[] = " { \"ab\" : [ 1 , 2 ] , \"cd\" : [ 3 , 4 ] } "; - JsonError err = deserializeJson(obj, jsonString); + JsonError err = deserializeJson(doc, jsonString); + JsonObject& obj = doc.as(); - JsonArray &array1 = obj["ab"]; - const JsonArray &array2 = obj["cd"]; - JsonArray &array3 = obj["ef"]; + JsonArray& array1 = obj["ab"]; + const JsonArray& array2 = obj["cd"]; + JsonArray& array3 = obj["ef"]; REQUIRE(err == JsonError::Ok); @@ -165,40 +214,49 @@ TEST_CASE("deserializeJson(DynamicJsonObject&)") { SECTION("Misc") { SECTION("The opening brace is missing") { - JsonError err = deserializeJson(obj, "}"); - REQUIRE(err == JsonError::OpeningBraceExpected); + JsonError err = deserializeJson(doc, "}"); + + REQUIRE(err == JsonError::InvalidInput); } SECTION("The closing brace is missing") { - JsonError err = deserializeJson(obj, "{\"hello\":\"world\""); - REQUIRE(err == JsonError::ClosingBraceExpected); + JsonError err = deserializeJson(doc, "{\"hello\":\"world\""); + + REQUIRE(err == JsonError::InvalidInput); } SECTION("A quoted key without value") { - JsonError err = deserializeJson(obj, "{\"key\"}"); - REQUIRE(err == JsonError::ColonExpected); + JsonError err = deserializeJson(doc, "{\"key\"}"); + + REQUIRE(err == JsonError::InvalidInput); } SECTION("A non-quoted key without value") { - JsonError err = deserializeJson(obj, "{key}"); - REQUIRE(err == JsonError::ColonExpected); + JsonError err = deserializeJson(doc, "{key}"); + + REQUIRE(err == JsonError::InvalidInput); } SECTION("A dangling comma") { - JsonError err = deserializeJson(obj, "{\"key1\":\"value1\",}"); - REQUIRE(err == JsonError::ColonExpected); + JsonError err = deserializeJson(doc, "{\"key1\":\"value1\",}"); + + REQUIRE(err == JsonError::InvalidInput); } SECTION("null as a key") { - JsonError err = deserializeJson(obj, "{null:\"value\"}"); + JsonError err = deserializeJson(doc, "{null:\"value\"}"); + REQUIRE(err == JsonError::Ok); } } SECTION("Should clear the JsonObject") { - deserializeJson(obj, "{\"hello\":\"world\"}"); - deserializeJson(obj, "{}"); + deserializeJson(doc, "{\"hello\":\"world\"}"); + deserializeJson(doc, "{}"); + JsonObject& obj = doc.as(); + + REQUIRE(doc.is()); REQUIRE(obj.size() == 0); - REQUIRE(obj.memoryUsage() == JSON_OBJECT_SIZE(0)); + REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(0)); } } diff --git a/test/JsonParser/StaticJsonObject.cpp b/test/JsonDeserializer/deserializeJsonObjectStatic.cpp similarity index 50% rename from test/JsonParser/StaticJsonObject.cpp rename to test/JsonDeserializer/deserializeJsonObjectStatic.cpp index 525f5184..ab44b2a1 100644 --- a/test/JsonParser/StaticJsonObject.cpp +++ b/test/JsonDeserializer/deserializeJsonObjectStatic.cpp @@ -5,76 +5,76 @@ #include #include -TEST_CASE("deserializeJson(StaticJsonObject&)") { +TEST_CASE("deserialize JSON object with StaticJsonDocument") { SECTION("BufferOfTheRightSizeForEmptyObject") { - StaticJsonObject obj; + StaticJsonDocument doc; char input[] = "{}"; - JsonError err = deserializeJson(obj, input); + JsonError err = deserializeJson(doc, input); REQUIRE(err == JsonError::Ok); } SECTION("TooSmallBufferForObjectWithOneValue") { - StaticJsonObject obj; + StaticJsonDocument doc; char input[] = "{\"a\":1}"; - JsonError err = deserializeJson(obj, input); + JsonError err = deserializeJson(doc, input); REQUIRE(err != JsonError::Ok); } SECTION("BufferOfTheRightSizeForObjectWithOneValue") { - StaticJsonObject obj; + StaticJsonDocument doc; char input[] = "{\"a\":1}"; - JsonError err = deserializeJson(obj, input); + JsonError err = deserializeJson(doc, input); REQUIRE(err == JsonError::Ok); } SECTION("TooSmallBufferForObjectWithNestedObject") { - StaticJsonObject obj; + StaticJsonDocument doc; char input[] = "{\"a\":[]}"; - JsonError err = deserializeJson(obj, input); + JsonError err = deserializeJson(doc, input); REQUIRE(err != JsonError::Ok); } SECTION("BufferOfTheRightSizeForObjectWithNestedObject") { - StaticJsonObject obj; + StaticJsonDocument doc; char input[] = "{\"a\":[]}"; - JsonError err = deserializeJson(obj, input); + JsonError err = deserializeJson(doc, input); REQUIRE(err == JsonError::Ok); } SECTION("CharPtrNull") { - StaticJsonObject<100> obj; + StaticJsonDocument<100> doc; - JsonError err = deserializeJson(obj, static_cast(0)); + JsonError err = deserializeJson(doc, static_cast(0)); REQUIRE(err != JsonError::Ok); } SECTION("ConstCharPtrNull") { - StaticJsonObject<100> obj; + StaticJsonDocument<100> doc; - JsonError err = deserializeJson(obj, static_cast(0)); + JsonError err = deserializeJson(doc, static_cast(0)); REQUIRE(err != JsonError::Ok); } SECTION("Should clear the JsonObject") { - StaticJsonObject obj; + StaticJsonDocument doc; char input[] = "{\"hello\":\"world\"}"; - deserializeJson(obj, input); - deserializeJson(obj, "{}"); + deserializeJson(doc, input); + deserializeJson(doc, "{}"); - REQUIRE(obj.size() == 0); - REQUIRE(obj.memoryUsage() == JSON_OBJECT_SIZE(0)); + REQUIRE(doc.as().size() == 0); + REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(0)); } } diff --git a/test/JsonDeserializer/deserializeJsonValue.cpp b/test/JsonDeserializer/deserializeJsonValue.cpp new file mode 100644 index 00000000..4d374d5c --- /dev/null +++ b/test/JsonDeserializer/deserializeJsonValue.cpp @@ -0,0 +1,103 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +using namespace Catch::Matchers; + +TEST_CASE("deserializeJson(DynamicJsonDocument&)") { + DynamicJsonDocument doc; + + SECTION("EmptyObject") { + JsonError err = deserializeJson(doc, "{}"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); + } + + SECTION("EmptyArray") { + JsonError err = deserializeJson(doc, "[]"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); + } + + SECTION("Integer") { + JsonError err = deserializeJson(doc, "-42"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); + REQUIRE_FALSE(doc.is()); + REQUIRE(doc.as() == -42); + } + + SECTION("Double") { + JsonError err = deserializeJson(doc, "-1.23e+4"); + + REQUIRE(err == JsonError::Ok); + REQUIRE_FALSE(doc.is()); + REQUIRE(doc.is()); + REQUIRE(doc.as() == Approx(-1.23e+4)); + } + + SECTION("Double quoted string") { + JsonError err = deserializeJson(doc, "\"hello world\""); + + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); + REQUIRE_THAT(doc.as(), Equals("hello world")); + } + + SECTION("Single quoted string") { + JsonError err = deserializeJson(doc, "\'hello world\'"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); + REQUIRE_THAT(doc.as(), Equals("hello world")); + } + + SECTION("True") { + JsonError err = deserializeJson(doc, "true"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); + REQUIRE(doc.as() == true); + } + + SECTION("False") { + JsonError err = deserializeJson(doc, "false"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); + REQUIRE(doc.as() == false); + } + + SECTION("OpenBrace") { + JsonError err = deserializeJson(doc, "{"); + + REQUIRE(err != JsonError::Ok); + } + + SECTION("Incomplete string") { + JsonError err = deserializeJson(doc, "\"hello"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); + REQUIRE_THAT(doc.as(), Equals("hello")); + } + + SECTION("Unterminated escape sequence") { + JsonError err = deserializeJson(doc, "\"\\\0\""); + REQUIRE(err == JsonError::InvalidInput); + } + + SECTION("Should clear the JsonVariant") { + deserializeJson(doc, "[1,2,3]"); + deserializeJson(doc, "{}"); + + REQUIRE(doc.is()); + REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(0)); + } +} diff --git a/test/JsonDeserializer/nestingLimit.cpp b/test/JsonDeserializer/nestingLimit.cpp new file mode 100644 index 00000000..0eecb4ff --- /dev/null +++ b/test/JsonDeserializer/nestingLimit.cpp @@ -0,0 +1,32 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +#define SHOULD_WORK(expression) REQUIRE(JsonError::Ok == expression); +#define SHOULD_FAIL(expression) REQUIRE(JsonError::TooDeep == expression); + +TEST_CASE("JsonDeserializer nestingLimit") { + DynamicJsonDocument doc; + + SECTION("limit = 0") { + SHOULD_WORK(deserializeJson(doc, "\"toto\"", 0)); + SHOULD_WORK(deserializeJson(doc, "123", 0)); + SHOULD_WORK(deserializeJson(doc, "true", 0)); + SHOULD_FAIL(deserializeJson(doc, "[]", 0)); + SHOULD_FAIL(deserializeJson(doc, "{}", 0)); + SHOULD_FAIL(deserializeJson(doc, "[\"toto\"]", 0)); + SHOULD_FAIL(deserializeJson(doc, "{\"toto\":1}", 0)); + } + + SECTION("limit = 1") { + SHOULD_WORK(deserializeJson(doc, "[\"toto\"]", 1)); + SHOULD_WORK(deserializeJson(doc, "{\"toto\":1}", 1)); + SHOULD_FAIL(deserializeJson(doc, "{\"toto\":{}}", 1)); + SHOULD_FAIL(deserializeJson(doc, "{\"toto\":[]}", 1)); + SHOULD_FAIL(deserializeJson(doc, "[[\"toto\"]]", 1)); + SHOULD_FAIL(deserializeJson(doc, "[{\"toto\":1}]", 1)); + } +} diff --git a/test/JsonObject/basics.cpp b/test/JsonObject/basics.cpp index a5e58458..6a9f4e6c 100644 --- a/test/JsonObject/basics.cpp +++ b/test/JsonObject/basics.cpp @@ -6,13 +6,10 @@ #include TEST_CASE("JsonObject basics") { - DynamicJsonObject _object; - - SECTION("InitialSizeIsZero") { - REQUIRE(0 == _object.size()); - } + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); SECTION("SuccessIsTrue") { - REQUIRE(_object.success()); + REQUIRE(obj.success()); } } diff --git a/test/JsonObject/containsKey.cpp b/test/JsonObject/containsKey.cpp index c28d11e0..71e22ad4 100644 --- a/test/JsonObject/containsKey.cpp +++ b/test/JsonObject/containsKey.cpp @@ -6,24 +6,25 @@ #include TEST_CASE("JsonObject::containsKey()") { - DynamicJsonObject _object; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); SECTION("ContainsKeyReturnsFalseForNonExistingKey") { - _object.set("hello", 42); + obj.set("hello", 42); - REQUIRE(false == _object.containsKey("world")); + REQUIRE(false == obj.containsKey("world")); } SECTION("ContainsKeyReturnsTrueForDefinedValue") { - _object.set("hello", 42); + obj.set("hello", 42); - REQUIRE(true == _object.containsKey("hello")); + REQUIRE(true == obj.containsKey("hello")); } SECTION("ContainsKeyReturnsFalseAfterRemove") { - _object.set("hello", 42); - _object.remove("hello"); + obj.set("hello", 42); + obj.remove("hello"); - REQUIRE(false == _object.containsKey("hello")); + REQUIRE(false == obj.containsKey("hello")); } } diff --git a/test/JsonObject/get.cpp b/test/JsonObject/get.cpp index d1fb8317..ec6ed4ea 100644 --- a/test/JsonObject/get.cpp +++ b/test/JsonObject/get.cpp @@ -8,7 +8,8 @@ using namespace Catch::Matchers; TEST_CASE("JsonObject::get()") { - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); SECTION("GetConstCharPointer_GivenStringLiteral") { obj.set("hello", "world"); diff --git a/test/JsonObject/iterator.cpp b/test/JsonObject/iterator.cpp index 661f27d8..306d1986 100644 --- a/test/JsonObject/iterator.cpp +++ b/test/JsonObject/iterator.cpp @@ -8,7 +8,8 @@ using namespace Catch::Matchers; TEST_CASE("JsonObject::begin()/end()") { - StaticJsonObject obj; + StaticJsonDocument doc; + JsonObject& obj = doc.to(); obj["ab"] = 12; obj["cd"] = 34; diff --git a/test/JsonObject/remove.cpp b/test/JsonObject/remove.cpp index 4048ebd5..395e6b50 100644 --- a/test/JsonObject/remove.cpp +++ b/test/JsonObject/remove.cpp @@ -7,7 +7,8 @@ #include TEST_CASE("JsonObject::remove()") { - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); SECTION("SizeDecreased_WhenValuesAreRemoved") { obj["hello"] = 1; @@ -26,7 +27,9 @@ TEST_CASE("JsonObject::remove()") { } SECTION("RemoveByIterator") { - deserializeJson(obj, "{\"a\":0,\"b\":1,\"c\":2}"); + obj["a"] = 0; + obj["b"] = 1; + obj["c"] = 2; for (JsonObject::iterator it = obj.begin(); it != obj.end(); ++it) { if (it->value == 1) obj.remove(it); diff --git a/test/JsonObject/set.cpp b/test/JsonObject/set.cpp index fbc32ee6..25406c9d 100644 --- a/test/JsonObject/set.cpp +++ b/test/JsonObject/set.cpp @@ -7,129 +7,136 @@ #include TEST_CASE("JsonObject::set()") { - DynamicJsonObject _object; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); SECTION("int") { - _object.set("hello", 123); + obj.set("hello", 123); - REQUIRE(123 == _object["hello"].as()); - REQUIRE(_object["hello"].is()); - REQUIRE_FALSE(_object["hello"].is()); + REQUIRE(123 == obj["hello"].as()); + REQUIRE(obj["hello"].is()); + REQUIRE_FALSE(obj["hello"].is()); } SECTION("double") { - _object.set("hello", 123.45); + obj.set("hello", 123.45); - REQUIRE(123.45 == _object["hello"].as()); - REQUIRE(_object["hello"].is()); - REQUIRE_FALSE(_object["hello"].is()); + REQUIRE(123.45 == obj["hello"].as()); + REQUIRE(obj["hello"].is()); + REQUIRE_FALSE(obj["hello"].is()); } SECTION("bool") { - _object.set("hello", true); + obj.set("hello", true); - REQUIRE(_object["hello"].as()); - REQUIRE(_object["hello"].is()); - REQUIRE_FALSE(_object["hello"].is()); + REQUIRE(obj["hello"].as()); + REQUIRE(obj["hello"].is()); + REQUIRE_FALSE(obj["hello"].is()); } SECTION("const char*") { - _object.set("hello", "h3110"); + obj.set("hello", "h3110"); - REQUIRE(std::string("h3110") == _object["hello"].as()); - REQUIRE(_object["hello"].is()); - REQUIRE_FALSE(_object["hello"].is()); + REQUIRE(std::string("h3110") == obj["hello"].as()); + REQUIRE(obj["hello"].is()); + REQUIRE_FALSE(obj["hello"].is()); } SECTION("nested array") { - DynamicJsonArray arr; + DynamicJsonDocument doc2; + JsonArray& arr = doc2.to(); - _object.set("hello", arr); + obj.set("hello", arr); - REQUIRE(&arr == &_object["hello"].as()); - REQUIRE(_object["hello"].is()); - REQUIRE_FALSE(_object["hello"].is()); + REQUIRE(&arr == &obj["hello"].as()); + REQUIRE(obj["hello"].is()); + REQUIRE_FALSE(obj["hello"].is()); } SECTION("nested object") { - DynamicJsonObject obj; + DynamicJsonDocument doc2; + JsonObject& obj2 = doc2.to(); - _object.set("hello", obj); + obj.set("hello", obj2); - REQUIRE(&obj == &_object["hello"].as()); - REQUIRE(_object["hello"].is()); - REQUIRE_FALSE(_object["hello"].is()); + REQUIRE(&obj2 == &obj["hello"].as()); + REQUIRE(obj["hello"].is()); + REQUIRE_FALSE(obj["hello"].is()); } SECTION("array subscript") { - DynamicJsonArray arr; + DynamicJsonDocument doc2; + JsonArray& arr = doc2.to(); arr.add(42); - _object.set("a", arr[0]); + obj.set("a", arr[0]); - REQUIRE(42 == _object["a"]); + REQUIRE(42 == obj["a"]); } SECTION("object subscript") { - DynamicJsonObject obj; - obj.set("x", 42); + DynamicJsonDocument doc2; + JsonObject& obj2 = doc2.to(); + obj2.set("x", 42); - _object.set("a", obj["x"]); + obj.set("a", obj2["x"]); - REQUIRE(42 == _object["a"]); + REQUIRE(42 == obj["a"]); } SECTION("returns true when allocation succeeds") { - StaticJsonObject obj; + StaticJsonDocument doc2; + JsonObject& obj2 = doc2.to(); - REQUIRE(true == obj.set(std::string("hello"), std::string("world"))); + REQUIRE(true == obj2.set(std::string("hello"), std::string("world"))); } SECTION("returns false when allocation fails") { - StaticJsonObject obj; + StaticJsonDocument doc2; + JsonObject& obj2 = doc2.to(); - REQUIRE(false == obj.set(std::string("hello"), std::string("world"))); + REQUIRE(false == obj2.set(std::string("hello"), std::string("world"))); } SECTION("should not duplicate const char*") { - _object.set("hello", "world"); + obj.set("hello", "world"); const size_t expectedSize = JSON_OBJECT_SIZE(1); - REQUIRE(expectedSize == _object.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should duplicate char* value") { - _object.set("hello", const_cast("world")); + obj.set("hello", const_cast("world")); const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; - REQUIRE(expectedSize == _object.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should duplicate char* key") { - _object.set(const_cast("hello"), "world"); + obj.set(const_cast("hello"), "world"); const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; - REQUIRE(expectedSize == _object.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should duplicate char* key&value") { - _object.set(const_cast("hello"), const_cast("world")); + obj.set(const_cast("hello"), const_cast("world")); const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12; - REQUIRE(expectedSize <= _object.memoryUsage()); + REQUIRE(expectedSize <= doc.memoryUsage()); } SECTION("should duplicate std::string value") { - _object.set("hello", std::string("world")); + obj.set("hello", std::string("world")); const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; - REQUIRE(expectedSize == _object.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should duplicate std::string key") { - _object.set(std::string("hello"), "world"); + obj.set(std::string("hello"), "world"); const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; - REQUIRE(expectedSize == _object.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should duplicate std::string key&value") { - _object.set(std::string("hello"), std::string("world")); + obj.set(std::string("hello"), std::string("world")); const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12; - REQUIRE(expectedSize <= _object.memoryUsage()); + REQUIRE(expectedSize <= doc.memoryUsage()); } } diff --git a/test/JsonObject/size.cpp b/test/JsonObject/size.cpp index ee3b413f..5f6f0f2a 100644 --- a/test/JsonObject/size.cpp +++ b/test/JsonObject/size.cpp @@ -7,16 +7,21 @@ #include TEST_CASE("JsonObject::size()") { - DynamicJsonObject _object; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); + + SECTION("initial size is zero") { + REQUIRE(0 == obj.size()); + } SECTION("increases when values are added") { - _object.set("hello", 42); - REQUIRE(1 == _object.size()); + obj.set("hello", 42); + REQUIRE(1 == obj.size()); } SECTION("doesn't increase when the smae key is added twice") { - _object["hello"] = 1; - _object["hello"] = 2; - REQUIRE(1 == _object.size()); + obj["hello"] = 1; + obj["hello"] = 2; + REQUIRE(1 == obj.size()); } } diff --git a/test/JsonObject/subscript.cpp b/test/JsonObject/subscript.cpp index aecfb0ce..1ac365cd 100644 --- a/test/JsonObject/subscript.cpp +++ b/test/JsonObject/subscript.cpp @@ -6,146 +6,150 @@ #include TEST_CASE("JsonObject::operator[]") { - DynamicJsonObject _object; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); SECTION("int") { - _object["hello"] = 123; + obj["hello"] = 123; - REQUIRE(123 == _object["hello"].as()); - REQUIRE(true == _object["hello"].is()); - REQUIRE(false == _object["hello"].is()); + REQUIRE(123 == obj["hello"].as()); + REQUIRE(true == obj["hello"].is()); + REQUIRE(false == obj["hello"].is()); } SECTION("volatile int") { // issue #415 volatile int i = 123; - _object["hello"] = i; + obj["hello"] = i; - REQUIRE(123 == _object["hello"].as()); - REQUIRE(true == _object["hello"].is()); - REQUIRE(false == _object["hello"].is()); + REQUIRE(123 == obj["hello"].as()); + REQUIRE(true == obj["hello"].is()); + REQUIRE(false == obj["hello"].is()); } SECTION("double") { - _object["hello"] = 123.45; + obj["hello"] = 123.45; - REQUIRE(true == _object["hello"].is()); - REQUIRE(false == _object["hello"].is()); - REQUIRE(123.45 == _object["hello"].as()); + REQUIRE(true == obj["hello"].is()); + REQUIRE(false == obj["hello"].is()); + REQUIRE(123.45 == obj["hello"].as()); } SECTION("bool") { - _object["hello"] = true; + obj["hello"] = true; - REQUIRE(true == _object["hello"].is()); - REQUIRE(false == _object["hello"].is()); - REQUIRE(true == _object["hello"].as()); + REQUIRE(true == obj["hello"].is()); + REQUIRE(false == obj["hello"].is()); + REQUIRE(true == obj["hello"].as()); } SECTION("const char*") { - _object["hello"] = "h3110"; + obj["hello"] = "h3110"; - REQUIRE(true == _object["hello"].is()); - REQUIRE(false == _object["hello"].is()); - REQUIRE(std::string("h3110") == _object["hello"].as()); - REQUIRE(std::string("h3110") == - _object["hello"].as()); // <- short hand + REQUIRE(true == obj["hello"].is()); + REQUIRE(false == obj["hello"].is()); + REQUIRE(std::string("h3110") == obj["hello"].as()); + REQUIRE(std::string("h3110") == obj["hello"].as()); // <- short hand } SECTION("array") { - DynamicJsonArray arr; + DynamicJsonDocument doc2; + JsonArray& arr = doc2.to(); - _object["hello"] = arr; + obj["hello"] = arr; - REQUIRE(&arr == &_object["hello"].as()); - REQUIRE(&arr == &_object["hello"].as()); // <- short hand - REQUIRE(&arr == &_object["hello"].as()); - REQUIRE(&arr == &_object["hello"].as()); // <- short hand - REQUIRE(true == _object["hello"].is()); - REQUIRE(true == _object["hello"].is()); - REQUIRE(true == _object["hello"].is()); - REQUIRE(true == _object["hello"].is()); - REQUIRE(false == _object["hello"].is()); + REQUIRE(&arr == &obj["hello"].as()); + REQUIRE(&arr == &obj["hello"].as()); // <- short hand + REQUIRE(&arr == &obj["hello"].as()); + REQUIRE(&arr == &obj["hello"].as()); // <- short hand + REQUIRE(true == obj["hello"].is()); + REQUIRE(true == obj["hello"].is()); + REQUIRE(true == obj["hello"].is()); + REQUIRE(true == obj["hello"].is()); + REQUIRE(false == obj["hello"].is()); } SECTION("object") { - DynamicJsonObject obj; + DynamicJsonDocument doc2; + JsonObject& obj2 = doc2.to(); - _object["hello"] = obj; + obj["hello"] = obj2; - REQUIRE(&obj == &_object["hello"].as()); - REQUIRE(&obj == &_object["hello"].as()); // <- short hand - REQUIRE(&obj == &_object["hello"].as()); - REQUIRE(&obj == &_object["hello"].as()); // <- short hand - REQUIRE(true == _object["hello"].is()); - REQUIRE(true == _object["hello"].is()); - REQUIRE(true == _object["hello"].is()); - REQUIRE(true == _object["hello"].is()); - REQUIRE(false == _object["hello"].is()); + REQUIRE(&obj2 == &obj["hello"].as()); + REQUIRE(&obj2 == &obj["hello"].as()); // <- short hand + REQUIRE(&obj2 == &obj["hello"].as()); + REQUIRE(&obj2 == &obj["hello"].as()); // <- short hand + REQUIRE(true == obj["hello"].is()); + REQUIRE(true == obj["hello"].is()); + REQUIRE(true == obj["hello"].is()); + REQUIRE(true == obj["hello"].is()); + REQUIRE(false == obj["hello"].is()); } SECTION("array subscript") { - DynamicJsonArray arr; + DynamicJsonDocument doc2; + JsonArray& arr = doc2.to(); arr.add(42); - _object["a"] = arr[0]; + obj["a"] = arr[0]; - REQUIRE(42 == _object["a"]); + REQUIRE(42 == obj["a"]); } SECTION("object subscript") { - DynamicJsonObject obj; - obj.set("x", 42); + DynamicJsonDocument doc2; + JsonObject& obj2 = doc2.to(); + obj2.set("x", 42); - _object["a"] = obj["x"]; + obj["a"] = obj2["x"]; - REQUIRE(42 == _object["a"]); + REQUIRE(42 == obj["a"]); } SECTION("char key[]") { // issue #423 char key[] = "hello"; - _object[key] = 42; - REQUIRE(42 == _object[key]); + obj[key] = 42; + REQUIRE(42 == obj[key]); } SECTION("should not duplicate const char*") { - _object["hello"] = "world"; + obj["hello"] = "world"; const size_t expectedSize = JSON_OBJECT_SIZE(1); - REQUIRE(expectedSize == _object.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should duplicate char* value") { - _object["hello"] = const_cast("world"); + obj["hello"] = const_cast("world"); const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; - REQUIRE(expectedSize == _object.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should duplicate char* key") { - _object[const_cast("hello")] = "world"; + obj[const_cast("hello")] = "world"; const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; - REQUIRE(expectedSize == _object.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should duplicate char* key&value") { - _object[const_cast("hello")] = const_cast("world"); + obj[const_cast("hello")] = const_cast("world"); const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12; - REQUIRE(expectedSize <= _object.memoryUsage()); + REQUIRE(expectedSize <= doc.memoryUsage()); } SECTION("should duplicate std::string value") { - _object["hello"] = std::string("world"); + obj["hello"] = std::string("world"); const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; - REQUIRE(expectedSize == _object.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should duplicate std::string key") { - _object[std::string("hello")] = "world"; + obj[std::string("hello")] = "world"; const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; - REQUIRE(expectedSize == _object.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should duplicate std::string key&value") { - _object[std::string("hello")] = std::string("world"); + obj[std::string("hello")] = std::string("world"); const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12; - REQUIRE(expectedSize <= _object.memoryUsage()); + REQUIRE(expectedSize <= doc.memoryUsage()); } } diff --git a/test/JsonParser/CMakeLists.txt b/test/JsonParser/CMakeLists.txt deleted file mode 100644 index 35f8e57c..00000000 --- a/test/JsonParser/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -# ArduinoJson - arduinojson.org -# Copyright Benoit Blanchon 2014-2018 -# MIT License - -add_executable(JsonParserTests - DynamicJsonArray.cpp - DynamicJsonObject.cpp - DynamicJsonVariant.cpp - JsonError.cpp - nestingLimit.cpp - StaticJsonArray.cpp - StaticJsonObject.cpp - StaticJsonVariant.cpp -) - -target_link_libraries(JsonParserTests catch) -add_test(JsonParser JsonParserTests) diff --git a/test/JsonParser/DynamicJsonVariant.cpp b/test/JsonParser/DynamicJsonVariant.cpp deleted file mode 100644 index 50449d9a..00000000 --- a/test/JsonParser/DynamicJsonVariant.cpp +++ /dev/null @@ -1,98 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#include -#include - -using namespace Catch::Matchers; - -TEST_CASE("deserializeJson(DynamicJsonVariant&)") { - DynamicJsonVariant variant; - - SECTION("EmptyObject") { - JsonError err = deserializeJson(variant, "{}"); - - REQUIRE(err == JsonError::Ok); - REQUIRE(variant.is()); - } - - SECTION("EmptyArray") { - JsonError err = deserializeJson(variant, "[]"); - - REQUIRE(err == JsonError::Ok); - REQUIRE(variant.is()); - } - - SECTION("Integer") { - JsonError err = deserializeJson(variant, "-42"); - - REQUIRE(err == JsonError::Ok); - REQUIRE(variant.is()); - REQUIRE_FALSE(variant.is()); - REQUIRE(variant == -42); - } - - SECTION("Double") { - JsonError err = deserializeJson(variant, "-1.23e+4"); - - REQUIRE(err == JsonError::Ok); - REQUIRE_FALSE(variant.is()); - REQUIRE(variant.is()); - REQUIRE(variant.as() == Approx(-1.23e+4)); - } - - SECTION("Double quoted string") { - JsonError err = deserializeJson(variant, "\"hello world\""); - - REQUIRE(err == JsonError::Ok); - REQUIRE(variant.is()); - REQUIRE_THAT(variant.as(), Equals("hello world")); - } - - SECTION("Single quoted string") { - JsonError err = deserializeJson(variant, "\'hello world\'"); - - REQUIRE(err == JsonError::Ok); - REQUIRE(variant.is()); - REQUIRE_THAT(variant.as(), Equals("hello world")); - } - - SECTION("True") { - JsonError err = deserializeJson(variant, "true"); - - REQUIRE(err == JsonError::Ok); - REQUIRE(variant.is()); - REQUIRE(variant == true); - } - - SECTION("False") { - JsonError err = deserializeJson(variant, "false"); - - REQUIRE(err == JsonError::Ok); - REQUIRE(variant.is()); - REQUIRE(variant == false); - } - - SECTION("OpenBrace") { - JsonError err = deserializeJson(variant, "{"); - - REQUIRE(err != JsonError::Ok); - } - - SECTION("Incomplete string") { - JsonError err = deserializeJson(variant, "\"hello"); - - REQUIRE(err == JsonError::Ok); - REQUIRE(variant.is()); - REQUIRE_THAT(variant.as(), Equals("hello")); - } - - SECTION("Should clear the JsonVariant") { - deserializeJson(variant, "[1,2,3]"); - deserializeJson(variant, "{}"); - - REQUIRE(variant.is()); - REQUIRE(variant.memoryUsage() == JSON_OBJECT_SIZE(0)); - } -} diff --git a/test/JsonParser/StaticJsonArray.cpp b/test/JsonParser/StaticJsonArray.cpp deleted file mode 100644 index 3a79749b..00000000 --- a/test/JsonParser/StaticJsonArray.cpp +++ /dev/null @@ -1,90 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#include -#include - -TEST_CASE("deserializeJson(StaticJsonArray&)") { - SECTION("BufferOfTheRightSizeForEmptyArray") { - StaticJsonArray arr; - char input[] = "[]"; - - JsonError err = deserializeJson(arr, input); - - REQUIRE(err == JsonError::Ok); - } - - SECTION("TooSmallBufferForArrayWithOneValue") { - StaticJsonArray arr; - char input[] = "[1]"; - - JsonError err = deserializeJson(arr, input); - - REQUIRE(err != JsonError::Ok); - } - - SECTION("BufferOfTheRightSizeForArrayWithOneValue") { - StaticJsonArray arr; - char input[] = "[1]"; - - JsonError err = deserializeJson(arr, input); - - REQUIRE(err == JsonError::Ok); - } - - SECTION("TooSmallBufferForArrayWithNestedObject") { - StaticJsonArray arr; - char input[] = "[{}]"; - - JsonError err = deserializeJson(arr, input); - - REQUIRE(err != JsonError::Ok); - } - - SECTION("BufferOfTheRightSizeForArrayWithNestedObject") { - StaticJsonArray arr; - char input[] = "[{}]"; - - JsonError err = deserializeJson(arr, input); - - REQUIRE(err == JsonError::Ok); - } - - SECTION("CharPtrNull") { - StaticJsonArray<100> arr; - - JsonError err = deserializeJson(arr, static_cast(0)); - - REQUIRE(err != JsonError::Ok); - } - - SECTION("ConstCharPtrNull") { - StaticJsonArray<100> arr; - - JsonError err = deserializeJson(arr, static_cast(0)); - - REQUIRE(err != JsonError::Ok); - } - - SECTION("CopyStringNotSpaces") { - StaticJsonArray<100> arr; - - deserializeJson(arr, " [ \"1234567\" ] "); - - REQUIRE(JSON_ARRAY_SIZE(1) + sizeof("1234567") == arr.memoryUsage()); - // note: we use a string of 8 bytes to be sure that the StaticJsonBuffer - // will not insert bytes to enforce alignement - } - - SECTION("Should clear the JsonArray") { - StaticJsonArray arr; - char input[] = "[1,2,3,4]"; - - deserializeJson(arr, input); - deserializeJson(arr, "[]"); - - REQUIRE(arr.size() == 0); - REQUIRE(arr.memoryUsage() == JSON_ARRAY_SIZE(0)); - } -} diff --git a/test/JsonParser/StaticJsonVariant.cpp b/test/JsonParser/StaticJsonVariant.cpp deleted file mode 100644 index a3fba6e1..00000000 --- a/test/JsonParser/StaticJsonVariant.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#include -#include - -using namespace Catch::Matchers; - -TEST_CASE("deserializeJson(StaticJsonVariant&)") { - SECTION("Array") { - StaticJsonVariant variant; - - char input[] = "[1,2]"; - JsonError err = deserializeJson(variant, input); - - REQUIRE(err == JsonError::Ok); - REQUIRE(variant.is()); - REQUIRE(variant[0] == 1); - REQUIRE(variant[1] == 2); - REQUIRE(variant.memoryUsage() == JSON_ARRAY_SIZE(2)); - } - - SECTION("Should clear the JsonVariant") { - StaticJsonVariant variant; - char input[] = "[1,2]"; - deserializeJson(variant, input); - - JsonError err = deserializeJson(variant, "{}"); - - REQUIRE(err == JsonError::Ok); - REQUIRE(variant.is()); - REQUIRE(variant.memoryUsage() == JSON_OBJECT_SIZE(0)); - } -} diff --git a/test/JsonParser/nestingLimit.cpp b/test/JsonParser/nestingLimit.cpp deleted file mode 100644 index 74148956..00000000 --- a/test/JsonParser/nestingLimit.cpp +++ /dev/null @@ -1,70 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#include -#include - -#define SHOULD_WORK(expression) REQUIRE(JsonError::Ok == expression); -#define SHOULD_FAIL(expression) REQUIRE(JsonError::TooDeep == expression); - -TEST_CASE("JsonParser nestingLimit") { - SECTION("deserializeJson(JsonArray&)") { - DynamicJsonArray arr; - - SECTION("limit = 0") { - SHOULD_FAIL(deserializeJson(arr, "[]", 0)); - } - - SECTION("limit = 1") { - SHOULD_WORK(deserializeJson(arr, "[]", 1)); - SHOULD_FAIL(deserializeJson(arr, "[[]]", 1)); - } - - SECTION("limit = 2") { - SHOULD_WORK(deserializeJson(arr, "[[]]", 2)); - SHOULD_FAIL(deserializeJson(arr, "[[[]]]", 2)); - } - } - - SECTION("deserializeJson(JsonObject&)") { - DynamicJsonObject obj; - - SECTION("limit = 0") { - SHOULD_FAIL(deserializeJson(obj, "{}", 0)); - } - - SECTION("limit = 1") { - SHOULD_WORK(deserializeJson(obj, "{\"key\":42}", 1)); - SHOULD_FAIL(deserializeJson(obj, "{\"key\":{\"key\":42}}", 1)); - } - - SECTION("limit = 2") { - SHOULD_WORK(deserializeJson(obj, "{\"key\":{\"key\":42}}", 2)); - SHOULD_FAIL(deserializeJson(obj, "{\"key\":{\"key\":{\"key\":42}}}", 2)); - } - } - - SECTION("deserializeJson(JsonVariant&)") { - DynamicJsonVariant var; - - SECTION("limit = 0") { - SHOULD_WORK(deserializeJson(var, "\"toto\"", 0)); - SHOULD_WORK(deserializeJson(var, "123", 0)); - SHOULD_WORK(deserializeJson(var, "true", 0)); - SHOULD_FAIL(deserializeJson(var, "[]", 0)); - SHOULD_FAIL(deserializeJson(var, "{}", 0)); - SHOULD_FAIL(deserializeJson(var, "[\"toto\"]", 0)); - SHOULD_FAIL(deserializeJson(var, "{\"toto\":1}", 0)); - } - - SECTION("limit = 1") { - SHOULD_WORK(deserializeJson(var, "[\"toto\"]", 1)); - SHOULD_WORK(deserializeJson(var, "{\"toto\":1}", 1)); - SHOULD_FAIL(deserializeJson(var, "{\"toto\":{}}", 1)); - SHOULD_FAIL(deserializeJson(var, "{\"toto\":[]}", 1)); - SHOULD_FAIL(deserializeJson(var, "[[\"toto\"]]", 1)); - SHOULD_FAIL(deserializeJson(var, "[{\"toto\":1}]", 1)); - } - } -} diff --git a/test/JsonSerializer/JsonArray.cpp b/test/JsonSerializer/JsonArray.cpp index ced91238..1556b495 100644 --- a/test/JsonSerializer/JsonArray.cpp +++ b/test/JsonSerializer/JsonArray.cpp @@ -15,7 +15,8 @@ static void check(JsonArray &array, std::string expected) { } TEST_CASE("serializeJson(JsonArray)") { - StaticJsonArray array; + StaticJsonDocument doc; + JsonArray &array = doc.to(); SECTION("Empty") { check(array, "[]"); diff --git a/test/JsonSerializer/JsonArrayPretty.cpp b/test/JsonSerializer/JsonArrayPretty.cpp index 4785d643..fc3af2e4 100644 --- a/test/JsonSerializer/JsonArrayPretty.cpp +++ b/test/JsonSerializer/JsonArrayPretty.cpp @@ -15,7 +15,8 @@ static void check(JsonArray& array, std::string expected) { } TEST_CASE("serializeJsonPretty(JsonArray)") { - DynamicJsonArray array; + DynamicJsonDocument doc; + JsonArray& array = doc.to(); SECTION("Empty") { check(array, "[]"); diff --git a/test/JsonSerializer/JsonObject.cpp b/test/JsonSerializer/JsonObject.cpp index 25476928..3674b1b8 100644 --- a/test/JsonSerializer/JsonObject.cpp +++ b/test/JsonSerializer/JsonObject.cpp @@ -17,7 +17,8 @@ void check(const JsonObject &obj, const std::string &expected) { } TEST_CASE("serializeJson(JsonObject)") { - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject &obj = doc.to(); SECTION("EmptyObject") { check(obj, "{}"); @@ -92,22 +93,23 @@ TEST_CASE("serializeJson(JsonObject)") { } SECTION("ThreeNestedArrays") { - DynamicJsonArray b, c; + DynamicJsonDocument b; + DynamicJsonDocument c; obj.createNestedArray("a"); - obj["b"] = b; - obj.set("c", c); + obj["b"] = b.to(); + obj.set("c", c.to()); check(obj, "{\"a\":[],\"b\":[],\"c\":[]}"); } SECTION("ThreeNestedObjects") { - DynamicJsonObject b; - DynamicJsonObject c; + DynamicJsonDocument b; + DynamicJsonDocument c; obj.createNestedObject("a"); - obj["b"] = b; - obj.set("c", c); + obj["b"] = b.to(); + obj.set("c", c.to()); check(obj, "{\"a\":{},\"b\":{},\"c\":{}}"); } diff --git a/test/JsonSerializer/JsonObjectPretty.cpp b/test/JsonSerializer/JsonObjectPretty.cpp index efcc947e..ec3ef14b 100644 --- a/test/JsonSerializer/JsonObjectPretty.cpp +++ b/test/JsonSerializer/JsonObjectPretty.cpp @@ -18,7 +18,8 @@ void check(const JsonObject &obj, const std::string expected) { } TEST_CASE("serializeJsonPretty(JsonObject)") { - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject &obj = doc.to(); SECTION("EmptyObject") { check(obj, "{}"); diff --git a/test/JsonVariant/as.cpp b/test/JsonVariant/as.cpp index bf03b1b6..8254b101 100644 --- a/test/JsonVariant/as.cpp +++ b/test/JsonVariant/as.cpp @@ -192,7 +192,8 @@ TEST_CASE("JsonVariant::as()") { } SECTION("ObjectAsString") { - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); obj["key"] = "value"; @@ -201,7 +202,8 @@ TEST_CASE("JsonVariant::as()") { } SECTION("ArrayAsString") { - DynamicJsonArray arr; + DynamicJsonDocument doc; + JsonArray& arr = doc.to(); arr.add(4); arr.add(2); @@ -210,7 +212,8 @@ TEST_CASE("JsonVariant::as()") { } SECTION("ArrayAsJsonArray") { - DynamicJsonArray arr; + DynamicJsonDocument doc; + JsonArray& arr = doc.to(); JsonVariant variant = arr; REQUIRE(&arr == &variant.as()); @@ -218,7 +221,8 @@ TEST_CASE("JsonVariant::as()") { } SECTION("ObjectAsJsonObject") { - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); JsonVariant variant = obj; REQUIRE(&obj == &variant.as()); diff --git a/test/JsonVariant/compare.cpp b/test/JsonVariant/compare.cpp index 0364ec44..85010a5e 100644 --- a/test/JsonVariant/compare.cpp +++ b/test/JsonVariant/compare.cpp @@ -97,8 +97,9 @@ TEST_CASE("JsonVariant comparisons") { } SECTION("StringLiteral") { - DynamicJsonVariant variant; - deserializeJson(variant, "\"hello\""); + DynamicJsonDocument doc; + deserializeJson(doc, "\"hello\""); + JsonVariant variant = doc.as(); REQUIRE(variant == "hello"); REQUIRE_FALSE(variant != "hello"); @@ -114,8 +115,7 @@ TEST_CASE("JsonVariant comparisons") { } SECTION("String") { - DynamicJsonVariant variant; - deserializeJson(variant, "\"hello\""); + JsonVariant variant = "hello"; REQUIRE(variant == std::string("hello")); REQUIRE_FALSE(variant != std::string("hello")); @@ -179,7 +179,10 @@ TEST_CASE("JsonVariant comparisons") { } SECTION("ArrayInVariant") { - DynamicJsonArray array1, array2; + DynamicJsonDocument doc1; + JsonArray& array1 = doc1.to(); + DynamicJsonDocument doc2; + JsonArray& array2 = doc2.to(); JsonVariant variant1 = array1; JsonVariant variant2 = array1; @@ -193,8 +196,10 @@ TEST_CASE("JsonVariant comparisons") { } SECTION("ObjectInVariant") { - DynamicJsonObject obj1; - DynamicJsonObject obj2; + DynamicJsonDocument doc1; + JsonObject& obj1 = doc1.to(); + DynamicJsonDocument doc2; + JsonObject& obj2 = doc2.to(); JsonVariant variant1 = obj1; JsonVariant variant2 = obj1; @@ -208,8 +213,11 @@ TEST_CASE("JsonVariant comparisons") { } SECTION("VariantsOfDifferentTypes") { - DynamicJsonObject obj; - DynamicJsonArray arr; + DynamicJsonDocument doc1; + JsonObject& obj = doc1.to(); + + DynamicJsonDocument doc2; + JsonArray& arr = doc2.to(); JsonVariant variants[] = { true, 42, 666.667, "hello", arr, obj, }; diff --git a/test/JsonVariant/copy.cpp b/test/JsonVariant/copy.cpp index ebd8b90b..d894f607 100644 --- a/test/JsonVariant/copy.cpp +++ b/test/JsonVariant/copy.cpp @@ -38,11 +38,12 @@ TEST_CASE("JsonVariant copy") { _variant2 = _variant1; _variant1 = "world"; - REQUIRE(std::string("hello") == _variant2.as()); + REQUIRE(std::string("hello") == _variant2.as()); } SECTION("ObjectsAreCopiedByReference") { - DynamicJsonObject object; + DynamicJsonDocument doc; + JsonObject& object = doc.to(); _variant1 = object; @@ -52,7 +53,8 @@ TEST_CASE("JsonVariant copy") { } SECTION("ArraysAreCopiedByReference") { - DynamicJsonArray array; + DynamicJsonDocument doc; + JsonArray& array = doc.to(); _variant1 = array; diff --git a/test/JsonVariant/is.cpp b/test/JsonVariant/is.cpp index 7ecfdcdf..d5776553 100644 --- a/test/JsonVariant/is.cpp +++ b/test/JsonVariant/is.cpp @@ -69,10 +69,9 @@ void checkIsString(JsonVariant var) { } TEST_CASE("JsonVariant::is()") { - DynamicJsonBuffer jsonBuffer; - SECTION("JsonArray") { - DynamicJsonArray array; + DynamicJsonDocument doc; + JsonArray& array = doc.to(); checkIsArray(array); } diff --git a/test/JsonVariant/set_get.cpp b/test/JsonVariant/set_get.cpp index ef6a09a9..b63775ba 100644 --- a/test/JsonVariant/set_get.cpp +++ b/test/JsonVariant/set_get.cpp @@ -122,7 +122,8 @@ TEST_CASE("JsonVariant set()/get()") { #endif SECTION("CanStoreObject") { - DynamicJsonObject object; + DynamicJsonDocument doc; + JsonObject &object = doc.to(); checkReference(object); } diff --git a/test/JsonVariant/subscript.cpp b/test/JsonVariant/subscript.cpp index 122ba47c..72783292 100644 --- a/test/JsonVariant/subscript.cpp +++ b/test/JsonVariant/subscript.cpp @@ -7,7 +7,8 @@ TEST_CASE("JsonVariant::operator[]") { SECTION("Array") { - DynamicJsonArray array; + DynamicJsonDocument doc; + JsonArray& array = doc.to(); array.add("element at index 0"); array.add("element at index 1"); @@ -24,7 +25,8 @@ TEST_CASE("JsonVariant::operator[]") { } SECTION("Object") { - DynamicJsonObject object; + DynamicJsonDocument doc; + JsonObject& object = doc.to(); object["a"] = "element at key \"a\""; object["b"] = "element at key \"b\""; @@ -52,7 +54,8 @@ TEST_CASE("JsonVariant::operator[]") { } SECTION("ObjectSetValue") { - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); JsonVariant var = obj; var["hello"] = "world"; REQUIRE(1 == var.size()); @@ -60,16 +63,19 @@ TEST_CASE("JsonVariant::operator[]") { } SECTION("ArraySetValue") { - DynamicJsonVariant var; - deserializeJson(var, "[\"hello\"]"); + DynamicJsonDocument doc; + JsonArray& arr = doc.to(); + arr.add("hello"); + JsonVariant var = arr; var[0] = "world"; REQUIRE(1 == var.size()); REQUIRE(std::string("world") == var[0]); } SECTION("NestedObjectSetValue") { - DynamicJsonVariant var; - deserializeJson(var, "[{}]"); + DynamicJsonDocument doc; + deserializeJson(doc, "[{}]"); + JsonVariant var = doc.as(); var[0]["hello"] = "world"; REQUIRE(1 == var.size()); REQUIRE(1 == var[0].size()); diff --git a/test/JsonVariant/success.cpp b/test/JsonVariant/success.cpp index a06fbf23..ecef9ac5 100644 --- a/test/JsonVariant/success.cpp +++ b/test/JsonVariant/success.cpp @@ -17,14 +17,16 @@ TEST_CASE("JsonVariant::success()") { } SECTION("ReturnsTrue_WhenEmptyArray") { - DynamicJsonArray array; + DynamicJsonDocument doc; + JsonArray& array = doc.to(); JsonVariant variant = array; REQUIRE(true == variant.success()); } SECTION("ReturnsTrue_WhenEmptyObject") { - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); JsonVariant variant = obj; REQUIRE(true == variant.success()); diff --git a/test/Misc/std_stream.cpp b/test/Misc/std_stream.cpp index b2b171a3..5ac6701f 100644 --- a/test/Misc/std_stream.cpp +++ b/test/Misc/std_stream.cpp @@ -23,7 +23,8 @@ TEST_CASE("std::stream") { SECTION("JsonObject") { std::ostringstream os; - DynamicJsonObject object; + DynamicJsonDocument doc; + JsonObject& object = doc.to(); object["key"] = "value"; os << object; REQUIRE("{\"key\":\"value\"}" == os.str()); @@ -31,7 +32,8 @@ TEST_CASE("std::stream") { SECTION("JsonObjectSubscript") { std::ostringstream os; - DynamicJsonObject object; + DynamicJsonDocument doc; + JsonObject& object = doc.to(); object["key"] = "value"; os << object["key"]; REQUIRE("\"value\"" == os.str()); @@ -39,7 +41,8 @@ TEST_CASE("std::stream") { SECTION("JsonArray") { std::ostringstream os; - DynamicJsonArray array; + DynamicJsonDocument doc; + JsonArray& array = doc.to(); array.add("value"); os << array; REQUIRE("[\"value\"]" == os.str()); @@ -47,7 +50,8 @@ TEST_CASE("std::stream") { SECTION("JsonArraySubscript") { std::ostringstream os; - DynamicJsonArray array; + DynamicJsonDocument doc; + JsonArray& array = doc.to(); array.add("value"); os << array[0]; REQUIRE("\"value\"" == os.str()); @@ -55,8 +59,9 @@ TEST_CASE("std::stream") { SECTION("ParseArray") { std::istringstream json(" [ 42 /* comment */ ] "); - DynamicJsonArray arr; - JsonError err = deserializeJson(arr, json); + DynamicJsonDocument doc; + JsonError err = deserializeJson(doc, json); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(1 == arr.size()); @@ -65,8 +70,9 @@ TEST_CASE("std::stream") { SECTION("ParseObject") { std::istringstream json(" { hello : world // comment\n }"); - DynamicJsonObject obj; - JsonError err = deserializeJson(obj, json); + DynamicJsonDocument doc; + JsonError err = deserializeJson(doc, json); + JsonObject& obj = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(1 == obj.size()); @@ -75,8 +81,8 @@ TEST_CASE("std::stream") { SECTION("ShouldNotReadPastTheEnd") { std::istringstream json("{}123"); - DynamicJsonObject obj; - deserializeJson(obj, json); + DynamicJsonDocument doc; + deserializeJson(doc, json); REQUIRE('1' == json.get()); } } diff --git a/test/Misc/std_string.cpp b/test/Misc/std_string.cpp index 9e58e0f1..4765f707 100644 --- a/test/Misc/std_string.cpp +++ b/test/Misc/std_string.cpp @@ -11,20 +11,21 @@ static void eraseString(std::string &str) { } TEST_CASE("std::string") { - DynamicJsonBuffer jb; + SECTION("deserializeJson duplicates content") { + std::string json("[\"hello\"]"); + + DynamicJsonDocument doc; + JsonError err = deserializeJson(doc, json); + eraseString(json); + + JsonArray &array = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(std::string("hello") == array[0]); + } SECTION("JsonArray") { - DynamicJsonArray array; - - SECTION("deserializeJson") { - std::string json("[\"hello\"]"); - - JsonError err = deserializeJson(array, json); - eraseString(json); - - REQUIRE(err == JsonError::Ok); - REQUIRE(std::string("hello") == array[0]); - } + DynamicJsonDocument doc; + JsonArray &array = doc.to(); SECTION("add()") { std::string value("hello"); @@ -67,168 +68,190 @@ TEST_CASE("std::string") { } SECTION("JsonObject") { - DynamicJsonObject object; + DynamicJsonDocument doc; SECTION("deserializeJson()") { std::string json("{\"hello\":\"world\"}"); - JsonError err = deserializeJson(object, json); + JsonError err = deserializeJson(doc, json); + JsonObject &obj = doc.as(); eraseString(json); REQUIRE(err == JsonError::Ok); - REQUIRE(std::string("world") == object["hello"]); + REQUIRE(std::string("world") == obj["hello"]); } SECTION("operator[]") { char json[] = "{\"key\":\"value\"}"; - deserializeJson(object, json); + deserializeJson(doc, json); + JsonObject &obj = doc.as(); - REQUIRE(std::string("value") == object[std::string("key")]); + REQUIRE(std::string("value") == obj[std::string("key")]); } SECTION("operator[] const") { char json[] = "{\"key\":\"value\"}"; - deserializeJson(object, json); - const JsonObject &obj = object; + deserializeJson(doc, json); + JsonObject &obj = doc.as(); REQUIRE(std::string("value") == obj[std::string("key")]); } SECTION("set(key)") { + JsonObject &obj = doc.to(); std::string key("hello"); - object.set(key, "world"); + obj.set(key, "world"); eraseString(key); - REQUIRE(std::string("world") == object["hello"]); + REQUIRE(std::string("world") == obj["hello"]); } SECTION("set(value)") { + JsonObject &obj = doc.to(); std::string value("world"); - object.set("hello", value); + obj.set("hello", value); eraseString(value); - REQUIRE(std::string("world") == object["hello"]); + REQUIRE(std::string("world") == obj["hello"]); } SECTION("set(key,value)") { + JsonObject &obj = doc.to(); std::string key("hello"); std::string value("world"); - object.set(key, value); + obj.set(key, value); eraseString(key); eraseString(value); - REQUIRE(std::string("world") == object["hello"]); + REQUIRE(std::string("world") == obj["hello"]); } SECTION("set(JsonArraySubscript)") { - DynamicJsonArray arr; + JsonObject &obj = doc.to(); + DynamicJsonDocument doc2; + JsonArray &arr = doc2.to(); arr.add("world"); - object.set(std::string("hello"), arr[0]); + obj.set(std::string("hello"), arr[0]); - REQUIRE(std::string("world") == object["hello"]); + REQUIRE(std::string("world") == obj["hello"]); } SECTION("set(JsonObjectSubscript)") { - DynamicJsonObject obj; - obj.set("x", "world"); + JsonObject &obj = doc.to(); + DynamicJsonDocument doc2; + JsonObject &obj2 = doc2.to(); + obj2.set("x", "world"); - object.set(std::string("hello"), obj["x"]); + obj.set(std::string("hello"), obj2["x"]); - REQUIRE(std::string("world") == object["hello"]); + REQUIRE(std::string("world") == obj["hello"]); } SECTION("get()") { char json[] = "{\"key\":\"value\"}"; - deserializeJson(object, json); + deserializeJson(doc, json); + JsonObject &obj = doc.as(); REQUIRE(std::string("value") == - object.get(std::string("key"))); + obj.get(std::string("key"))); } SECTION("is()") { char json[] = "{\"key\":\"value\"}"; - deserializeJson(object, json); - REQUIRE(true == object.is(std::string("key"))); + deserializeJson(doc, json); + JsonObject &obj = doc.as(); + + REQUIRE(true == obj.is(std::string("key"))); } SECTION("createNestedObject()") { + JsonObject &obj = doc.to(); std::string key = "key"; char json[64]; - object.createNestedObject(key); + obj.createNestedObject(key); eraseString(key); - serializeJson(object, json, sizeof(json)); + serializeJson(doc, json, sizeof(json)); REQUIRE(std::string("{\"key\":{}}") == json); } SECTION("createNestedArray()") { + JsonObject &obj = doc.to(); std::string key = "key"; char json[64]; - object.createNestedArray(key); + obj.createNestedArray(key); eraseString(key); - serializeJson(object, json, sizeof(json)); + serializeJson(doc, json, sizeof(json)); REQUIRE(std::string("{\"key\":[]}") == json); } SECTION("containsKey()") { char json[] = "{\"key\":\"value\"}"; - deserializeJson(object, json); - REQUIRE(true == object.containsKey(std::string("key"))); + deserializeJson(doc, json); + JsonObject &obj = doc.as(); + REQUIRE(true == obj.containsKey(std::string("key"))); } SECTION("remove()") { - char json[] = "{\"key\":\"value\"}"; - deserializeJson(object, json); - REQUIRE(1 == object.size()); - object.remove(std::string("key")); - REQUIRE(0 == object.size()); + JsonObject &obj = doc.to(); + obj["key"] = "value"; + + obj.remove(std::string("key")); + + REQUIRE(0 == obj.size()); } SECTION("operator[], set key") { std::string key("hello"); - object[key] = "world"; + JsonObject &obj = doc.to(); + obj[key] = "world"; eraseString(key); - REQUIRE(std::string("world") == object["hello"]); + REQUIRE(std::string("world") == obj["hello"]); } SECTION("operator[], set value") { std::string value("world"); - object["hello"] = value; + JsonObject &obj = doc.to(); + obj["hello"] = value; eraseString(value); - REQUIRE(std::string("world") == object["hello"]); + REQUIRE(std::string("world") == obj["hello"]); } SECTION("serializeJson()") { - object["key"] = "value"; + JsonObject &obj = doc.to(); + obj["key"] = "value"; std::string json; - serializeJson(object, json); + serializeJson(doc, json); REQUIRE(std::string("{\"key\":\"value\"}") == json); } SECTION("serializeJsonPretty()") { - object["key"] = "value"; + JsonObject &obj = doc.to(); + obj["key"] = "value"; std::string json; - serializeJsonPretty(object, json); + serializeJsonPretty(doc, json); REQUIRE(std::string("{\r\n \"key\": \"value\"\r\n}") == json); } SECTION("memoryUsage() increases when adding a new key") { std::string key1("hello"), key2("world"); + JsonObject &obj = doc.to(); - object[key1] = 1; - size_t sizeBefore = object.memoryUsage(); - object[key2] = 2; - size_t sizeAfter = object.memoryUsage(); + obj[key1] = 1; + size_t sizeBefore = doc.memoryUsage(); + obj[key2] = 2; + size_t sizeAfter = doc.memoryUsage(); REQUIRE(sizeAfter - sizeBefore >= key2.size()); } SECTION("memoryUsage() remains when adding the same key") { std::string key("hello"); + JsonObject &obj = doc.to(); - object[key] = 1; - size_t sizeBefore = object.memoryUsage(); - object[key] = 2; - size_t sizeAfter = object.memoryUsage(); + obj[key] = 1; + size_t sizeBefore = doc.memoryUsage(); + obj[key] = 2; + size_t sizeAfter = doc.memoryUsage(); REQUIRE(sizeBefore == sizeAfter); } diff --git a/test/Misc/unsigned_char.cpp b/test/Misc/unsigned_char.cpp index 23752b9e..87f3cab6 100644 --- a/test/Misc/unsigned_char.cpp +++ b/test/Misc/unsigned_char.cpp @@ -13,8 +13,8 @@ TEST_CASE("unsigned char string") { SECTION("JsonBuffer::parseArray") { unsigned char json[] = "[42]"; - StaticJsonArray arr; - JsonError err = deserializeJson(arr, json); + StaticJsonDocument doc; + JsonError err = deserializeJson(doc, json); REQUIRE(err == JsonError::Ok); } @@ -22,8 +22,8 @@ TEST_CASE("unsigned char string") { SECTION("JsonBuffer::parseObject") { unsigned char json[] = "{\"a\":42}"; - StaticJsonObject obj; - JsonError err = deserializeJson(obj, json); + StaticJsonDocument doc; + JsonError err = deserializeJson(doc, json); REQUIRE(err == JsonError::Ok); } @@ -49,8 +49,9 @@ TEST_CASE("unsigned char string") { SECTION("JsonVariant::operator[]") { unsigned char key[] = "hello"; - DynamicJsonVariant variant; - deserializeJson(variant, "{\"hello\":\"world\"}"); + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + JsonVariant variant = doc.as(); REQUIRE(std::string("world") == variant[key]); } @@ -60,8 +61,9 @@ TEST_CASE("unsigned char string") { SECTION("JsonVariant::operator[] const") { unsigned char key[] = "hello"; - DynamicJsonVariant variant; - deserializeJson(variant, "{\"hello\":\"world\"}"); + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + const JsonVariant variant = doc.as(); REQUIRE(std::string("world") == variant[key]); } @@ -70,7 +72,7 @@ TEST_CASE("unsigned char string") { SECTION("JsonVariant::operator==") { unsigned char comparand[] = "hello"; - DynamicJsonVariant variant; + JsonVariant variant; variant = "hello"; REQUIRE(comparand == variant); @@ -82,7 +84,7 @@ TEST_CASE("unsigned char string") { SECTION("JsonVariant::operator!=") { unsigned char comparand[] = "hello"; - DynamicJsonVariant variant; + JsonVariant variant; variant = "world"; REQUIRE(comparand != variant); @@ -95,7 +97,8 @@ TEST_CASE("unsigned char string") { SECTION("JsonObject::operator[]") { unsigned char key[] = "hello"; - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); obj[key] = "world"; REQUIRE(std::string("world") == obj["hello"]); @@ -105,7 +108,8 @@ TEST_CASE("unsigned char string") { SECTION("JsonObjectSubscript::operator=") { // issue #416 unsigned char value[] = "world"; - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); obj["hello"] = value; REQUIRE(std::string("world") == obj["hello"]); @@ -114,7 +118,8 @@ TEST_CASE("unsigned char string") { SECTION("JsonObjectSubscript::set()") { unsigned char value[] = "world"; - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); obj["hello"].set(value); REQUIRE(std::string("world") == obj["hello"]); @@ -124,9 +129,10 @@ TEST_CASE("unsigned char string") { SECTION("JsonObject::operator[] const") { unsigned char key[] = "hello"; - DynamicJsonObject obj; - deserializeJson(obj, "{\"hello\":\"world\"}"); + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + JsonObject& obj = doc.as(); REQUIRE(std::string("world") == obj[key]); } #endif @@ -134,16 +140,17 @@ TEST_CASE("unsigned char string") { SECTION("JsonObject::get()") { unsigned char key[] = "hello"; - DynamicJsonObject obj; - deserializeJson(obj, "{\"hello\":\"world\"}"); - + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + JsonObject& obj = doc.as(); REQUIRE(std::string("world") == obj.get(key)); } SECTION("JsonObject::set() key") { unsigned char key[] = "hello"; - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); obj.set(key, "world"); REQUIRE(std::string("world") == obj["hello"]); @@ -152,7 +159,8 @@ TEST_CASE("unsigned char string") { SECTION("JsonObject::set() value") { unsigned char value[] = "world"; - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); obj.set("hello", value); REQUIRE(std::string("world") == obj["hello"]); @@ -161,7 +169,8 @@ TEST_CASE("unsigned char string") { SECTION("JsonObject::set key&value") { unsigned char key[] = "world"; - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); obj.set(key, key); REQUIRE(std::string("world") == obj["world"]); @@ -170,17 +179,18 @@ TEST_CASE("unsigned char string") { SECTION("JsonObject::containsKey()") { unsigned char key[] = "hello"; - DynamicJsonObject obj; - deserializeJson(obj, "{\"hello\":\"world\"}"); - + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + JsonObject& obj = doc.as(); REQUIRE(true == obj.containsKey(key)); } SECTION("JsonObject::remove()") { unsigned char key[] = "hello"; - DynamicJsonObject obj; - deserializeJson(obj, "{\"hello\":\"world\"}"); + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + JsonObject& obj = doc.as(); obj.remove(key); REQUIRE(0 == obj.size()); @@ -189,8 +199,9 @@ TEST_CASE("unsigned char string") { SECTION("JsonObject::is()") { unsigned char key[] = "hello"; - DynamicJsonObject obj; - deserializeJson(obj, "{\"hello\":42}"); + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":42}"); + JsonObject& obj = doc.as(); REQUIRE(true == obj.is(key)); } @@ -198,21 +209,24 @@ TEST_CASE("unsigned char string") { SECTION("JsonObject::createNestedArray()") { unsigned char key[] = "hello"; - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); obj.createNestedArray(key); } SECTION("JsonObject::createNestedObject()") { unsigned char key[] = "hello"; - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); obj.createNestedObject(key); } SECTION("JsonArray::add()") { unsigned char value[] = "world"; - DynamicJsonArray arr; + DynamicJsonDocument doc; + JsonArray& arr = doc.to(); arr.add(value); REQUIRE(std::string("world") == arr[0]); @@ -221,7 +235,8 @@ TEST_CASE("unsigned char string") { SECTION("JsonArray::set()") { unsigned char value[] = "world"; - DynamicJsonArray arr; + DynamicJsonDocument doc; + JsonArray& arr = doc.to(); arr.add("hello"); arr.set(0, value); @@ -231,7 +246,8 @@ TEST_CASE("unsigned char string") { SECTION("JsonArraySubscript::set()") { unsigned char value[] = "world"; - DynamicJsonArray arr; + DynamicJsonDocument doc; + JsonArray& arr = doc.to(); arr.add("hello"); arr[0].set(value); @@ -241,7 +257,8 @@ TEST_CASE("unsigned char string") { SECTION("JsonArraySubscript::operator=") { unsigned char value[] = "world"; - DynamicJsonArray arr; + DynamicJsonDocument doc; + JsonArray& arr = doc.to(); arr.add("hello"); arr[0] = value; diff --git a/test/Misc/vla.cpp b/test/Misc/vla.cpp index 98a110d3..2fd84453 100644 --- a/test/Misc/vla.cpp +++ b/test/Misc/vla.cpp @@ -22,8 +22,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "[42]"); - StaticJsonArray arr; - JsonError err = deserializeJson(arr, vla); + StaticJsonDocument doc; + JsonError err = deserializeJson(doc, vla); REQUIRE(err == JsonError::Ok); } @@ -33,10 +33,10 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "{\"a\":42}"); - StaticJsonObject obj; - deserializeJson(obj, vla); + StaticJsonDocument doc; + JsonError error = deserializeJson(doc, vla); - REQUIRE(true == obj.success()); + REQUIRE(error == JsonError::Ok); } SECTION("Parse") { @@ -44,7 +44,7 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "42"); - StaticJsonVariant<> variant; + StaticJsonDocument<> variant; deserializeJson(variant, vla); REQUIRE(42 == variant.as()); @@ -77,8 +77,9 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonVariant variant; - deserializeJson(variant, "{\"hello\":\"world\"}"); + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + JsonVariant variant = doc.as(); REQUIRE(std::string("world") == variant[vla]); } @@ -90,8 +91,9 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonVariant variant; - deserializeJson(variant, "{\"hello\":\"world\"}"); + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + const JsonVariant variant = doc.as(); REQUIRE(std::string("world") == variant[vla]); } @@ -102,7 +104,7 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonVariant variant; + JsonVariant variant; variant = "hello"; REQUIRE((vla == variant)); @@ -116,7 +118,7 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonVariant variant; + JsonVariant variant; variant = "world"; REQUIRE((vla != variant)); @@ -131,7 +133,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); obj[vla] = "world"; REQUIRE(std::string("world") == obj["hello"]); @@ -143,7 +146,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "world"); - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); obj["hello"] = vla; REQUIRE(std::string("world") == obj["hello"].as()); @@ -154,7 +158,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "world"); - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); obj["hello"].set(vla); REQUIRE(std::string("world") == obj["hello"].as()); @@ -166,9 +171,10 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonObject obj; - deserializeJson(obj, "{\"hello\":\"world\"}"); + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + JsonObject& obj = doc.as(); REQUIRE(std::string("world") == obj[vla]); } #endif @@ -178,9 +184,10 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonObject obj; - deserializeJson(obj, "{\"hello\":\"world\"}"); + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + JsonObject& obj = doc.as(); REQUIRE(std::string("world") == obj.get(vla)); } @@ -189,7 +196,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); obj.set(vla, "world"); REQUIRE(std::string("world") == obj["hello"]); @@ -200,7 +208,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "world"); - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); obj.set("hello", vla); REQUIRE(std::string("world") == obj["hello"]); @@ -211,7 +220,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "world"); - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); obj.set(vla, vla); REQUIRE(std::string("world") == obj["world"]); @@ -222,9 +232,10 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonObject obj; - deserializeJson(obj, "{\"hello\":\"world\"}"); + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + JsonObject& obj = doc.as(); REQUIRE(true == obj.containsKey(vla)); } @@ -233,8 +244,9 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonObject obj; - deserializeJson(obj, "{\"hello\":\"world\"}"); + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + JsonObject& obj = doc.as(); obj.remove(vla); REQUIRE(0 == obj.size()); @@ -245,8 +257,9 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonObject obj; - deserializeJson(obj, "{\"hello\":42}"); + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":42}"); + JsonObject& obj = doc.as(); REQUIRE(true == obj.is(vla)); } @@ -256,7 +269,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); obj.createNestedArray(vla); } @@ -265,7 +279,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); obj.createNestedObject(vla); } @@ -274,7 +289,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "world"); - DynamicJsonArray arr; + DynamicJsonDocument doc; + JsonArray& arr = doc.to(); arr.add(vla); REQUIRE(std::string("world") == arr[0]); @@ -285,7 +301,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "world"); - DynamicJsonArray arr; + DynamicJsonDocument doc; + JsonArray& arr = doc.to(); arr.add("hello"); arr.set(0, vla); @@ -297,7 +314,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "world"); - DynamicJsonArray arr; + DynamicJsonDocument doc; + JsonArray& arr = doc.to(); arr.add("hello"); arr[0].set(vla); @@ -309,7 +327,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "world"); - DynamicJsonArray arr; + DynamicJsonDocument doc; + JsonArray& arr = doc.to(); arr.add("hello"); arr[0] = vla; diff --git a/test/MsgPack/MsgPackError.cpp b/test/MsgPack/MsgPackError.cpp index 8de7c79a..3f070260 100644 --- a/test/MsgPack/MsgPackError.cpp +++ b/test/MsgPack/MsgPackError.cpp @@ -24,8 +24,6 @@ TEST_CASE("MsgPackError") { TEST_STRINGIFICATION(Ok); TEST_STRINGIFICATION(NotSupported); TEST_STRINGIFICATION(NoMemory); - TEST_STRINGIFICATION(NotAnArray); - TEST_STRINGIFICATION(NotAnObject); TEST_STRINGIFICATION(TooDeep); } @@ -33,8 +31,12 @@ TEST_CASE("MsgPackError") { TEST_BOOLIFICATION(Ok, false); TEST_BOOLIFICATION(NotSupported, true); TEST_BOOLIFICATION(NoMemory, true); - TEST_BOOLIFICATION(NotAnArray, true); - TEST_BOOLIFICATION(NotAnObject, true); TEST_BOOLIFICATION(TooDeep, true); } + + SECTION("ostream") { + std::stringstream s; + s << MsgPackError::NotSupported; + REQUIRE(s.str() == "NotSupported"); + } } diff --git a/test/MsgPack/deserializationErrors.cpp b/test/MsgPack/deserializationErrors.cpp index 8483674b..c9e0e94e 100644 --- a/test/MsgPack/deserializationErrors.cpp +++ b/test/MsgPack/deserializationErrors.cpp @@ -7,7 +7,7 @@ static void check(const char* input, MsgPackError expected, uint8_t nestingLimit = 10) { - DynamicJsonVariant variant; + DynamicJsonDocument variant; MsgPackError error = deserializeMsgPack(variant, input, nestingLimit); diff --git a/test/MsgPack/deserializeArray.cpp b/test/MsgPack/deserializeArray.cpp index a0c492d6..c1b8beed 100644 --- a/test/MsgPack/deserializeArray.cpp +++ b/test/MsgPack/deserializeArray.cpp @@ -6,21 +6,14 @@ #include TEST_CASE("deserializeMsgPack(JsonArray&)") { - DynamicJsonArray array; - - SECTION("not an array") { - const char* input = "\xA0"; - - MsgPackError error = deserializeMsgPack(array, input); - - REQUIRE(error == MsgPackError::NotAnArray); - } + DynamicJsonDocument doc; SECTION("fixarray") { SECTION("empty") { const char* input = "\x90"; - MsgPackError error = deserializeMsgPack(array, input); + MsgPackError error = deserializeMsgPack(doc, input); + JsonArray& array = doc.as(); REQUIRE(error == MsgPackError::Ok); REQUIRE(array.size() == 0); @@ -29,7 +22,8 @@ TEST_CASE("deserializeMsgPack(JsonArray&)") { SECTION("two integers") { const char* input = "\x92\x01\x02"; - MsgPackError error = deserializeMsgPack(array, input); + MsgPackError error = deserializeMsgPack(doc, input); + JsonArray& array = doc.as(); REQUIRE(error == MsgPackError::Ok); REQUIRE(array.size() == 2); @@ -42,7 +36,8 @@ TEST_CASE("deserializeMsgPack(JsonArray&)") { SECTION("empty") { const char* input = "\xDC\x00\x00"; - MsgPackError error = deserializeMsgPack(array, input); + MsgPackError error = deserializeMsgPack(doc, input); + JsonArray& array = doc.as(); REQUIRE(error == MsgPackError::Ok); REQUIRE(array.size() == 0); @@ -51,7 +46,8 @@ TEST_CASE("deserializeMsgPack(JsonArray&)") { SECTION("two strings") { const char* input = "\xDC\x00\x02\xA5hello\xA5world"; - MsgPackError error = deserializeMsgPack(array, input); + MsgPackError error = deserializeMsgPack(doc, input); + JsonArray& array = doc.as(); REQUIRE(error == MsgPackError::Ok); REQUIRE(array.size() == 2); @@ -64,7 +60,8 @@ TEST_CASE("deserializeMsgPack(JsonArray&)") { SECTION("empty") { const char* input = "\xDD\x00\x00\x00\x00"; - MsgPackError error = deserializeMsgPack(array, input); + MsgPackError error = deserializeMsgPack(doc, input); + JsonArray& array = doc.as(); REQUIRE(error == MsgPackError::Ok); REQUIRE(array.size() == 0); @@ -74,7 +71,8 @@ TEST_CASE("deserializeMsgPack(JsonArray&)") { const char* input = "\xDD\x00\x00\x00\x02\xCA\x00\x00\x00\x00\xCA\x40\x48\xF5\xC3"; - MsgPackError error = deserializeMsgPack(array, input); + MsgPackError error = deserializeMsgPack(doc, input); + JsonArray& array = doc.as(); REQUIRE(error == MsgPackError::Ok); REQUIRE(array.size() == 2); diff --git a/test/MsgPack/deserializeObject.cpp b/test/MsgPack/deserializeObject.cpp index 508b93bc..9557a28e 100644 --- a/test/MsgPack/deserializeObject.cpp +++ b/test/MsgPack/deserializeObject.cpp @@ -5,36 +5,32 @@ #include #include -TEST_CASE("deserializeMsgPack(JsonObject&)") { - DynamicJsonObject object; - - SECTION("not an object") { - const char* input = "\xA0"; - - MsgPackError error = deserializeMsgPack(object, input); - - REQUIRE(error == MsgPackError::NotAnObject); - } +TEST_CASE("deserialize MsgPack object") { + DynamicJsonDocument doc; SECTION("fixmap") { SECTION("empty") { const char* input = "\x80"; - MsgPackError error = deserializeMsgPack(object, input); + MsgPackError error = deserializeMsgPack(doc, input); + JsonObject& obj = doc.as(); REQUIRE(error == MsgPackError::Ok); - REQUIRE(object.size() == 0); + REQUIRE(doc.is()); + REQUIRE(obj.size() == 0); } SECTION("two integers") { const char* input = "\x82\xA3one\x01\xA3two\x02"; - MsgPackError error = deserializeMsgPack(object, input); + MsgPackError error = deserializeMsgPack(doc, input); + JsonObject& obj = doc.as(); REQUIRE(error == MsgPackError::Ok); - REQUIRE(object.size() == 2); - REQUIRE(object["one"] == 1); - REQUIRE(object["two"] == 2); + REQUIRE(doc.is()); + REQUIRE(obj.size() == 2); + REQUIRE(obj["one"] == 1); + REQUIRE(obj["two"] == 2); } } @@ -42,21 +38,25 @@ TEST_CASE("deserializeMsgPack(JsonObject&)") { SECTION("empty") { const char* input = "\xDE\x00\x00"; - MsgPackError error = deserializeMsgPack(object, input); + MsgPackError error = deserializeMsgPack(doc, input); + JsonObject& obj = doc.as(); REQUIRE(error == MsgPackError::Ok); - REQUIRE(object.size() == 0); + REQUIRE(doc.is()); + REQUIRE(obj.size() == 0); } SECTION("two strings") { const char* input = "\xDE\x00\x02\xA1H\xA5hello\xA1W\xA5world"; - MsgPackError error = deserializeMsgPack(object, input); + MsgPackError error = deserializeMsgPack(doc, input); + JsonObject& obj = doc.as(); REQUIRE(error == MsgPackError::Ok); - REQUIRE(object.size() == 2); - REQUIRE(object["H"] == "hello"); - REQUIRE(object["W"] == "world"); + REQUIRE(doc.is()); + REQUIRE(obj.size() == 2); + REQUIRE(obj["H"] == "hello"); + REQUIRE(obj["W"] == "world"); } } @@ -64,10 +64,12 @@ TEST_CASE("deserializeMsgPack(JsonObject&)") { SECTION("empty") { const char* input = "\xDF\x00\x00\x00\x00"; - MsgPackError error = deserializeMsgPack(object, input); + MsgPackError error = deserializeMsgPack(doc, input); + JsonObject& obj = doc.as(); REQUIRE(error == MsgPackError::Ok); - REQUIRE(object.size() == 0); + REQUIRE(doc.is()); + REQUIRE(obj.size() == 0); } SECTION("two floats") { @@ -75,12 +77,14 @@ TEST_CASE("deserializeMsgPack(JsonObject&)") { "\xDF\x00\x00\x00\x02\xA4zero\xCA\x00\x00\x00\x00\xA2pi\xCA\x40\x48" "\xF5\xC3"; - MsgPackError error = deserializeMsgPack(object, input); + MsgPackError error = deserializeMsgPack(doc, input); + JsonObject& obj = doc.as(); REQUIRE(error == MsgPackError::Ok); - REQUIRE(object.size() == 2); - REQUIRE(object["zero"] == 0.0f); - REQUIRE(object["pi"] == 3.14f); + REQUIRE(doc.is()); + REQUIRE(obj.size() == 2); + REQUIRE(obj["zero"] == 0.0f); + REQUIRE(obj["pi"] == 3.14f); } } } diff --git a/test/MsgPack/deserializeStaticVariant.cpp b/test/MsgPack/deserializeStaticVariant.cpp index 01ceb21d..f4eb831c 100644 --- a/test/MsgPack/deserializeStaticVariant.cpp +++ b/test/MsgPack/deserializeStaticVariant.cpp @@ -9,14 +9,14 @@ static const size_t epsilon = sizeof(void*); template static void check(const char* input, MsgPackError expected) { - StaticJsonVariant variant; + StaticJsonDocument variant; MsgPackError error = deserializeMsgPack(variant, input); REQUIRE(error == expected); } -TEST_CASE("deserializeMsgPack(StaticJsonVariant&)") { +TEST_CASE("deserializeMsgPack(StaticJsonDocument&)") { SECTION("single values always fit") { check<0>("\xc0", MsgPackError::Ok); // nil check<0>("\xc2", MsgPackError::Ok); // false @@ -82,15 +82,14 @@ TEST_CASE("deserializeMsgPack(StaticJsonVariant&)") { check("\x80", MsgPackError::Ok); } SECTION("{H:1}") { - check("\x81\xA1H\x01", - MsgPackError::NoMemory); + check("\x81\xA1H\x01", MsgPackError::NoMemory); check("\x81\xA1H\x01", MsgPackError::Ok); } SECTION("{H:1,W:2}") { check("\x82\xA1H\x01\xA1W\x02", - MsgPackError::NoMemory); - check("\x82\xA1H\x01\xA1W\x02", - MsgPackError::Ok); + MsgPackError::NoMemory); + check("\x82\xA1H\x01\xA1W\x02", + MsgPackError::Ok); } } @@ -101,13 +100,14 @@ TEST_CASE("deserializeMsgPack(StaticJsonVariant&)") { SECTION("{H:1}") { check("\xDE\x00\x01\xA1H\x01", MsgPackError::NoMemory); - check("\xDE\x00\x01\xA1H\x01", MsgPackError::Ok); + check("\xDE\x00\x01\xA1H\x01", + MsgPackError::Ok); } SECTION("{H:1,W:2}") { check("\xDE\x00\x02\xA1H\x01\xA1W\x02", - MsgPackError::NoMemory); - check("\xDE\x00\x02\xA1H\x01\xA1W\x02", - MsgPackError::Ok); + MsgPackError::NoMemory); + check("\xDE\x00\x02\xA1H\x01\xA1W\x02", + MsgPackError::Ok); } } @@ -119,13 +119,13 @@ TEST_CASE("deserializeMsgPack(StaticJsonVariant&)") { check("\xDF\x00\x00\x00\x01\xA1H\x01", MsgPackError::NoMemory); check("\xDF\x00\x00\x00\x01\xA1H\x01", - MsgPackError::Ok); + MsgPackError::Ok); } SECTION("{H:1,W:2}") { - check("\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02", - MsgPackError::NoMemory); - check("\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02", - MsgPackError::Ok); + check( + "\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02", MsgPackError::NoMemory); + check( + "\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02", MsgPackError::Ok); } } } diff --git a/test/MsgPack/deserializeVariant.cpp b/test/MsgPack/deserializeVariant.cpp index f25ed897..25c32c32 100644 --- a/test/MsgPack/deserializeVariant.cpp +++ b/test/MsgPack/deserializeVariant.cpp @@ -7,7 +7,7 @@ template static void check(const char* input, U expected) { - DynamicJsonVariant variant; + DynamicJsonDocument variant; MsgPackError error = deserializeMsgPack(variant, input); @@ -127,151 +127,4 @@ TEST_CASE("deserializeMsgPack(JsonVariant&)") { SECTION("str 32") { check("\xdb\x00\x00\x00\x05hello", std::string("hello")); } - - SECTION("fixarray") { - DynamicJsonVariant variant; - - SECTION("empty") { - const char* input = "\x90"; - - MsgPackError error = deserializeMsgPack(variant, input); - - REQUIRE(error == MsgPackError::Ok); - REQUIRE(variant.size() == 0); - } - - SECTION("two integers") { - const char* input = "\x92\x01\x02"; - - MsgPackError error = deserializeMsgPack(variant, input); - - REQUIRE(error == MsgPackError::Ok); - REQUIRE(variant.size() == 2); - REQUIRE(variant[0] == 1); - REQUIRE(variant[1] == 2); - } - } - - SECTION("array 16") { - DynamicJsonVariant variant; - - SECTION("empty") { - const char* input = "\xDC\x00\x00"; - - MsgPackError error = deserializeMsgPack(variant, input); - - REQUIRE(error == MsgPackError::Ok); - REQUIRE(variant.size() == 0); - } - - SECTION("two strings") { - const char* input = "\xDC\x00\x02\xA5hello\xA5world"; - - MsgPackError error = deserializeMsgPack(variant, input); - - REQUIRE(error == MsgPackError::Ok); - REQUIRE(variant.size() == 2); - REQUIRE(variant[0] == "hello"); - REQUIRE(variant[1] == "world"); - } - } - - SECTION("array 32") { - DynamicJsonVariant variant; - - SECTION("empty") { - const char* input = "\xDD\x00\x00\x00\x00"; - - MsgPackError error = deserializeMsgPack(variant, input); - - REQUIRE(error == MsgPackError::Ok); - REQUIRE(variant.size() == 0); - } - - SECTION("two floats") { - const char* input = - "\xDD\x00\x00\x00\x02\xCA\x00\x00\x00\x00\xCA\x40\x48\xF5\xC3"; - - MsgPackError error = deserializeMsgPack(variant, input); - - REQUIRE(error == MsgPackError::Ok); - REQUIRE(variant.size() == 2); - REQUIRE(variant[0] == 0.0f); - REQUIRE(variant[1] == 3.14f); - } - } - - SECTION("fixmap") { - DynamicJsonVariant variant; - - SECTION("empty") { - const char* input = "\x80"; - - MsgPackError error = deserializeMsgPack(variant, input); - - REQUIRE(error == MsgPackError::Ok); - REQUIRE(variant.size() == 0); - } - - SECTION("two integers") { - const char* input = "\x82\xA3one\x01\xA3two\x02"; - - MsgPackError error = deserializeMsgPack(variant, input); - - REQUIRE(error == MsgPackError::Ok); - REQUIRE(variant.size() == 2); - REQUIRE(variant["one"] == 1); - REQUIRE(variant["two"] == 2); - } - } - - SECTION("map 16") { - DynamicJsonVariant variant; - - SECTION("empty") { - const char* input = "\xDE\x00\x00"; - - MsgPackError error = deserializeMsgPack(variant, input); - - REQUIRE(error == MsgPackError::Ok); - REQUIRE(variant.size() == 0); - } - - SECTION("two strings") { - const char* input = "\xDE\x00\x02\xA1H\xA5hello\xA1W\xA5world"; - - MsgPackError error = deserializeMsgPack(variant, input); - - REQUIRE(error == MsgPackError::Ok); - REQUIRE(variant.size() == 2); - REQUIRE(variant["H"] == "hello"); - REQUIRE(variant["W"] == "world"); - } - } - - SECTION("map 32") { - DynamicJsonVariant variant; - - SECTION("empty") { - const char* input = "\xDF\x00\x00\x00\x00"; - - MsgPackError error = deserializeMsgPack(variant, input); - - REQUIRE(error == MsgPackError::Ok); - REQUIRE(variant.size() == 0); - } - - SECTION("two floats") { - const char* input = - "\xDF\x00\x00\x00\x02\xA4zero\xCA\x00\x00\x00\x00\xA2pi\xCA\x40\x48" - "\xF5\xC3"; - - MsgPackError error = deserializeMsgPack(variant, input); - - REQUIRE(error == MsgPackError::Ok); - REQUIRE(variant.size() == 2); - REQUIRE(variant["zero"] == 0.0f); - REQUIRE(variant["pi"] == 3.14f); - } - } } diff --git a/test/StaticJsonBuffer/alloc.cpp b/test/StaticJsonBuffer/alloc.cpp index 9141def8..13387185 100644 --- a/test/StaticJsonBuffer/alloc.cpp +++ b/test/StaticJsonBuffer/alloc.cpp @@ -2,9 +2,11 @@ // Copyright Benoit Blanchon 2014-2018 // MIT License -#include +#include #include +using namespace ArduinoJson::Internals; + static bool isAligned(void *ptr) { const size_t mask = sizeof(void *) - 1; size_t addr = reinterpret_cast(ptr); diff --git a/test/StaticJsonBuffer/size.cpp b/test/StaticJsonBuffer/size.cpp index 5ef76bf4..88b3dc20 100644 --- a/test/StaticJsonBuffer/size.cpp +++ b/test/StaticJsonBuffer/size.cpp @@ -2,9 +2,11 @@ // Copyright Benoit Blanchon 2014-2018 // MIT License -#include +#include #include +using namespace ArduinoJson::Internals; + TEST_CASE("StaticJsonBuffer::size()") { StaticJsonBuffer<64> buffer;