Don't use JsonBuffer to create or parse objects and arrays.

* Added DynamicJsonArray and StaticJsonArray
* Added DynamicJsonObject and StaticJsonObject
* Added DynamicJsonVariant and StaticJsonVariant
* Added deserializeJson()
* Removed JsonBuffer::parseArray(), parseObject() and parse()
* Removed JsonBuffer::createArray() and createObject()
This commit is contained in:
Benoit Blanchon
2018-02-26 16:05:16 +01:00
parent baf5adcf33
commit 7a2a64803a
89 changed files with 1612 additions and 1691 deletions

View File

@ -1,6 +1,59 @@
ArduinoJson: change log ArduinoJson: change log
======================= =======================
HEAD
----
* Added DynamicJsonArray and StaticJsonArray
* Added DynamicJsonObject and StaticJsonObject
* Added DynamicJsonVariant and StaticJsonVariant
* Added deserializeJson()
* Removed JsonBuffer::parseArray(), parseObject() and parse()
* Removed JsonBuffer::createArray() and createObject()
> ### BREAKING CHANGES
>
> #### Deserialization
>
> Old code:
>
> ```c++
> DynamicJsonBuffer jb;
> JsonObject& obj = jb.parseObject(json);
> if (obj.success()) {
>
> }
> ```
>
> New code:
>
> ```c++
> DynamicJsonObject obj;
> bool success = deserializeJson(obj, json);
> if (success) {
>
> }
> ```
>
> #### Serialization
>
> Old code:
>
> ```c++
> DynamicJsonBuffer jb;
> JsonObject& obj = jb.createObject();
> obj["key"] = "value";
> obj.printTo(Serial);
> ```
>
> New code:
>
> ```c++
> DynamicJsonObject obj;
> obj["key"] = "value";
> obj.printTo(Serial);
> ```
v5.13.1 v5.13.1
------- -------

View File

@ -59,9 +59,8 @@ Here is a program that parses a JSON document with ArduinoJson.
```c++ ```c++
char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}"; char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
StaticJsonBuffer<200> jsonBuffer; DynamicJsonObject root;
derserializeJson(root, json);
JsonObject& root = jsonBuffer.parseObject(json);
const char* sensor = root["sensor"]; const char* sensor = root["sensor"];
long time = root["time"]; long time = root["time"];
@ -76,9 +75,7 @@ See the [tutorial on arduinojson.org](https://arduinojson.org/doc/decoding/?utm_
Here is a program that generates a JSON document with ArduinoJson: Here is a program that generates a JSON document with ArduinoJson:
```c++ ```c++
StaticJsonBuffer<200> jsonBuffer; DynamicJsonObject root;
JsonObject& root = jsonBuffer.createObject();
root["sensor"] = "gps"; root["sensor"] = "gps";
root["time"] = 1351824120; root["time"] = 1351824120;

View File

@ -32,12 +32,12 @@ void loadConfiguration(const char *filename, Config &config) {
// Allocate the memory pool on the stack. // Allocate the memory pool on the stack.
// Don't forget to change the capacity to match your JSON document. // Don't forget to change the capacity to match your JSON document.
// Use arduinojson.org/assistant to compute the capacity. // Use arduinojson.org/assistant to compute the capacity.
StaticJsonBuffer<512> jsonBuffer; StaticJsonObject<512> root;
// Parse the root object // Parse the root object
JsonObject &root = jsonBuffer.parseObject(file); bool success = deserializeJson(root, file);
if (!root.success()) if (!success)
Serial.println(F("Failed to read file, using default configuration")); Serial.println(F("Failed to read file, using default configuration"));
// Copy values from the JsonObject to the Config // Copy values from the JsonObject to the Config
@ -65,10 +65,7 @@ void saveConfiguration(const char *filename, const Config &config) {
// Allocate the memory pool on the stack // Allocate the memory pool on the stack
// Don't forget to change the capacity to match your JSON document. // Don't forget to change the capacity to match your JSON document.
// Use https://arduinojson.org/assistant/ to compute the capacity. // Use https://arduinojson.org/assistant/ to compute the capacity.
StaticJsonBuffer<256> jsonBuffer; StaticJsonObject<256> root;
// Parse the root object
JsonObject &root = jsonBuffer.createObject();
// Set the values // Set the values
root["hostname"] = config.hostname; root["hostname"] = config.hostname;

View File

@ -11,24 +11,17 @@ void setup() {
Serial.begin(9600); Serial.begin(9600);
while (!Serial) continue; while (!Serial) continue;
// Memory pool for JSON object tree. // Root JSON object
// //
// Inside the brackets, 200 is the size of the pool in bytes. // 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. // Don't forget to change this value to match your JSON document.
// Use arduinojson.org/assistant to compute the capacity. // Use arduinojson.org/assistant to compute the capacity.
StaticJsonBuffer<200> jsonBuffer; StaticJsonObject<200> root;
// StaticJsonBuffer allocates memory on the stack, it can be // StaticJsonObject allocates memory on the stack, it can be
// replaced by DynamicJsonBuffer which allocates in the heap. // replaced by DynamicJsonObject which allocates in the heap.
// //
// DynamicJsonBuffer jsonBuffer(200); // DynamicJsonObject root(200);
// Create the 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.
JsonObject& root = jsonBuffer.createObject();
// Add values in the object // Add values in the object
// //

View File

@ -73,10 +73,10 @@ void setup() {
// Allocate JsonBuffer // Allocate JsonBuffer
// Use arduinojson.org/assistant to compute the capacity. // Use arduinojson.org/assistant to compute the capacity.
const size_t capacity = JSON_OBJECT_SIZE(3) + JSON_ARRAY_SIZE(2) + 60; const size_t capacity = JSON_OBJECT_SIZE(3) + JSON_ARRAY_SIZE(2) + 60;
DynamicJsonBuffer jsonBuffer(capacity); DynamicJsonObject root(capacity);
// Parse JSON object // Parse JSON object
JsonObject& root = jsonBuffer.parseObject(client); bool success = deserializeJson(root, client);
if (!root.success()) { if (!root.success()) {
Serial.println(F("Parsing failed!")); Serial.println(F("Parsing failed!"));
return; return;

View File

@ -11,17 +11,17 @@ void setup() {
Serial.begin(9600); Serial.begin(9600);
while (!Serial) continue; while (!Serial) continue;
// Memory pool for JSON object tree. // Root JSON object
// //
// Inside the brackets, 200 is the size of the pool in bytes. // 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. // Don't forget to change this value to match your JSON document.
// Use arduinojson.org/assistant to compute the capacity. // Use arduinojson.org/assistant to compute the capacity.
StaticJsonBuffer<200> jsonBuffer; StaticJsonObject<200> root;
// StaticJsonBuffer allocates memory on the stack, it can be // StaticJsonObject allocates memory on the stack, it can be
// replaced by DynamicJsonBuffer which allocates in the heap. // replaced by DynamicJsonObject which allocates in the heap.
// //
// DynamicJsonBuffer jsonBuffer(200); // DynamicJsonObject root(200);
// JSON input string. // JSON input string.
// //
@ -36,10 +36,10 @@ void setup() {
// It's a reference to the JsonObject, the actual bytes are inside the // It's a reference to the JsonObject, the actual bytes are inside the
// JsonBuffer with all the other nodes of the object tree. // JsonBuffer with all the other nodes of the object tree.
// Memory is freed when jsonBuffer goes out of scope. // Memory is freed when jsonBuffer goes out of scope.
JsonObject& root = jsonBuffer.parseObject(json); bool success = deserializeJson(root, json);
// Test if parsing succeeds. // Test if parsing succeeds.
if (!root.success()) { if (!success) {
Serial.println("parseObject() failed"); Serial.println("parseObject() failed");
return; return;
} }

View File

@ -51,12 +51,9 @@ void loop() {
// Read the request (we ignore the content in this example) // Read the request (we ignore the content in this example)
while (client.available()) client.read(); while (client.available()) client.read();
// Allocate JsonBuffer // Allocate the root JsonObject
// Use arduinojson.org/assistant to compute the capacity. // Use arduinojson.org/assistant to compute the capacity.
StaticJsonBuffer<500> jsonBuffer; StaticJsonObject<500> root;
// Create the root object
JsonObject& root = jsonBuffer.createObject();
// Create the "analog" array // Create the "analog" array
JsonArray& analogValues = root.createNestedArray("analog"); JsonArray& analogValues = root.createNestedArray("analog");

View File

@ -43,12 +43,9 @@ void setup() {
} }
void loop() { void loop() {
// Allocate JsonBuffer // Allocate the root JsonObject
// Use arduinojson.org/assistant to compute the capacity. // Use arduinojson.org/assistant to compute the capacity.
StaticJsonBuffer<500> jsonBuffer; StaticJsonObject<500> root;
// Create the root object
JsonObject& root = jsonBuffer.createObject();
// Create the "analog" array // Create the "analog" array
JsonArray& analogValues = root.createNestedArray("analog"); JsonArray& analogValues = root.createNestedArray("analog");

View File

@ -14,13 +14,12 @@
void setup() { void setup() {
#ifdef PROGMEM // <- check that Flash strings are supported #ifdef PROGMEM // <- check that Flash strings are supported
DynamicJsonBuffer jsonBuffer; DynamicJsonObject root;
// You can use a Flash String as your JSON input. // You can use a Flash String as your JSON input.
// WARNING: the content of the Flash String will be duplicated in the // WARNING: the content of the Flash String will be duplicated in the
// JsonBuffer. // JsonBuffer.
JsonObject& root = deserializeJson(root, F("{\"sensor\":\"gps\",\"time\":1351824120,"
jsonBuffer.parseObject(F("{\"sensor\":\"gps\",\"time\":1351824120,"
"\"data\":[48.756080,2.302038]}")); "\"data\":[48.756080,2.302038]}"));
// You can use a Flash String to get an element of a JsonObject // You can use a Flash String to get an element of a JsonObject

View File

@ -11,13 +11,13 @@
#include <ArduinoJson.h> #include <ArduinoJson.h>
void setup() { void setup() {
DynamicJsonBuffer jsonBuffer; DynamicJsonObject root;
// You can use a String as your JSON input. // You can use a String as your JSON input.
// WARNING: the content of the String will be duplicated in the JsonBuffer. // WARNING: the content of the String will be duplicated in the JsonBuffer.
String input = String input =
"{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}"; "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
JsonObject& root = jsonBuffer.parseObject(input); deserializeJson(root, input);
// You can use a String to get an element of a JsonObject // You can use a String to get an element of a JsonObject
// No duplication is done. // No duplication is done.

View File

@ -4,10 +4,8 @@ JsonVariant KEYWORD1
StaticJsonBuffer KEYWORD1 StaticJsonBuffer KEYWORD1
DynamicJsonBuffer KEYWORD1 DynamicJsonBuffer KEYWORD1
add KEYWORD2 add KEYWORD2
createArray KEYWORD2
createNestedArray KEYWORD2 createNestedArray KEYWORD2
createNestedObject KEYWORD2 createNestedObject KEYWORD2
createObject KEYWORD2
parseArray KEYWORD2 parseArray KEYWORD2
parseObject KEYWORD2 parseObject KEYWORD2
prettyPrintTo KEYWORD2 prettyPrintTo KEYWORD2

View File

@ -4,14 +4,18 @@
#pragma once #pragma once
#include "ArduinoJson/DynamicJsonArray.hpp"
#include "ArduinoJson/DynamicJsonBuffer.hpp" #include "ArduinoJson/DynamicJsonBuffer.hpp"
#include "ArduinoJson/JsonArray.hpp" #include "ArduinoJson/DynamicJsonObject.hpp"
#include "ArduinoJson/JsonObject.hpp" #include "ArduinoJson/DynamicJsonVariant.hpp"
#include "ArduinoJson/StaticJsonArray.hpp"
#include "ArduinoJson/StaticJsonBuffer.hpp" #include "ArduinoJson/StaticJsonBuffer.hpp"
#include "ArduinoJson/StaticJsonObject.hpp"
#include "ArduinoJson/StaticJsonVariant.hpp"
#include "ArduinoJson/deserializeJson.hpp"
#include "ArduinoJson/Deserialization/JsonParserImpl.hpp" #include "ArduinoJson/Deserialization/JsonParserImpl.hpp"
#include "ArduinoJson/JsonArrayImpl.hpp" #include "ArduinoJson/JsonArrayImpl.hpp"
#include "ArduinoJson/JsonBufferImpl.hpp"
#include "ArduinoJson/JsonObjectImpl.hpp" #include "ArduinoJson/JsonObjectImpl.hpp"
#include "ArduinoJson/JsonVariantImpl.hpp" #include "ArduinoJson/JsonVariantImpl.hpp"
#include "ArduinoJson/Serialization/JsonSerializerImpl.hpp" #include "ArduinoJson/Serialization/JsonSerializerImpl.hpp"

View File

@ -27,7 +27,7 @@ class List {
// When buffer is NULL, the List is not able to grow and success() returns // When buffer is NULL, the List is not able to grow and success() returns
// false. This is used to identify bad memory allocations and parsing // false. This is used to identify bad memory allocations and parsing
// failures. // failures.
explicit List(JsonBuffer *buffer) : _buffer(buffer), _firstNode(NULL) {} explicit List(JsonBuffer *buf) : _buffer(buf), _firstNode(NULL) {}
// Returns true if the object is valid // Returns true if the object is valid
// Would return false in the following situation: // Would return false in the following situation:
@ -84,11 +84,15 @@ class List {
} }
} }
JsonBuffer &buffer() const {
return *_buffer;
}
protected: protected:
JsonBuffer *_buffer; JsonBuffer *_buffer;
private: private:
node_type *_firstNode; node_type *_firstNode;
}; };
} } // namespace Internals
} } // namespace ArduinoJson

View File

@ -24,15 +24,9 @@ class JsonParser {
_reader(reader), _reader(reader),
_writer(writer), _writer(writer),
_nestingLimit(nestingLimit) {} _nestingLimit(nestingLimit) {}
bool parse(JsonArray &destination);
JsonArray &parseArray(); bool parse(JsonObject &destination);
JsonObject &parseObject(); bool parse(JsonVariant &destination);
JsonVariant parseVariant() {
JsonVariant result;
parseAnythingTo(&result);
return result;
}
private: private:
JsonParser &operator=(const JsonParser &); // non-copiable JsonParser &operator=(const JsonParser &); // non-copiable

View File

@ -46,11 +46,8 @@ ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseAnythingToUnsafe(
} }
template <typename TReader, typename TWriter> template <typename TReader, typename TWriter>
inline ArduinoJson::JsonArray & inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::parse(
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseArray() { JsonArray &array) {
// Create an empty array
JsonArray &array = _buffer->createArray();
// Check opening braket // Check opening braket
if (!eat('[')) goto ERROR_MISSING_BRACKET; if (!eat('[')) goto ERROR_MISSING_BRACKET;
if (eat(']')) goto SUCCESS_EMPTY_ARRAY; if (eat(']')) goto SUCCESS_EMPTY_ARRAY;
@ -69,31 +66,18 @@ ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseArray() {
SUCCESS_EMPTY_ARRAY: SUCCESS_EMPTY_ARRAY:
SUCCES_NON_EMPTY_ARRAY: SUCCES_NON_EMPTY_ARRAY:
return array; return true;
ERROR_INVALID_VALUE: ERROR_INVALID_VALUE:
ERROR_MISSING_BRACKET: ERROR_MISSING_BRACKET:
ERROR_MISSING_COMMA: ERROR_MISSING_COMMA:
ERROR_NO_MEMORY: ERROR_NO_MEMORY:
return JsonArray::invalid(); return false;
} }
template <typename TReader, typename TWriter> template <typename TReader, typename TWriter>
inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseArrayTo( inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::parse(
JsonVariant *destination) { JsonObject &object) {
JsonArray &array = parseArray();
if (!array.success()) return false;
*destination = array;
return true;
}
template <typename TReader, typename TWriter>
inline ArduinoJson::JsonObject &
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseObject() {
// Create an empty object
JsonObject &object = _buffer->createObject();
// Check opening brace // Check opening brace
if (!eat('{')) goto ERROR_MISSING_BRACE; if (!eat('{')) goto ERROR_MISSING_BRACE;
if (eat('}')) goto SUCCESS_EMPTY_OBJECT; if (eat('}')) goto SUCCESS_EMPTY_OBJECT;
@ -117,7 +101,7 @@ ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseObject() {
SUCCESS_EMPTY_OBJECT: SUCCESS_EMPTY_OBJECT:
SUCCESS_NON_EMPTY_OBJECT: SUCCESS_NON_EMPTY_OBJECT:
return object; return true;
ERROR_INVALID_KEY: ERROR_INVALID_KEY:
ERROR_INVALID_VALUE: ERROR_INVALID_VALUE:
@ -125,17 +109,31 @@ ERROR_MISSING_BRACE:
ERROR_MISSING_COLON: ERROR_MISSING_COLON:
ERROR_MISSING_COMMA: ERROR_MISSING_COMMA:
ERROR_NO_MEMORY: ERROR_NO_MEMORY:
return JsonObject::invalid(); return false;
}
template <typename TReader, typename TWriter>
inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::parse(
JsonVariant &variant) {
return parseAnythingTo(&variant);
}
template <typename TReader, typename TWriter>
inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseArrayTo(
JsonVariant *destination) {
JsonArray *array = new (_buffer) JsonArray(_buffer);
if (!array) return false;
*destination = array;
return parse(*array);
} }
template <typename TReader, typename TWriter> template <typename TReader, typename TWriter>
inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseObjectTo( inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseObjectTo(
JsonVariant *destination) { JsonVariant *destination) {
JsonObject &object = parseObject(); JsonObject *object = new (_buffer) JsonObject(_buffer);
if (!object.success()) return false; if (!object) return false;
*destination = object; *destination = object;
return true; return parse(*object);
} }
template <typename TReader, typename TWriter> template <typename TReader, typename TWriter>

View File

@ -0,0 +1,27 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#pragma once
#include "DynamicJsonBuffer.hpp"
#include "JsonArray.hpp"
namespace ArduinoJson {
class DynamicJsonArray : public JsonArray {
DynamicJsonBuffer _buffer;
public:
DynamicJsonArray() : JsonArray(&_buffer) {}
DynamicJsonArray(size_t capacity)
: JsonArray(&_buffer), _buffer(capacity - sizeof(JsonArray)) {}
size_t memoryUsage() const {
return _buffer.size() + sizeof(JsonArray);
}
DynamicJsonBuffer& buffer() {
return _buffer;
}
};
} // namespace ArduinoJson

View File

@ -4,7 +4,7 @@
#pragma once #pragma once
#include "JsonBufferBase.hpp" #include "JsonBuffer.hpp"
#include <stdlib.h> #include <stdlib.h>
@ -31,8 +31,7 @@ class DefaultAllocator {
}; };
template <typename TAllocator> template <typename TAllocator>
class DynamicJsonBufferBase class DynamicJsonBufferBase : public JsonBuffer {
: public JsonBufferBase<DynamicJsonBufferBase<TAllocator> > {
struct Block; struct Block;
struct EmptyBlock { struct EmptyBlock {
Block* next; Block* next;
@ -152,7 +151,7 @@ class DynamicJsonBufferBase
Block* _head; Block* _head;
size_t _nextBlockCapacity; size_t _nextBlockCapacity;
}; };
} } // namespace Internals
#if defined(__clang__) #if defined(__clang__)
#pragma clang diagnostic pop #pragma clang diagnostic pop
@ -167,4 +166,4 @@ class DynamicJsonBufferBase
// more suitable for embedded systems. // more suitable for embedded systems.
typedef Internals::DynamicJsonBufferBase<Internals::DefaultAllocator> typedef Internals::DynamicJsonBufferBase<Internals::DefaultAllocator>
DynamicJsonBuffer; DynamicJsonBuffer;
} } // namespace ArduinoJson

View File

@ -0,0 +1,27 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#pragma once
#include "DynamicJsonBuffer.hpp"
#include "JsonObject.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;
}
size_t memoryUsage() const {
return _buffer.size() + sizeof(JsonObject);
}
};
} // namespace ArduinoJson

View File

@ -0,0 +1,40 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#pragma once
#include "DynamicJsonBuffer.hpp"
#include "JsonVariant.hpp"
namespace ArduinoJson {
class DynamicJsonVariant : public JsonVariant {
DynamicJsonBuffer _buffer;
public:
DynamicJsonVariant() : JsonVariant() {}
template <typename T>
DynamicJsonVariant& operator=(const T& value) {
_buffer.clear();
JsonVariant::operator=(value);
return *this;
}
template <typename T>
DynamicJsonVariant& operator=(const T* value) {
_buffer.clear();
JsonVariant::operator=(value);
return *this;
}
DynamicJsonBuffer& buffer() {
return _buffer;
}
size_t memoryUsage() const {
return _buffer.size() + sizeof(JsonVariant);
}
};
} // namespace ArduinoJson

View File

@ -30,23 +30,14 @@ namespace Internals {
class JsonArraySubscript; class JsonArraySubscript;
} }
// An array of JsonVariant.
//
// The constructor is private, instances must be created via
// JsonBuffer::createArray() or JsonBuffer::parseArray().
// A JsonArray can be serialized to a JSON string via JsonArray::printTo().
// It can also be deserialized from a JSON string via JsonBuffer::parseArray().
class JsonArray : public Internals::JsonPrintable<JsonArray>, class JsonArray : public Internals::JsonPrintable<JsonArray>,
public Internals::ReferenceType, public Internals::ReferenceType,
public Internals::NonCopyable, public Internals::NonCopyable,
public Internals::List<JsonVariant>, public Internals::List<JsonVariant>,
public Internals::JsonBufferAllocated { public Internals::JsonBufferAllocated {
public: public:
// Create an empty JsonArray attached to the specified JsonBuffer. explicit JsonArray(JsonBuffer *buf) throw()
// You should not call this constructor directly. : Internals::List<JsonVariant>(buf) {}
// Instead, use JsonBuffer::createArray() or JsonBuffer::parseArray().
explicit JsonArray(JsonBuffer *buffer) throw()
: Internals::List<JsonVariant>(buffer) {}
// Gets the value at the specified index // Gets the value at the specified index
const Internals::JsonArraySubscript operator[](size_t index) const; const Internals::JsonArraySubscript operator[](size_t index) const;
@ -119,11 +110,9 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>,
} }
// Creates a JsonArray and adds a reference at the end of the array. // Creates a JsonArray and adds a reference at the end of the array.
// It's a shortcut for JsonBuffer::createArray() and JsonArray::add()
JsonArray &createNestedArray(); JsonArray &createNestedArray();
// Creates a JsonObject and adds a reference at the end of the array. // Creates a JsonObject and adds a reference at the end of the array.
// It's a shortcut for JsonBuffer::createObject() and JsonArray::add()
JsonObject &createNestedObject(); JsonObject &createNestedObject();
// Removes element at specified index. // Removes element at specified index.
@ -223,5 +212,5 @@ struct JsonVariantDefault<JsonArray> {
return JsonArray::invalid(); return JsonArray::invalid();
} }
}; };
} } // namespace Internals
} } // namespace ArduinoJson

View File

@ -11,16 +11,18 @@
namespace ArduinoJson { namespace ArduinoJson {
inline JsonArray &JsonArray::createNestedArray() { inline JsonArray &JsonArray::createNestedArray() {
if (!_buffer) return JsonArray::invalid(); JsonArray *array = new (_buffer) JsonArray(_buffer);
JsonArray &array = _buffer->createArray(); if (!array) return JsonArray::invalid();
add(array); add(array);
return array; return *array;
} }
inline JsonObject &JsonArray::createNestedObject() { inline JsonObject &JsonArray::createNestedObject() {
if (!_buffer) return JsonObject::invalid(); JsonObject *object = new (_buffer) JsonObject(_buffer);
JsonObject &object = _buffer->createObject(); if (!object) return JsonObject::invalid();
add(object); add(object);
return object; return *object;
}
} }
} // namespace ArduinoJson

View File

@ -24,18 +24,6 @@ class JsonObject;
// fixed memory allocation. // fixed memory allocation.
class JsonBuffer : Internals::NonCopyable { class JsonBuffer : Internals::NonCopyable {
public: public:
// Allocates an empty JsonArray.
//
// Returns a reference to the new JsonArray or JsonArray::invalid() if the
// allocation fails.
JsonArray &createArray();
// Allocates an empty JsonObject.
//
// Returns a reference to the new JsonObject or JsonObject::invalid() if the
// allocation fails.
JsonObject &createObject();
// Duplicates a string // Duplicates a string
// //
// const char* strdup(TValue); // const char* strdup(TValue);
@ -75,4 +63,4 @@ class JsonBuffer : Internals::NonCopyable {
#endif #endif
} }
}; };
} } // namespace ArduinoJson

View File

@ -1,127 +0,0 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#pragma once
#include "Deserialization/JsonParser.hpp"
namespace ArduinoJson {
namespace Internals {
template <typename TDerived>
class JsonBufferBase : public JsonBuffer {
public:
// Allocates and populate a JsonArray from a JSON string.
//
// The First argument is a pointer to the JSON string, the memory must be
// writable
// because the parser will insert null-terminators and replace escaped chars.
//
// The second argument set the nesting limit
//
// Returns a reference to the new JsonObject or JsonObject::invalid() if the
// allocation fails.
// With this overload, the JsonBuffer will make a copy of the string
//
// JsonArray& parseArray(TString);
// TString = const std::string&, const String&
template <typename TString>
typename Internals::EnableIf<!Internals::IsArray<TString>::value,
JsonArray &>::type
parseArray(const TString &json,
uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
return Internals::makeParser(that(), json, nestingLimit).parseArray();
}
//
// JsonArray& parseArray(TString);
// TString = const char*, const char[N], const FlashStringHelper*
template <typename TString>
JsonArray &parseArray(
TString *json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
return Internals::makeParser(that(), json, nestingLimit).parseArray();
}
//
// JsonArray& parseArray(TString);
// TString = std::istream&, Stream&
template <typename TString>
JsonArray &parseArray(
TString &json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
return Internals::makeParser(that(), json, nestingLimit).parseArray();
}
// Allocates and populate a JsonObject from a JSON string.
//
// The First argument is a pointer to the JSON string, the memory must be
// writable
// because the parser will insert null-terminators and replace escaped chars.
//
// The second argument set the nesting limit
//
// Returns a reference to the new JsonObject or JsonObject::invalid() if the
// allocation fails.
//
// JsonObject& parseObject(TString);
// TString = const std::string&, const String&
template <typename TString>
typename Internals::EnableIf<!Internals::IsArray<TString>::value,
JsonObject &>::type
parseObject(const TString &json,
uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
return Internals::makeParser(that(), json, nestingLimit).parseObject();
}
//
// JsonObject& parseObject(TString);
// TString = const char*, const char[N], const FlashStringHelper*
template <typename TString>
JsonObject &parseObject(
TString *json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
return Internals::makeParser(that(), json, nestingLimit).parseObject();
}
//
// JsonObject& parseObject(TString);
// TString = std::istream&, Stream&
template <typename TString>
JsonObject &parseObject(
TString &json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
return Internals::makeParser(that(), json, nestingLimit).parseObject();
}
// Generalized version of parseArray() and parseObject(), also works for
// integral types.
//
// JsonVariant parse(TString);
// TString = const std::string&, const String&
template <typename TString>
typename Internals::EnableIf<!Internals::IsArray<TString>::value,
JsonVariant>::type
parse(const TString &json,
uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
return Internals::makeParser(that(), json, nestingLimit).parseVariant();
}
//
// JsonVariant parse(TString);
// TString = const char*, const char[N], const FlashStringHelper*
template <typename TString>
JsonVariant parse(TString *json,
uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
return Internals::makeParser(that(), json, nestingLimit).parseVariant();
}
//
// JsonVariant parse(TString);
// TString = std::istream&, Stream&
template <typename TString>
JsonVariant parse(TString &json,
uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
return Internals::makeParser(that(), json, nestingLimit).parseVariant();
}
protected:
~JsonBufferBase() {}
private:
TDerived *that() {
return static_cast<TDerived *>(this);
}
};
}
}

View File

@ -1,17 +0,0 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#pragma once
#include "Deserialization/JsonParser.hpp"
inline ArduinoJson::JsonArray &ArduinoJson::JsonBuffer::createArray() {
JsonArray *ptr = new (this) JsonArray(this);
return ptr ? *ptr : JsonArray::invalid();
}
inline ArduinoJson::JsonObject &ArduinoJson::JsonBuffer::createObject() {
JsonObject *ptr = new (this) JsonObject(this);
return ptr ? *ptr : JsonObject::invalid();
}

View File

@ -31,12 +31,6 @@ template <typename>
class JsonObjectSubscript; class JsonObjectSubscript;
} }
// A dictionary of JsonVariant indexed by string (char*)
//
// The constructor is private, instances must be created via
// JsonBuffer::createObject() or JsonBuffer::parseObject().
// A JsonObject can be serialized to a JSON string via JsonObject::printTo().
// It can also be deserialized from a JSON string via JsonBuffer::parseObject().
class JsonObject : public Internals::JsonPrintable<JsonObject>, class JsonObject : public Internals::JsonPrintable<JsonObject>,
public Internals::ReferenceType, public Internals::ReferenceType,
public Internals::NonCopyable, public Internals::NonCopyable,
@ -45,9 +39,8 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
public: public:
// Create an empty JsonArray attached to the specified JsonBuffer. // Create an empty JsonArray attached to the specified JsonBuffer.
// You should not use this constructor directly. // You should not use this constructor directly.
// Instead, use JsonBuffer::createObject() or JsonBuffer.parseObject(). explicit JsonObject(JsonBuffer* buf) throw()
explicit JsonObject(JsonBuffer* buffer) throw() : Internals::List<JsonPair>(buf) {}
: Internals::List<JsonPair>(buffer) {}
// Gets or sets the value associated with the specified key. // Gets or sets the value associated with the specified key.
// //
@ -318,5 +311,5 @@ struct JsonVariantDefault<JsonObject> {
return JsonObject::invalid(); return JsonObject::invalid();
} }
}; };
} } // namespace Internals
} } // namespace ArduinoJson

View File

@ -12,17 +12,17 @@ namespace ArduinoJson {
template <typename TStringRef> template <typename TStringRef>
inline JsonArray &JsonObject::createNestedArray_impl(TStringRef key) { inline JsonArray &JsonObject::createNestedArray_impl(TStringRef key) {
if (!_buffer) return JsonArray::invalid(); JsonArray *array = new (_buffer) JsonArray(_buffer);
JsonArray &array = _buffer->createArray(); if (!array) return JsonArray::invalid();
set(key, array); set(key, array);
return array; return *array;
} }
template <typename TStringRef> template <typename TStringRef>
inline JsonObject &JsonObject::createNestedObject_impl(TStringRef key) { inline JsonObject &JsonObject::createNestedObject_impl(TStringRef key) {
if (!_buffer) return JsonObject::invalid(); JsonObject *object = new (_buffer) JsonObject(_buffer);
JsonObject &object = _buffer->createObject(); if (!object) return JsonObject::invalid();
set(key, object); set(key, object);
return object; return *object;
}
} }
} // namespace ArduinoJson

View File

@ -134,6 +134,16 @@ class JsonVariant : public Internals::JsonVariantBase<JsonVariant> {
// if the variant is converted back to a JsonObject& // if the variant is converted back to a JsonObject&
JsonVariant(const JsonObject &object); JsonVariant(const JsonObject &object);
JsonVariant(JsonArray *array) {
_content.asArray = array;
_type = Internals::JSON_ARRAY;
}
JsonVariant(JsonObject *object) {
_content.asObject = object;
_type = Internals::JSON_OBJECT;
}
// Get the variant as the specified type. // Get the variant as the specified type.
// //
// char as<char>() const; // char as<char>() const;
@ -352,4 +362,4 @@ DEPRECATED("Decimal places are ignored, use the double value instead")
inline JsonVariant double_with_n_digits(double value, uint8_t) { inline JsonVariant double_with_n_digits(double value, uint8_t) {
return JsonVariant(value); return JsonVariant(value);
} }
} } // namespace ArduinoJson

View File

@ -0,0 +1,27 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#pragma once
#include "JsonArray.hpp"
#include "StaticJsonBuffer.hpp"
namespace ArduinoJson {
template <size_t CAPACITY>
class StaticJsonArray : public JsonArray {
StaticJsonBuffer<CAPACITY - sizeof(JsonArray)> _buffer;
public:
StaticJsonArray() : JsonArray(&_buffer) {}
size_t memoryUsage() const {
return _buffer.size() + sizeof(JsonArray);
}
Internals::StaticJsonBufferBase& buffer() {
return _buffer;
}
};
} // namespace ArduinoJson

View File

@ -4,12 +4,13 @@
#pragma once #pragma once
#include "JsonBufferBase.hpp" #include "JsonBuffer.hpp"
#include "TypeTraits/Max.hpp"
namespace ArduinoJson { namespace ArduinoJson {
namespace Internals { namespace Internals {
class StaticJsonBufferBase : public JsonBufferBase<StaticJsonBufferBase> { class StaticJsonBufferBase : public JsonBuffer {
public: public:
class String { class String {
public: public:
@ -91,7 +92,7 @@ class StaticJsonBufferBase : public JsonBufferBase<StaticJsonBufferBase> {
size_t _capacity; size_t _capacity;
size_t _size; size_t _size;
}; };
} } // namespace Internals
#if defined(__clang__) #if defined(__clang__)
#pragma clang diagnostic push #pragma clang diagnostic push
@ -108,14 +109,16 @@ class StaticJsonBufferBase : public JsonBufferBase<StaticJsonBufferBase> {
// bytes. // bytes.
template <size_t CAPACITY> template <size_t CAPACITY>
class StaticJsonBuffer : public Internals::StaticJsonBufferBase { class StaticJsonBuffer : public Internals::StaticJsonBufferBase {
static const size_t ACTUAL_CAPACITY = Internals::Max<1, CAPACITY>::value;
public: public:
explicit StaticJsonBuffer() explicit StaticJsonBuffer()
: Internals::StaticJsonBufferBase(_buffer, CAPACITY) {} : Internals::StaticJsonBufferBase(_buffer, ACTUAL_CAPACITY) {}
private: private:
char _buffer[CAPACITY]; char _buffer[ACTUAL_CAPACITY];
}; };
} } // namespace ArduinoJson
#if defined(__clang__) #if defined(__clang__)
#pragma clang diagnostic pop #pragma clang diagnostic pop

View File

@ -0,0 +1,27 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#pragma once
#include "JsonObject.hpp"
#include "StaticJsonBuffer.hpp"
namespace ArduinoJson {
template <size_t CAPACITY>
class StaticJsonObject : public JsonObject {
StaticJsonBuffer<CAPACITY - sizeof(JsonObject)> _buffer;
public:
StaticJsonObject() : JsonObject(&_buffer) {}
size_t memoryUsage() const {
return _buffer.size() + sizeof(JsonObject);
}
Internals::StaticJsonBufferBase& buffer() {
return _buffer;
}
};
} // namespace ArduinoJson

View File

@ -0,0 +1,39 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#pragma once
#include "JsonVariant.hpp"
#include "StaticJsonBuffer.hpp"
namespace ArduinoJson {
template <size_t CAPACITY = sizeof(JsonVariant)>
class StaticJsonVariant : public JsonVariant {
StaticJsonBuffer<CAPACITY - sizeof(JsonVariant)> _buffer;
public:
template <typename T>
StaticJsonVariant& operator=(const T& value) {
_buffer.clear();
JsonVariant::operator=(value);
return *this;
}
template <typename T>
StaticJsonVariant& operator=(const T* value) {
_buffer.clear();
JsonVariant::operator=(value);
return *this;
}
Internals::StaticJsonBufferBase& buffer() {
return _buffer;
}
size_t memoryUsage() const {
return _buffer.size() + sizeof(JsonVariant);
}
};
} // namespace ArduinoJson

View File

@ -0,0 +1,24 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#pragma once
namespace ArduinoJson {
namespace Internals {
// A meta-function that returns the highest value
template <size_t X, size_t Y, bool MaxIsX = (X > Y)>
struct Max {};
template <size_t X, size_t Y>
struct Max<X, Y, true> {
static const size_t value = X;
};
template <size_t X, size_t Y>
struct Max<X, Y, false> {
static const size_t value = Y;
};
} // namespace Internals
} // namespace ArduinoJson

View File

@ -0,0 +1,40 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#pragma once
#include "Deserialization/JsonParser.hpp"
namespace ArduinoJson {
// bool deserializeJson(TDestination& destination, TString json);
// TDestination = JsonArray, JsonObject, JsonVariant
// TString = const std::string&, const String&
template <typename TDestination, typename TString>
typename Internals::EnableIf<!Internals::IsArray<TString>::value, bool>::type
deserializeJson(TDestination &destination, const TString &json,
uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
return Internals::makeParser(&destination.buffer(), json, nestingLimit)
.parse(destination);
}
//
// bool deserializeJson(TDestination& destination, TString json);
// TDestination = JsonArray, JsonObject, JsonVariant
// TString = const char*, const char[N], const FlashStringHelper*
template <typename TDestination, typename TString>
bool deserializeJson(TDestination &destination, TString *json,
uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
return Internals::makeParser(&destination.buffer(), json, nestingLimit)
.parse(destination);
}
//
// bool deserializeJson(TDestination& destination, TString json);
// TDestination = JsonArray, JsonObject, JsonVariant
// TString = std::istream&, Stream&
template <typename TDestination, typename TString>
bool deserializeJson(TDestination &destination, TString &json,
uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
return Internals::makeParser(&destination.buffer(), json, nestingLimit)
.parse(destination);
}
} // namespace ArduinoJson

View File

@ -67,8 +67,8 @@ endif()
add_subdirectory(DynamicJsonBuffer) add_subdirectory(DynamicJsonBuffer)
add_subdirectory(IntegrationTests) add_subdirectory(IntegrationTests)
add_subdirectory(JsonArray) add_subdirectory(JsonArray)
add_subdirectory(JsonBuffer)
add_subdirectory(JsonObject) add_subdirectory(JsonObject)
add_subdirectory(JsonParser)
add_subdirectory(JsonVariant) add_subdirectory(JsonVariant)
add_subdirectory(JsonWriter) add_subdirectory(JsonWriter)
add_subdirectory(Misc) add_subdirectory(Misc)

View File

@ -4,8 +4,6 @@
add_executable(DynamicJsonBufferTests add_executable(DynamicJsonBufferTests
alloc.cpp alloc.cpp
createArray.cpp
createObject.cpp
no_memory.cpp no_memory.cpp
size.cpp size.cpp
startString.cpp startString.cpp

View File

@ -1,28 +0,0 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("DynamicJsonBuffer::createArray()") {
DynamicJsonBuffer jsonBuffer;
JsonArray &array = jsonBuffer.createArray();
SECTION("GrowsWithArray") {
REQUIRE(JSON_ARRAY_SIZE(0) == jsonBuffer.size());
array.add("hello");
REQUIRE(JSON_ARRAY_SIZE(1) == jsonBuffer.size());
array.add("world");
REQUIRE(JSON_ARRAY_SIZE(2) == jsonBuffer.size());
}
SECTION("CanAdd1000Values") {
for (size_t i = 1; i <= 1000; i++) {
array.add("hello");
REQUIRE(array.size() == i);
}
}
}

View File

@ -1,22 +0,0 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("DynamicJsonBuffer::createObject()") {
DynamicJsonBuffer json;
JsonObject &obj = json.createObject();
REQUIRE(JSON_OBJECT_SIZE(0) == json.size());
obj["hello"] = 1;
REQUIRE(JSON_OBJECT_SIZE(1) == json.size());
obj["world"] = 2;
REQUIRE(JSON_OBJECT_SIZE(2) == json.size());
obj["world"] = 3; // <- same key, should not grow
REQUIRE(JSON_OBJECT_SIZE(2) == json.size());
}

View File

@ -22,23 +22,25 @@ TEST_CASE("DynamicJsonBuffer no memory") {
NoMemoryAllocator().deallocate(NULL); NoMemoryAllocator().deallocate(NULL);
} }
SECTION("createArray()") { // TODO: uncomment
REQUIRE_FALSE(_jsonBuffer.createArray().success()); // SECTION("parseArray()") {
} // char json[] = "[{}]";
// DynamicJsonArray arr;
SECTION("createObject()") { // bool success = deserializeJson(arr, json);
REQUIRE_FALSE(_jsonBuffer.createObject().success());
}
SECTION("parseArray()") { // REQUIRE(success == false);
char json[] = "[]"; // }
REQUIRE_FALSE(_jsonBuffer.parseArray(json).success());
}
SECTION("parseObject()") { // TODO: uncomment
char json[] = "{}"; // SECTION("parseObject()") {
REQUIRE_FALSE(_jsonBuffer.parseObject(json).success()); // char json[] = "{[]}";
} // DynamicJsonObject obj;
// bool success = deserializeJson(obj, json);
// REQUIRE(success == false);
// }
SECTION("startString()") { SECTION("startString()") {
DynamicJsonBufferBase<NoMemoryAllocator>::String str = DynamicJsonBufferBase<NoMemoryAllocator>::String str =

View File

@ -6,9 +6,10 @@
#include <catch.hpp> #include <catch.hpp>
TEST_CASE("Gbathree") { TEST_CASE("Gbathree") {
DynamicJsonBuffer _buffer; DynamicJsonObject _object;
const JsonObject& _object = _buffer.parseObject( bool success = deserializeJson(
_object,
"{\"protocol_name\":\"fluorescence\",\"repeats\":1,\"wait\":0," "{\"protocol_name\":\"fluorescence\",\"repeats\":1,\"wait\":0,"
"\"averages\":1,\"measurements\":3,\"meas2_light\":15,\"meas1_" "\"averages\":1,\"measurements\":3,\"meas2_light\":15,\"meas1_"
"baseline\":0,\"act_light\":20,\"pulsesize\":25,\"pulsedistance\":" "baseline\":0,\"act_light\":20,\"pulsesize\":25,\"pulsedistance\":"
@ -21,7 +22,7 @@ TEST_CASE("Gbathree") {
"[15,15,15,15]],\"altc\":[2,2,2,2],\"altd\":[2,2,2,2]}"); "[15,15,15,15]],\"altc\":[2,2,2,2],\"altd\":[2,2,2,2]}");
SECTION("Success") { SECTION("Success") {
REQUIRE(_object.success()); REQUIRE(success == true);
} }
SECTION("ProtocolName") { SECTION("ProtocolName") {

View File

@ -6,13 +6,15 @@
#include <catch.hpp> #include <catch.hpp>
void check(std::string originalJson) { void check(std::string originalJson) {
DynamicJsonBuffer jb; DynamicJsonObject obj;
std::string prettyJson; std::string prettyJson;
jb.parseObject(originalJson).prettyPrintTo(prettyJson); deserializeJson(obj, originalJson);
obj.prettyPrintTo(prettyJson);
std::string finalJson; std::string finalJson;
jb.parseObject(prettyJson).printTo(finalJson); deserializeJson(obj, originalJson);
obj.printTo(finalJson);
REQUIRE(originalJson == finalJson); REQUIRE(originalJson == finalJson);
} }

View File

@ -6,8 +6,7 @@
#include <catch.hpp> #include <catch.hpp>
TEST_CASE("JsonArray::add()") { TEST_CASE("JsonArray::add()") {
DynamicJsonBuffer _jsonBuffer; DynamicJsonArray _array;
JsonArray& _array = _jsonBuffer.createArray();
SECTION("int") { SECTION("int") {
_array.add(123); _array.add(123);
@ -39,7 +38,7 @@ TEST_CASE("JsonArray::add()") {
} }
SECTION("nested array") { SECTION("nested array") {
JsonArray& arr = _jsonBuffer.createArray(); DynamicJsonArray arr;
_array.add(arr); _array.add(arr);
@ -49,7 +48,7 @@ TEST_CASE("JsonArray::add()") {
} }
SECTION("nested object") { SECTION("nested object") {
JsonObject& obj = _jsonBuffer.createObject(); DynamicJsonObject obj;
_array.add(obj); _array.add(obj);
@ -60,7 +59,7 @@ TEST_CASE("JsonArray::add()") {
SECTION("array subscript") { SECTION("array subscript") {
const char* str = "hello"; const char* str = "hello";
JsonArray& arr = _jsonBuffer.createArray(); DynamicJsonArray arr;
arr.add(str); arr.add(str);
_array.add(arr[0]); _array.add(arr[0]);
@ -70,7 +69,7 @@ TEST_CASE("JsonArray::add()") {
SECTION("object subscript") { SECTION("object subscript") {
const char* str = "hello"; const char* str = "hello";
JsonObject& obj = _jsonBuffer.createObject(); DynamicJsonObject obj;
obj["x"] = str; obj["x"] = str;
_array.add(obj["x"]); _array.add(obj["x"]);
@ -81,30 +80,30 @@ TEST_CASE("JsonArray::add()") {
SECTION("should not duplicate const char*") { SECTION("should not duplicate const char*") {
_array.add("world"); _array.add("world");
const size_t expectedSize = JSON_ARRAY_SIZE(1); const size_t expectedSize = JSON_ARRAY_SIZE(1);
REQUIRE(expectedSize == _jsonBuffer.size()); REQUIRE(expectedSize == _array.memoryUsage());
} }
SECTION("should duplicate char*") { SECTION("should duplicate char*") {
_array.add(const_cast<char*>("world")); _array.add(const_cast<char*>("world"));
const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6;
REQUIRE(expectedSize == _jsonBuffer.size()); REQUIRE(expectedSize == _array.memoryUsage());
} }
SECTION("should duplicate std::string") { SECTION("should duplicate std::string") {
_array.add(std::string("world")); _array.add(std::string("world"));
const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6;
REQUIRE(expectedSize == _jsonBuffer.size()); REQUIRE(expectedSize == _array.memoryUsage());
} }
SECTION("should not duplicate RawJson(const char*)") { SECTION("should not duplicate RawJson(const char*)") {
_array.add(RawJson("{}")); _array.add(RawJson("{}"));
const size_t expectedSize = JSON_ARRAY_SIZE(1); const size_t expectedSize = JSON_ARRAY_SIZE(1);
REQUIRE(expectedSize == _jsonBuffer.size()); REQUIRE(expectedSize == _array.memoryUsage());
} }
SECTION("should duplicate RawJson(char*)") { SECTION("should duplicate RawJson(char*)") {
_array.add(RawJson(const_cast<char*>("{}"))); _array.add(RawJson(const_cast<char*>("{}")));
const size_t expectedSize = JSON_ARRAY_SIZE(1) + 3; const size_t expectedSize = JSON_ARRAY_SIZE(1) + 3;
REQUIRE(expectedSize == _jsonBuffer.size()); REQUIRE(expectedSize == _array.memoryUsage());
} }
} }

View File

@ -6,8 +6,7 @@
#include <catch.hpp> #include <catch.hpp>
TEST_CASE("JsonArray basics") { TEST_CASE("JsonArray basics") {
DynamicJsonBuffer jb; DynamicJsonArray array;
JsonArray& array = jb.createArray();
SECTION("SuccessIsTrue") { SECTION("SuccessIsTrue") {
REQUIRE(array.success()); REQUIRE(array.success());

View File

@ -7,8 +7,7 @@
TEST_CASE("JsonArray::copyFrom()") { TEST_CASE("JsonArray::copyFrom()") {
SECTION("OneDimension") { SECTION("OneDimension") {
DynamicJsonBuffer jsonBuffer; DynamicJsonArray array;
JsonArray& array = jsonBuffer.createArray();
char json[32]; char json[32];
int source[] = {1, 2, 3}; int source[] = {1, 2, 3};
@ -21,8 +20,7 @@ TEST_CASE("JsonArray::copyFrom()") {
SECTION("OneDimension_JsonBufferTooSmall") { SECTION("OneDimension_JsonBufferTooSmall") {
const size_t SIZE = JSON_ARRAY_SIZE(2); const size_t SIZE = JSON_ARRAY_SIZE(2);
StaticJsonBuffer<SIZE> jsonBuffer; StaticJsonArray<SIZE> array;
JsonArray& array = jsonBuffer.createArray();
char json[32]; char json[32];
int source[] = {1, 2, 3}; int source[] = {1, 2, 3};
@ -34,8 +32,7 @@ TEST_CASE("JsonArray::copyFrom()") {
} }
SECTION("TwoDimensions") { SECTION("TwoDimensions") {
DynamicJsonBuffer jsonBuffer; DynamicJsonArray array;
JsonArray& array = jsonBuffer.createArray();
char json[32]; char json[32];
int source[][3] = {{1, 2, 3}, {4, 5, 6}}; int source[][3] = {{1, 2, 3}, {4, 5, 6}};
@ -49,8 +46,7 @@ TEST_CASE("JsonArray::copyFrom()") {
SECTION("TwoDimensions_JsonBufferTooSmall") { SECTION("TwoDimensions_JsonBufferTooSmall") {
const size_t SIZE = const size_t SIZE =
JSON_ARRAY_SIZE(2) + JSON_ARRAY_SIZE(3) + JSON_ARRAY_SIZE(2); JSON_ARRAY_SIZE(2) + JSON_ARRAY_SIZE(3) + JSON_ARRAY_SIZE(2);
StaticJsonBuffer<SIZE> jsonBuffer; StaticJsonArray<SIZE> array;
JsonArray& array = jsonBuffer.createArray();
char json[32]; char json[32];
int source[][3] = {{1, 2, 3}, {4, 5, 6}}; int source[][3] = {{1, 2, 3}, {4, 5, 6}};

View File

@ -6,11 +6,12 @@
#include <catch.hpp> #include <catch.hpp>
TEST_CASE("JsonArray::copyTo()") { TEST_CASE("JsonArray::copyTo()") {
DynamicJsonBuffer jsonBuffer; DynamicJsonArray array;
SECTION("BiggerOneDimensionIntegerArray") { SECTION("BiggerOneDimensionIntegerArray") {
char json[] = "[1,2,3]"; char json[] = "[1,2,3]";
JsonArray& array = jsonBuffer.parseArray(json); bool success = deserializeJson(array, json);
REQUIRE(success == true);
int destination[4] = {0}; int destination[4] = {0};
size_t result = array.copyTo(destination); size_t result = array.copyTo(destination);
@ -24,7 +25,8 @@ TEST_CASE("JsonArray::copyTo()") {
SECTION("SmallerOneDimensionIntegerArray") { SECTION("SmallerOneDimensionIntegerArray") {
char json[] = "[1,2,3]"; char json[] = "[1,2,3]";
JsonArray& array = jsonBuffer.parseArray(json); bool success = deserializeJson(array, json);
REQUIRE(success == true);
int destination[2] = {0}; int destination[2] = {0};
size_t result = array.copyTo(destination); size_t result = array.copyTo(destination);
@ -37,7 +39,8 @@ TEST_CASE("JsonArray::copyTo()") {
SECTION("TwoOneDimensionIntegerArray") { SECTION("TwoOneDimensionIntegerArray") {
char json[] = "[[1,2],[3],[4]]"; char json[] = "[[1,2],[3],[4]]";
JsonArray& array = jsonBuffer.parseArray(json); bool success = deserializeJson(array, json);
REQUIRE(success == true);
int destination[3][2] = {{0}}; int destination[3][2] = {{0}};
array.copyTo(destination); array.copyTo(destination);

View File

@ -7,9 +7,7 @@
template <typename TIterator> template <typename TIterator>
static void run_iterator_test() { static void run_iterator_test() {
StaticJsonBuffer<JSON_ARRAY_SIZE(2)> jsonBuffer; StaticJsonArray<JSON_ARRAY_SIZE(2)> array;
JsonArray &array = jsonBuffer.createArray();
array.add(12); array.add(12);
array.add(34); array.add(34);

View File

@ -15,8 +15,7 @@ static void check(JsonArray& array, std::string expected) {
} }
TEST_CASE("JsonArray::prettyPrintTo()") { TEST_CASE("JsonArray::prettyPrintTo()") {
DynamicJsonBuffer jb; DynamicJsonArray array;
JsonArray& array = jb.createArray();
SECTION("Empty") { SECTION("Empty") {
check(array, "[]"); check(array, "[]");

View File

@ -15,8 +15,7 @@ static void check(JsonArray &array, std::string expected) {
} }
TEST_CASE("JsonArray::printTo()") { TEST_CASE("JsonArray::printTo()") {
StaticJsonBuffer<JSON_ARRAY_SIZE(2)> jb; StaticJsonArray<JSON_ARRAY_SIZE(2)> array;
JsonArray &array = jb.createArray();
SECTION("Empty") { SECTION("Empty") {
check(array, "[]"); check(array, "[]");
@ -74,13 +73,10 @@ TEST_CASE("JsonArray::printTo()") {
} }
SECTION("RawJson(char*)") { SECTION("RawJson(char*)") {
DynamicJsonBuffer jb2;
JsonArray &arr = jb2.createArray();
char tmp[] = "{\"key\":\"value\"}"; char tmp[] = "{\"key\":\"value\"}";
arr.add(RawJson(tmp)); array.add(RawJson(tmp));
check(arr, "[{\"key\":\"value\"}]"); check(array, "[{\"key\":\"value\"}]");
} }
SECTION("OneIntegerOverCapacity") { SECTION("OneIntegerOverCapacity") {

View File

@ -6,8 +6,7 @@
#include <catch.hpp> #include <catch.hpp>
TEST_CASE("JsonArray::remove()") { TEST_CASE("JsonArray::remove()") {
DynamicJsonBuffer _jsonBuffer; DynamicJsonArray _array;
JsonArray& _array = _jsonBuffer.createArray();
_array.add(1); _array.add(1);
_array.add(2); _array.add(2);
_array.add(3); _array.add(3);

View File

@ -8,8 +8,7 @@
using namespace Catch::Matchers; using namespace Catch::Matchers;
TEST_CASE("JsonArray::set()") { TEST_CASE("JsonArray::set()") {
DynamicJsonBuffer _jsonBuffer; DynamicJsonArray _array;
JsonArray& _array = _jsonBuffer.createArray();
_array.add(0); _array.add(0);
SECTION("int") { SECTION("int") {
@ -41,7 +40,7 @@ TEST_CASE("JsonArray::set()") {
} }
SECTION("nested array") { SECTION("nested array") {
JsonArray& arr = _jsonBuffer.createArray(); DynamicJsonArray arr;
_array.set(0, arr); _array.set(0, arr);
@ -51,7 +50,7 @@ TEST_CASE("JsonArray::set()") {
} }
SECTION("nested object") { SECTION("nested object") {
JsonObject& obj = _jsonBuffer.createObject(); DynamicJsonObject obj;
_array.set(0, obj); _array.set(0, obj);
@ -61,7 +60,7 @@ TEST_CASE("JsonArray::set()") {
} }
SECTION("array subscript") { SECTION("array subscript") {
JsonArray& arr = _jsonBuffer.createArray(); DynamicJsonArray arr;
arr.add("hello"); arr.add("hello");
_array.set(0, arr[0]); _array.set(0, arr[0]);
@ -70,7 +69,7 @@ TEST_CASE("JsonArray::set()") {
} }
SECTION("object subscript") { SECTION("object subscript") {
JsonObject& obj = _jsonBuffer.createObject(); DynamicJsonObject obj;
obj["x"] = "hello"; obj["x"] = "hello";
_array.set(0, obj["x"]); _array.set(0, obj["x"]);
@ -81,18 +80,18 @@ TEST_CASE("JsonArray::set()") {
SECTION("should not duplicate const char*") { SECTION("should not duplicate const char*") {
_array.set(0, "world"); _array.set(0, "world");
const size_t expectedSize = JSON_ARRAY_SIZE(1); const size_t expectedSize = JSON_ARRAY_SIZE(1);
REQUIRE(expectedSize == _jsonBuffer.size()); REQUIRE(expectedSize == _array.memoryUsage());
} }
SECTION("should duplicate char*") { SECTION("should duplicate char*") {
_array.set(0, const_cast<char*>("world")); _array.set(0, const_cast<char*>("world"));
const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6;
REQUIRE(expectedSize == _jsonBuffer.size()); REQUIRE(expectedSize == _array.memoryUsage());
} }
SECTION("should duplicate std::string") { SECTION("should duplicate std::string") {
_array.set(0, std::string("world")); _array.set(0, std::string("world"));
const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6;
REQUIRE(expectedSize == _jsonBuffer.size()); REQUIRE(expectedSize == _array.memoryUsage());
} }
} }

View File

@ -6,8 +6,7 @@
#include <catch.hpp> #include <catch.hpp>
TEST_CASE("JsonArray::size()") { TEST_CASE("JsonArray::size()") {
DynamicJsonBuffer _jsonBuffer; DynamicJsonArray _array;
JsonArray& _array = _jsonBuffer.createArray();
SECTION("increases after add()") { SECTION("increases after add()") {
_array.add("hello"); _array.add("hello");

View File

@ -7,8 +7,7 @@
#include <catch.hpp> #include <catch.hpp>
TEST_CASE("JsonArray::operator[]") { TEST_CASE("JsonArray::operator[]") {
DynamicJsonBuffer _jsonBuffer; DynamicJsonArray _array;
JsonArray& _array = _jsonBuffer.createArray();
_array.add(0); _array.add(0);
SECTION("int") { SECTION("int") {
@ -52,7 +51,7 @@ TEST_CASE("JsonArray::operator[]") {
} }
SECTION("nested array") { SECTION("nested array") {
JsonArray& arr = _jsonBuffer.createArray(); DynamicJsonArray arr;
_array[0] = arr; _array[0] = arr;
@ -65,7 +64,7 @@ TEST_CASE("JsonArray::operator[]") {
} }
SECTION("nested object") { SECTION("nested object") {
JsonObject& obj = _jsonBuffer.createObject(); DynamicJsonObject obj;
_array[0] = obj; _array[0] = obj;
@ -78,7 +77,7 @@ TEST_CASE("JsonArray::operator[]") {
} }
SECTION("array subscript") { SECTION("array subscript") {
JsonArray& arr = _jsonBuffer.createArray(); DynamicJsonArray arr;
const char* str = "hello"; const char* str = "hello";
arr.add(str); arr.add(str);
@ -89,7 +88,7 @@ TEST_CASE("JsonArray::operator[]") {
} }
SECTION("object subscript") { SECTION("object subscript") {
JsonObject& obj = _jsonBuffer.createObject(); DynamicJsonObject obj;
const char* str = "hello"; const char* str = "hello";
obj["x"] = str; obj["x"] = str;
@ -102,18 +101,18 @@ TEST_CASE("JsonArray::operator[]") {
SECTION("should not duplicate const char*") { SECTION("should not duplicate const char*") {
_array[0] = "world"; _array[0] = "world";
const size_t expectedSize = JSON_ARRAY_SIZE(1); const size_t expectedSize = JSON_ARRAY_SIZE(1);
REQUIRE(expectedSize == _jsonBuffer.size()); REQUIRE(expectedSize == _array.memoryUsage());
} }
SECTION("should duplicate char*") { SECTION("should duplicate char*") {
_array[0] = const_cast<char*>("world"); _array[0] = const_cast<char*>("world");
const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6;
REQUIRE(expectedSize == _jsonBuffer.size()); REQUIRE(expectedSize == _array.memoryUsage());
} }
SECTION("should duplicate std::string") { SECTION("should duplicate std::string") {
_array[0] = std::string("world"); _array[0] = std::string("world");
const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6;
REQUIRE(expectedSize == _jsonBuffer.size()); REQUIRE(expectedSize == _array.memoryUsage());
} }
} }

View File

@ -1,14 +0,0 @@
# ArduinoJson - arduinojson.org
# Copyright Benoit Blanchon 2014-2018
# MIT License
add_executable(JsonBufferTests
nested.cpp
nestingLimit.cpp
parse.cpp
parseArray.cpp
parseObject.cpp
)
target_link_libraries(JsonBufferTests catch)
add_test(JsonBuffer JsonBufferTests)

View File

@ -1,63 +0,0 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("JsonBuffer nested objects") {
SECTION("ArrayNestedInObject") {
DynamicJsonBuffer jsonBuffer;
char jsonString[] = " { \"ab\" : [ 1 , 2 ] , \"cd\" : [ 3 , 4 ] } ";
JsonObject &object = jsonBuffer.parseObject(jsonString);
JsonArray &array1 = object["ab"];
const JsonArray &array2 = object["cd"];
JsonArray &array3 = object["ef"];
REQUIRE(true == object.success());
REQUIRE(true == array1.success());
REQUIRE(true == array2.success());
REQUIRE(false == array3.success());
REQUIRE(2 == array1.size());
REQUIRE(2 == array2.size());
REQUIRE(0 == array3.size());
REQUIRE(1 == array1[0].as<int>());
REQUIRE(2 == array1[1].as<int>());
REQUIRE(3 == array2[0].as<int>());
REQUIRE(4 == array2[1].as<int>());
REQUIRE(0 == array3[0].as<int>());
}
SECTION("ObjectNestedInArray") {
DynamicJsonBuffer jsonBuffer;
char jsonString[] =
" [ { \"a\" : 1 , \"b\" : 2 } , { \"c\" : 3 , \"d\" : 4 } ] ";
JsonArray &array = jsonBuffer.parseArray(jsonString);
JsonObject &object1 = array[0];
const JsonObject &object2 = array[1];
JsonObject &object3 = array[2];
REQUIRE(true == array.success());
REQUIRE(true == object1.success());
REQUIRE(true == object2.success());
REQUIRE(false == object3.success());
REQUIRE(2 == object1.size());
REQUIRE(2 == object2.size());
REQUIRE(0 == object3.size());
REQUIRE(1 == object1["a"].as<int>());
REQUIRE(2 == object1["b"].as<int>());
REQUIRE(3 == object2["c"].as<int>());
REQUIRE(4 == object2["d"].as<int>());
REQUIRE(0 == object3["e"].as<int>());
}
}

View File

@ -1,318 +0,0 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("JsonBuffer::parseArray()") {
DynamicJsonBuffer jb;
SECTION("EmptyArray") {
JsonArray& arr = jb.parseArray("[]");
REQUIRE(arr.success());
REQUIRE(0 == arr.size());
}
SECTION("MissingOpeningBracket") {
JsonArray& arr = jb.parseArray("]");
REQUIRE_FALSE(arr.success());
}
SECTION("ArrayWithNoEnd") {
JsonArray& arr = jb.parseArray("[");
REQUIRE_FALSE(arr.success());
}
SECTION("EmptyArrayWithLeadingSpaces") {
JsonArray& arr = jb.parseArray(" []");
REQUIRE(arr.success());
REQUIRE(0 == arr.size());
}
SECTION("Garbage") {
JsonArray& arr = jb.parseArray("%*$£¤");
REQUIRE_FALSE(arr.success());
}
SECTION("OneInteger") {
JsonArray& arr = jb.parseArray("[42]");
REQUIRE(arr.success());
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == 42);
}
SECTION("OneIntegerWithSpacesBefore") {
JsonArray& arr = jb.parseArray("[ \t\r\n42]");
REQUIRE(arr.success());
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == 42);
}
SECTION("OneIntegerWithSpaceAfter") {
JsonArray& arr = jb.parseArray("[42 \t\r\n]");
REQUIRE(arr.success());
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == 42);
}
SECTION("TwoIntegers") {
JsonArray& arr = jb.parseArray("[42,84]");
REQUIRE(arr.success());
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == 42);
REQUIRE(arr[1] == 84);
}
SECTION("TwoDoubles") {
JsonArray& arr = jb.parseArray("[4.2,1e2]");
REQUIRE(arr.success());
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == 4.2);
REQUIRE(arr[1] == 1e2);
}
SECTION("UnsignedLong") {
JsonArray& arr = jb.parseArray("[4294967295]");
REQUIRE(arr.success());
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == 4294967295UL);
}
SECTION("TwoBooleans") {
JsonArray& arr = jb.parseArray("[true,false]");
REQUIRE(arr.success());
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == true);
REQUIRE(arr[1] == false);
}
SECTION("TwoNulls") {
JsonArray& arr = jb.parseArray("[null,null]");
REQUIRE(arr.success());
REQUIRE(2 == arr.size());
REQUIRE(arr[0].as<char*>() == 0);
REQUIRE(arr[1].as<char*>() == 0);
}
SECTION("TwoStringsDoubleQuotes") {
JsonArray& arr = jb.parseArray("[ \"hello\" , \"world\" ]");
REQUIRE(arr.success());
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world");
}
SECTION("TwoStringsSingleQuotes") {
JsonArray& arr = jb.parseArray("[ 'hello' , 'world' ]");
REQUIRE(arr.success());
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world");
}
SECTION("TwoStringsNoQuotes") {
JsonArray& arr = jb.parseArray("[ hello , world ]");
REQUIRE(arr.success());
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world");
}
SECTION("EmptyStringsDoubleQuotes") {
JsonArray& arr = jb.parseArray("[\"\",\"\"]");
REQUIRE(arr.success());
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "");
REQUIRE(arr[1] == "");
}
SECTION("EmptyStringSingleQuotes") {
JsonArray& arr = jb.parseArray("[\'\',\'\']");
REQUIRE(arr.success());
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "");
REQUIRE(arr[1] == "");
}
SECTION("EmptyStringNoQuotes") {
JsonArray& arr = jb.parseArray("[,]");
REQUIRE(arr.success());
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "");
REQUIRE(arr[1] == "");
}
SECTION("ClosingDoubleQuoteMissing") {
JsonArray& arr = jb.parseArray("[\"]");
REQUIRE_FALSE(arr.success());
}
SECTION("ClosingSignleQuoteMissing") {
JsonArray& arr = jb.parseArray("[\']");
REQUIRE_FALSE(arr.success());
}
SECTION("StringWithEscapedChars") {
JsonArray& arr = jb.parseArray("[\"1\\\"2\\\\3\\/4\\b5\\f6\\n7\\r8\\t9\"]");
REQUIRE(arr.success());
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "1\"2\\3/4\b5\f6\n7\r8\t9");
}
SECTION("StringWithUnterminatedEscapeSequence") {
JsonArray& arr = jb.parseArray("\"\\\0\"", 4);
REQUIRE_FALSE(arr.success());
}
SECTION("CCommentBeforeOpeningBracket") {
JsonArray& arr = jb.parseArray("/*COMMENT*/ [\"hello\"]");
REQUIRE(arr.success());
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("CCommentAfterOpeningBracket") {
JsonArray& arr = jb.parseArray("[/*COMMENT*/ \"hello\"]");
REQUIRE(arr.success());
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("CCommentBeforeClosingBracket") {
JsonArray& arr = jb.parseArray("[\"hello\"/*COMMENT*/]");
REQUIRE(arr.success());
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("CCommentAfterClosingBracket") {
JsonArray& arr = jb.parseArray("[\"hello\"]/*COMMENT*/");
REQUIRE(arr.success());
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("CCommentBeforeComma") {
JsonArray& arr = jb.parseArray("[\"hello\"/*COMMENT*/,\"world\"]");
REQUIRE(arr.success());
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world");
}
SECTION("CCommentAfterComma") {
JsonArray& arr = jb.parseArray("[\"hello\",/*COMMENT*/ \"world\"]");
REQUIRE(arr.success());
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world");
}
SECTION("CppCommentBeforeOpeningBracket") {
JsonArray& arr = jb.parseArray("//COMMENT\n\t[\"hello\"]");
REQUIRE(arr.success());
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("CppCommentAfterOpeningBracket") {
JsonArray& arr = jb.parseArray("[//COMMENT\n\"hello\"]");
REQUIRE(arr.success());
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("CppCommentBeforeClosingBracket") {
JsonArray& arr = jb.parseArray("[\"hello\"//COMMENT\r\n]");
REQUIRE(arr.success());
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("CppCommentAfterClosingBracket") {
JsonArray& arr = jb.parseArray("[\"hello\"]//COMMENT\n");
REQUIRE(arr.success());
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("CppCommentBeforeComma") {
JsonArray& arr = jb.parseArray("[\"hello\"//COMMENT\n,\"world\"]");
REQUIRE(arr.success());
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world");
}
SECTION("CppCommentAfterComma") {
JsonArray& arr = jb.parseArray("[\"hello\",//COMMENT\n\"world\"]");
REQUIRE(arr.success());
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world");
}
SECTION("InvalidCppComment") {
JsonArray& arr = jb.parseArray("[/COMMENT\n]");
REQUIRE_FALSE(arr.success());
}
SECTION("InvalidComment") {
JsonArray& arr = jb.parseArray("[/*/\n]");
REQUIRE_FALSE(arr.success());
}
SECTION("UnfinishedCComment") {
JsonArray& arr = jb.parseArray("[/*COMMENT]");
REQUIRE_FALSE(arr.success());
}
SECTION("EndsInCppComment") {
JsonArray& arr = jb.parseArray("[//COMMENT");
REQUIRE_FALSE(arr.success());
}
SECTION("AfterClosingStar") {
JsonArray& arr = jb.parseArray("[/*COMMENT*");
REQUIRE_FALSE(arr.success());
}
SECTION("DeeplyNested") {
JsonArray& arr =
jb.parseArray("[[[[[[[[[[[[[[[[[[[\"Not too deep\"]]]]]]]]]]]]]]]]]]]");
REQUIRE(arr.success());
}
}

View File

@ -1,170 +0,0 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("JsonBuffer::parseObject()") {
DynamicJsonBuffer jb;
SECTION("An empty object") {
JsonObject& obj = jb.parseObject("{}");
REQUIRE(obj.success());
REQUIRE(obj.size() == 0);
}
SECTION("Quotes") {
SECTION("Double quotes") {
JsonObject& obj = jb.parseObject("{\"key\":\"value\"}");
REQUIRE(obj.success());
REQUIRE(obj.size() == 1);
REQUIRE(obj["key"] == "value");
}
SECTION("Single quotes") {
JsonObject& obj = jb.parseObject("{'key':'value'}");
REQUIRE(obj.success());
REQUIRE(obj.size() == 1);
REQUIRE(obj["key"] == "value");
}
SECTION("No quotes") {
JsonObject& obj = jb.parseObject("{key:value}");
REQUIRE(obj.success());
REQUIRE(obj.size() == 1);
REQUIRE(obj["key"] == "value");
}
SECTION("No quotes, allow underscore in key") {
JsonObject& obj = jb.parseObject("{_k_e_y_:42}");
REQUIRE(obj.success());
REQUIRE(obj.size() == 1);
REQUIRE(obj["_k_e_y_"] == 42);
}
}
SECTION("Spaces") {
SECTION("Before the key") {
JsonObject& obj = jb.parseObject("{ \"key\":\"value\"}");
REQUIRE(obj.success());
REQUIRE(obj.size() == 1);
REQUIRE(obj["key"] == "value");
}
SECTION("After the key") {
JsonObject& obj = jb.parseObject("{\"key\" :\"value\"}");
REQUIRE(obj.success());
REQUIRE(obj.size() == 1);
REQUIRE(obj["key"] == "value");
}
SECTION("Before the value") {
JsonObject& obj = jb.parseObject("{\"key\": \"value\"}");
REQUIRE(obj.success());
REQUIRE(obj.size() == 1);
REQUIRE(obj["key"] == "value");
}
SECTION("After the value") {
JsonObject& obj = jb.parseObject("{\"key\":\"value\" }");
REQUIRE(obj.success());
REQUIRE(obj.size() == 1);
REQUIRE(obj["key"] == "value");
}
SECTION("Before the colon") {
JsonObject& obj =
jb.parseObject("{\"key1\":\"value1\" ,\"key2\":\"value2\"}");
REQUIRE(obj.success());
REQUIRE(obj.size() == 2);
REQUIRE(obj["key1"] == "value1");
REQUIRE(obj["key2"] == "value2");
}
SECTION("After the colon") {
JsonObject& obj =
jb.parseObject("{\"key1\":\"value1\" ,\"key2\":\"value2\"}");
REQUIRE(obj.success());
REQUIRE(obj.size() == 2);
REQUIRE(obj["key1"] == "value1");
REQUIRE(obj["key2"] == "value2");
}
}
SECTION("Values types") {
SECTION("String") {
JsonObject& obj =
jb.parseObject("{\"key1\":\"value1\",\"key2\":\"value2\"}");
REQUIRE(obj.success());
REQUIRE(obj.size() == 2);
REQUIRE(obj["key1"] == "value1");
REQUIRE(obj["key2"] == "value2");
}
SECTION("Integer") {
JsonObject& obj = jb.parseObject("{\"key1\":42,\"key2\":-42}");
REQUIRE(obj.success());
REQUIRE(obj.size() == 2);
REQUIRE(obj["key1"] == 42);
REQUIRE(obj["key2"] == -42);
}
SECTION("Double") {
JsonObject& obj = jb.parseObject("{\"key1\":12.345,\"key2\":-7E89}");
REQUIRE(obj.success());
REQUIRE(obj.size() == 2);
REQUIRE(obj["key1"] == 12.345);
REQUIRE(obj["key2"] == -7E89);
}
SECTION("Booleans") {
JsonObject& obj = jb.parseObject("{\"key1\":true,\"key2\":false}");
REQUIRE(obj.success());
REQUIRE(obj.size() == 2);
REQUIRE(obj["key1"] == true);
REQUIRE(obj["key2"] == false);
}
SECTION("Null") {
JsonObject& obj = jb.parseObject("{\"key1\":null,\"key2\":null}");
REQUIRE(obj.success());
REQUIRE(obj.size() == 2);
REQUIRE(obj["key1"].as<char*>() == 0);
REQUIRE(obj["key2"].as<char*>() == 0);
}
}
SECTION("Misc") {
SECTION("The opening brace is missing") {
JsonObject& obj = jb.parseObject("}");
REQUIRE_FALSE(obj.success());
}
SECTION("The closing brace is missing") {
JsonObject& obj = jb.parseObject("{");
REQUIRE_FALSE(obj.success());
}
SECTION("A quoted key without value") {
JsonObject& obj = jb.parseObject("{\"key\"}");
REQUIRE_FALSE(obj.success());
}
SECTION("A non-quoted key without value") {
JsonObject& obj = jb.parseObject("{key}");
REQUIRE_FALSE(obj.success());
}
SECTION("A dangling comma") {
JsonObject& obj = jb.parseObject("{\"key1\":\"value1\",}");
REQUIRE_FALSE(obj.success());
REQUIRE(obj.size() == 0);
}
SECTION("null as a key") {
JsonObject& obj = jb.parseObject("null:\"value\"}");
REQUIRE_FALSE(obj.success());
}
}
}

View File

@ -6,8 +6,7 @@
#include <catch.hpp> #include <catch.hpp>
TEST_CASE("JsonObject basics") { TEST_CASE("JsonObject basics") {
DynamicJsonBuffer _jsonBuffer; DynamicJsonObject _object;
JsonObject& _object = _jsonBuffer.createObject();
SECTION("InitialSizeIsZero") { SECTION("InitialSizeIsZero") {
REQUIRE(0 == _object.size()); REQUIRE(0 == _object.size());

View File

@ -6,8 +6,7 @@
#include <catch.hpp> #include <catch.hpp>
TEST_CASE("JsonObject::containsKey()") { TEST_CASE("JsonObject::containsKey()") {
DynamicJsonBuffer _jsonBuffer; DynamicJsonObject _object;
JsonObject& _object = _jsonBuffer.createObject();
SECTION("ContainsKeyReturnsFalseForNonExistingKey") { SECTION("ContainsKeyReturnsFalseForNonExistingKey") {
_object.set("hello", 42); _object.set("hello", 42);

View File

@ -8,8 +8,7 @@
using namespace Catch::Matchers; using namespace Catch::Matchers;
TEST_CASE("JsonObject::get()") { TEST_CASE("JsonObject::get()") {
DynamicJsonBuffer jb; DynamicJsonObject obj;
JsonObject& obj = jb.createObject();
SECTION("GetConstCharPointer_GivenStringLiteral") { SECTION("GetConstCharPointer_GivenStringLiteral") {
obj.set("hello", "world"); obj.set("hello", "world");

View File

@ -8,8 +8,7 @@
using namespace Catch::Matchers; using namespace Catch::Matchers;
TEST_CASE("JsonObject::begin()/end()") { TEST_CASE("JsonObject::begin()/end()") {
StaticJsonBuffer<JSON_OBJECT_SIZE(2)> jb; StaticJsonObject<JSON_OBJECT_SIZE(2)> obj;
JsonObject& obj = jb.createObject();
obj["ab"] = 12; obj["ab"] = 12;
obj["cd"] = 34; obj["cd"] = 34;

View File

@ -18,8 +18,7 @@ void check(const JsonObject &obj, const std::string expected) {
} }
TEST_CASE("JsonObject::prettyPrintTo()") { TEST_CASE("JsonObject::prettyPrintTo()") {
DynamicJsonBuffer jb; DynamicJsonObject obj;
JsonObject &obj = jb.createObject();
SECTION("EmptyObject") { SECTION("EmptyObject") {
check(obj, "{}"); check(obj, "{}");

View File

@ -16,8 +16,7 @@ void check(const JsonObject &obj, const std::string &expected) {
REQUIRE(expected.size() == measuredLen); REQUIRE(expected.size() == measuredLen);
} }
TEST_CASE("JsonObject::printTo()") { TEST_CASE("JsonObject::printTo()") {
DynamicJsonBuffer _jsonBuffer; DynamicJsonObject obj;
JsonObject &obj = _jsonBuffer.createObject();
SECTION("EmptyObject") { SECTION("EmptyObject") {
check(obj, "{}"); check(obj, "{}");
@ -92,17 +91,22 @@ TEST_CASE("JsonObject::printTo()") {
} }
SECTION("ThreeNestedArrays") { SECTION("ThreeNestedArrays") {
DynamicJsonArray b, c;
obj.createNestedArray("a"); obj.createNestedArray("a");
obj["b"] = _jsonBuffer.createArray(); obj["b"] = b;
obj.set("c", _jsonBuffer.createArray()); obj.set("c", c);
check(obj, "{\"a\":[],\"b\":[],\"c\":[]}"); check(obj, "{\"a\":[],\"b\":[],\"c\":[]}");
} }
SECTION("ThreeNestedObjects") { SECTION("ThreeNestedObjects") {
DynamicJsonObject b;
DynamicJsonObject c;
obj.createNestedObject("a"); obj.createNestedObject("a");
obj["b"] = _jsonBuffer.createObject(); obj["b"] = b;
obj.set("c", _jsonBuffer.createObject()); obj.set("c", c);
check(obj, "{\"a\":{},\"b\":{},\"c\":{}}"); check(obj, "{\"a\":{},\"b\":{},\"c\":{}}");
} }

View File

@ -7,10 +7,9 @@
#include <string> #include <string>
TEST_CASE("JsonObject::remove()") { TEST_CASE("JsonObject::remove()") {
DynamicJsonBuffer jb; DynamicJsonObject obj;
SECTION("SizeDecreased_WhenValuesAreRemoved") { SECTION("SizeDecreased_WhenValuesAreRemoved") {
JsonObject& obj = jb.createObject();
obj["hello"] = 1; obj["hello"] = 1;
obj.remove("hello"); obj.remove("hello");
@ -19,7 +18,6 @@ TEST_CASE("JsonObject::remove()") {
} }
SECTION("SizeUntouched_WhenRemoveIsCalledWithAWrongKey") { SECTION("SizeUntouched_WhenRemoveIsCalledWithAWrongKey") {
JsonObject& obj = jb.createObject();
obj["hello"] = 1; obj["hello"] = 1;
obj.remove("world"); obj.remove("world");
@ -28,7 +26,7 @@ TEST_CASE("JsonObject::remove()") {
} }
SECTION("RemoveByIterator") { SECTION("RemoveByIterator") {
JsonObject& obj = jb.parseObject("{\"a\":0,\"b\":1,\"c\":2}"); deserializeJson(obj, "{\"a\":0,\"b\":1,\"c\":2}");
for (JsonObject::iterator it = obj.begin(); it != obj.end(); ++it) { for (JsonObject::iterator it = obj.begin(); it != obj.end(); ++it) {
if (it->value == 1) obj.remove(it); if (it->value == 1) obj.remove(it);

View File

@ -7,8 +7,7 @@
#include <string> #include <string>
TEST_CASE("JsonObject::set()") { TEST_CASE("JsonObject::set()") {
DynamicJsonBuffer jb; DynamicJsonObject _object;
JsonObject& _object = jb.createObject();
SECTION("int") { SECTION("int") {
_object.set("hello", 123); _object.set("hello", 123);
@ -43,7 +42,7 @@ TEST_CASE("JsonObject::set()") {
} }
SECTION("nested array") { SECTION("nested array") {
JsonArray& arr = jb.createArray(); DynamicJsonArray arr;
_object.set("hello", arr); _object.set("hello", arr);
@ -53,7 +52,7 @@ TEST_CASE("JsonObject::set()") {
} }
SECTION("nested object") { SECTION("nested object") {
JsonObject& obj = jb.createObject(); DynamicJsonObject obj;
_object.set("hello", obj); _object.set("hello", obj);
@ -63,7 +62,7 @@ TEST_CASE("JsonObject::set()") {
} }
SECTION("array subscript") { SECTION("array subscript") {
JsonArray& arr = jb.createArray(); DynamicJsonArray arr;
arr.add(42); arr.add(42);
_object.set("a", arr[0]); _object.set("a", arr[0]);
@ -72,7 +71,7 @@ TEST_CASE("JsonObject::set()") {
} }
SECTION("object subscript") { SECTION("object subscript") {
JsonObject& obj = jb.createObject(); DynamicJsonObject obj;
obj.set("x", 42); obj.set("x", 42);
_object.set("a", obj["x"]); _object.set("a", obj["x"]);
@ -81,15 +80,13 @@ TEST_CASE("JsonObject::set()") {
} }
SECTION("returns true when allocation succeeds") { SECTION("returns true when allocation succeeds") {
StaticJsonBuffer<JSON_OBJECT_SIZE(1) + 15> jsonBuffer; StaticJsonObject<JSON_OBJECT_SIZE(1) + 15> obj;
JsonObject& obj = jsonBuffer.createObject();
REQUIRE(true == obj.set(std::string("hello"), std::string("world"))); REQUIRE(true == obj.set(std::string("hello"), std::string("world")));
} }
SECTION("returns false when allocation fails") { SECTION("returns false when allocation fails") {
StaticJsonBuffer<JSON_OBJECT_SIZE(1) + 10> jsonBuffer; StaticJsonObject<JSON_OBJECT_SIZE(1) + 10> obj;
JsonObject& obj = jsonBuffer.createObject();
REQUIRE(false == obj.set(std::string("hello"), std::string("world"))); REQUIRE(false == obj.set(std::string("hello"), std::string("world")));
} }
@ -97,42 +94,42 @@ TEST_CASE("JsonObject::set()") {
SECTION("should not duplicate const char*") { SECTION("should not duplicate const char*") {
_object.set("hello", "world"); _object.set("hello", "world");
const size_t expectedSize = JSON_OBJECT_SIZE(1); const size_t expectedSize = JSON_OBJECT_SIZE(1);
REQUIRE(expectedSize == jb.size()); REQUIRE(expectedSize == _object.memoryUsage());
} }
SECTION("should duplicate char* value") { SECTION("should duplicate char* value") {
_object.set("hello", const_cast<char*>("world")); _object.set("hello", const_cast<char*>("world"));
const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6;
REQUIRE(expectedSize == jb.size()); REQUIRE(expectedSize == _object.memoryUsage());
} }
SECTION("should duplicate char* key") { SECTION("should duplicate char* key") {
_object.set(const_cast<char*>("hello"), "world"); _object.set(const_cast<char*>("hello"), "world");
const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6;
REQUIRE(expectedSize == jb.size()); REQUIRE(expectedSize == _object.memoryUsage());
} }
SECTION("should duplicate char* key&value") { SECTION("should duplicate char* key&value") {
_object.set(const_cast<char*>("hello"), const_cast<char*>("world")); _object.set(const_cast<char*>("hello"), const_cast<char*>("world"));
const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12; const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12;
REQUIRE(expectedSize <= jb.size()); REQUIRE(expectedSize <= _object.memoryUsage());
} }
SECTION("should duplicate std::string value") { SECTION("should duplicate std::string value") {
_object.set("hello", std::string("world")); _object.set("hello", std::string("world"));
const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6;
REQUIRE(expectedSize == jb.size()); REQUIRE(expectedSize == _object.memoryUsage());
} }
SECTION("should duplicate std::string key") { SECTION("should duplicate std::string key") {
_object.set(std::string("hello"), "world"); _object.set(std::string("hello"), "world");
const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6;
REQUIRE(expectedSize == jb.size()); REQUIRE(expectedSize == _object.memoryUsage());
} }
SECTION("should duplicate std::string key&value") { SECTION("should duplicate std::string key&value") {
_object.set(std::string("hello"), std::string("world")); _object.set(std::string("hello"), std::string("world"));
const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12; const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12;
REQUIRE(expectedSize <= jb.size()); REQUIRE(expectedSize <= _object.memoryUsage());
} }
} }

View File

@ -7,8 +7,7 @@
#include <string> #include <string>
TEST_CASE("JsonObject::size()") { TEST_CASE("JsonObject::size()") {
DynamicJsonBuffer jb; DynamicJsonObject _object;
JsonObject& _object = jb.createObject();
SECTION("increases when values are added") { SECTION("increases when values are added") {
_object.set("hello", 42); _object.set("hello", 42);

View File

@ -6,8 +6,7 @@
#include <catch.hpp> #include <catch.hpp>
TEST_CASE("JsonObject::operator[]") { TEST_CASE("JsonObject::operator[]") {
DynamicJsonBuffer _jsonBuffer; DynamicJsonObject _object;
JsonObject& _object = _jsonBuffer.createObject();
SECTION("int") { SECTION("int") {
_object["hello"] = 123; _object["hello"] = 123;
@ -53,7 +52,7 @@ TEST_CASE("JsonObject::operator[]") {
} }
SECTION("array") { SECTION("array") {
JsonArray& arr = _jsonBuffer.createArray(); DynamicJsonArray arr;
_object["hello"] = arr; _object["hello"] = arr;
@ -69,7 +68,7 @@ TEST_CASE("JsonObject::operator[]") {
} }
SECTION("object") { SECTION("object") {
JsonObject& obj = _jsonBuffer.createObject(); DynamicJsonObject obj;
_object["hello"] = obj; _object["hello"] = obj;
@ -85,7 +84,7 @@ TEST_CASE("JsonObject::operator[]") {
} }
SECTION("array subscript") { SECTION("array subscript") {
JsonArray& arr = _jsonBuffer.createArray(); DynamicJsonArray arr;
arr.add(42); arr.add(42);
_object["a"] = arr[0]; _object["a"] = arr[0];
@ -94,7 +93,7 @@ TEST_CASE("JsonObject::operator[]") {
} }
SECTION("object subscript") { SECTION("object subscript") {
JsonObject& obj = _jsonBuffer.createObject(); DynamicJsonObject obj;
obj.set("x", 42); obj.set("x", 42);
_object["a"] = obj["x"]; _object["a"] = obj["x"];
@ -111,42 +110,42 @@ TEST_CASE("JsonObject::operator[]") {
SECTION("should not duplicate const char*") { SECTION("should not duplicate const char*") {
_object["hello"] = "world"; _object["hello"] = "world";
const size_t expectedSize = JSON_OBJECT_SIZE(1); const size_t expectedSize = JSON_OBJECT_SIZE(1);
REQUIRE(expectedSize == _jsonBuffer.size()); REQUIRE(expectedSize == _object.memoryUsage());
} }
SECTION("should duplicate char* value") { SECTION("should duplicate char* value") {
_object["hello"] = const_cast<char*>("world"); _object["hello"] = const_cast<char*>("world");
const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6;
REQUIRE(expectedSize == _jsonBuffer.size()); REQUIRE(expectedSize == _object.memoryUsage());
} }
SECTION("should duplicate char* key") { SECTION("should duplicate char* key") {
_object[const_cast<char*>("hello")] = "world"; _object[const_cast<char*>("hello")] = "world";
const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6;
REQUIRE(expectedSize == _jsonBuffer.size()); REQUIRE(expectedSize == _object.memoryUsage());
} }
SECTION("should duplicate char* key&value") { SECTION("should duplicate char* key&value") {
_object[const_cast<char*>("hello")] = const_cast<char*>("world"); _object[const_cast<char*>("hello")] = const_cast<char*>("world");
const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12; const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12;
REQUIRE(expectedSize <= _jsonBuffer.size()); REQUIRE(expectedSize <= _object.memoryUsage());
} }
SECTION("should duplicate std::string value") { SECTION("should duplicate std::string value") {
_object["hello"] = std::string("world"); _object["hello"] = std::string("world");
const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6;
REQUIRE(expectedSize == _jsonBuffer.size()); REQUIRE(expectedSize == _object.memoryUsage());
} }
SECTION("should duplicate std::string key") { SECTION("should duplicate std::string key") {
_object[std::string("hello")] = "world"; _object[std::string("hello")] = "world";
const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6;
REQUIRE(expectedSize == _jsonBuffer.size()); REQUIRE(expectedSize == _object.memoryUsage());
} }
SECTION("should duplicate std::string key&value") { SECTION("should duplicate std::string key&value") {
_object[std::string("hello")] = std::string("world"); _object[std::string("hello")] = std::string("world");
const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12; const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12;
REQUIRE(expectedSize <= _jsonBuffer.size()); REQUIRE(expectedSize <= _object.memoryUsage());
} }
} }

View File

@ -0,0 +1,15 @@
# ArduinoJson - arduinojson.org
# Copyright Benoit Blanchon 2014-2018
# MIT License
add_executable(JsonParserTests
JsonArray.cpp
JsonObject.cpp
JsonVariant.cpp
nestingLimit.cpp
StaticJsonArray.cpp
StaticJsonObject.cpp
)
target_link_libraries(JsonParserTests catch)
add_test(JsonParser JsonParserTests)

View File

@ -0,0 +1,346 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("deserializeJson(JsonArray&)") {
DynamicJsonArray arr;
SECTION("EmptyArray") {
bool success = deserializeJson(arr, "[]");
REQUIRE(success == true);
REQUIRE(0 == arr.size());
}
SECTION("MissingOpeningBracket") {
bool success = deserializeJson(arr, "]");
REQUIRE_FALSE(success == true);
}
SECTION("ArrayWithNoEnd") {
bool success = deserializeJson(arr, "[");
REQUIRE_FALSE(success == true);
}
SECTION("EmptyArrayWithLeadingSpaces") {
bool success = deserializeJson(arr, " []");
REQUIRE(success == true);
REQUIRE(0 == arr.size());
}
SECTION("Garbage") {
bool success = deserializeJson(arr, "%*$£¤");
REQUIRE_FALSE(success == true);
}
SECTION("OneInteger") {
bool success = deserializeJson(arr, "[42]");
REQUIRE(success == true);
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == 42);
}
SECTION("OneIntegerWithSpacesBefore") {
bool success = deserializeJson(arr, "[ \t\r\n42]");
REQUIRE(success == true);
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == 42);
}
SECTION("OneIntegerWithSpaceAfter") {
bool success = deserializeJson(arr, "[42 \t\r\n]");
REQUIRE(success == true);
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == 42);
}
SECTION("TwoIntegers") {
bool success = deserializeJson(arr, "[42,84]");
REQUIRE(success == true);
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == 42);
REQUIRE(arr[1] == 84);
}
SECTION("TwoDoubles") {
bool success = deserializeJson(arr, "[4.2,1e2]");
REQUIRE(success == true);
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == 4.2);
REQUIRE(arr[1] == 1e2);
}
SECTION("UnsignedLong") {
bool success = deserializeJson(arr, "[4294967295]");
REQUIRE(success == true);
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == 4294967295UL);
}
SECTION("TwoBooleans") {
bool success = deserializeJson(arr, "[true,false]");
REQUIRE(success == true);
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == true);
REQUIRE(arr[1] == false);
}
SECTION("TwoNulls") {
bool success = deserializeJson(arr, "[null,null]");
REQUIRE(success == true);
REQUIRE(2 == arr.size());
REQUIRE(arr[0].as<char *>() == 0);
REQUIRE(arr[1].as<char *>() == 0);
}
SECTION("TwoStringsDoubleQuotes") {
bool success = deserializeJson(arr, "[ \"hello\" , \"world\" ]");
REQUIRE(success == true);
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world");
}
SECTION("TwoStringsSingleQuotes") {
bool success = deserializeJson(arr, "[ 'hello' , 'world' ]");
REQUIRE(success == true);
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world");
}
SECTION("TwoStringsNoQuotes") {
bool success = deserializeJson(arr, "[ hello , world ]");
REQUIRE(success == true);
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world");
}
SECTION("EmptyStringsDoubleQuotes") {
bool success = deserializeJson(arr, "[\"\",\"\"]");
REQUIRE(success == true);
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "");
REQUIRE(arr[1] == "");
}
SECTION("EmptyStringSingleQuotes") {
bool success = deserializeJson(arr, "[\'\',\'\']");
REQUIRE(success == true);
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "");
REQUIRE(arr[1] == "");
}
SECTION("EmptyStringNoQuotes") {
bool success = deserializeJson(arr, "[,]");
REQUIRE(success == true);
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "");
REQUIRE(arr[1] == "");
}
SECTION("ClosingDoubleQuoteMissing") {
bool success = deserializeJson(arr, "[\"]");
REQUIRE_FALSE(success == true);
}
SECTION("ClosingSignleQuoteMissing") {
bool success = deserializeJson(arr, "[\']");
REQUIRE_FALSE(success == true);
}
SECTION("StringWithEscapedChars") {
bool success =
deserializeJson(arr, "[\"1\\\"2\\\\3\\/4\\b5\\f6\\n7\\r8\\t9\"]");
REQUIRE(success == true);
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "1\"2\\3/4\b5\f6\n7\r8\t9");
}
SECTION("StringWithUnterminatedEscapeSequence") {
bool success = deserializeJson(arr, "\"\\\0\"", 4);
REQUIRE_FALSE(success == true);
}
SECTION("CCommentBeforeOpeningBracket") {
bool success = deserializeJson(arr, "/*COMMENT*/ [\"hello\"]");
REQUIRE(success == true);
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("CCommentAfterOpeningBracket") {
bool success = deserializeJson(arr, "[/*COMMENT*/ \"hello\"]");
REQUIRE(success == true);
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("CCommentBeforeClosingBracket") {
bool success = deserializeJson(arr, "[\"hello\"/*COMMENT*/]");
REQUIRE(success == true);
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("CCommentAfterClosingBracket") {
bool success = deserializeJson(arr, "[\"hello\"]/*COMMENT*/");
REQUIRE(success == true);
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("CCommentBeforeComma") {
bool success = deserializeJson(arr, "[\"hello\"/*COMMENT*/,\"world\"]");
REQUIRE(success == true);
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world");
}
SECTION("CCommentAfterComma") {
bool success = deserializeJson(arr, "[\"hello\",/*COMMENT*/ \"world\"]");
REQUIRE(success == true);
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world");
}
SECTION("CppCommentBeforeOpeningBracket") {
bool success = deserializeJson(arr, "//COMMENT\n\t[\"hello\"]");
REQUIRE(success == true);
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("CppCommentAfterOpeningBracket") {
bool success = deserializeJson(arr, "[//COMMENT\n\"hello\"]");
REQUIRE(success == true);
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("CppCommentBeforeClosingBracket") {
bool success = deserializeJson(arr, "[\"hello\"//COMMENT\r\n]");
REQUIRE(success == true);
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("CppCommentAfterClosingBracket") {
bool success = deserializeJson(arr, "[\"hello\"]//COMMENT\n");
REQUIRE(success == true);
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("CppCommentBeforeComma") {
bool success = deserializeJson(arr, "[\"hello\"//COMMENT\n,\"world\"]");
REQUIRE(success == true);
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world");
}
SECTION("CppCommentAfterComma") {
bool success = deserializeJson(arr, "[\"hello\",//COMMENT\n\"world\"]");
REQUIRE(success == true);
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world");
}
SECTION("InvalidCppComment") {
bool success = deserializeJson(arr, "[/COMMENT\n]");
REQUIRE_FALSE(success == true);
}
SECTION("InvalidComment") {
bool success = deserializeJson(arr, "[/*/\n]");
REQUIRE_FALSE(success == true);
}
SECTION("UnfinishedCComment") {
bool success = deserializeJson(arr, "[/*COMMENT]");
REQUIRE_FALSE(success == true);
}
SECTION("EndsInCppComment") {
bool success = deserializeJson(arr, "[//COMMENT");
REQUIRE_FALSE(success == true);
}
SECTION("AfterClosingStar") {
bool success = deserializeJson(arr, "[/*COMMENT*");
REQUIRE_FALSE(success == true);
}
SECTION("DeeplyNested") {
bool success = deserializeJson(
arr, "[[[[[[[[[[[[[[[[[[[\"Not too deep\"]]]]]]]]]]]]]]]]]]]");
REQUIRE(success == true);
}
SECTION("ObjectNestedInArray") {
char jsonString[] =
" [ { \"a\" : 1 , \"b\" : 2 } , { \"c\" : 3 , \"d\" : 4 } ] ";
bool success = deserializeJson(arr, jsonString);
JsonObject &object1 = arr[0];
const JsonObject &object2 = arr[1];
JsonObject &object3 = arr[2];
REQUIRE(true == success);
REQUIRE(true == object1.success());
REQUIRE(true == object2.success());
REQUIRE(false == object3.success());
REQUIRE(2 == object1.size());
REQUIRE(2 == object2.size());
REQUIRE(0 == object3.size());
REQUIRE(1 == object1["a"].as<int>());
REQUIRE(2 == object1["b"].as<int>());
REQUIRE(3 == object2["c"].as<int>());
REQUIRE(4 == object2["d"].as<int>());
REQUIRE(0 == object3["e"].as<int>());
}
}

View File

@ -0,0 +1,197 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("deserializeJson(JsonObject&)") {
DynamicJsonObject obj;
SECTION("An empty object") {
bool success = deserializeJson(obj, "{}");
REQUIRE(success == true);
REQUIRE(obj.size() == 0);
}
SECTION("Quotes") {
SECTION("Double quotes") {
bool success = deserializeJson(obj, "{\"key\":\"value\"}");
REQUIRE(success == true);
REQUIRE(obj.size() == 1);
REQUIRE(obj["key"] == "value");
}
SECTION("Single quotes") {
bool success = deserializeJson(obj, "{'key':'value'}");
REQUIRE(success == true);
REQUIRE(obj.size() == 1);
REQUIRE(obj["key"] == "value");
}
SECTION("No quotes") {
bool success = deserializeJson(obj, "{key:value}");
REQUIRE(success == true);
REQUIRE(obj.size() == 1);
REQUIRE(obj["key"] == "value");
}
SECTION("No quotes, allow underscore in key") {
bool success = deserializeJson(obj, "{_k_e_y_:42}");
REQUIRE(success == true);
REQUIRE(obj.size() == 1);
REQUIRE(obj["_k_e_y_"] == 42);
}
}
SECTION("Spaces") {
SECTION("Before the key") {
bool success = deserializeJson(obj, "{ \"key\":\"value\"}");
REQUIRE(success == true);
REQUIRE(obj.size() == 1);
REQUIRE(obj["key"] == "value");
}
SECTION("After the key") {
bool success = deserializeJson(obj, "{\"key\" :\"value\"}");
REQUIRE(success == true);
REQUIRE(obj.size() == 1);
REQUIRE(obj["key"] == "value");
}
SECTION("Before the value") {
bool success = deserializeJson(obj, "{\"key\": \"value\"}");
REQUIRE(success == true);
REQUIRE(obj.size() == 1);
REQUIRE(obj["key"] == "value");
}
SECTION("After the value") {
bool success = deserializeJson(obj, "{\"key\":\"value\" }");
REQUIRE(success == true);
REQUIRE(obj.size() == 1);
REQUIRE(obj["key"] == "value");
}
SECTION("Before the colon") {
bool success =
deserializeJson(obj, "{\"key1\":\"value1\" ,\"key2\":\"value2\"}");
REQUIRE(success == true);
REQUIRE(obj.size() == 2);
REQUIRE(obj["key1"] == "value1");
REQUIRE(obj["key2"] == "value2");
}
SECTION("After the colon") {
bool success =
deserializeJson(obj, "{\"key1\":\"value1\" ,\"key2\":\"value2\"}");
REQUIRE(success == true);
REQUIRE(obj.size() == 2);
REQUIRE(obj["key1"] == "value1");
REQUIRE(obj["key2"] == "value2");
}
}
SECTION("Values types") {
SECTION("String") {
bool success =
deserializeJson(obj, "{\"key1\":\"value1\",\"key2\":\"value2\"}");
REQUIRE(success == true);
REQUIRE(obj.size() == 2);
REQUIRE(obj["key1"] == "value1");
REQUIRE(obj["key2"] == "value2");
}
SECTION("Integer") {
bool success = deserializeJson(obj, "{\"key1\":42,\"key2\":-42}");
REQUIRE(success == true);
REQUIRE(obj.size() == 2);
REQUIRE(obj["key1"] == 42);
REQUIRE(obj["key2"] == -42);
}
SECTION("Double") {
bool success = deserializeJson(obj, "{\"key1\":12.345,\"key2\":-7E89}");
REQUIRE(success == true);
REQUIRE(obj.size() == 2);
REQUIRE(obj["key1"] == 12.345);
REQUIRE(obj["key2"] == -7E89);
}
SECTION("Booleans") {
bool success = deserializeJson(obj, "{\"key1\":true,\"key2\":false}");
REQUIRE(success == true);
REQUIRE(obj.size() == 2);
REQUIRE(obj["key1"] == true);
REQUIRE(obj["key2"] == false);
}
SECTION("Null") {
bool success = deserializeJson(obj, "{\"key1\":null,\"key2\":null}");
REQUIRE(success == true);
REQUIRE(obj.size() == 2);
REQUIRE(obj["key1"].as<char *>() == 0);
REQUIRE(obj["key2"].as<char *>() == 0);
}
SECTION("Array") {
char jsonString[] = " { \"ab\" : [ 1 , 2 ] , \"cd\" : [ 3 , 4 ] } ";
bool success = deserializeJson(obj, jsonString);
JsonArray &array1 = obj["ab"];
const JsonArray &array2 = obj["cd"];
JsonArray &array3 = obj["ef"];
REQUIRE(true == success);
REQUIRE(true == array1.success());
REQUIRE(true == array2.success());
REQUIRE(false == array3.success());
REQUIRE(2 == array1.size());
REQUIRE(2 == array2.size());
REQUIRE(0 == array3.size());
REQUIRE(1 == array1[0].as<int>());
REQUIRE(2 == array1[1].as<int>());
REQUIRE(3 == array2[0].as<int>());
REQUIRE(4 == array2[1].as<int>());
REQUIRE(0 == array3[0].as<int>());
}
}
SECTION("Misc") {
SECTION("The opening brace is missing") {
bool success = deserializeJson(obj, "}");
REQUIRE(success == false);
}
SECTION("The closing brace is missing") {
bool success = deserializeJson(obj, "{");
REQUIRE(success == false);
}
SECTION("A quoted key without value") {
bool success = deserializeJson(obj, "{\"key\"}");
REQUIRE(success == false);
}
SECTION("A non-quoted key without value") {
bool success = deserializeJson(obj, "{key}");
REQUIRE(success == false);
}
SECTION("A dangling comma") {
bool success = deserializeJson(obj, "{\"key1\":\"value1\",}");
REQUIRE(success == false);
}
SECTION("null as a key") {
bool success = deserializeJson(obj, "null:\"value\"}");
REQUIRE(success == false);
}
}
}

View File

@ -7,73 +7,83 @@
using namespace Catch::Matchers; using namespace Catch::Matchers;
TEST_CASE("JsonBuffer::parse()") { TEST_CASE("deserializeJson(JsonVariant&)") {
DynamicJsonBuffer jb; DynamicJsonVariant variant;
SECTION("EmptyObject") { SECTION("EmptyObject") {
JsonVariant variant = jb.parse("{}"); bool success = deserializeJson(variant, "{}");
REQUIRE(variant.success());
REQUIRE(success == true);
REQUIRE(variant.is<JsonObject>()); REQUIRE(variant.is<JsonObject>());
} }
SECTION("EmptyArray") { SECTION("EmptyArray") {
JsonVariant variant = jb.parse("[]"); bool success = deserializeJson(variant, "[]");
REQUIRE(variant.success());
REQUIRE(success == true);
REQUIRE(variant.is<JsonArray>()); REQUIRE(variant.is<JsonArray>());
} }
SECTION("Integer") { SECTION("Integer") {
JsonVariant variant = jb.parse("-42"); bool success = deserializeJson(variant, "-42");
REQUIRE(variant.success());
REQUIRE(success == true);
REQUIRE(variant.is<int>()); REQUIRE(variant.is<int>());
REQUIRE_FALSE(variant.is<bool>()); REQUIRE_FALSE(variant.is<bool>());
REQUIRE(variant == -42); REQUIRE(variant == -42);
} }
SECTION("Double") { SECTION("Double") {
JsonVariant variant = jb.parse("-1.23e+4"); bool success = deserializeJson(variant, "-1.23e+4");
REQUIRE(variant.success());
REQUIRE(success == true);
REQUIRE_FALSE(variant.is<int>()); REQUIRE_FALSE(variant.is<int>());
REQUIRE(variant.is<double>()); REQUIRE(variant.is<double>());
REQUIRE(variant.as<double>() == Approx(-1.23e+4)); REQUIRE(variant.as<double>() == Approx(-1.23e+4));
} }
SECTION("Double quoted string") { SECTION("Double quoted string") {
JsonVariant variant = jb.parse("\"hello world\""); bool success = deserializeJson(variant, "\"hello world\"");
REQUIRE(variant.success());
REQUIRE(success == true);
REQUIRE(variant.is<char*>()); REQUIRE(variant.is<char*>());
REQUIRE_THAT(variant.as<char*>(), Equals("hello world")); REQUIRE_THAT(variant.as<char*>(), Equals("hello world"));
} }
SECTION("Single quoted string") { SECTION("Single quoted string") {
JsonVariant variant = jb.parse("\'hello world\'"); bool success = deserializeJson(variant, "\'hello world\'");
REQUIRE(variant.success());
REQUIRE(success == true);
REQUIRE(variant.is<char*>()); REQUIRE(variant.is<char*>());
REQUIRE_THAT(variant.as<char*>(), Equals("hello world")); REQUIRE_THAT(variant.as<char*>(), Equals("hello world"));
} }
SECTION("True") { SECTION("True") {
JsonVariant variant = jb.parse("true"); bool success = deserializeJson(variant, "true");
REQUIRE(variant.success());
REQUIRE(success == true);
REQUIRE(variant.is<bool>()); REQUIRE(variant.is<bool>());
REQUIRE(variant == true); REQUIRE(variant == true);
} }
SECTION("False") { SECTION("False") {
JsonVariant variant = jb.parse("false"); bool success = deserializeJson(variant, "false");
REQUIRE(variant.success());
REQUIRE(success == true);
REQUIRE(variant.is<bool>()); REQUIRE(variant.is<bool>());
REQUIRE(variant == false); REQUIRE(variant == false);
} }
SECTION("OpenBrace") { SECTION("OpenBrace") {
JsonVariant variant = jb.parse("{"); bool success = deserializeJson(variant, "{");
REQUIRE_FALSE(variant.success());
REQUIRE(success == false);
} }
SECTION("Incomplete string") { SECTION("Incomplete string") {
JsonVariant variant = jb.parse("\"hello"); bool success = deserializeJson(variant, "\"hello");
REQUIRE(variant.success());
REQUIRE(success == true);
REQUIRE(variant.is<char*>()); REQUIRE(variant.is<char*>());
REQUIRE_THAT(variant.as<char*>(), Equals("hello")); REQUIRE_THAT(variant.as<char*>(), Equals("hello"));
} }

View File

@ -0,0 +1,79 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("deserializeJson(StaticJsonArray&)") {
SECTION("BufferOfTheRightSizeForEmptyArray") {
StaticJsonArray<JSON_ARRAY_SIZE(0)> arr;
char input[] = "[]";
bool success = deserializeJson(arr, input);
REQUIRE(success == true);
}
SECTION("TooSmallBufferForArrayWithOneValue") {
StaticJsonArray<JSON_ARRAY_SIZE(1) - 1> arr;
char input[] = "[1]";
bool success = deserializeJson(arr, input);
REQUIRE(success == false);
}
SECTION("BufferOfTheRightSizeForArrayWithOneValue") {
StaticJsonArray<JSON_ARRAY_SIZE(1)> arr;
char input[] = "[1]";
bool success = deserializeJson(arr, input);
REQUIRE(success == true);
}
SECTION("TooSmallBufferForArrayWithNestedObject") {
StaticJsonArray<JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(0) - 1> arr;
char input[] = "[{}]";
bool success = deserializeJson(arr, input);
REQUIRE(success == false);
}
SECTION("BufferOfTheRightSizeForArrayWithNestedObject") {
StaticJsonArray<JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(0)> arr;
char input[] = "[{}]";
bool success = deserializeJson(arr, input);
REQUIRE(success == true);
}
SECTION("CharPtrNull") {
StaticJsonArray<100> arr;
bool success = deserializeJson(arr, static_cast<char*>(0));
REQUIRE(success == false);
}
SECTION("ConstCharPtrNull") {
StaticJsonArray<100> arr;
bool success = deserializeJson(arr, static_cast<const char*>(0));
REQUIRE(success == false);
}
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
}
}

View File

@ -0,0 +1,69 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("deserializeJson(StaticJsonObject&)") {
SECTION("BufferOfTheRightSizeForEmptyObject") {
StaticJsonObject<JSON_OBJECT_SIZE(0)> obj;
char input[] = "{}";
bool success = deserializeJson(obj, input);
REQUIRE(success == true);
}
SECTION("TooSmallBufferForObjectWithOneValue") {
StaticJsonObject<JSON_OBJECT_SIZE(1) - 1> obj;
char input[] = "{\"a\":1}";
bool success = deserializeJson(obj, input);
REQUIRE(success == false);
}
SECTION("BufferOfTheRightSizeForObjectWithOneValue") {
StaticJsonObject<JSON_OBJECT_SIZE(1)> obj;
char input[] = "{\"a\":1}";
bool success = deserializeJson(obj, input);
REQUIRE(success == true);
}
SECTION("TooSmallBufferForObjectWithNestedObject") {
StaticJsonObject<JSON_OBJECT_SIZE(1) + JSON_ARRAY_SIZE(0) - 1> obj;
char input[] = "{\"a\":[]}";
bool success = deserializeJson(obj, input);
REQUIRE(success == false);
}
SECTION("BufferOfTheRightSizeForObjectWithNestedObject") {
StaticJsonObject<JSON_OBJECT_SIZE(1) + JSON_ARRAY_SIZE(0)> obj;
char input[] = "{\"a\":[]}";
bool success = deserializeJson(obj, input);
REQUIRE(success == true);
}
SECTION("CharPtrNull") {
StaticJsonObject<100> obj;
bool success = deserializeJson(obj, static_cast<char*>(0));
REQUIRE(success == false);
}
SECTION("ConstCharPtrNull") {
StaticJsonObject<100> obj;
bool success = deserializeJson(obj, static_cast<const char*>(0));
REQUIRE(success == false);
}
}

View File

@ -6,13 +6,13 @@
#include <catch.hpp> #include <catch.hpp>
bool tryParseArray(const char *json, uint8_t nestingLimit) { bool tryParseArray(const char *json, uint8_t nestingLimit) {
DynamicJsonBuffer buffer; DynamicJsonArray array;
return buffer.parseArray(json, nestingLimit).success(); return deserializeJson(array, json, nestingLimit);
} }
bool tryParseObject(const char *json, uint8_t nestingLimit) { bool tryParseObject(const char *json, uint8_t nestingLimit) {
DynamicJsonBuffer buffer; DynamicJsonObject obj;
return buffer.parseObject(json, nestingLimit).success(); return deserializeJson(obj, json, nestingLimit);
} }
TEST_CASE("JsonParser nestingLimit") { TEST_CASE("JsonParser nestingLimit") {

View File

@ -192,9 +192,8 @@ TEST_CASE("JsonVariant::as()") {
} }
SECTION("ObjectAsString") { SECTION("ObjectAsString") {
DynamicJsonBuffer buffer; DynamicJsonObject obj;
JsonObject& obj = buffer.createObject();
obj["key"] = "value"; obj["key"] = "value";
JsonVariant variant = obj; JsonVariant variant = obj;
@ -202,9 +201,7 @@ TEST_CASE("JsonVariant::as()") {
} }
SECTION("ArrayAsString") { SECTION("ArrayAsString") {
DynamicJsonBuffer buffer; DynamicJsonArray arr;
JsonArray& arr = buffer.createArray();
arr.add(4); arr.add(4);
arr.add(2); arr.add(2);
@ -213,8 +210,7 @@ TEST_CASE("JsonVariant::as()") {
} }
SECTION("ArrayAsJsonArray") { SECTION("ArrayAsJsonArray") {
DynamicJsonBuffer buffer; DynamicJsonArray arr;
JsonArray& arr = buffer.createArray();
JsonVariant variant = arr; JsonVariant variant = arr;
REQUIRE(&arr == &variant.as<JsonArray&>()); REQUIRE(&arr == &variant.as<JsonArray&>());
@ -222,11 +218,10 @@ TEST_CASE("JsonVariant::as()") {
} }
SECTION("ObjectAsJsonObject") { SECTION("ObjectAsJsonObject") {
DynamicJsonBuffer buffer; DynamicJsonObject obj;
JsonObject& arr = buffer.createObject();
JsonVariant variant = arr; JsonVariant variant = obj;
REQUIRE(&arr == &variant.as<JsonObject&>()); REQUIRE(&obj == &variant.as<JsonObject&>());
REQUIRE(&arr == &variant.as<JsonObject>()); // <- shorthand REQUIRE(&obj == &variant.as<JsonObject>()); // <- shorthand
} }
} }

View File

@ -97,8 +97,8 @@ TEST_CASE("JsonVariant comparisons") {
} }
SECTION("StringLiteral") { SECTION("StringLiteral") {
DynamicJsonBuffer jsonBuffer; DynamicJsonVariant variant;
JsonVariant variant = jsonBuffer.parse("\"hello\""); deserializeJson(variant, "\"hello\"");
REQUIRE(variant == "hello"); REQUIRE(variant == "hello");
REQUIRE_FALSE(variant != "hello"); REQUIRE_FALSE(variant != "hello");
@ -114,8 +114,8 @@ TEST_CASE("JsonVariant comparisons") {
} }
SECTION("String") { SECTION("String") {
DynamicJsonBuffer jsonBuffer; DynamicJsonVariant variant;
JsonVariant variant = jsonBuffer.parse("\"hello\""); deserializeJson(variant, "\"hello\"");
REQUIRE(variant == std::string("hello")); REQUIRE(variant == std::string("hello"));
REQUIRE_FALSE(variant != std::string("hello")); REQUIRE_FALSE(variant != std::string("hello"));
@ -179,9 +179,7 @@ TEST_CASE("JsonVariant comparisons") {
} }
SECTION("ArrayInVariant") { SECTION("ArrayInVariant") {
DynamicJsonBuffer jsonBuffer; DynamicJsonArray array1, array2;
JsonArray& array1 = jsonBuffer.createArray();
JsonArray& array2 = jsonBuffer.createArray();
JsonVariant variant1 = array1; JsonVariant variant1 = array1;
JsonVariant variant2 = array1; JsonVariant variant2 = array1;
@ -195,9 +193,8 @@ TEST_CASE("JsonVariant comparisons") {
} }
SECTION("ObjectInVariant") { SECTION("ObjectInVariant") {
DynamicJsonBuffer jsonBuffer; DynamicJsonObject obj1;
JsonObject& obj1 = jsonBuffer.createObject(); DynamicJsonObject obj2;
JsonObject& obj2 = jsonBuffer.createObject();
JsonVariant variant1 = obj1; JsonVariant variant1 = obj1;
JsonVariant variant2 = obj1; JsonVariant variant2 = obj1;
@ -211,14 +208,10 @@ TEST_CASE("JsonVariant comparisons") {
} }
SECTION("VariantsOfDifferentTypes") { SECTION("VariantsOfDifferentTypes") {
DynamicJsonBuffer jsonBuffer; DynamicJsonObject obj;
DynamicJsonArray arr;
JsonVariant variants[] = { JsonVariant variants[] = {
true, true, 42, 666.667, "hello", arr, obj,
42,
666.667,
"hello",
jsonBuffer.createArray(),
jsonBuffer.createObject(),
}; };
size_t n = sizeof(variants) / sizeof(variants[0]); size_t n = sizeof(variants) / sizeof(variants[0]);

View File

@ -6,7 +6,6 @@
#include <catch.hpp> #include <catch.hpp>
TEST_CASE("JsonVariant copy") { TEST_CASE("JsonVariant copy") {
DynamicJsonBuffer _jsonBuffer;
JsonVariant _variant1; JsonVariant _variant1;
JsonVariant _variant2; JsonVariant _variant2;
@ -43,7 +42,7 @@ TEST_CASE("JsonVariant copy") {
} }
SECTION("ObjectsAreCopiedByReference") { SECTION("ObjectsAreCopiedByReference") {
JsonObject &object = _jsonBuffer.createObject(); DynamicJsonObject object;
_variant1 = object; _variant1 = object;
@ -53,7 +52,7 @@ TEST_CASE("JsonVariant copy") {
} }
SECTION("ArraysAreCopiedByReference") { SECTION("ArraysAreCopiedByReference") {
JsonArray &array = _jsonBuffer.createArray(); DynamicJsonArray array;
_variant1 = array; _variant1 = array;

View File

@ -72,7 +72,8 @@ TEST_CASE("JsonVariant::is()") {
DynamicJsonBuffer jsonBuffer; DynamicJsonBuffer jsonBuffer;
SECTION("JsonArray") { SECTION("JsonArray") {
checkIsArray(jsonBuffer.createArray()); DynamicJsonArray array;
checkIsArray(array);
} }
SECTION("bool") { SECTION("bool") {

View File

@ -122,9 +122,8 @@ TEST_CASE("JsonVariant set()/get()") {
#endif #endif
SECTION("CanStoreObject") { SECTION("CanStoreObject") {
DynamicJsonBuffer jsonBuffer; DynamicJsonObject object;
JsonObject &object = jsonBuffer.createObject();
checkReference(object); checkReference<JsonObject>(object);
} }
} }

View File

@ -6,10 +6,8 @@
#include <catch.hpp> #include <catch.hpp>
TEST_CASE("JsonVariant::operator[]") { TEST_CASE("JsonVariant::operator[]") {
DynamicJsonBuffer _jsonBuffer;
SECTION("Array") { SECTION("Array") {
JsonArray &array = _jsonBuffer.createArray(); DynamicJsonArray array;
array.add("element at index 0"); array.add("element at index 0");
array.add("element at index 1"); array.add("element at index 1");
@ -26,7 +24,7 @@ TEST_CASE("JsonVariant::operator[]") {
} }
SECTION("Object") { SECTION("Object") {
JsonObject &object = _jsonBuffer.createObject(); DynamicJsonObject object;
object["a"] = "element at key \"a\""; object["a"] = "element at key \"a\"";
object["b"] = "element at key \"b\""; object["b"] = "element at key \"b\"";
@ -54,21 +52,24 @@ TEST_CASE("JsonVariant::operator[]") {
} }
SECTION("ObjectSetValue") { SECTION("ObjectSetValue") {
JsonVariant var = _jsonBuffer.createObject(); DynamicJsonObject obj;
JsonVariant var = obj;
var["hello"] = "world"; var["hello"] = "world";
REQUIRE(1 == var.size()); REQUIRE(1 == var.size());
REQUIRE(std::string("world") == var["hello"]); REQUIRE(std::string("world") == var["hello"]);
} }
SECTION("ArraySetValue") { SECTION("ArraySetValue") {
JsonVariant var = _jsonBuffer.parseArray("[\"hello\"]"); DynamicJsonVariant var;
deserializeJson(var, "[\"hello\"]");
var[0] = "world"; var[0] = "world";
REQUIRE(1 == var.size()); REQUIRE(1 == var.size());
REQUIRE(std::string("world") == var[0]); REQUIRE(std::string("world") == var[0]);
} }
SECTION("NestedObjectSetValue") { SECTION("NestedObjectSetValue") {
JsonVariant var = _jsonBuffer.parseArray("[{}]"); DynamicJsonVariant var;
deserializeJson(var, "[{}]");
var[0]["hello"] = "world"; var[0]["hello"] = "world";
REQUIRE(1 == var.size()); REQUIRE(1 == var.size());
REQUIRE(1 == var[0].size()); REQUIRE(1 == var[0].size());

View File

@ -17,16 +17,16 @@ TEST_CASE("JsonVariant::success()") {
} }
SECTION("ReturnsTrue_WhenEmptyArray") { SECTION("ReturnsTrue_WhenEmptyArray") {
DynamicJsonBuffer jsonBuffer; DynamicJsonArray array;
JsonVariant variant = jsonBuffer.createArray(); JsonVariant variant = array;
REQUIRE(true == variant.success()); REQUIRE(true == variant.success());
} }
SECTION("ReturnsTrue_WhenEmptyObject") { SECTION("ReturnsTrue_WhenEmptyObject") {
DynamicJsonBuffer jsonBuffer; DynamicJsonObject obj;
JsonVariant variant = jsonBuffer.createObject(); JsonVariant variant = obj;
REQUIRE(true == variant.success()); REQUIRE(true == variant.success());
} }

View File

@ -16,15 +16,15 @@
#endif #endif
TEST_CASE("Deprecated functions") { TEST_CASE("Deprecated functions") {
DynamicJsonBuffer jsonBuffer;
SECTION("JsonVariant::asArray()") { SECTION("JsonVariant::asArray()") {
JsonVariant variant = jsonBuffer.createArray(); DynamicJsonArray array;
JsonVariant variant = array;
REQUIRE(variant.asArray().success()); REQUIRE(variant.asArray().success());
} }
SECTION("JsonVariant::asObject()") { SECTION("JsonVariant::asObject()") {
JsonVariant variant = jsonBuffer.createObject(); DynamicJsonObject obj;
JsonVariant variant = obj;
REQUIRE(variant.asObject().success()); REQUIRE(variant.asObject().success());
} }
@ -34,7 +34,7 @@ TEST_CASE("Deprecated functions") {
} }
SECTION("JsonArray::removeAt()") { SECTION("JsonArray::removeAt()") {
JsonArray& arr = jsonBuffer.createArray(); DynamicJsonArray arr;
arr.removeAt(0); arr.removeAt(0);
} }
@ -59,7 +59,7 @@ TEST_CASE("Deprecated functions") {
} }
SECTION("JsonArraySubscript::set(double, uint8_t)") { SECTION("JsonArraySubscript::set(double, uint8_t)") {
JsonArray& arr = jsonBuffer.createArray(); DynamicJsonArray arr;
arr.add(666); arr.add(666);
arr[0].set(123.45, 2); arr[0].set(123.45, 2);
REQUIRE(123.45 == arr[0].as<double>()); REQUIRE(123.45 == arr[0].as<double>());
@ -68,26 +68,26 @@ TEST_CASE("Deprecated functions") {
} }
SECTION("JsonArray::add(double, uint8_t)") { SECTION("JsonArray::add(double, uint8_t)") {
JsonArray& arr = jsonBuffer.createArray(); DynamicJsonArray arr;
arr.add(3.14159265358979323846, 4); arr.add(3.14159265358979323846, 4);
} }
SECTION("JsonArray::add(float, uint8_t)") { SECTION("JsonArray::add(float, uint8_t)") {
JsonArray& arr = jsonBuffer.createArray(); DynamicJsonArray arr;
arr.add(3.14159265358979323846f, 4); arr.add(3.14159265358979323846f, 4);
} }
SECTION("JsonObject::set(unsigned char[], double, uint8_t)") { SECTION("JsonObject::set(unsigned char[], double, uint8_t)") {
unsigned char key[] = "hello"; unsigned char key[] = "hello";
JsonObject& obj = jsonBuffer.createObject(); DynamicJsonObject obj;
obj.set(key, 3.14, 2); obj.set(key, 3.14, 2);
REQUIRE(3.14 == obj["hello"]); REQUIRE(3.14 == obj["hello"]);
} }
SECTION("JsonObject::set(const char*, double, uint8_t)") { SECTION("JsonObject::set(const char*, double, uint8_t)") {
JsonObject& obj = jsonBuffer.createObject(); DynamicJsonObject obj;
obj.set("hello", 123.45, 2); obj.set("hello", 123.45, 2);
REQUIRE(123.45 == obj["hello"].as<double>()); REQUIRE(123.45 == obj["hello"].as<double>());
@ -96,7 +96,7 @@ TEST_CASE("Deprecated functions") {
} }
SECTION("JsonObjectSubscript::set(double, uint8_t)") { SECTION("JsonObjectSubscript::set(double, uint8_t)") {
JsonObject& obj = jsonBuffer.createObject(); DynamicJsonObject obj;
obj["hello"].set(123.45, 2); obj["hello"].set(123.45, 2);
REQUIRE(true == obj["hello"].is<double>()); REQUIRE(true == obj["hello"].is<double>());

View File

@ -23,8 +23,7 @@ TEST_CASE("std::stream") {
SECTION("JsonObject") { SECTION("JsonObject") {
std::ostringstream os; std::ostringstream os;
DynamicJsonBuffer jsonBuffer; DynamicJsonObject object;
JsonObject& object = jsonBuffer.createObject();
object["key"] = "value"; object["key"] = "value";
os << object; os << object;
REQUIRE("{\"key\":\"value\"}" == os.str()); REQUIRE("{\"key\":\"value\"}" == os.str());
@ -32,8 +31,7 @@ TEST_CASE("std::stream") {
SECTION("JsonObjectSubscript") { SECTION("JsonObjectSubscript") {
std::ostringstream os; std::ostringstream os;
DynamicJsonBuffer jsonBuffer; DynamicJsonObject object;
JsonObject& object = jsonBuffer.createObject();
object["key"] = "value"; object["key"] = "value";
os << object["key"]; os << object["key"];
REQUIRE("\"value\"" == os.str()); REQUIRE("\"value\"" == os.str());
@ -41,8 +39,7 @@ TEST_CASE("std::stream") {
SECTION("JsonArray") { SECTION("JsonArray") {
std::ostringstream os; std::ostringstream os;
DynamicJsonBuffer jsonBuffer; DynamicJsonArray array;
JsonArray& array = jsonBuffer.createArray();
array.add("value"); array.add("value");
os << array; os << array;
REQUIRE("[\"value\"]" == os.str()); REQUIRE("[\"value\"]" == os.str());
@ -50,8 +47,7 @@ TEST_CASE("std::stream") {
SECTION("JsonArraySubscript") { SECTION("JsonArraySubscript") {
std::ostringstream os; std::ostringstream os;
DynamicJsonBuffer jsonBuffer; DynamicJsonArray array;
JsonArray& array = jsonBuffer.createArray();
array.add("value"); array.add("value");
os << array[0]; os << array[0];
REQUIRE("\"value\"" == os.str()); REQUIRE("\"value\"" == os.str());
@ -59,26 +55,28 @@ TEST_CASE("std::stream") {
SECTION("ParseArray") { SECTION("ParseArray") {
std::istringstream json(" [ 42 /* comment */ ] "); std::istringstream json(" [ 42 /* comment */ ] ");
DynamicJsonBuffer jsonBuffer; DynamicJsonArray arr;
JsonArray& arr = jsonBuffer.parseArray(json); bool success = deserializeJson(arr, json);
REQUIRE(true == arr.success());
REQUIRE(true == success);
REQUIRE(1 == arr.size()); REQUIRE(1 == arr.size());
REQUIRE(42 == arr[0]); REQUIRE(42 == arr[0]);
} }
SECTION("ParseObject") { SECTION("ParseObject") {
std::istringstream json(" { hello : world // comment\n }"); std::istringstream json(" { hello : world // comment\n }");
DynamicJsonBuffer jsonBuffer; DynamicJsonObject obj;
JsonObject& obj = jsonBuffer.parseObject(json); bool success = deserializeJson(obj, json);
REQUIRE(true == obj.success());
REQUIRE(true == success);
REQUIRE(1 == obj.size()); REQUIRE(1 == obj.size());
REQUIRE(std::string("world") == obj["hello"]); REQUIRE(std::string("world") == obj["hello"]);
} }
SECTION("ShouldNotReadPastTheEnd") { SECTION("ShouldNotReadPastTheEnd") {
std::istringstream json("{}123"); std::istringstream json("{}123");
DynamicJsonBuffer jsonBuffer; DynamicJsonObject obj;
jsonBuffer.parseObject(json); deserializeJson(obj, json);
REQUIRE('1' == json.get()); REQUIRE('1' == json.get());
} }
} }

View File

@ -13,52 +13,104 @@ static void eraseString(std::string &str) {
TEST_CASE("std::string") { TEST_CASE("std::string") {
DynamicJsonBuffer jb; DynamicJsonBuffer jb;
SECTION("JsonBuffer_ParseArray") { SECTION("JsonArray") {
DynamicJsonArray array;
SECTION("deserializeJson") {
std::string json("[\"hello\"]"); std::string json("[\"hello\"]");
JsonArray &array = jb.parseArray(json);
bool success = deserializeJson(array, json);
eraseString(json); eraseString(json);
REQUIRE(true == array.success());
REQUIRE(true == success);
REQUIRE(std::string("hello") == array[0]); REQUIRE(std::string("hello") == array[0]);
} }
SECTION("JsonBuffer_ParseObject") { SECTION("add()") {
std::string value("hello");
array.add(value);
eraseString(value);
REQUIRE(std::string("hello") == array[0]);
}
SECTION("set()") {
std::string value("world");
array.add("hello");
array.set(0, value);
eraseString(value);
REQUIRE(std::string("world") == array[0]);
}
SECTION("operator[]") {
std::string value("world");
array.add("hello");
array[0] = value;
eraseString(value);
REQUIRE(std::string("world") == array[0]);
}
SECTION("printTo()") {
array.add(4);
array.add(2);
std::string json;
array.printTo(json);
REQUIRE(std::string("[4,2]") == json);
}
SECTION("prettyPrintTo") {
array.add(4);
array.add(2);
std::string json;
array.prettyPrintTo(json);
REQUIRE(std::string("[\r\n 4,\r\n 2\r\n]") == json);
}
}
SECTION("JsonObject") {
DynamicJsonObject object;
SECTION("deserializeJson") {
std::string json("{\"hello\":\"world\"}"); std::string json("{\"hello\":\"world\"}");
JsonObject &object = jb.parseObject(json);
bool success = deserializeJson(object, json);
eraseString(json); eraseString(json);
REQUIRE(true == object.success());
REQUIRE(true == success);
REQUIRE(std::string("world") == object["hello"]); REQUIRE(std::string("world") == object["hello"]);
} }
SECTION("JsonObject_Subscript") { SECTION("operator[]") {
char json[] = "{\"key\":\"value\"}"; char json[] = "{\"key\":\"value\"}";
JsonObject &object = jb.parseObject(json);
deserializeJson(object, json);
REQUIRE(std::string("value") == object[std::string("key")]); REQUIRE(std::string("value") == object[std::string("key")]);
} }
SECTION("JsonObject_ConstSubscript") { SECTION("operator[] const") {
char json[] = "{\"key\":\"value\"}"; char json[] = "{\"key\":\"value\"}";
const JsonObject &object = jb.parseObject(json);
REQUIRE(std::string("value") == object[std::string("key")]); deserializeJson(object, json);
const JsonObject &obj = object;
REQUIRE(std::string("value") == obj[std::string("key")]);
} }
SECTION("JsonObject_SetKey") { SECTION("set(key)") {
JsonObject &object = jb.createObject();
std::string key("hello"); std::string key("hello");
object.set(key, "world"); object.set(key, "world");
eraseString(key); eraseString(key);
REQUIRE(std::string("world") == object["hello"]); REQUIRE(std::string("world") == object["hello"]);
} }
SECTION("JsonObject_SetValue") { SECTION("set(value)") {
JsonObject &object = jb.createObject();
std::string value("world"); std::string value("world");
object.set("hello", value); object.set("hello", value);
eraseString(value); eraseString(value);
REQUIRE(std::string("world") == object["hello"]); REQUIRE(std::string("world") == object["hello"]);
} }
SECTION("JsonObject_SetKeyValue") { SECTION("set(key,value)") {
JsonObject &object = jb.createObject();
std::string key("hello"); std::string key("hello");
std::string value("world"); std::string value("world");
object.set(key, value); object.set(key, value);
@ -67,177 +119,118 @@ TEST_CASE("std::string") {
REQUIRE(std::string("world") == object["hello"]); REQUIRE(std::string("world") == object["hello"]);
} }
SECTION("JsonObject_SetToArraySubscript") { SECTION("set(JsonArraySubscript)") {
JsonArray &arr = jb.createArray(); DynamicJsonArray arr;
arr.add("world"); arr.add("world");
JsonObject &object = jb.createObject();
object.set(std::string("hello"), arr[0]); object.set(std::string("hello"), arr[0]);
REQUIRE(std::string("world") == object["hello"]); REQUIRE(std::string("world") == object["hello"]);
} }
SECTION("JsonObject_SetToObjectSubscript") { SECTION("set(JsonObjectSubscript)") {
JsonObject &arr = jb.createObject(); DynamicJsonObject obj;
arr.set("x", "world"); obj.set("x", "world");
JsonObject &object = jb.createObject(); object.set(std::string("hello"), obj["x"]);
object.set(std::string("hello"), arr["x"]);
REQUIRE(std::string("world") == object["hello"]); REQUIRE(std::string("world") == object["hello"]);
} }
SECTION("JsonObject_Get") { SECTION("get<T>()") {
char json[] = "{\"key\":\"value\"}"; char json[] = "{\"key\":\"value\"}";
const JsonObject &object = jb.parseObject(json); deserializeJson(object, json);
REQUIRE(std::string("value") == REQUIRE(std::string("value") ==
object.get<const char *>(std::string("key"))); object.get<const char *>(std::string("key")));
} }
SECTION("JsonObject_GetT") { SECTION("is<T>()") {
char json[] = "{\"key\":\"value\"}"; char json[] = "{\"key\":\"value\"}";
const JsonObject &object = jb.parseObject(json); deserializeJson(object, json);
REQUIRE(std::string("value") ==
object.get<const char *>(std::string("key")));
}
SECTION("JsonObject_IsT") {
char json[] = "{\"key\":\"value\"}";
const JsonObject &object = jb.parseObject(json);
REQUIRE(true == object.is<const char *>(std::string("key"))); REQUIRE(true == object.is<const char *>(std::string("key")));
} }
SECTION("JsonObject_CreateNestedObject") { SECTION("createNestedObject()") {
std::string key = "key"; std::string key = "key";
char json[64]; char json[64];
JsonObject &object = jb.createObject();
object.createNestedObject(key); object.createNestedObject(key);
eraseString(key); eraseString(key);
object.printTo(json, sizeof(json)); object.printTo(json, sizeof(json));
REQUIRE(std::string("{\"key\":{}}") == json); REQUIRE(std::string("{\"key\":{}}") == json);
} }
SECTION("JsonObject_CreateNestedArray") { SECTION("createNestedArray()") {
std::string key = "key"; std::string key = "key";
char json[64]; char json[64];
JsonObject &object = jb.createObject();
object.createNestedArray(key); object.createNestedArray(key);
eraseString(key); eraseString(key);
object.printTo(json, sizeof(json)); object.printTo(json, sizeof(json));
REQUIRE(std::string("{\"key\":[]}") == json); REQUIRE(std::string("{\"key\":[]}") == json);
} }
SECTION("JsonObject_ContainsKey") { SECTION("containsKey()") {
char json[] = "{\"key\":\"value\"}"; char json[] = "{\"key\":\"value\"}";
const JsonObject &object = jb.parseObject(json); deserializeJson(object, json);
REQUIRE(true == object.containsKey(std::string("key"))); REQUIRE(true == object.containsKey(std::string("key")));
} }
SECTION("JsonObject_Remove") { SECTION("remove()") {
char json[] = "{\"key\":\"value\"}"; char json[] = "{\"key\":\"value\"}";
JsonObject &object = jb.parseObject(json); deserializeJson(object, json);
REQUIRE(1 == object.size()); REQUIRE(1 == object.size());
object.remove(std::string("key")); object.remove(std::string("key"));
REQUIRE(0 == object.size()); REQUIRE(0 == object.size());
} }
SECTION("JsonObjectSubscript_SetKey") { SECTION("operator[], set key") {
JsonObject &object = jb.createObject();
std::string key("hello"); std::string key("hello");
object[key] = "world"; object[key] = "world";
eraseString(key); eraseString(key);
REQUIRE(std::string("world") == object["hello"]); REQUIRE(std::string("world") == object["hello"]);
} }
SECTION("JsonObjectSubscript_SetValue") { SECTION("operator[], set value") {
JsonObject &object = jb.createObject();
std::string value("world"); std::string value("world");
object["hello"] = value; object["hello"] = value;
eraseString(value); eraseString(value);
REQUIRE(std::string("world") == object["hello"]); REQUIRE(std::string("world") == object["hello"]);
} }
SECTION("JsonArray_Add") { SECTION("printTo") {
JsonArray &array = jb.createArray();
std::string value("hello");
array.add(value);
eraseString(value);
REQUIRE(std::string("hello") == array[0]);
}
SECTION("JsonArray_Set") {
JsonArray &array = jb.createArray();
std::string value("world");
array.add("hello");
array.set(0, value);
eraseString(value);
REQUIRE(std::string("world") == array[0]);
}
SECTION("JsonArraySubscript") {
JsonArray &array = jb.createArray();
std::string value("world");
array.add("hello");
array[0] = value;
eraseString(value);
REQUIRE(std::string("world") == array[0]);
}
SECTION("JsonArray_PrintTo") {
JsonArray &array = jb.createArray();
array.add(4);
array.add(2);
std::string json;
array.printTo(json);
REQUIRE(std::string("[4,2]") == json);
}
SECTION("JsonArray_PrettyPrintTo") {
JsonArray &array = jb.createArray();
array.add(4);
array.add(2);
std::string json;
array.prettyPrintTo(json);
REQUIRE(std::string("[\r\n 4,\r\n 2\r\n]") == json);
}
SECTION("JsonObject_PrintTo") {
JsonObject &object = jb.createObject();
object["key"] = "value"; object["key"] = "value";
std::string json; std::string json;
object.printTo(json); object.printTo(json);
REQUIRE(std::string("{\"key\":\"value\"}") == json); REQUIRE(std::string("{\"key\":\"value\"}") == json);
} }
SECTION("JsonObject_PrettyPrintTo") { SECTION("prettyPrintTo") {
JsonObject &object = jb.createObject();
object["key"] = "value"; object["key"] = "value";
std::string json; std::string json;
object.prettyPrintTo(json); object.prettyPrintTo(json);
REQUIRE(std::string("{\r\n \"key\": \"value\"\r\n}") == json); REQUIRE(std::string("{\r\n \"key\": \"value\"\r\n}") == json);
} }
SECTION("JsonBuffer_GrowWhenAddingNewKey") { SECTION("memoryUsage() increases when adding a new key") {
JsonObject &object = jb.createObject();
std::string key1("hello"), key2("world"); std::string key1("hello"), key2("world");
object[key1] = 1; object[key1] = 1;
size_t sizeBefore = jb.size(); size_t sizeBefore = object.memoryUsage();
object[key2] = 2; object[key2] = 2;
size_t sizeAfter = jb.size(); size_t sizeAfter = object.memoryUsage();
REQUIRE(sizeAfter - sizeBefore >= key2.size()); REQUIRE(sizeAfter - sizeBefore >= key2.size());
} }
SECTION("JsonBuffer_DontGrowWhenReusingKey") { SECTION("memoryUsage() remains when adding the same key") {
JsonObject &object = jb.createObject();
std::string key("hello"); std::string key("hello");
object[key] = 1; object[key] = 1;
size_t sizeBefore = jb.size(); size_t sizeBefore = object.memoryUsage();
object[key] = 2; object[key] = 2;
size_t sizeAfter = jb.size(); size_t sizeAfter = object.memoryUsage();
REQUIRE(sizeBefore == sizeAfter); REQUIRE(sizeBefore == sizeAfter);
} }
}
} }

View File

@ -13,19 +13,19 @@ TEST_CASE("unsigned char string") {
SECTION("JsonBuffer::parseArray") { SECTION("JsonBuffer::parseArray") {
unsigned char json[] = "[42]"; unsigned char json[] = "[42]";
StaticJsonBuffer<JSON_ARRAY_SIZE(1)> jsonBuffer; StaticJsonArray<JSON_ARRAY_SIZE(1)> arr;
JsonArray& arr = jsonBuffer.parseArray(json); bool success = deserializeJson(arr, json);
REQUIRE(true == arr.success()); REQUIRE(true == success);
} }
SECTION("JsonBuffer::parseObject") { SECTION("JsonBuffer::parseObject") {
unsigned char json[] = "{\"a\":42}"; unsigned char json[] = "{\"a\":42}";
StaticJsonBuffer<JSON_OBJECT_SIZE(1)> jsonBuffer; StaticJsonObject<JSON_OBJECT_SIZE(1)> obj;
JsonObject& obj = jsonBuffer.parseObject(json); bool success = deserializeJson(obj, json);
REQUIRE(true == obj.success()); REQUIRE(true == success);
} }
SECTION("JsonVariant constructor") { SECTION("JsonVariant constructor") {
@ -49,8 +49,8 @@ TEST_CASE("unsigned char string") {
SECTION("JsonVariant::operator[]") { SECTION("JsonVariant::operator[]") {
unsigned char key[] = "hello"; unsigned char key[] = "hello";
DynamicJsonBuffer jsonBuffer; DynamicJsonVariant variant;
JsonVariant variant = jsonBuffer.parseObject("{\"hello\":\"world\"}"); deserializeJson(variant, "{\"hello\":\"world\"}");
REQUIRE(std::string("world") == variant[key]); REQUIRE(std::string("world") == variant[key]);
} }
@ -60,8 +60,8 @@ TEST_CASE("unsigned char string") {
SECTION("JsonVariant::operator[] const") { SECTION("JsonVariant::operator[] const") {
unsigned char key[] = "hello"; unsigned char key[] = "hello";
DynamicJsonBuffer jsonBuffer; DynamicJsonVariant variant;
const JsonVariant variant = jsonBuffer.parseObject("{\"hello\":\"world\"}"); deserializeJson(variant, "{\"hello\":\"world\"}");
REQUIRE(std::string("world") == variant[key]); REQUIRE(std::string("world") == variant[key]);
} }
@ -70,8 +70,8 @@ TEST_CASE("unsigned char string") {
SECTION("JsonVariant::operator==") { SECTION("JsonVariant::operator==") {
unsigned char comparand[] = "hello"; unsigned char comparand[] = "hello";
DynamicJsonBuffer jsonBuffer; DynamicJsonVariant variant;
const JsonVariant variant = "hello"; variant = "hello";
REQUIRE(comparand == variant); REQUIRE(comparand == variant);
REQUIRE(variant == comparand); REQUIRE(variant == comparand);
@ -82,8 +82,8 @@ TEST_CASE("unsigned char string") {
SECTION("JsonVariant::operator!=") { SECTION("JsonVariant::operator!=") {
unsigned char comparand[] = "hello"; unsigned char comparand[] = "hello";
DynamicJsonBuffer jsonBuffer; DynamicJsonVariant variant;
const JsonVariant variant = "world"; variant = "world";
REQUIRE(comparand != variant); REQUIRE(comparand != variant);
REQUIRE(variant != comparand); REQUIRE(variant != comparand);
@ -95,8 +95,7 @@ TEST_CASE("unsigned char string") {
SECTION("JsonObject::operator[]") { SECTION("JsonObject::operator[]") {
unsigned char key[] = "hello"; unsigned char key[] = "hello";
DynamicJsonBuffer jsonBuffer; DynamicJsonObject obj;
JsonObject& obj = jsonBuffer.createObject();
obj[key] = "world"; obj[key] = "world";
REQUIRE(std::string("world") == obj["hello"]); REQUIRE(std::string("world") == obj["hello"]);
@ -106,8 +105,7 @@ TEST_CASE("unsigned char string") {
SECTION("JsonObjectSubscript::operator=") { // issue #416 SECTION("JsonObjectSubscript::operator=") { // issue #416
unsigned char value[] = "world"; unsigned char value[] = "world";
DynamicJsonBuffer jsonBuffer; DynamicJsonObject obj;
JsonObject& obj = jsonBuffer.createObject();
obj["hello"] = value; obj["hello"] = value;
REQUIRE(std::string("world") == obj["hello"]); REQUIRE(std::string("world") == obj["hello"]);
@ -116,8 +114,7 @@ TEST_CASE("unsigned char string") {
SECTION("JsonObjectSubscript::set()") { SECTION("JsonObjectSubscript::set()") {
unsigned char value[] = "world"; unsigned char value[] = "world";
DynamicJsonBuffer jsonBuffer; DynamicJsonObject obj;
JsonObject& obj = jsonBuffer.createObject();
obj["hello"].set(value); obj["hello"].set(value);
REQUIRE(std::string("world") == obj["hello"]); REQUIRE(std::string("world") == obj["hello"]);
@ -127,8 +124,8 @@ TEST_CASE("unsigned char string") {
SECTION("JsonObject::operator[] const") { SECTION("JsonObject::operator[] const") {
unsigned char key[] = "hello"; unsigned char key[] = "hello";
DynamicJsonBuffer jsonBuffer; DynamicJsonObject obj;
const JsonObject& obj = jsonBuffer.parseObject("{\"hello\":\"world\"}"); deserializeJson(obj, "{\"hello\":\"world\"}");
REQUIRE(std::string("world") == obj[key]); REQUIRE(std::string("world") == obj[key]);
} }
@ -137,8 +134,8 @@ TEST_CASE("unsigned char string") {
SECTION("JsonObject::get()") { SECTION("JsonObject::get()") {
unsigned char key[] = "hello"; unsigned char key[] = "hello";
DynamicJsonBuffer jsonBuffer; DynamicJsonObject obj;
JsonObject& obj = jsonBuffer.parseObject("{\"hello\":\"world\"}"); deserializeJson(obj, "{\"hello\":\"world\"}");
REQUIRE(std::string("world") == obj.get<char*>(key)); REQUIRE(std::string("world") == obj.get<char*>(key));
} }
@ -146,8 +143,7 @@ TEST_CASE("unsigned char string") {
SECTION("JsonObject::set() key") { SECTION("JsonObject::set() key") {
unsigned char key[] = "hello"; unsigned char key[] = "hello";
DynamicJsonBuffer jsonBuffer; DynamicJsonObject obj;
JsonObject& obj = jsonBuffer.createObject();
obj.set(key, "world"); obj.set(key, "world");
REQUIRE(std::string("world") == obj["hello"]); REQUIRE(std::string("world") == obj["hello"]);
@ -156,8 +152,7 @@ TEST_CASE("unsigned char string") {
SECTION("JsonObject::set() value") { SECTION("JsonObject::set() value") {
unsigned char value[] = "world"; unsigned char value[] = "world";
DynamicJsonBuffer jsonBuffer; DynamicJsonObject obj;
JsonObject& obj = jsonBuffer.createObject();
obj.set("hello", value); obj.set("hello", value);
REQUIRE(std::string("world") == obj["hello"]); REQUIRE(std::string("world") == obj["hello"]);
@ -166,8 +161,7 @@ TEST_CASE("unsigned char string") {
SECTION("JsonObject::set key&value") { SECTION("JsonObject::set key&value") {
unsigned char key[] = "world"; unsigned char key[] = "world";
DynamicJsonBuffer jsonBuffer; DynamicJsonObject obj;
JsonObject& obj = jsonBuffer.createObject();
obj.set(key, key); obj.set(key, key);
REQUIRE(std::string("world") == obj["world"]); REQUIRE(std::string("world") == obj["world"]);
@ -176,8 +170,8 @@ TEST_CASE("unsigned char string") {
SECTION("JsonObject::containsKey()") { SECTION("JsonObject::containsKey()") {
unsigned char key[] = "hello"; unsigned char key[] = "hello";
DynamicJsonBuffer jsonBuffer; DynamicJsonObject obj;
const JsonObject& obj = jsonBuffer.parseObject("{\"hello\":\"world\"}"); deserializeJson(obj, "{\"hello\":\"world\"}");
REQUIRE(true == obj.containsKey(key)); REQUIRE(true == obj.containsKey(key));
} }
@ -185,8 +179,8 @@ TEST_CASE("unsigned char string") {
SECTION("JsonObject::remove()") { SECTION("JsonObject::remove()") {
unsigned char key[] = "hello"; unsigned char key[] = "hello";
DynamicJsonBuffer jsonBuffer; DynamicJsonObject obj;
JsonObject& obj = jsonBuffer.parseObject("{\"hello\":\"world\"}"); deserializeJson(obj, "{\"hello\":\"world\"}");
obj.remove(key); obj.remove(key);
REQUIRE(0 == obj.size()); REQUIRE(0 == obj.size());
@ -195,8 +189,8 @@ TEST_CASE("unsigned char string") {
SECTION("JsonObject::is()") { SECTION("JsonObject::is()") {
unsigned char key[] = "hello"; unsigned char key[] = "hello";
DynamicJsonBuffer jsonBuffer; DynamicJsonObject obj;
JsonObject& obj = jsonBuffer.parseObject("{\"hello\":42}"); deserializeJson(obj, "{\"hello\":42}");
REQUIRE(true == obj.is<int>(key)); REQUIRE(true == obj.is<int>(key));
} }
@ -204,24 +198,21 @@ TEST_CASE("unsigned char string") {
SECTION("JsonObject::createNestedArray()") { SECTION("JsonObject::createNestedArray()") {
unsigned char key[] = "hello"; unsigned char key[] = "hello";
DynamicJsonBuffer jsonBuffer; DynamicJsonObject obj;
JsonObject& obj = jsonBuffer.createObject();
obj.createNestedArray(key); obj.createNestedArray(key);
} }
SECTION("JsonObject::createNestedObject()") { SECTION("JsonObject::createNestedObject()") {
unsigned char key[] = "hello"; unsigned char key[] = "hello";
DynamicJsonBuffer jsonBuffer; DynamicJsonObject obj;
JsonObject& obj = jsonBuffer.createObject();
obj.createNestedObject(key); obj.createNestedObject(key);
} }
SECTION("JsonArray::add()") { SECTION("JsonArray::add()") {
unsigned char value[] = "world"; unsigned char value[] = "world";
DynamicJsonBuffer jsonBuffer; DynamicJsonArray arr;
JsonArray& arr = jsonBuffer.createArray();
arr.add(value); arr.add(value);
REQUIRE(std::string("world") == arr[0]); REQUIRE(std::string("world") == arr[0]);
@ -230,8 +221,7 @@ TEST_CASE("unsigned char string") {
SECTION("JsonArray::set()") { SECTION("JsonArray::set()") {
unsigned char value[] = "world"; unsigned char value[] = "world";
DynamicJsonBuffer jsonBuffer; DynamicJsonArray arr;
JsonArray& arr = jsonBuffer.createArray();
arr.add("hello"); arr.add("hello");
arr.set(0, value); arr.set(0, value);
@ -241,8 +231,7 @@ TEST_CASE("unsigned char string") {
SECTION("JsonArraySubscript::set()") { SECTION("JsonArraySubscript::set()") {
unsigned char value[] = "world"; unsigned char value[] = "world";
DynamicJsonBuffer jsonBuffer; DynamicJsonArray arr;
JsonArray& arr = jsonBuffer.createArray();
arr.add("hello"); arr.add("hello");
arr[0].set(value); arr[0].set(value);
@ -252,8 +241,7 @@ TEST_CASE("unsigned char string") {
SECTION("JsonArraySubscript::operator=") { SECTION("JsonArraySubscript::operator=") {
unsigned char value[] = "world"; unsigned char value[] = "world";
DynamicJsonBuffer jsonBuffer; DynamicJsonArray arr;
JsonArray& arr = jsonBuffer.createArray();
arr.add("hello"); arr.add("hello");
arr[0] = value; arr[0] = value;

View File

@ -22,10 +22,10 @@ TEST_CASE("Variable Length Array") {
char vla[i]; char vla[i];
strcpy(vla, "[42]"); strcpy(vla, "[42]");
StaticJsonBuffer<JSON_ARRAY_SIZE(1)> jsonBuffer; StaticJsonArray<JSON_ARRAY_SIZE(1)> arr;
JsonArray& arr = jsonBuffer.parseArray(vla); bool success = deserializeJson(arr, vla);
REQUIRE(true == arr.success()); REQUIRE(true == success);
} }
SECTION("ParseObject") { SECTION("ParseObject") {
@ -33,8 +33,8 @@ TEST_CASE("Variable Length Array") {
char vla[i]; char vla[i];
strcpy(vla, "{\"a\":42}"); strcpy(vla, "{\"a\":42}");
StaticJsonBuffer<JSON_OBJECT_SIZE(1)> jsonBuffer; StaticJsonObject<JSON_OBJECT_SIZE(1)> obj;
JsonObject& obj = jsonBuffer.parseObject(vla); deserializeJson(obj, vla);
REQUIRE(true == obj.success()); REQUIRE(true == obj.success());
} }
@ -44,8 +44,8 @@ TEST_CASE("Variable Length Array") {
char vla[i]; char vla[i];
strcpy(vla, "42"); strcpy(vla, "42");
StaticJsonBuffer<1> jsonBuffer; StaticJsonVariant<> variant;
JsonVariant variant = jsonBuffer.parse(vla); deserializeJson(variant, vla);
REQUIRE(42 == variant.as<int>()); REQUIRE(42 == variant.as<int>());
} }
@ -77,8 +77,8 @@ TEST_CASE("Variable Length Array") {
char vla[i]; char vla[i];
strcpy(vla, "hello"); strcpy(vla, "hello");
DynamicJsonBuffer jsonBuffer; DynamicJsonVariant variant;
JsonVariant variant = jsonBuffer.parseObject("{\"hello\":\"world\"}"); deserializeJson(variant, "{\"hello\":\"world\"}");
REQUIRE(std::string("world") == variant[vla]); REQUIRE(std::string("world") == variant[vla]);
} }
@ -90,8 +90,8 @@ TEST_CASE("Variable Length Array") {
char vla[i]; char vla[i];
strcpy(vla, "hello"); strcpy(vla, "hello");
DynamicJsonBuffer jsonBuffer; DynamicJsonVariant variant;
const JsonVariant variant = jsonBuffer.parseObject("{\"hello\":\"world\"}"); deserializeJson(variant, "{\"hello\":\"world\"}");
REQUIRE(std::string("world") == variant[vla]); REQUIRE(std::string("world") == variant[vla]);
} }
@ -102,8 +102,8 @@ TEST_CASE("Variable Length Array") {
char vla[i]; char vla[i];
strcpy(vla, "hello"); strcpy(vla, "hello");
DynamicJsonBuffer jsonBuffer; DynamicJsonVariant variant;
const JsonVariant variant = "hello"; variant = "hello";
REQUIRE((vla == variant)); REQUIRE((vla == variant));
REQUIRE((variant == vla)); REQUIRE((variant == vla));
@ -116,8 +116,8 @@ TEST_CASE("Variable Length Array") {
char vla[i]; char vla[i];
strcpy(vla, "hello"); strcpy(vla, "hello");
DynamicJsonBuffer jsonBuffer; DynamicJsonVariant variant;
const JsonVariant variant = "world"; variant = "world";
REQUIRE((vla != variant)); REQUIRE((vla != variant));
REQUIRE((variant != vla)); REQUIRE((variant != vla));
@ -131,8 +131,7 @@ TEST_CASE("Variable Length Array") {
char vla[i]; char vla[i];
strcpy(vla, "hello"); strcpy(vla, "hello");
DynamicJsonBuffer jsonBuffer; DynamicJsonObject obj;
JsonObject& obj = jsonBuffer.createObject();
obj[vla] = "world"; obj[vla] = "world";
REQUIRE(std::string("world") == obj["hello"]); REQUIRE(std::string("world") == obj["hello"]);
@ -144,8 +143,7 @@ TEST_CASE("Variable Length Array") {
char vla[i]; char vla[i];
strcpy(vla, "world"); strcpy(vla, "world");
DynamicJsonBuffer jsonBuffer; DynamicJsonObject obj;
JsonObject& obj = jsonBuffer.createObject();
obj["hello"] = vla; obj["hello"] = vla;
REQUIRE(std::string("world") == obj["hello"].as<char*>()); REQUIRE(std::string("world") == obj["hello"].as<char*>());
@ -156,8 +154,7 @@ TEST_CASE("Variable Length Array") {
char vla[i]; char vla[i];
strcpy(vla, "world"); strcpy(vla, "world");
DynamicJsonBuffer jsonBuffer; DynamicJsonObject obj;
JsonObject& obj = jsonBuffer.createObject();
obj["hello"].set(vla); obj["hello"].set(vla);
REQUIRE(std::string("world") == obj["hello"].as<char*>()); REQUIRE(std::string("world") == obj["hello"].as<char*>());
@ -169,8 +166,8 @@ TEST_CASE("Variable Length Array") {
char vla[i]; char vla[i];
strcpy(vla, "hello"); strcpy(vla, "hello");
DynamicJsonBuffer jsonBuffer; DynamicJsonObject obj;
const JsonObject& obj = jsonBuffer.parseObject("{\"hello\":\"world\"}"); deserializeJson(obj, "{\"hello\":\"world\"}");
REQUIRE(std::string("world") == obj[vla]); REQUIRE(std::string("world") == obj[vla]);
} }
@ -181,8 +178,8 @@ TEST_CASE("Variable Length Array") {
char vla[i]; char vla[i];
strcpy(vla, "hello"); strcpy(vla, "hello");
DynamicJsonBuffer jsonBuffer; DynamicJsonObject obj;
JsonObject& obj = jsonBuffer.parseObject("{\"hello\":\"world\"}"); deserializeJson(obj, "{\"hello\":\"world\"}");
REQUIRE(std::string("world") == obj.get<char*>(vla)); REQUIRE(std::string("world") == obj.get<char*>(vla));
} }
@ -192,8 +189,7 @@ TEST_CASE("Variable Length Array") {
char vla[i]; char vla[i];
strcpy(vla, "hello"); strcpy(vla, "hello");
DynamicJsonBuffer jsonBuffer; DynamicJsonObject obj;
JsonObject& obj = jsonBuffer.createObject();
obj.set(vla, "world"); obj.set(vla, "world");
REQUIRE(std::string("world") == obj["hello"]); REQUIRE(std::string("world") == obj["hello"]);
@ -204,8 +200,7 @@ TEST_CASE("Variable Length Array") {
char vla[i]; char vla[i];
strcpy(vla, "world"); strcpy(vla, "world");
DynamicJsonBuffer jsonBuffer; DynamicJsonObject obj;
JsonObject& obj = jsonBuffer.createObject();
obj.set("hello", vla); obj.set("hello", vla);
REQUIRE(std::string("world") == obj["hello"]); REQUIRE(std::string("world") == obj["hello"]);
@ -216,8 +211,7 @@ TEST_CASE("Variable Length Array") {
char vla[i]; char vla[i];
strcpy(vla, "world"); strcpy(vla, "world");
DynamicJsonBuffer jsonBuffer; DynamicJsonObject obj;
JsonObject& obj = jsonBuffer.createObject();
obj.set(vla, vla); obj.set(vla, vla);
REQUIRE(std::string("world") == obj["world"]); REQUIRE(std::string("world") == obj["world"]);
@ -228,8 +222,8 @@ TEST_CASE("Variable Length Array") {
char vla[i]; char vla[i];
strcpy(vla, "hello"); strcpy(vla, "hello");
DynamicJsonBuffer jsonBuffer; DynamicJsonObject obj;
const JsonObject& obj = jsonBuffer.parseObject("{\"hello\":\"world\"}"); deserializeJson(obj, "{\"hello\":\"world\"}");
REQUIRE(true == obj.containsKey(vla)); REQUIRE(true == obj.containsKey(vla));
} }
@ -239,8 +233,8 @@ TEST_CASE("Variable Length Array") {
char vla[i]; char vla[i];
strcpy(vla, "hello"); strcpy(vla, "hello");
DynamicJsonBuffer jsonBuffer; DynamicJsonObject obj;
JsonObject& obj = jsonBuffer.parseObject("{\"hello\":\"world\"}"); deserializeJson(obj, "{\"hello\":\"world\"}");
obj.remove(vla); obj.remove(vla);
REQUIRE(0 == obj.size()); REQUIRE(0 == obj.size());
@ -251,8 +245,8 @@ TEST_CASE("Variable Length Array") {
char vla[i]; char vla[i];
strcpy(vla, "hello"); strcpy(vla, "hello");
DynamicJsonBuffer jsonBuffer; DynamicJsonObject obj;
JsonObject& obj = jsonBuffer.parseObject("{\"hello\":42}"); deserializeJson(obj, "{\"hello\":42}");
REQUIRE(true == obj.is<int>(vla)); REQUIRE(true == obj.is<int>(vla));
} }
@ -262,8 +256,7 @@ TEST_CASE("Variable Length Array") {
char vla[i]; char vla[i];
strcpy(vla, "hello"); strcpy(vla, "hello");
DynamicJsonBuffer jsonBuffer; DynamicJsonObject obj;
JsonObject& obj = jsonBuffer.createObject();
obj.createNestedArray(vla); obj.createNestedArray(vla);
} }
@ -272,8 +265,7 @@ TEST_CASE("Variable Length Array") {
char vla[i]; char vla[i];
strcpy(vla, "hello"); strcpy(vla, "hello");
DynamicJsonBuffer jsonBuffer; DynamicJsonObject obj;
JsonObject& obj = jsonBuffer.createObject();
obj.createNestedObject(vla); obj.createNestedObject(vla);
} }
@ -282,8 +274,7 @@ TEST_CASE("Variable Length Array") {
char vla[i]; char vla[i];
strcpy(vla, "world"); strcpy(vla, "world");
DynamicJsonBuffer jsonBuffer; DynamicJsonArray arr;
JsonArray& arr = jsonBuffer.createArray();
arr.add(vla); arr.add(vla);
REQUIRE(std::string("world") == arr[0]); REQUIRE(std::string("world") == arr[0]);
@ -294,8 +285,7 @@ TEST_CASE("Variable Length Array") {
char vla[i]; char vla[i];
strcpy(vla, "world"); strcpy(vla, "world");
DynamicJsonBuffer jsonBuffer; DynamicJsonArray arr;
JsonArray& arr = jsonBuffer.createArray();
arr.add("hello"); arr.add("hello");
arr.set(0, vla); arr.set(0, vla);
@ -307,8 +297,7 @@ TEST_CASE("Variable Length Array") {
char vla[i]; char vla[i];
strcpy(vla, "world"); strcpy(vla, "world");
DynamicJsonBuffer jsonBuffer; DynamicJsonArray arr;
JsonArray& arr = jsonBuffer.createArray();
arr.add("hello"); arr.add("hello");
arr[0].set(vla); arr[0].set(vla);
@ -320,8 +309,7 @@ TEST_CASE("Variable Length Array") {
char vla[i]; char vla[i];
strcpy(vla, "world"); strcpy(vla, "world");
DynamicJsonBuffer jsonBuffer; DynamicJsonArray arr;
JsonArray& arr = jsonBuffer.createArray();
arr.add("hello"); arr.add("hello");
arr[0] = vla; arr[0] = vla;

View File

@ -4,10 +4,6 @@
add_executable(StaticJsonBufferTests add_executable(StaticJsonBufferTests
alloc.cpp alloc.cpp
createArray.cpp
createObject.cpp
parseArray.cpp
parseObject.cpp
size.cpp size.cpp
startString.cpp startString.cpp
) )

View File

@ -1,45 +0,0 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("StaticJsonBuffer::createArray()") {
SECTION("GrowsWithArray") {
StaticJsonBuffer<JSON_ARRAY_SIZE(2)> json;
JsonArray &array = json.createArray();
REQUIRE(JSON_ARRAY_SIZE(0) == json.size());
array.add("hello");
REQUIRE(JSON_ARRAY_SIZE(1) == json.size());
array.add("world");
REQUIRE(JSON_ARRAY_SIZE(2) == json.size());
}
SECTION("SucceedWhenBigEnough") {
StaticJsonBuffer<JSON_ARRAY_SIZE(0)> json;
JsonArray &array = json.createArray();
REQUIRE(array.success());
}
SECTION("FailsWhenTooSmall") {
StaticJsonBuffer<JSON_ARRAY_SIZE(0) - 1> json;
JsonArray &array = json.createArray();
REQUIRE_FALSE(array.success());
}
SECTION("ArrayDoesntGrowWhenFull") {
StaticJsonBuffer<JSON_ARRAY_SIZE(1)> json;
JsonArray &array = json.createArray();
array.add("hello");
array.add("world");
REQUIRE(1 == array.size());
}
}

View File

@ -1,56 +0,0 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("StaticJsonBuffer::createObject()") {
SECTION("GrowsWithObject") {
StaticJsonBuffer<JSON_OBJECT_SIZE(3)> buffer;
JsonObject &obj = buffer.createObject();
REQUIRE(JSON_OBJECT_SIZE(0) == buffer.size());
obj["hello"];
REQUIRE(JSON_OBJECT_SIZE(0) == buffer.size());
obj["hello"] = 1;
REQUIRE(JSON_OBJECT_SIZE(1) == buffer.size());
obj["world"] = 2;
REQUIRE(JSON_OBJECT_SIZE(2) == buffer.size());
obj["world"] = 3; // <- same key, should not grow
REQUIRE(JSON_OBJECT_SIZE(2) == buffer.size());
}
SECTION("SucceedWhenBigEnough") {
StaticJsonBuffer<JSON_OBJECT_SIZE(0)> buffer;
JsonObject &object = buffer.createObject();
REQUIRE(object.success());
}
SECTION("FailsWhenTooSmall") {
StaticJsonBuffer<JSON_OBJECT_SIZE(0) - 1> buffer;
JsonObject &object = buffer.createObject();
REQUIRE_FALSE(object.success());
}
SECTION("ObjectDoesntGrowWhenFull") {
StaticJsonBuffer<JSON_OBJECT_SIZE(1)> buffer;
JsonObject &obj = buffer.createObject();
obj["hello"] = 1;
obj["world"] = 2;
REQUIRE(JSON_OBJECT_SIZE(1) == buffer.size());
REQUIRE(1 == obj.size());
char json[64];
obj.printTo(json, sizeof(json));
REQUIRE(std::string("{\"hello\":1}") == json);
}
}

View File

@ -1,71 +0,0 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("StaticJsonBuffer::parseArray()") {
SECTION("TooSmallBufferForEmptyArray") {
StaticJsonBuffer<JSON_ARRAY_SIZE(0) - 1> bufferTooSmall;
char input[] = "[]";
JsonArray& arr = bufferTooSmall.parseArray(input);
REQUIRE_FALSE(arr.success());
}
SECTION("BufferOfTheRightSizeForEmptyArray") {
StaticJsonBuffer<JSON_ARRAY_SIZE(0)> bufferOfRightSize;
char input[] = "[]";
JsonArray& arr = bufferOfRightSize.parseArray(input);
REQUIRE(arr.success());
}
SECTION("TooSmallBufferForArrayWithOneValue") {
StaticJsonBuffer<JSON_ARRAY_SIZE(1) - 1> bufferTooSmall;
char input[] = "[1]";
JsonArray& arr = bufferTooSmall.parseArray(input);
REQUIRE_FALSE(arr.success());
}
SECTION("BufferOfTheRightSizeForArrayWithOneValue") {
StaticJsonBuffer<JSON_ARRAY_SIZE(1)> bufferOfRightSize;
char input[] = "[1]";
JsonArray& arr = bufferOfRightSize.parseArray(input);
REQUIRE(arr.success());
}
SECTION("TooSmallBufferForArrayWithNestedObject") {
StaticJsonBuffer<JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(0) - 1>
bufferTooSmall;
char input[] = "[{}]";
JsonArray& arr = bufferTooSmall.parseArray(input);
REQUIRE_FALSE(arr.success());
}
SECTION("BufferOfTheRightSizeForArrayWithNestedObject") {
StaticJsonBuffer<JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(0)>
bufferOfRightSize;
char input[] = "[{}]";
JsonArray& arr = bufferOfRightSize.parseArray(input);
REQUIRE(arr.success());
}
SECTION("CharPtrNull") {
REQUIRE_FALSE(
StaticJsonBuffer<100>().parseArray(static_cast<char*>(0)).success());
}
SECTION("ConstCharPtrNull") {
REQUIRE_FALSE(StaticJsonBuffer<100>()
.parseArray(static_cast<const char*>(0))
.success());
}
SECTION("CopyStringNotSpaces") {
StaticJsonBuffer<100> jsonBuffer;
jsonBuffer.parseArray(" [ \"1234567\" ] ");
REQUIRE(JSON_ARRAY_SIZE(1) + sizeof("1234567") == jsonBuffer.size());
// note we use a string of 8 bytes to be sure that the StaticJsonBuffer
// will not insert bytes to enforce alignement
}
}

View File

@ -1,62 +0,0 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("StaticJsonBuffer::parseObject()") {
SECTION("TooSmallBufferForEmptyObject") {
StaticJsonBuffer<JSON_OBJECT_SIZE(0) - 1> bufferTooSmall;
char input[] = "{}";
JsonObject& obj = bufferTooSmall.parseObject(input);
REQUIRE_FALSE(obj.success());
}
SECTION("BufferOfTheRightSizeForEmptyObject") {
StaticJsonBuffer<JSON_OBJECT_SIZE(0)> bufferOfRightSize;
char input[] = "{}";
JsonObject& obj = bufferOfRightSize.parseObject(input);
REQUIRE(obj.success());
}
SECTION("TooSmallBufferForObjectWithOneValue") {
StaticJsonBuffer<JSON_OBJECT_SIZE(1) - 1> bufferTooSmall;
char input[] = "{\"a\":1}";
JsonObject& obj = bufferTooSmall.parseObject(input);
REQUIRE_FALSE(obj.success());
}
SECTION("BufferOfTheRightSizeForObjectWithOneValue") {
StaticJsonBuffer<JSON_OBJECT_SIZE(1)> bufferOfRightSize;
char input[] = "{\"a\":1}";
JsonObject& obj = bufferOfRightSize.parseObject(input);
REQUIRE(obj.success());
}
SECTION("TooSmallBufferForObjectWithNestedObject") {
StaticJsonBuffer<JSON_OBJECT_SIZE(1) + JSON_ARRAY_SIZE(0) - 1>
bufferTooSmall;
char input[] = "{\"a\":[]}";
JsonObject& obj = bufferTooSmall.parseObject(input);
REQUIRE_FALSE(obj.success());
}
SECTION("BufferOfTheRightSizeForObjectWithNestedObject") {
StaticJsonBuffer<JSON_OBJECT_SIZE(1) + JSON_ARRAY_SIZE(0)>
bufferOfRightSize;
char input[] = "{\"a\":[]}";
JsonObject& obj = bufferOfRightSize.parseObject(input);
REQUIRE(obj.success());
}
SECTION("CharPtrNull") {
REQUIRE_FALSE(
StaticJsonBuffer<100>().parseObject(static_cast<char*>(0)).success());
}
SECTION("ConstCharPtrNull") {
REQUIRE_FALSE(StaticJsonBuffer<100>()
.parseObject(static_cast<const char*>(0))
.success());
}
}