Formated code with clang-format

This commit is contained in:
Benoit Blanchon
2014-10-23 19:54:00 +02:00
parent 888fdc1d54
commit 9175046f35
52 changed files with 2002 additions and 2638 deletions

1
.clang-format Normal file
View File

@ -0,0 +1 @@
BasedOnStyle: LLVM

View File

@ -11,16 +11,14 @@
#include <stdint.h> #include <stdint.h>
// This class reproduces Arduino's Print // This class reproduces Arduino's Print
class Print class Print {
{
public: public:
virtual size_t write(uint8_t) = 0;
virtual size_t write(uint8_t) = 0; size_t print(const char[]);
size_t print(double, int = 2);
size_t print(const char[]); size_t print(long);
size_t print(double, int = 2); size_t println();
size_t print(long);
size_t println();
}; };
#else #else

View File

@ -11,11 +11,9 @@
class Print; class Print;
class Printable class Printable {
{
public: public:
virtual size_t printTo(Print &p) const = 0;
virtual size_t printTo(Print& p) const = 0;
}; };
#else #else
@ -23,4 +21,3 @@ public:
#include <Printable.h> #include <Printable.h>
#endif #endif

View File

@ -2,47 +2,23 @@
#include "ArduinoJson/Internals/JsonWriter.hpp" #include "ArduinoJson/Internals/JsonWriter.hpp"
namespace ArduinoJson namespace ArduinoJson {
{ namespace Internals {
namespace Internals class CompactJsonWriter : public JsonWriter {
{ public:
class CompactJsonWriter : public JsonWriter explicit CompactJsonWriter(Print *sink) : JsonWriter(sink) {}
{
public:
explicit CompactJsonWriter(Print* sink)
: JsonWriter(sink)
{
}
virtual void beginArray() virtual void beginArray() { _length += _sink->write('['); }
{
_length += _sink->write('[');
}
virtual void endArray() virtual void endArray() { _length += _sink->write(']'); }
{
_length += _sink->write(']');
}
virtual void writeColon() virtual void writeColon() { _length += _sink->write(':'); }
{
_length += _sink->write(':');
}
virtual void writeComma() virtual void writeComma() { _length += _sink->write(','); }
{
_length += _sink->write(',');
}
virtual void beginObject() virtual void beginObject() { _length += _sink->write('{'); }
{
_length += _sink->write('{');
}
virtual void endObject() virtual void endObject() { _length += _sink->write('}'); }
{ };
_length += _sink->write('}'); }
}
};
}
} }

View File

@ -7,47 +7,40 @@
#include "../Arduino/Print.hpp" #include "../Arduino/Print.hpp"
namespace ArduinoJson namespace ArduinoJson {
{ namespace Internals {
namespace Internals // Decorator on top of Print to allow indented output.
{ // This class is used by JsonPrintable::prettyPrintTo() but can also be used
// Decorator on top of Print to allow indented output. // for your own purpose, like logging.
// This class is used by JsonPrintable::prettyPrintTo() but can also be used class IndentedPrint : public Print {
// for your own purpose, like logging. public:
class IndentedPrint : public Print IndentedPrint(Print &p) : sink(&p) {
{ level = 0;
public: tabSize = 2;
isNewLine = true;
}
IndentedPrint(Print& p) virtual size_t write(uint8_t);
: sink(&p)
{
level = 0;
tabSize = 2;
isNewLine = true;
}
virtual size_t write(uint8_t); // Adds one level of indentation
void indent();
// Adds one level of indentation // Removes one level of indentation
void indent(); void unindent();
// Removes one level of indentation // Set the number of space printed for each level of indentation
void unindent(); void setTabSize(uint8_t n);
// Set the number of space printed for each level of indentation private:
void setTabSize(uint8_t n); Print *sink;
uint8_t level : 4;
uint8_t tabSize : 3;
bool isNewLine : 1;
private: size_t writeTabs();
Print* sink;
uint8_t level : 4;
uint8_t tabSize : 3;
bool isNewLine : 1;
size_t writeTabs();
static const int MAX_LEVEL = 15; // because it's only 4 bits static const int MAX_LEVEL = 15; // because it's only 4 bits
static const int MAX_TAB_SIZE = 7; // because it's only 3 bits static const int MAX_TAB_SIZE = 7; // because it's only 3 bits
}; };
} }
} }

View File

@ -1,191 +1,159 @@
#pragma once #pragma once
namespace ArduinoJson namespace ArduinoJson {
{ class JsonBuffer;
class JsonBuffer;
namespace Internals namespace Internals {
{ class JsonWriter;
class JsonWriter;
class JsonNode class JsonNode {
{ enum JsonNodeType {
enum JsonNodeType JSON_UNDEFINED,
{ JSON_NULL,
JSON_UNDEFINED, JSON_ARRAY,
JSON_NULL, JSON_OBJECT,
JSON_ARRAY, JSON_KEY_VALUE,
JSON_OBJECT, JSON_BOOLEAN,
JSON_KEY_VALUE, JSON_STRING,
JSON_BOOLEAN, JSON_LONG,
JSON_STRING, JSON_PROXY,
JSON_LONG, JSON_DOUBLE_0_DECIMALS,
JSON_PROXY, JSON_DOUBLE_1_DECIMAL,
JSON_DOUBLE_0_DECIMALS, JSON_DOUBLE_2_DECIMALS
JSON_DOUBLE_1_DECIMAL, // etc.
JSON_DOUBLE_2_DECIMALS };
// etc.
};
union JsonNodeContent union JsonNodeContent {
{ bool asBoolean;
bool asBoolean; double asDouble;
double asDouble; long asInteger;
long asInteger; const char *asString;
const char* asString;
struct struct {
{ const char *key;
const char* key; JsonNode *value;
JsonNode* value; } asKeyValue;
} asKeyValue;
struct struct {
{ JsonNode *child;
JsonNode* child; JsonBuffer *buffer;
JsonBuffer* buffer; } asContainer;
} asContainer;
struct struct {
{ JsonNode *target;
JsonNode* target; } asProxy;
} asProxy; };
}; public:
JsonNode() : next(0), type(JSON_UNDEFINED) {}
public: JsonNode *next;
JsonNode()
: next(0), type(JSON_UNDEFINED)
{
} void writeTo(JsonWriter &); // TODO: <- move in JsonNodeSerializer
JsonNode* next; void setAsArray(JsonBuffer *buffer) {
type = JSON_ARRAY;
content.asContainer.child = 0;
content.asContainer.buffer = buffer;
}
void writeTo(JsonWriter&); // TODO: <- move in JsonNodeSerializer void setAsBoolean(bool value) {
type = JSON_BOOLEAN;
content.asBoolean = value;
}
void setAsArray(JsonBuffer* buffer) void setAsLong(int value) {
{ type = JSON_LONG;
type = JSON_ARRAY; content.asInteger = value;
content.asContainer.child = 0; }
content.asContainer.buffer = buffer;
}
void setAsBoolean(bool value) void setAsString(char const *value) {
{ type = JSON_STRING;
type = JSON_BOOLEAN; content.asString = value;
content.asBoolean = value; }
}
void setAsLong(int value) void setAsDouble(double value, int decimals) {
{ type = static_cast<JsonNodeType>(JSON_DOUBLE_0_DECIMALS + decimals);
type = JSON_LONG; content.asDouble = value;
content.asInteger = value; }
}
void setAsString(char const* value) void setAsObject(JsonBuffer *buffer) {
{ type = JSON_OBJECT;
type = JSON_STRING; content.asContainer.child = 0;
content.asString = value; content.asContainer.buffer = buffer;
} }
void setAsDouble(double value, int decimals) void setAsObjectKeyValue(const char *key, JsonNode *value) {
{ type = JSON_KEY_VALUE;
type = static_cast<JsonNodeType>(JSON_DOUBLE_0_DECIMALS + decimals); content.asKeyValue.key = key;
content.asDouble = value; content.asKeyValue.value = value;
} }
void setAsObject(JsonBuffer* buffer) bool getAsBoolean() {
{ return type == JSON_BOOLEAN ? content.asBoolean : false;
type = JSON_OBJECT; }
content.asContainer.child = 0;
content.asContainer.buffer = buffer;
}
void setAsObjectKeyValue(const char* key, JsonNode* value) double getAsDouble() {
{ return type >= JSON_DOUBLE_0_DECIMALS ? content.asDouble : 0;
type = JSON_KEY_VALUE; }
content.asKeyValue.key = key;
content.asKeyValue.value = value;
}
bool getAsBoolean() long getAsInteger() { return type == JSON_LONG ? content.asInteger : 0; }
{
return type == JSON_BOOLEAN ? content.asBoolean : false;
}
double getAsDouble() const char *getAsString() {
{ return type == JSON_STRING ? content.asString : 0;
return type >= JSON_DOUBLE_0_DECIMALS ? content.asDouble : 0; }
}
long getAsInteger() JsonBuffer *getContainerBuffer() {
{ if (type == JSON_PROXY)
return type == JSON_LONG ? content.asInteger : 0; return content.asProxy.target->getContainerBuffer();
} return type == JSON_ARRAY || type == JSON_OBJECT
? content.asContainer.buffer
: 0;
}
const char* getAsString() JsonNode *getContainerChild() {
{ if (type == JSON_PROXY)
return type == JSON_STRING ? content.asString : 0; return content.asProxy.target->getContainerChild();
} return type == JSON_ARRAY || type == JSON_OBJECT ? content.asContainer.child
: 0;
}
JsonBuffer* getContainerBuffer() const char *getAsObjectKey() {
{ return type == JSON_KEY_VALUE ? content.asKeyValue.key : 0;
if (type == JSON_PROXY) return content.asProxy.target->getContainerBuffer(); }
return type == JSON_ARRAY || type == JSON_OBJECT ? content.asContainer.buffer : 0;
}
JsonNode* getContainerChild() JsonNode *getAsObjectValue() {
{ return type == JSON_KEY_VALUE ? content.asKeyValue.value : 0;
if (type == JSON_PROXY) return content.asProxy.target->getContainerChild(); }
return type == JSON_ARRAY || type == JSON_OBJECT ? content.asContainer.child : 0;
}
const char* getAsObjectKey() JsonNode *getProxyTarget() {
{ return type == JSON_PROXY ? content.asProxy.target : this;
return type == JSON_KEY_VALUE ? content.asKeyValue.key : 0; }
}
JsonNode* getAsObjectValue() bool isArray() { return type == JSON_ARRAY; }
{
return type == JSON_KEY_VALUE ? content.asKeyValue.value : 0;
}
JsonNode* getProxyTarget() bool isObject() { return type == JSON_OBJECT; }
{
return type == JSON_PROXY ? content.asProxy.target : this;
}
bool isArray() void addChild(JsonNode *childToAdd);
{
return type == JSON_ARRAY;
}
bool isObject() void removeChild(JsonNode *childToRemove);
{
return type == JSON_OBJECT;
}
void addChild(JsonNode* childToAdd); void duplicate(JsonNode *other);
void removeChild(JsonNode* childToRemove); private:
JsonNodeType type;
JsonNodeContent content;
void duplicate(JsonNode* other); inline void writeArrayTo(JsonWriter &); // TODO: <- move in JsonNodeSerializer
inline void
writeObjectTo(JsonWriter &); // TODO: <- move in JsonNodeSerializer
private: void setAsProxyOfSelf();
JsonNodeType type;
JsonNodeContent content;
inline void writeArrayTo(JsonWriter&);// TODO: <- move in JsonNodeSerializer void setAsProxyOf(JsonNode *target) {
inline void writeObjectTo(JsonWriter&);// TODO: <- move in JsonNodeSerializer type = JSON_PROXY;
content.asProxy.target = target;
void setAsProxyOfSelf(); }
};
void setAsProxyOf(JsonNode* target) }
{
type = JSON_PROXY;
content.asProxy.target = target;
}
};
}
} }

View File

@ -2,42 +2,25 @@
#include "JsonNode.hpp" #include "JsonNode.hpp"
namespace ArduinoJson namespace ArduinoJson {
{ namespace Internals {
namespace Internals // TODO: replace by JsonArrayIterator and JsonObjectIterator
{ class JsonNodeIterator {
// TODO: replace by JsonArrayIterator and JsonObjectIterator public:
class JsonNodeIterator explicit JsonNodeIterator(JsonNode *node) : _node(node) {}
{
public:
explicit JsonNodeIterator(JsonNode* node) bool operator!=(const JsonNodeIterator &other) const {
: _node(node) return _node != other._node;
{ }
}
bool operator!= (const JsonNodeIterator& other) const void operator++() { _node = _node->next; }
{
return _node != other._node;
}
void operator++() JsonNode *operator*() const { return _node; }
{
_node = _node->next;
}
JsonNode* operator*() const JsonNode *operator->() const { return _node; }
{
return _node;
}
JsonNode* operator->() const private:
{ JsonNode *_node;
return _node; };
} }
private:
JsonNode* _node;
};
}
} }

View File

@ -2,42 +2,28 @@
#include "JsonNode.hpp" #include "JsonNode.hpp"
namespace ArduinoJson namespace ArduinoJson {
{ class JsonValue;
class JsonValue ;
namespace Internals
{
class JsonNodeWrapper
{
friend class JsonValue;
public: namespace Internals {
JsonNodeWrapper() class JsonNodeWrapper {
: _node(0) friend class JsonValue;
{
}
explicit JsonNodeWrapper(JsonNode* node) public:
: _node(node) JsonNodeWrapper() : _node(0) {}
{
}
protected: explicit JsonNodeWrapper(JsonNode *node) : _node(node) {}
void duplicate(const JsonNodeWrapper& other) protected:
{ void duplicate(const JsonNodeWrapper &other) {
if (!_node) if (!_node) {
{ _node = other._node;
_node = other._node; } else {
} _node->duplicate(other._node);
else
{
_node->duplicate(other._node);
}
}
JsonNode* _node;
};
} }
}
JsonNode *_node;
};
}
} }

View File

@ -2,44 +2,34 @@
#include "JsonNode.hpp" #include "JsonNode.hpp"
namespace ArduinoJson namespace ArduinoJson {
{ class JsonBuffer;
class JsonBuffer;
namespace Internals namespace Internals {
{ class JsonNode;
class JsonNode;
class JsonParser class JsonParser {
{ public:
public: JsonParser(JsonBuffer *buffer, char *json) : _buffer(buffer), _ptr(json) {}
JsonParser(JsonBuffer* buffer, char* json)
: _buffer(buffer), _ptr(json)
{
} JsonNode *parseAnything();
JsonNode* parseAnything(); private:
JsonBuffer *_buffer;
char *_ptr;
private: bool isEnd() { return *_ptr == 0; }
JsonBuffer* _buffer;
char* _ptr;
bool isEnd() bool skip(char charToSkip);
{ void skipSpaces();
return *_ptr == 0;
}
bool skip(char charToSkip); inline JsonNode *parseArray();
void skipSpaces(); inline JsonNode *parseBoolean();
inline JsonNode *parseNull();
inline JsonNode* parseArray(); inline JsonNode *parseNumber();
inline JsonNode* parseBoolean(); inline JsonNode *parseObject();
inline JsonNode* parseNull(); inline JsonNode *parseObjectKeyValue();
inline JsonNode* parseNumber(); inline JsonNode *parseString();
inline JsonNode* parseObject(); };
inline JsonNode* parseObjectKeyValue(); }
inline JsonNode* parseString();
};
}
} }

View File

@ -2,53 +2,38 @@
#include "../Arduino/Print.hpp" #include "../Arduino/Print.hpp"
namespace ArduinoJson namespace ArduinoJson {
{ namespace Internals {
namespace Internals class JsonWriter {
{ public:
class JsonWriter explicit JsonWriter(Print *sink) : _sink(sink), _length(0) {}
{
public:
explicit JsonWriter(Print* sink)
: _sink(sink), _length(0)
{
}
size_t bytesWritten() size_t bytesWritten() { return _length; }
{
return _length;
}
virtual void beginArray() = 0; virtual void beginArray() = 0;
virtual void endArray() = 0; virtual void endArray() = 0;
virtual void beginObject() = 0; virtual void beginObject() = 0;
virtual void endObject() = 0; virtual void endObject() = 0;
void writeString(const char* value); void writeString(const char *value);
void writeInteger(long value); void writeInteger(long value);
void writeBoolean(bool value); void writeBoolean(bool value);
void writeDouble(double value, int decimals); void writeDouble(double value, int decimals);
virtual void writeColon() = 0; virtual void writeColon() = 0;
virtual void writeComma() = 0; virtual void writeComma() = 0;
void writeEmptyArray() void writeEmptyArray() { _length += _sink->print("[]"); }
{
_length += _sink->print("[]");
}
void writeEmptyObject() void writeEmptyObject() { _length += _sink->print("{}"); }
{
_length += _sink->print("{}");
}
protected: protected:
Print* _sink; Print *_sink;
size_t _length; size_t _length;
}; };
} }
} }

View File

@ -3,67 +3,52 @@
#include "JsonWriter.hpp" #include "JsonWriter.hpp"
#include "IndentedPrint.hpp" #include "IndentedPrint.hpp"
namespace ArduinoJson namespace ArduinoJson {
{ namespace Internals {
namespace Internals class PrettyJsonWriter : public JsonWriter {
{ public:
class PrettyJsonWriter : public JsonWriter explicit PrettyJsonWriter(IndentedPrint *sink)
{ : JsonWriter(sink), _indenter(sink) {}
public:
explicit PrettyJsonWriter(IndentedPrint* sink)
: JsonWriter(sink), _indenter(sink)
{
}
virtual void beginArray() virtual void beginArray() {
{ _length += _sink->write('[');
_length += _sink->write('['); indent();
indent(); }
}
virtual void endArray() virtual void endArray() {
{ unindent();
unindent(); _length += _sink->write(']');
_length += _sink->write(']'); }
}
virtual void writeColon() virtual void writeColon() { _length += _sink->print(": "); }
{
_length += _sink->print(": ");
}
virtual void writeComma() virtual void writeComma() {
{ _length += _sink->write(',');
_length += _sink->write(','); _length += _indenter->println();
_length += _indenter->println(); }
}
virtual void beginObject() virtual void beginObject() {
{ _length += _sink->write('{');
_length += _sink->write('{'); indent();
indent(); }
}
virtual void endObject() virtual void endObject() {
{ unindent();
unindent(); _length += _sink->write('}');
_length += _sink->write('}'); }
}
private: private:
IndentedPrint* _indenter; IndentedPrint *_indenter;
void indent() void indent() {
{ _indenter->indent();
_indenter->indent(); _length += _indenter->println();
_length += _indenter->println(); }
}
void unindent() void unindent() {
{ _length += _indenter->println();
_length += _indenter->println(); _indenter->unindent();
_indenter->unindent(); }
} };
}; }
}
} }

View File

@ -7,16 +7,13 @@
#include "../Arduino/Print.hpp" #include "../Arduino/Print.hpp"
namespace ArduinoJson namespace ArduinoJson {
{ namespace Internals {
namespace Internals class QuotedString {
{ public:
class QuotedString static size_t printTo(const char *, Print *);
{
public:
static size_t printTo(const char*, Print*);
static char* extractFrom(char* input, char** end); static char *extractFrom(char *input, char **end);
}; };
} }
} }

View File

@ -7,25 +7,21 @@
#include "../Arduino/Print.hpp" #include "../Arduino/Print.hpp"
namespace ArduinoJson namespace ArduinoJson {
{ namespace Internals {
namespace Internals class StringBuilder : public Print {
{ public:
class StringBuilder : public Print StringBuilder(char *buf, int size)
{ : buffer(buf), capacity(size - 1), length(0) {
public: buffer[0] = 0;
StringBuilder(char* buf, int size) }
: buffer(buf), capacity(size - 1), length(0)
{
buffer[0] = 0;
}
virtual size_t write(uint8_t c); virtual size_t write(uint8_t c);
private: private:
char* buffer; char *buffer;
int capacity; int capacity;
int length; int length;
}; };
} }
} }

View File

@ -3,42 +3,29 @@
#include "JsonContainer.hpp" #include "JsonContainer.hpp"
#include "JsonArrayIterator.hpp" #include "JsonArrayIterator.hpp"
namespace ArduinoJson namespace ArduinoJson {
{ class JsonArray : public JsonContainer {
class JsonArray : public JsonContainer public:
{ JsonArray() {}
public:
JsonArray()
{
}
explicit JsonArray(Internals::JsonNode* node) explicit JsonArray(Internals::JsonNode *node) : JsonContainer(node) {}
: JsonContainer(node)
{
}
JsonValue operator[](int index) const; JsonValue operator[](int index) const;
void add(bool value); void add(bool value);
void add(const char* value); void add(const char *value);
void add(double value, int decimals=2); void add(double value, int decimals = 2);
void add(int value) { add(static_cast<long>(value)); } void add(int value) { add(static_cast<long>(value)); }
void add(long value); void add(long value);
void add(JsonContainer nestedArray); // TODO: should allow JsonValue too void add(JsonContainer nestedArray); // TODO: should allow JsonValue too
JsonArray createNestedArray(); JsonArray createNestedArray();
JsonObject createNestedObject(); JsonObject createNestedObject();
bool success() bool success() { return _node && _node->isArray(); }
{
return _node && _node->isArray();
}
JsonArrayIterator begin(); JsonArrayIterator begin();
JsonArrayIterator end() JsonArrayIterator end() { return JsonArrayIterator(0); }
{ };
return JsonArrayIterator(0);
}
};
} }

View File

@ -2,41 +2,28 @@
#include "ArduinoJson/JsonValue.hpp" #include "ArduinoJson/JsonValue.hpp"
namespace ArduinoJson namespace ArduinoJson {
{ class JsonArray;
class JsonArray;
class JsonArrayIterator class JsonArrayIterator {
{ friend class JsonArray;
friend class JsonArray;
public: public:
explicit JsonArrayIterator(Internals::JsonNode* node) explicit JsonArrayIterator(Internals::JsonNode *node) : _node(node) {}
: _node(node)
{
}
void operator++() void operator++() { _node = _node->next; }
{
_node = _node->next;
}
JsonValue operator*() const JsonValue operator*() const { return JsonValue(_node); }
{
return JsonValue(_node);
}
bool operator==(const JsonArrayIterator& other) const bool operator==(const JsonArrayIterator &other) const {
{ return _node == other._node;
return _node == other._node; }
}
bool operator!=(const JsonArrayIterator& other) const bool operator!=(const JsonArrayIterator &other) const {
{ return _node != other._node;
return _node != other._node; }
}
private: private:
Internals::JsonNode* _node; Internals::JsonNode *_node;
}; };
} }

View File

@ -3,50 +3,42 @@
#include "JsonArray.hpp" #include "JsonArray.hpp"
#include "JsonObject.hpp" #include "JsonObject.hpp"
namespace ArduinoJson namespace ArduinoJson {
{ namespace Internals {
namespace Internals class JsonParser;
{ }
class JsonParser;
}
class JsonBuffer class JsonBuffer {
{ friend class JsonContainer;
friend class JsonContainer; friend class Internals::JsonNode;
friend class Internals::JsonNode; friend class Internals::JsonParser;
friend class Internals::JsonParser;
public: public:
virtual ~JsonBuffer() {}; virtual ~JsonBuffer(){};
JsonArray createArray() JsonArray createArray() { return JsonArray(createArrayNode()); }
{
return JsonArray(createArrayNode());
}
JsonObject createObject() JsonObject createObject() { return JsonObject(createObjectNode()); }
{
return JsonObject(createObjectNode());
}
JsonValue createValue(); JsonValue createValue();
JsonArray parseArray(char* json); JsonArray parseArray(char *json);
JsonObject parseObject(char* json); JsonObject parseObject(char *json);
JsonValue parseValue(char* json); // TODO: remove JsonValue parseValue(char *json); // TODO: remove
protected: protected:
virtual void* allocateNode() = 0; virtual void *allocateNode() = 0;
private: private:
Internals::JsonNode* createNode(); Internals::JsonNode *createNode();
Internals::JsonNode* createArrayNode(); Internals::JsonNode *createArrayNode();
Internals::JsonNode* createBoolNode(bool value); Internals::JsonNode *createBoolNode(bool value);
Internals::JsonNode* createDoubleNode(double value, int decimals); Internals::JsonNode *createDoubleNode(double value, int decimals);
Internals::JsonNode* createLongNode(long value); Internals::JsonNode *createLongNode(long value);
Internals::JsonNode* createObjectNode(); Internals::JsonNode *createObjectNode();
Internals::JsonNode* createObjectKeyValueNode(const char* key, Internals::JsonNode* value); Internals::JsonNode *createObjectKeyValueNode(const char *key,
Internals::JsonNode* createStringNode(const char* value); Internals::JsonNode *value);
}; Internals::JsonNode *createStringNode(const char *value);
};
} }

View File

@ -6,49 +6,41 @@
#include "Internals/IndentedPrint.hpp" #include "Internals/IndentedPrint.hpp"
#include "Internals/JsonNodeWrapper.hpp" #include "Internals/JsonNodeWrapper.hpp"
namespace ArduinoJson namespace ArduinoJson {
{ class JsonArray;
class JsonArray; class JsonObject;
class JsonObject; class JsonValue;
class JsonValue;
class JsonContainer : public Printable, public Internals::JsonNodeWrapper class JsonContainer : public Printable, public Internals::JsonNodeWrapper {
{ friend class JsonArray;
friend class JsonArray;
public: public:
JsonContainer() {} JsonContainer() {}
explicit JsonContainer(Internals::JsonNode* node) explicit JsonContainer(Internals::JsonNode *node) : JsonNodeWrapper(node) {}
: JsonNodeWrapper(node)
{
}
size_t size() const; size_t size() const;
bool operator==(JsonContainer const& other) const; bool operator==(JsonContainer const &other) const;
size_t printTo(char* buffer, size_t bufferSize) const; size_t printTo(char *buffer, size_t bufferSize) const;
virtual size_t printTo(Print& print) const; virtual size_t printTo(Print &print) const;
size_t prettyPrintTo(char* buffer, size_t bufferSize) const; size_t prettyPrintTo(char *buffer, size_t bufferSize) const;
size_t prettyPrintTo(ArduinoJson::Internals::IndentedPrint& print) const; size_t prettyPrintTo(ArduinoJson::Internals::IndentedPrint &print) const;
size_t prettyPrintTo(Print& print) const; size_t prettyPrintTo(Print &print) const;
protected: protected:
Internals::JsonNodeIterator beginChildren() const {
return Internals::JsonNodeIterator(_node ? _node->getContainerChild() : 0);
}
Internals::JsonNodeIterator beginChildren() const Internals::JsonNodeIterator endChildren() const {
{ return Internals::JsonNodeIterator(0);
return Internals::JsonNodeIterator(_node ? _node->getContainerChild() : 0); }
}
Internals::JsonNodeIterator endChildren() const void addChild(Internals::JsonNode *);
{ void removeChild(Internals::JsonNode *);
return Internals::JsonNodeIterator(0); Internals::JsonNode *createNode();
} };
void addChild(Internals::JsonNode*);
void removeChild(Internals::JsonNode*);
Internals::JsonNode* createNode();
};
} }

View File

@ -3,40 +3,26 @@
#include "ArduinoJson/JsonContainer.hpp" #include "ArduinoJson/JsonContainer.hpp"
#include "ArduinoJson/JsonObjectIterator.hpp" #include "ArduinoJson/JsonObjectIterator.hpp"
namespace ArduinoJson namespace ArduinoJson {
{ class JsonObject : public JsonContainer {
class JsonObject : public JsonContainer public:
{ JsonObject() {}
public:
JsonObject() explicit JsonObject(Internals::JsonNode *node) : JsonContainer(node) {}
{
}
explicit JsonObject(Internals::JsonNode* node) JsonValue operator[](const char *key);
: JsonContainer(node) void remove(const char *key);
{
}
JsonValue operator[](const char* key); JsonArray createNestedArray(const char *key);
void remove(const char* key); JsonObject createNestedObject(const char *key);
JsonArray createNestedArray(const char* key); bool success() { return _node && _node->isObject(); }
JsonObject createNestedObject(const char* key);
bool success() JsonObjectIterator begin();
{
return _node && _node->isObject();
}
JsonObjectIterator begin(); JsonObjectIterator end() { return JsonObjectIterator(0); }
JsonObjectIterator end() private:
{ Internals::JsonNode *getOrCreateNodeAt(const char *key);
return JsonObjectIterator(0); };
}
private:
Internals::JsonNode* getOrCreateNodeAt(const char* key);
};
} }

View File

@ -2,47 +2,34 @@
#include "ArduinoJson/JsonObjectKeyValue.hpp" #include "ArduinoJson/JsonObjectKeyValue.hpp"
namespace ArduinoJson namespace ArduinoJson {
{ class JsonObject;
class JsonObject;
class JsonObjectIterator class JsonObjectIterator {
{ friend class JsonObject;
friend class JsonObject;
public: public:
explicit JsonObjectIterator(Internals::JsonNode* node) explicit JsonObjectIterator(Internals::JsonNode *node)
: _objectKeyValue(node) : _objectKeyValue(node) {}
{
}
JsonObjectIterator& operator++() JsonObjectIterator &operator++() {
{ _objectKeyValue = JsonObjectKeyValue(_objectKeyValue.next());
_objectKeyValue = JsonObjectKeyValue(_objectKeyValue.next()); return *this;
return *this; }
}
JsonObjectKeyValue operator*() const JsonObjectKeyValue operator*() const { return _objectKeyValue; }
{
return _objectKeyValue;
}
JsonObjectKeyValue* operator->() JsonObjectKeyValue *operator->() { return &_objectKeyValue; }
{
return &_objectKeyValue;
}
bool operator==(const JsonObjectIterator& other) const bool operator==(const JsonObjectIterator &other) const {
{ return _objectKeyValue == other._objectKeyValue;
return _objectKeyValue == other._objectKeyValue; }
}
bool operator!=(const JsonObjectIterator& other) const bool operator!=(const JsonObjectIterator &other) const {
{ return _objectKeyValue != other._objectKeyValue;
return _objectKeyValue != other._objectKeyValue; }
}
private: private:
JsonObjectKeyValue _objectKeyValue; JsonObjectKeyValue _objectKeyValue;
}; };
} }

View File

@ -2,42 +2,26 @@
#include "ArduinoJson/JsonValue.hpp" #include "ArduinoJson/JsonValue.hpp"
namespace ArduinoJson namespace ArduinoJson {
{ class JsonObjectKeyValue {
class JsonObjectKeyValue public:
{ explicit JsonObjectKeyValue(Internals::JsonNode *node) : _node(node) {}
public:
explicit JsonObjectKeyValue(Internals::JsonNode* node)
: _node(node)
{
}
const char* key() const const char *key() const { return _node->getAsObjectKey(); }
{
return _node->getAsObjectKey();
}
JsonValue value() JsonValue value() { return JsonValue(_node->getAsObjectValue()); }
{
return JsonValue(_node->getAsObjectValue());
}
bool operator==(const JsonObjectKeyValue& other) const bool operator==(const JsonObjectKeyValue &other) const {
{ return _node == other._node;
return _node == other._node; }
}
bool operator!=(const JsonObjectKeyValue& other) const bool operator!=(const JsonObjectKeyValue &other) const {
{ return _node != other._node;
return _node != other._node; }
}
Internals::JsonNode* next() Internals::JsonNode *next() { return _node->next; }
{
return _node->next;
}
private: private:
Internals::JsonNode* _node; Internals::JsonNode *_node;
}; };
} }

View File

@ -2,44 +2,36 @@
#include "Internals/JsonNodeWrapper.hpp" #include "Internals/JsonNodeWrapper.hpp"
namespace ArduinoJson namespace ArduinoJson {
{ class JsonArray;
class JsonArray; class JsonContainer;
class JsonContainer; class JsonObject;
class JsonObject;
class JsonValue : public Internals::JsonNodeWrapper class JsonValue : public Internals::JsonNodeWrapper {
{ public:
public: JsonValue() {}
JsonValue() {} explicit JsonValue(Internals::JsonNode *node) : JsonNodeWrapper(node) {}
explicit JsonValue(Internals::JsonNode* node) void operator=(bool);
: JsonNodeWrapper(node) void operator=(const char *);
{ void operator=(double x) { set(x, 2); }
} void operator=(int);
void operator=(const JsonValue &value) { duplicate(value); }
void operator=(const Internals::JsonNodeWrapper &object) {
duplicate(object);
}
void operator=(bool); operator bool() const;
void operator=(const char*); operator const char *() const;
void operator=(double x) { set(x, 2); } operator double() const;
void operator=(int); operator long() const;
void operator=(const JsonValue& value) { duplicate(value); } operator int() const { return operator long(); }
void operator=(const Internals::JsonNodeWrapper& object) { duplicate(object); } operator JsonArray() const;
operator JsonObject() const;
operator bool() const; void set(double value, int decimals);
operator const char*() const;
operator double() const;
operator long() const;
operator int() const { return operator long(); }
operator JsonArray() const;
operator JsonObject() const;
void set(double value, int decimals); template <typename T> T as() { return static_cast<T>(*this); }
};
template<typename T>
T as()
{
return static_cast<T>(*this);
}
};
} }

View File

@ -3,42 +3,29 @@
#include "JsonBuffer.hpp" #include "JsonBuffer.hpp"
#include "JsonObject.hpp" #include "JsonObject.hpp"
namespace ArduinoJson namespace ArduinoJson {
{ template <int CAPACITY> class StaticJsonBuffer : public JsonBuffer {
template<int CAPACITY> friend class JsonObject;
class StaticJsonBuffer : public JsonBuffer
{
friend class JsonObject;
public: public:
explicit StaticJsonBuffer() : _size(0) {}
explicit StaticJsonBuffer() virtual ~StaticJsonBuffer() {}
: _size(0)
{
}
virtual ~StaticJsonBuffer() {} int capacity() { return CAPACITY; }
int capacity() int size() { return _size; }
{
return CAPACITY;
}
int size() protected:
{ virtual void *allocateNode() {
return _size; if (_size >= CAPACITY)
} return 0;
protected: return &_buffer[_size++];
virtual void* allocateNode() }
{
if (_size >= CAPACITY) return 0;
return &_buffer[_size++]; private:
} Internals::JsonNode _buffer[CAPACITY];
int _size;
private: };
Internals::JsonNode _buffer[CAPACITY];
int _size;
};
} }

1
scripts/format-code.sh Normal file
View File

@ -0,0 +1 @@
find .. -regex ".*\.[ch]pp$" -exec clang-format -i {} \;

View File

@ -8,33 +8,26 @@
#include "ArduinoJson/Arduino/Print.hpp" #include "ArduinoJson/Arduino/Print.hpp"
#include <cstdio> #include <cstdio>
size_t Print::print(const char s[]) size_t Print::print(const char s[]) {
{ size_t n = 0;
size_t n = 0; while (*s) {
while (*s) n += write(*s++);
{ }
n += write(*s++); return n;
}
return n;
} }
size_t Print::print(double value, int digits) size_t Print::print(double value, int digits) {
{ char tmp[32];
char tmp[32]; sprintf(tmp, "%.*g", digits + 1, value);
sprintf(tmp, "%.*g", digits+1, value); return print(tmp);
return print(tmp);
} }
size_t Print::print(long value) size_t Print::print(long value) {
{ char tmp[32];
char tmp[32]; sprintf(tmp, "%ld", value);
sprintf(tmp, "%ld", value); return print(tmp);
return print(tmp);
} }
size_t Print::println() size_t Print::println() { return write('\r') + write('\n'); }
{
return write('\r') + write('\n');
}
#endif #endif

View File

@ -2,44 +2,39 @@
using namespace ArduinoJson::Internals; using namespace ArduinoJson::Internals;
void IndentedPrint::indent() void IndentedPrint::indent() {
{ if (level < MAX_LEVEL)
if (level < MAX_LEVEL) level++;
level++;
} }
void IndentedPrint::unindent() void IndentedPrint::unindent() {
{ if (level > 0)
if (level > 0) level--;
level--;
} }
void IndentedPrint::setTabSize(uint8_t n) void IndentedPrint::setTabSize(uint8_t n) {
{ if (n < MAX_TAB_SIZE)
if (n < MAX_TAB_SIZE) tabSize = n;
tabSize = n;
} }
size_t IndentedPrint::write(uint8_t c) size_t IndentedPrint::write(uint8_t c) {
{ size_t n = 0;
size_t n = 0;
if (isNewLine) if (isNewLine)
n += writeTabs(); n += writeTabs();
n += sink->write(c); n += sink->write(c);
isNewLine = c == '\n'; isNewLine = c == '\n';
return n; return n;
} }
inline size_t IndentedPrint::writeTabs() inline size_t IndentedPrint::writeTabs() {
{ size_t n = 0;
size_t n = 0;
for (int i = 0; i < level*tabSize; i++) for (int i = 0; i < level * tabSize; i++)
n += sink->write(' '); n += sink->write(' ');
return n; return n;
} }

View File

@ -7,163 +7,144 @@
using namespace ArduinoJson::Internals; using namespace ArduinoJson::Internals;
void JsonNode::writeTo(JsonWriter& writer) void JsonNode::writeTo(JsonWriter &writer) {
{ switch (type) {
switch (type) case JSON_PROXY:
{ content.asProxy.target->writeTo(writer);
case JSON_PROXY: break;
content.asProxy.target->writeTo(writer);
break;
case JSON_ARRAY: case JSON_ARRAY:
writeArrayTo(writer); writeArrayTo(writer);
break; break;
case JSON_OBJECT: case JSON_OBJECT:
writeObjectTo(writer); writeObjectTo(writer);
break; break;
case JSON_STRING: case JSON_STRING:
writer.writeString(content.asString); writer.writeString(content.asString);
break; break;
case JSON_LONG: case JSON_LONG:
writer.writeInteger(content.asInteger); writer.writeInteger(content.asInteger);
break; break;
case JSON_BOOLEAN: case JSON_BOOLEAN:
writer.writeBoolean(content.asBoolean); writer.writeBoolean(content.asBoolean);
break; break;
default: // >= JSON_DOUBLE_0_DECIMALS default: // >= JSON_DOUBLE_0_DECIMALS
writer.writeDouble(content.asDouble, type - JSON_DOUBLE_0_DECIMALS); writer.writeDouble(content.asDouble, type - JSON_DOUBLE_0_DECIMALS);
break; break;
} }
} }
void JsonNode::addChild(JsonNode* childToAdd) void JsonNode::addChild(JsonNode *childToAdd) {
{ if (type == JSON_PROXY)
if (type == JSON_PROXY) return content.asProxy.target->addChild(childToAdd);
return content.asProxy.target->addChild(childToAdd);
if (type != JSON_ARRAY && type != JSON_OBJECT) if (type != JSON_ARRAY && type != JSON_OBJECT)
return; return;
JsonNode* lastChild = content.asContainer.child; JsonNode *lastChild = content.asContainer.child;
if (!lastChild) if (!lastChild) {
{ content.asContainer.child = childToAdd;
content.asContainer.child = childToAdd; return;
return; }
}
while (lastChild->next) while (lastChild->next)
lastChild = lastChild->next; lastChild = lastChild->next;
lastChild->next = childToAdd; lastChild->next = childToAdd;
} }
void JsonNode::removeChild(JsonNode* childToRemove) void JsonNode::removeChild(JsonNode *childToRemove) {
{ if (type == JSON_PROXY)
if (type == JSON_PROXY) return content.asProxy.target->removeChild(childToRemove);
return content.asProxy.target->removeChild(childToRemove);
if (type != JSON_ARRAY && type != JSON_OBJECT) return; if (type != JSON_ARRAY && type != JSON_OBJECT)
return;
if (content.asContainer.child == childToRemove) if (content.asContainer.child == childToRemove) {
{ content.asContainer.child = childToRemove->next;
content.asContainer.child = childToRemove->next; return;
return; }
}
for (JsonNode* child = content.asContainer.child; child; child = child->next) for (JsonNode *child = content.asContainer.child; child;
{ child = child->next) {
if (child->next == childToRemove) if (child->next == childToRemove)
child->next = childToRemove->next; child->next = childToRemove->next;
} }
} }
void JsonNode::writeArrayTo(JsonWriter& writer) void JsonNode::writeArrayTo(JsonWriter &writer) {
{ JsonNode *child = content.asContainer.child;
JsonNode* child = content.asContainer.child;
if (child) if (child) {
{ writer.beginArray();
writer.beginArray();
for (;;) for (;;) {
{ child->writeTo(writer);
child->writeTo(writer);
child = child->next; child = child->next;
if (!child) break; if (!child)
break;
writer.writeComma();
}
writer.endArray(); writer.writeComma();
}
else
{
writer.writeEmptyArray();
} }
writer.endArray();
} else {
writer.writeEmptyArray();
}
} }
void JsonNode::writeObjectTo(JsonWriter& writer) void JsonNode::writeObjectTo(JsonWriter &writer) {
{ JsonNode *child = content.asContainer.child;
JsonNode* child = content.asContainer.child;
if (child) if (child) {
{ writer.beginObject();
writer.beginObject();
for (;;) for (;;) {
{ writer.writeString(child->content.asKeyValue.key);
writer.writeString(child->content.asKeyValue.key); writer.writeColon();
writer.writeColon(); child->content.asKeyValue.value->writeTo(writer);
child->content.asKeyValue.value->writeTo(writer);
child = child->next; child = child->next;
if (!child) break; if (!child)
break;
writer.writeComma(); writer.writeComma();
}
writer.endObject();
}
else
{
writer.writeEmptyObject();
} }
writer.endObject();
} else {
writer.writeEmptyObject();
}
} }
void JsonNode::setAsProxyOfSelf() void JsonNode::setAsProxyOfSelf() {
{ JsonBuffer *buffer = content.asContainer.buffer;
JsonBuffer* buffer = content.asContainer.buffer; if (!buffer)
if (!buffer) return; return;
JsonNode* newNode = buffer->createNode();
if (!newNode) return;
*newNode = *this; JsonNode *newNode = buffer->createNode();
if (!newNode)
return;
setAsProxyOf(newNode); *newNode = *this;
setAsProxyOf(newNode);
} }
void JsonNode::duplicate(JsonNode* other) void JsonNode::duplicate(JsonNode *other) {
{ if (!other) {
if (!other) type = JSON_UNDEFINED;
{ } else if (other->type == JSON_ARRAY || other->type == JSON_OBJECT) {
type = JSON_UNDEFINED; other->setAsProxyOfSelf();
} setAsProxyOf(other->content.asProxy.target);
else if (other->type == JSON_ARRAY || other->type==JSON_OBJECT) } else {
{ *this = *other;
other->setAsProxyOfSelf(); }
setAsProxyOf(other->content.asProxy.target);
}
else
{
*this = *other;
}
} }

View File

@ -8,176 +8,163 @@
using namespace ArduinoJson::Internals; using namespace ArduinoJson::Internals;
void JsonParser::skipSpaces() void JsonParser::skipSpaces() {
{ while (isspace(*_ptr))
while(isspace(*_ptr)) _ptr++;
}
bool JsonParser::skip(char charToSkip)
{
skipSpaces();
if (*_ptr != charToSkip) return false;
_ptr++; _ptr++;
skipSpaces();
return true;
} }
JsonNode* JsonParser::parseAnything() bool JsonParser::skip(char charToSkip) {
{ skipSpaces();
skipSpaces(); if (*_ptr != charToSkip)
return false;
switch(*_ptr) _ptr++;
{ skipSpaces();
case '[': return true;
return parseArray();
case 't':
case 'f':
return parseBoolean();
case '-':
case '.':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
return parseNumber();
case 'n':
return parseNull();
case '{':
return parseObject();
case '\'':
case '\"':
return parseString();
default:
return NULL; // invalid JSON
}
} }
JsonNode* JsonParser::parseArray() JsonNode *JsonParser::parseAnything() {
{ skipSpaces();
JsonNode* node = _buffer->createArrayNode();
skip('['); switch (*_ptr) {
case '[':
return parseArray();
if (isEnd()) case 't':
return 0; case 'f':
return parseBoolean();
case '-':
case '.':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
return parseNumber();
case 'n':
return parseNull();
case '{':
return parseObject();
case '\'':
case '\"':
return parseString();
default:
return NULL; // invalid JSON
}
}
JsonNode *JsonParser::parseArray() {
JsonNode *node = _buffer->createArrayNode();
skip('[');
if (isEnd())
return 0;
if (skip(']'))
return node; // empty array
for (;;) {
JsonNode *child = parseAnything();
if (!child)
return 0; // child parsing failed
node->addChild(child);
if (skip(']')) if (skip(']'))
return node; // empty array return node; // end of the array
for(;;) if (!skip(','))
{ return 0; // comma is missing
JsonNode* child = parseAnything(); }
if (!child)
return 0; // child parsing failed
node->addChild(child);
if (skip(']'))
return node; // end of the array
if (!skip(','))
return 0; // comma is missing
}
} }
JsonNode *JsonParser::parseBoolean() JsonNode *JsonParser::parseBoolean() {
{ bool value = *_ptr == 't';
bool value = *_ptr == 't';
_ptr += value ? 4 : 5; _ptr += value ? 4 : 5;
// 4 = strlen("true") // 4 = strlen("true")
// 5 = strlen("false"); // 5 = strlen("false");
return _buffer->createBoolNode(value); return _buffer->createBoolNode(value);
} }
JsonNode* JsonParser::parseNumber() JsonNode *JsonParser::parseNumber() {
{ char *endOfLong;
char* endOfLong; long longValue = strtol(_ptr, &endOfLong, 10);
long longValue = strtol(_ptr, &endOfLong, 10);
if (*endOfLong == '.') // stopped on a decimal separator if (*endOfLong == '.') // stopped on a decimal separator
{ {
double value = strtod(_ptr, &_ptr); double value = strtod(_ptr, &_ptr);
int decimals = _ptr - endOfLong - 1; int decimals = _ptr - endOfLong - 1;
return _buffer->createDoubleNode(value, decimals); return _buffer->createDoubleNode(value, decimals);
} } else {
else _ptr = endOfLong;
{ return _buffer->createLongNode(longValue);
_ptr = endOfLong; }
return _buffer->createLongNode(longValue);
}
} }
JsonNode* JsonParser::parseNull() JsonNode *JsonParser::parseNull() {
{ _ptr += 4; // strlen("null")
_ptr += 4; // strlen("null")
return _buffer->createStringNode(0); return _buffer->createStringNode(0);
} }
JsonNode* JsonParser::parseObject() JsonNode *JsonParser::parseObject() {
{ JsonNode *node = _buffer->createObjectNode();
JsonNode* node = _buffer->createObjectNode();
skip('{'); skip('{');
if (isEnd()) if (isEnd())
return 0; // premature ending return 0; // premature ending
if (skip('}'))
return node; // empty object
for (;;) {
JsonNode *child = parseObjectKeyValue();
if (!child)
return 0; // child parsing failed
node->addChild(child);
if (skip('}')) if (skip('}'))
return node; // empty object return node; // end of the object
for(;;) if (!skip(','))
{ return 0; // comma is missing
JsonNode* child = parseObjectKeyValue(); }
if (!child)
return 0; // child parsing failed
node->addChild(child);
if (skip('}'))
return node; // end of the object
if (!skip(','))
return 0; // comma is missing
}
} }
JsonNode* JsonParser::parseObjectKeyValue() JsonNode *JsonParser::parseObjectKeyValue() {
{ const char *key = QuotedString::extractFrom(_ptr, &_ptr);
const char* key = QuotedString::extractFrom(_ptr, &_ptr);
if (!key) if (!key)
return 0; // failed to extract key return 0; // failed to extract key
if (!skip(':')) if (!skip(':'))
return 0; // colon is missing return 0; // colon is missing
JsonNode* value = parseAnything(); JsonNode *value = parseAnything();
if (!value) if (!value)
return 0; // value parsing failed return 0; // value parsing failed
return _buffer->createObjectKeyValueNode(key, value); return _buffer->createObjectKeyValueNode(key, value);
} }
JsonNode* JsonParser::parseString() JsonNode *JsonParser::parseString() {
{ const char *s = QuotedString::extractFrom(_ptr, &_ptr);
const char* s = QuotedString::extractFrom(_ptr, &_ptr); return _buffer->createStringNode(s);
return _buffer->createStringNode(s);
} }

View File

@ -3,22 +3,16 @@
using namespace ArduinoJson::Internals; using namespace ArduinoJson::Internals;
void JsonWriter::writeString(char const* value) void JsonWriter::writeString(char const *value) {
{ _length += QuotedString::printTo(value, _sink);
_length += QuotedString::printTo(value, _sink);
} }
void JsonWriter::writeInteger(long value) void JsonWriter::writeInteger(long value) { _length += _sink->print(value); }
{
_length += _sink->print(value); void JsonWriter::writeBoolean(bool value) {
_length += _sink->print(value ? "true" : "false");
} }
void JsonWriter::writeBoolean(bool value) void JsonWriter::writeDouble(double value, int decimals) {
{ _length += _sink->print(value, decimals);
_length += _sink->print(value ? "true" : "false");
}
void JsonWriter::writeDouble(double value, int decimals)
{
_length += _sink->print(value, decimals);
} }

View File

@ -7,109 +7,95 @@
using namespace ArduinoJson::Internals; using namespace ArduinoJson::Internals;
static inline char getSpecialChar(char c) static inline char getSpecialChar(char c) {
{ // Optimized for code size on a 8-bit AVR
// Optimized for code size on a 8-bit AVR
const char* p = "\"\"\\\\\bb\ff\nn\rr\tt\0"; const char *p = "\"\"\\\\\bb\ff\nn\rr\tt\0";
while (p[0] && p[0] != c) while (p[0] && p[0] != c) {
{ p += 2;
p += 2; }
}
return p[1]; return p[1];
} }
static inline size_t printCharTo(char c, Print* p) static inline size_t printCharTo(char c, Print *p) {
{ char specialChar = getSpecialChar(c);
char specialChar = getSpecialChar(c);
return specialChar != 0 return specialChar != 0 ? p->write('\\') + p->write(specialChar)
? p->write('\\') + p->write(specialChar) : p->write(c);
: p->write(c);
} }
size_t QuotedString::printTo(const char* s, Print* p) size_t QuotedString::printTo(const char *s, Print *p) {
{ if (!s)
if (!s) return p->print("null"); return p->print("null");
size_t n = p->write('\"');
while (*s) size_t n = p->write('\"');
{
n += printCharTo(*s++, p);
}
return n + p->write('\"'); while (*s) {
n += printCharTo(*s++, p);
}
return n + p->write('\"');
} }
static char unescapeChar(char c) static char unescapeChar(char c) {
{ // Optimized for code size on a 8-bit AVR
// Optimized for code size on a 8-bit AVR
const char* p = "b\bf\fn\nr\rt\t"; const char *p = "b\bf\fn\nr\rt\t";
for (;;) for (;;) {
{ if (p[0] == 0)
if (p[0] == 0) return c; return c;
if (p[0] == c) return p[1]; if (p[0] == c)
p += 2; return p[1];
} p += 2;
}
} }
static inline bool isQuote(char c) static inline bool isQuote(char c) { return c == '\"' || c == '\''; }
{
return c == '\"' || c == '\'';
}
char* QuotedString::extractFrom(char* input, char** endPtr) char *QuotedString::extractFrom(char *input, char **endPtr) {
{ char firstChar = *input;
char firstChar = *input;
if (!isQuote(firstChar)) if (!isQuote(firstChar)) {
{ // must start with a quote
// must start with a quote return 0;
return 0; }
char stopChar = firstChar; // closing quote is the same as opening quote
char *startPtr = input + 1; // skip the quote
char *readPtr = startPtr;
char *writePtr = startPtr;
char c;
for (;;) {
c = *readPtr++;
if (c == 0) {
// premature ending
return 0;
} }
char stopChar = firstChar; // closing quote is the same as opening quote if (c == stopChar) {
// closing quote
char* startPtr = input + 1; // skip the quote break;
char* readPtr = startPtr;
char* writePtr = startPtr;
char c;
for (;;)
{
c = *readPtr++;
if (c == 0)
{
// premature ending
return 0;
}
if (c == stopChar)
{
// closing quote
break;
}
if (c == '\\')
{
// replace char
c = unescapeChar(*readPtr++);
}
*writePtr++ = c;
} }
// end the string here if (c == '\\') {
*writePtr = 0; // replace char
c = unescapeChar(*readPtr++);
}
// update end ptr *writePtr++ = c;
*endPtr = readPtr; }
return startPtr; // end the string here
*writePtr = 0;
// update end ptr
*endPtr = readPtr;
return startPtr;
} }

View File

@ -7,11 +7,11 @@
using namespace ArduinoJson::Internals; using namespace ArduinoJson::Internals;
size_t StringBuilder::write(uint8_t c) size_t StringBuilder::write(uint8_t c) {
{ if (length >= capacity)
if (length >= capacity) return 0; return 0;
buffer[length++] = c; buffer[length++] = c;
buffer[length] = 0; buffer[length] = 0;
return 1; return 1;
} }

View File

@ -5,93 +5,87 @@
using namespace ArduinoJson; using namespace ArduinoJson;
using namespace ArduinoJson::Internals; using namespace ArduinoJson::Internals;
JsonValue JsonArray::operator[](int index) const JsonValue JsonArray::operator[](int index) const {
{ for (JsonNodeIterator it = beginChildren(); it != endChildren(); ++it) {
for (JsonNodeIterator it = beginChildren(); it != endChildren(); ++it) if (!index)
{ return JsonValue(*it);
if (!index) return JsonValue(*it); index--;
index--; }
}
return JsonValue(); return JsonValue();
} }
void JsonArray::add(bool value) void JsonArray::add(bool value) {
{ JsonNode *node = createNode();
JsonNode* node = createNode(); if (!node)
if (!node) return; return;
node->setAsBoolean(value); node->setAsBoolean(value);
addChild(node); addChild(node);
} }
void JsonArray::add(char const* value) void JsonArray::add(char const *value) {
{ JsonNode *node = createNode();
JsonNode* node = createNode(); if (!node)
if (!node) return; return;
node->setAsString(value); node->setAsString(value);
addChild(node); addChild(node);
} }
void JsonArray::add(double value, int decimals) void JsonArray::add(double value, int decimals) {
{ JsonNode *node = createNode();
JsonNode* node = createNode(); if (!node)
if (!node) return; return;
node->setAsDouble(value, decimals); node->setAsDouble(value, decimals);
addChild(node); addChild(node);
} }
void JsonArray::add(long value) void JsonArray::add(long value) {
{ JsonNode *node = createNode();
JsonNode* node = createNode(); if (!node)
if (!node) return; return;
node->setAsLong(value); node->setAsLong(value);
addChild(node); addChild(node);
} }
// TODO: we should have the same issue as in JsonValue // TODO: we should have the same issue as in JsonValue
void JsonArray::add(JsonContainer nestedContainer) void JsonArray::add(JsonContainer nestedContainer) {
{ JsonNode *node = createNode();
JsonNode* node = createNode(); if (!node)
if (!node) return; return;
node->duplicate(nestedContainer._node); node->duplicate(nestedContainer._node);
addChild(node);
}
JsonArray JsonArray::createNestedArray() {
JsonNode *node = createNode();
if (node) {
node->setAsArray(_node->getContainerBuffer());
addChild(node); addChild(node);
}
return JsonArray(node);
} }
JsonArray JsonArray::createNestedArray() JsonObject JsonArray::createNestedObject() {
{ JsonNode *node = createNode();
JsonNode* node = createNode();
if (node) {
if (node) node->setAsObject(_node->getContainerBuffer());
{ addChild(node);
node->setAsArray(_node->getContainerBuffer()); }
addChild(node);
} return JsonObject(node);
return JsonArray(node);
} }
JsonObject JsonArray::createNestedObject() JsonArrayIterator JsonArray::begin() {
{ if (!_node)
JsonNode* node = createNode(); return end();
if (node)
{
node->setAsObject(_node->getContainerBuffer());
addChild(node);
}
return JsonObject(node);
}
JsonArrayIterator JsonArray::begin() return JsonArrayIterator(_node->getContainerChild());
{
if (!_node)
return end();
return JsonArrayIterator(_node->getContainerChild());
} }

View File

@ -9,103 +9,91 @@
using namespace ArduinoJson; using namespace ArduinoJson;
using namespace ArduinoJson::Internals; using namespace ArduinoJson::Internals;
JsonValue JsonBuffer::createValue() JsonValue JsonBuffer::createValue() { return JsonValue(createNode()); }
{
return JsonValue(createNode()); JsonNode *JsonBuffer::createNode() {
void *node = allocateNode();
if (!node)
return 0;
return new (node) JsonNode();
} }
JsonNode* JsonBuffer::createNode() JsonArray JsonBuffer::parseArray(char *json) {
{ JsonParser parser(this, json);
void* node = allocateNode(); return JsonArray(parser.parseAnything());
if (!node) return 0;
return new (node) JsonNode();
} }
JsonArray JsonBuffer::parseArray(char* json) JsonObject JsonBuffer::parseObject(char *json) {
{ JsonParser parser(this, json);
JsonParser parser(this, json); return JsonObject(parser.parseAnything());
return JsonArray(parser.parseAnything());
} }
JsonObject JsonBuffer::parseObject(char* json) JsonValue JsonBuffer::parseValue(char *json) {
{ JsonParser parser(this, json);
JsonParser parser(this, json); return JsonValue(parser.parseAnything());
return JsonObject(parser.parseAnything());
} }
JsonValue JsonBuffer::parseValue(char* json) JsonNode *JsonBuffer::createArrayNode() {
{ JsonNode *node = createNode();
JsonParser parser(this, json);
return JsonValue(parser.parseAnything()); if (node)
node->setAsArray(this);
return node;
} }
JsonNode* JsonBuffer::createArrayNode() JsonNode *JsonBuffer::createBoolNode(bool value) {
{ JsonNode *node = createNode();
JsonNode* node = createNode();
if (node) if (node)
node->setAsArray(this); node->setAsBoolean(value);
return node; return node;
} }
JsonNode* JsonBuffer::createBoolNode(bool value) JsonNode *JsonBuffer::createDoubleNode(double value, int decimals) {
{ JsonNode *node = createNode();
JsonNode* node = createNode();
if (node) if (node)
node->setAsBoolean(value); node->setAsDouble(value, decimals);
return node; return node;
} }
JsonNode* JsonBuffer::createDoubleNode(double value, int decimals) JsonNode *JsonBuffer::createLongNode(long value) {
{ JsonNode *node = createNode();
JsonNode* node = createNode();
if (node) if (node)
node->setAsDouble(value, decimals); node->setAsLong(value);
return node; return node;
} }
JsonNode* JsonBuffer::createLongNode(long value) JsonNode *JsonBuffer::createObjectNode() {
{ JsonNode *node = createNode();
JsonNode* node = createNode();
if (node) if (node)
node->setAsLong(value); node->setAsObject(this);
return node; return node;
} }
JsonNode* JsonBuffer::createObjectNode() Internals::JsonNode *JsonBuffer::createObjectKeyValueNode(const char *key,
{ JsonNode *value) {
JsonNode* node = createNode(); JsonNode *node = createNode();
if (node) if (node)
node->setAsObject(this); node->setAsObjectKeyValue(key, value);
return node; return node;
} }
Internals::JsonNode* JsonBuffer::createObjectKeyValueNode(const char* key, JsonNode* value) JsonNode *JsonBuffer::createStringNode(const char *value) {
{ JsonNode *node = createNode();
JsonNode* node = createNode();
if (node) if (node)
node->setAsObjectKeyValue(key, value); node->setAsString(value);
return node; return node;
}
JsonNode* JsonBuffer::createStringNode(const char* value)
{
JsonNode* node = createNode();
if (node)
node->setAsString(value);
return node;
} }

View File

@ -8,76 +8,68 @@
using namespace ArduinoJson; using namespace ArduinoJson;
using namespace ArduinoJson::Internals; using namespace ArduinoJson::Internals;
size_t JsonContainer::printTo(char* buffer, size_t bufferSize) const size_t JsonContainer::printTo(char *buffer, size_t bufferSize) const {
{ StringBuilder sb(buffer, bufferSize);
StringBuilder sb(buffer, bufferSize); return printTo(sb);
return printTo(sb);
} }
size_t JsonContainer::printTo(Print& p) const size_t JsonContainer::printTo(Print &p) const {
{ CompactJsonWriter writer(&p);
CompactJsonWriter writer(&p); _node->writeTo(writer);
_node->writeTo(writer); return writer.bytesWritten();
return writer.bytesWritten();
} }
size_t JsonContainer::prettyPrintTo(char* buffer, size_t bufferSize) const size_t JsonContainer::prettyPrintTo(char *buffer, size_t bufferSize) const {
{ StringBuilder sb(buffer, bufferSize);
StringBuilder sb(buffer, bufferSize); return prettyPrintTo(sb);
return prettyPrintTo(sb);
} }
size_t JsonContainer::prettyPrintTo(IndentedPrint& p) const size_t JsonContainer::prettyPrintTo(IndentedPrint &p) const {
{ PrettyJsonWriter writer(&p);
PrettyJsonWriter writer(&p); _node->writeTo(writer);
_node->writeTo(writer); return writer.bytesWritten();
return writer.bytesWritten();
} }
size_t JsonContainer::prettyPrintTo(Print& print) const size_t JsonContainer::prettyPrintTo(Print &print) const {
{ IndentedPrint indentedPrint = IndentedPrint(print);
IndentedPrint indentedPrint = IndentedPrint(print); return prettyPrintTo(indentedPrint);
return prettyPrintTo(indentedPrint);
} }
JsonNode* JsonContainer::createNode() JsonNode *JsonContainer::createNode() {
{ if (!_node)
if (!_node) return 0; return 0;
JsonBuffer* buffer = _node->getContainerBuffer(); JsonBuffer *buffer = _node->getContainerBuffer();
if (!buffer) return 0; if (!buffer)
return 0;
return buffer->createNode(); return buffer->createNode();
} }
bool JsonContainer::operator==(const JsonContainer & other) const bool JsonContainer::operator==(const JsonContainer &other) const {
{ if (_node == other._node)
if (_node == other._node) return true; return true;
if (!_node || !other._node) return false; if (!_node || !other._node)
return _node->getProxyTarget() == other._node->getProxyTarget(); return false;
return _node->getProxyTarget() == other._node->getProxyTarget();
} }
void JsonContainer::addChild(JsonNode* childToAdd) void JsonContainer::addChild(JsonNode *childToAdd) {
{ if (_node)
if (_node) _node->addChild(childToAdd);
_node->addChild(childToAdd);
} }
void JsonContainer::removeChild(JsonNode* childToRemove) void JsonContainer::removeChild(JsonNode *childToRemove) {
{ if (_node)
if (_node) _node->removeChild(childToRemove);
_node->removeChild(childToRemove);
} }
size_t JsonContainer::size() const size_t JsonContainer::size() const {
{ int n = 0;
int n = 0;
for (JsonNodeIterator it = beginChildren(); it != endChildren(); ++it) for (JsonNodeIterator it = beginChildren(); it != endChildren(); ++it) {
{ n++;
n++; }
}
return n; return n;
} }

View File

@ -10,69 +10,62 @@
using namespace ArduinoJson; using namespace ArduinoJson;
using namespace ArduinoJson::Internals; using namespace ArduinoJson::Internals;
JsonValue JsonObject::operator[](char const* key) JsonValue JsonObject::operator[](char const *key) {
{ JsonNode *node = getOrCreateNodeAt(key);
JsonNode* node = getOrCreateNodeAt(key); return JsonValue(node);
return JsonValue(node);
} }
void JsonObject::remove(char const* key) void JsonObject::remove(char const *key) {
{ for (JsonNodeIterator it = beginChildren(); it != endChildren(); ++it) {
for (JsonNodeIterator it = beginChildren(); it != endChildren(); ++it) const char *childKey = it->getAsObjectKey();
{
const char* childKey = it->getAsObjectKey();
if (!strcmp(childKey, key)) if (!strcmp(childKey, key)) {
{ removeChild(*it);
removeChild(*it);
}
} }
}
} }
JsonArray JsonObject::createNestedArray(char const* key) JsonArray JsonObject::createNestedArray(char const *key) {
{ JsonNode *node = getOrCreateNodeAt(key);
JsonNode* node = getOrCreateNodeAt(key);
if (node) if (node)
node->setAsArray(_node->getContainerBuffer()); node->setAsArray(_node->getContainerBuffer());
return JsonArray(node); return JsonArray(node);
} }
JsonObject JsonObject::createNestedObject(char const* key) JsonObject JsonObject::createNestedObject(char const *key) {
{ JsonNode *node = getOrCreateNodeAt(key);
JsonNode* node = getOrCreateNodeAt(key);
if (node)
node->setAsObject(_node->getContainerBuffer());
return JsonObject(node); if (node)
node->setAsObject(_node->getContainerBuffer());
return JsonObject(node);
} }
JsonNode* JsonObject::getOrCreateNodeAt(const char* key) JsonNode *JsonObject::getOrCreateNodeAt(const char *key) {
{ for (JsonNodeIterator it = beginChildren(); it != endChildren(); ++it) {
for (JsonNodeIterator it = beginChildren(); it != endChildren(); ++it) const char *childKey = it->getAsObjectKey();
{
const char* childKey = it->getAsObjectKey();
if (!strcmp(childKey, key)) if (!strcmp(childKey, key))
return it->getAsObjectValue(); return it->getAsObjectValue();
} }
JsonNode* newValueNode = createNode();
if (!newValueNode) return 0;
JsonNode* newKeyNode = createNode();
if (!newKeyNode) return 0;
newKeyNode->setAsObjectKeyValue(key, newValueNode); JsonNode *newValueNode = createNode();
if (!newValueNode)
return 0;
addChild(newKeyNode); JsonNode *newKeyNode = createNode();
if (!newKeyNode)
return 0;
return newValueNode; newKeyNode->setAsObjectKeyValue(key, newValueNode);
addChild(newKeyNode);
return newValueNode;
} }
JsonObjectIterator JsonObject::begin() JsonObjectIterator JsonObject::begin() {
{ return JsonObjectIterator(_node->getContainerChild());
return JsonObjectIterator(_node->getContainerChild());
} }

View File

@ -6,56 +6,38 @@
using namespace ArduinoJson; using namespace ArduinoJson;
void JsonValue::operator=(bool value) void JsonValue::operator=(bool value) {
{ if (_node)
if (_node) _node->setAsBoolean(value);
_node->setAsBoolean(value);
} }
void JsonValue::operator=(char const* value) void JsonValue::operator=(char const *value) {
{ if (_node)
if (_node) _node->setAsString(value);
_node->setAsString(value);
} }
void JsonValue::set(double value, int decimals) void JsonValue::set(double value, int decimals) {
{ if (_node)
if (_node) _node->setAsDouble(value, decimals);
_node->setAsDouble(value, decimals);
} }
void JsonValue::operator=(int value) void JsonValue::operator=(int value) {
{ if (_node)
if (_node) _node->setAsLong(value);
_node->setAsLong(value);
} }
JsonValue::operator bool() const JsonValue::operator bool() const {
{ return _node ? _node->getAsBoolean() : false;
return _node ? _node->getAsBoolean() : false;
} }
JsonValue::operator char const*() const JsonValue::operator char const *() const {
{ return _node ? _node->getAsString() : 0;
return _node ? _node->getAsString() : 0;
} }
JsonValue::operator double() const JsonValue::operator double() const { return _node ? _node->getAsDouble() : 0; }
{
return _node ? _node->getAsDouble() : 0;
}
JsonValue::operator long() const JsonValue::operator long() const { return _node ? _node->getAsInteger() : 0; }
{
return _node ? _node->getAsInteger() : 0;
}
JsonValue::operator JsonArray() const JsonValue::operator JsonArray() const { return JsonArray(_node); }
{
return JsonArray(_node);
}
JsonValue::operator JsonObject() const JsonValue::operator JsonObject() const { return JsonObject(_node); }
{
return JsonObject(_node);
}

View File

@ -6,75 +6,65 @@
using namespace ArduinoJson; using namespace ArduinoJson;
struct Person struct Person {
{ int id;
int id; char name[32];
char name[32];
}; };
class Issue10 : public testing::Test class Issue10 : public testing::Test {
{
protected: protected:
virtual void SetUp() {
Person boss;
boss.id = 1;
strcpy(boss.name, "Jeff");
Person employee;
employee.id = 2;
strcpy(employee.name, "John");
persons[0] = boss;
persons[1] = employee;
}
virtual void SetUp() void checkJsonString(JsonContainer &p) {
{ char buffer[256];
Person boss; p.printTo(buffer, sizeof(buffer));
boss.id = 1;
strcpy(boss.name, "Jeff");
Person employee;
employee.id = 2;
strcpy(employee.name, "John");
persons[0] = boss;
persons[1] = employee;
}
void checkJsonString(JsonContainer& p) EXPECT_STREQ("[{\"id\":1,\"name\":\"Jeff\"},{\"id\":2,\"name\":\"John\"}]",
{ buffer);
char buffer[256]; }
p.printTo(buffer, sizeof(buffer));
EXPECT_STREQ("[{\"id\":1,\"name\":\"Jeff\"},{\"id\":2,\"name\":\"John\"}]", buffer); void nodeCountMustBe(int expected) { EXPECT_EQ(expected, json.size()); }
}
void nodeCountMustBe(int expected) Person persons[2];
{ StaticJsonBuffer<20> json;
EXPECT_EQ(expected, json.size());
}
Person persons[2];
StaticJsonBuffer<20> json;
}; };
TEST_F(Issue10, PopulateArrayByAddingAnObject) TEST_F(Issue10, PopulateArrayByAddingAnObject) {
{ JsonArray array = json.createArray();
JsonArray array= json.createArray();
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++) {
{ JsonObject object = json.createObject();
JsonObject object = json.createObject();
object["id"] = persons[i].id;
object["name"] = persons[i].name;
array.add(object); // <- adds a reference to an existing objet (creates 2 extra proxy nodes) object["id"] = persons[i].id;
} object["name"] = persons[i].name;
checkJsonString(array); array.add(object); // <- adds a reference to an existing objet (creates 2
nodeCountMustBe(15); // extra proxy nodes)
}
checkJsonString(array);
nodeCountMustBe(15);
} }
TEST_F(Issue10, PopulateArrayByCreatingNestedObjects) TEST_F(Issue10, PopulateArrayByCreatingNestedObjects) {
{ JsonArray array = json.createArray();
JsonArray array = json.createArray();
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++) {
{ JsonObject object = array.createNestedObject();
JsonObject object = array.createNestedObject();
object["id"] = persons[i].id; object["id"] = persons[i].id;
object["name"] = persons[i].name; object["name"] = persons[i].name;
} }
checkJsonString(array); checkJsonString(array);
nodeCountMustBe(11); nodeCountMustBe(11);
} }

View File

@ -4,149 +4,123 @@
using namespace ArduinoJson; using namespace ArduinoJson;
class JsonArray_Container_Tests : public ::testing::Test class JsonArray_Container_Tests : public ::testing::Test {
{
protected: protected:
virtual void SetUp() virtual void SetUp() { array = json.createArray(); }
{
array = json.createArray();
}
void nodeCountMustBe(int expected) void nodeCountMustBe(int expected) { EXPECT_EQ(expected, json.size()); }
{
EXPECT_EQ(expected, json.size());
}
template<typename T> template <typename T> void firstElementMustBe(T expected) {
void firstElementMustBe(T expected) elementAtIndexMustBe(0, expected);
{ }
elementAtIndexMustBe(0, expected);
}
template<typename T> template <typename T> void secondElementMustBe(T expected) {
void secondElementMustBe(T expected) elementAtIndexMustBe(1, expected);
{ }
elementAtIndexMustBe(1, expected);
}
void sizeMustBe(int expected) void sizeMustBe(int expected) { EXPECT_EQ(expected, array.size()); }
{
EXPECT_EQ(expected, array.size());
}
StaticJsonBuffer<42> json; StaticJsonBuffer<42> json;
JsonArray array; JsonArray array;
private: private:
template<typename T> template <typename T> void elementAtIndexMustBe(int index, T expected) {
void elementAtIndexMustBe(int index, T expected) EXPECT_EQ(expected, array[index].as<T>());
{ }
EXPECT_EQ(expected, array[index].as<T>());
}
}; };
TEST_F(JsonArray_Container_Tests, InitialSizeIsZero) TEST_F(JsonArray_Container_Tests, InitialSizeIsZero) {
{ sizeMustBe(0);
sizeMustBe(0); nodeCountMustBe(1);
nodeCountMustBe(1);
} }
TEST_F(JsonArray_Container_Tests, Grow_WhenValuesAreAdded) TEST_F(JsonArray_Container_Tests, Grow_WhenValuesAreAdded) {
{ array.add("hello");
array.add("hello"); sizeMustBe(1);
sizeMustBe(1); nodeCountMustBe(2);
nodeCountMustBe(2);
array.add("world"); array.add("world");
sizeMustBe(2); sizeMustBe(2);
nodeCountMustBe(3); nodeCountMustBe(3);
} }
TEST_F(JsonArray_Container_Tests, CanStoreIntegers) TEST_F(JsonArray_Container_Tests, CanStoreIntegers) {
{ array.add(123);
array.add(123); array.add(456);
array.add(456);
firstElementMustBe(123); firstElementMustBe(123);
secondElementMustBe(456); secondElementMustBe(456);
nodeCountMustBe(3); nodeCountMustBe(3);
} }
TEST_F(JsonArray_Container_Tests, CanStoreDoubles) TEST_F(JsonArray_Container_Tests, CanStoreDoubles) {
{ array.add(123.45);
array.add(123.45); array.add(456.78);
array.add(456.78);
firstElementMustBe(123.45); firstElementMustBe(123.45);
secondElementMustBe(456.78); secondElementMustBe(456.78);
nodeCountMustBe(3); nodeCountMustBe(3);
} }
TEST_F(JsonArray_Container_Tests, CanStoreBooleans) TEST_F(JsonArray_Container_Tests, CanStoreBooleans) {
{ array.add(true);
array.add(true); array.add(false);
array.add(false);
firstElementMustBe(true);
firstElementMustBe(true); secondElementMustBe(false);
secondElementMustBe(false); nodeCountMustBe(3);
nodeCountMustBe(3);
} }
TEST_F(JsonArray_Container_Tests, CanStoreStrings) TEST_F(JsonArray_Container_Tests, CanStoreStrings) {
{ const char *firstString = "h3110";
const char* firstString = "h3110"; const char *secondString = "w0r1d";
const char* secondString = "w0r1d";
array.add(firstString); array.add(firstString);
array.add(secondString); array.add(secondString);
firstElementMustBe(firstString); firstElementMustBe(firstString);
secondElementMustBe(secondString); secondElementMustBe(secondString);
nodeCountMustBe(3); nodeCountMustBe(3);
} }
TEST_F(JsonArray_Container_Tests, CanStoreNestedArrays) TEST_F(JsonArray_Container_Tests, CanStoreNestedArrays) {
{ JsonArray innerarray1 = json.createArray();
JsonArray innerarray1 = json.createArray(); JsonArray innerarray2 = json.createArray();
JsonArray innerarray2 = json.createArray();
array.add(innerarray1); array.add(innerarray1);
array.add(innerarray2); array.add(innerarray2);
firstElementMustBe(innerarray1); firstElementMustBe(innerarray1);
secondElementMustBe(innerarray2); secondElementMustBe(innerarray2);
nodeCountMustBe(1 + 3 + 3); nodeCountMustBe(1 + 3 + 3);
} }
TEST_F(JsonArray_Container_Tests, CanStoreNestedObjects) TEST_F(JsonArray_Container_Tests, CanStoreNestedObjects) {
{ JsonObject innerObject1 = json.createObject();
JsonObject innerObject1 = json.createObject(); JsonObject innerObject2 = json.createObject();
JsonObject innerObject2 = json.createObject();
array.add(innerObject1); array.add(innerObject1);
array.add(innerObject2); array.add(innerObject2);
firstElementMustBe(innerObject1); firstElementMustBe(innerObject1);
secondElementMustBe(innerObject2); secondElementMustBe(innerObject2);
nodeCountMustBe(1 + 3 + 3); nodeCountMustBe(1 + 3 + 3);
} }
TEST_F(JsonArray_Container_Tests, CanCreateNestedArrays) TEST_F(JsonArray_Container_Tests, CanCreateNestedArrays) {
{ JsonArray innerarray1 = array.createNestedArray();
JsonArray innerarray1 = array.createNestedArray(); JsonArray innerarray2 = array.createNestedArray();
JsonArray innerarray2 = array.createNestedArray();
firstElementMustBe(innerarray1); firstElementMustBe(innerarray1);
secondElementMustBe(innerarray2); secondElementMustBe(innerarray2);
nodeCountMustBe(1 + 1 + 1); nodeCountMustBe(1 + 1 + 1);
} }
TEST_F(JsonArray_Container_Tests, CanCreateNestedObjects) TEST_F(JsonArray_Container_Tests, CanCreateNestedObjects) {
{ JsonObject innerObject1 = array.createNestedObject();
JsonObject innerObject1 = array.createNestedObject(); JsonObject innerObject2 = array.createNestedObject();
JsonObject innerObject2 = array.createNestedObject();
firstElementMustBe(innerObject1); firstElementMustBe(innerObject1);
secondElementMustBe(innerObject2); secondElementMustBe(innerObject2);
nodeCountMustBe(3); nodeCountMustBe(3);
} }

View File

@ -4,22 +4,21 @@
using namespace ArduinoJson; using namespace ArduinoJson;
TEST(JsonArray_Iterator_Test, SimpleTest) TEST(JsonArray_Iterator_Test, SimpleTest) {
{ StaticJsonBuffer<42> jsonBuffer;
StaticJsonBuffer<42> jsonBuffer;
JsonArray array = jsonBuffer.createArray(); JsonArray array = jsonBuffer.createArray();
array.add(12); array.add(12);
array.add(34); array.add(34);
JsonArrayIterator it = array.begin(); JsonArrayIterator it = array.begin();
JsonArrayIterator end = array.end(); JsonArrayIterator end = array.end();
EXPECT_NE(end, it); EXPECT_NE(end, it);
EXPECT_EQ(12, (*it).as<int>()); // TODO: use -> EXPECT_EQ(12, (*it).as<int>()); // TODO: use ->
++it; ++it;
EXPECT_NE(end, it); EXPECT_NE(end, it);
EXPECT_EQ(34, (*it).as<int>()); // TODO: use -> EXPECT_EQ(34, (*it).as<int>()); // TODO: use ->
++it; ++it;
EXPECT_EQ(array.end(), it); EXPECT_EQ(array.end(), it);
} }

View File

@ -11,84 +11,68 @@
using namespace ArduinoJson; using namespace ArduinoJson;
class JsonArray_PrettyPrintTo_Tests : public testing::Test class JsonArray_PrettyPrintTo_Tests : public testing::Test {
{
protected: protected:
JsonArray array; JsonArray array;
StaticJsonBuffer<30> json; StaticJsonBuffer<30> json;
virtual void SetUp() virtual void SetUp() { array = json.createArray(); }
{
array = json.createArray();
}
void outputMustBe(const char* expected) void outputMustBe(const char *expected) {
{ size_t n = array.prettyPrintTo(buffer, sizeof(buffer));
size_t n = array.prettyPrintTo(buffer, sizeof(buffer)); EXPECT_STREQ(expected, buffer);
EXPECT_STREQ(expected, buffer); EXPECT_EQ(strlen(expected), n);
EXPECT_EQ(strlen(expected), n); }
}
private: private:
char buffer[256]; char buffer[256];
}; };
TEST_F(JsonArray_PrettyPrintTo_Tests, Empty) TEST_F(JsonArray_PrettyPrintTo_Tests, Empty) { outputMustBe("[]"); }
{
outputMustBe("[]"); TEST_F(JsonArray_PrettyPrintTo_Tests, OneElement) {
array.add(1);
outputMustBe("[\r\n"
" 1\r\n"
"]");
} }
TEST_F(JsonArray_PrettyPrintTo_Tests, OneElement) TEST_F(JsonArray_PrettyPrintTo_Tests, TwoElements) {
{ array.add(1);
array.add(1); array.add(2);
outputMustBe( outputMustBe("[\r\n"
"[\r\n" " 1,\r\n"
" 1\r\n" " 2\r\n"
"]"); "]");
} }
TEST_F(JsonArray_PrettyPrintTo_Tests, TwoElements) TEST_F(JsonArray_PrettyPrintTo_Tests, EmptyNestedArrays) {
{ array.createNestedArray();
array.add(1); array.createNestedArray();
array.add(2);
outputMustBe( outputMustBe("[\r\n"
"[\r\n" " [],\r\n"
" 1,\r\n" " []\r\n"
" 2\r\n" "]");
"]");
} }
TEST_F(JsonArray_PrettyPrintTo_Tests, EmptyNestedArrays) TEST_F(JsonArray_PrettyPrintTo_Tests, NestedArrays) {
{ JsonArray nested1 = array.createNestedArray();
array.createNestedArray(); nested1.add(1);
array.createNestedArray(); nested1.add(2);
outputMustBe( JsonObject nested2 = array.createNestedObject();
"[\r\n" nested2["key"] = 3;
" [],\r\n"
" []\r\n"
"]");
}
TEST_F(JsonArray_PrettyPrintTo_Tests, NestedArrays) outputMustBe("[\r\n"
{ " [\r\n"
JsonArray nested1 = array.createNestedArray(); " 1,\r\n"
nested1.add(1); " 2\r\n"
nested1.add(2); " ],\r\n"
" {\r\n"
JsonObject nested2 = array.createNestedObject(); " \"key\": 3\r\n"
nested2["key"] = 3; " }\r\n"
"]");
outputMustBe(
"[\r\n"
" [\r\n"
" 1,\r\n"
" 2\r\n"
" ],\r\n"
" {\r\n"
" \"key\": 3\r\n"
" }\r\n"
"]");
} }

View File

@ -10,141 +10,118 @@
using namespace ArduinoJson; using namespace ArduinoJson;
class JsonArray_PrintTo_Tests : public testing::Test class JsonArray_PrintTo_Tests : public testing::Test {
{
protected: protected:
JsonArray array; JsonArray array;
StaticJsonBuffer<3> json; StaticJsonBuffer<3> json;
virtual void SetUp() virtual void SetUp() { array = json.createArray(); }
{
array = json.createArray();
}
void outputMustBe(const char* expected) void outputMustBe(const char *expected) {
{ size_t n = array.printTo(buffer, sizeof(buffer));
size_t n = array.printTo(buffer, sizeof(buffer)); EXPECT_STREQ(expected, buffer);
EXPECT_STREQ(expected, buffer); EXPECT_EQ(strlen(expected), n);
EXPECT_EQ(strlen(expected), n); }
}
private: private:
char buffer[256]; char buffer[256];
}; };
TEST_F(JsonArray_PrintTo_Tests, Empty) TEST_F(JsonArray_PrintTo_Tests, Empty) { outputMustBe("[]"); }
{
outputMustBe("[]"); TEST_F(JsonArray_PrintTo_Tests, Null) {
array.add((char *)0);
outputMustBe("[null]");
} }
TEST_F(JsonArray_PrintTo_Tests, Null) TEST_F(JsonArray_PrintTo_Tests, OneString) {
{ array.add("hello");
array.add((char*) 0);
outputMustBe("[null]"); outputMustBe("[\"hello\"]");
} }
TEST_F(JsonArray_PrintTo_Tests, OneString) TEST_F(JsonArray_PrintTo_Tests, TwoStrings) {
{ array.add("hello");
array.add("hello"); array.add("world");
outputMustBe("[\"hello\"]"); outputMustBe("[\"hello\",\"world\"]");
} }
TEST_F(JsonArray_PrintTo_Tests, TwoStrings) TEST_F(JsonArray_PrintTo_Tests, OneStringOverCapacity) {
{ array.add("hello");
array.add("hello"); array.add("world");
array.add("world"); array.add("lost");
outputMustBe("[\"hello\",\"world\"]"); outputMustBe("[\"hello\",\"world\"]");
} }
TEST_F(JsonArray_PrintTo_Tests, OneStringOverCapacity) TEST_F(JsonArray_PrintTo_Tests, OneDoubleDefaultDigits) {
{ array.add(3.14159265358979323846);
array.add("hello"); outputMustBe("[3.14]");
array.add("world");
array.add("lost");
outputMustBe("[\"hello\",\"world\"]");
} }
TEST_F(JsonArray_PrintTo_Tests, OneDoubleDefaultDigits) TEST_F(JsonArray_PrintTo_Tests, OneDoubleFourDigits) {
{ array.add(3.14159265358979323846, 4);
array.add(3.14159265358979323846); outputMustBe("[3.1416]");
outputMustBe("[3.14]");
} }
TEST_F(JsonArray_PrintTo_Tests, OneDoubleFourDigits) TEST_F(JsonArray_PrintTo_Tests, OneInteger) {
{ array.add(1);
array.add(3.14159265358979323846, 4);
outputMustBe("[3.1416]"); outputMustBe("[1]");
} }
TEST_F(JsonArray_PrintTo_Tests, OneInteger) TEST_F(JsonArray_PrintTo_Tests, TwoIntegers) {
{ array.add(1);
array.add(1); array.add(2);
outputMustBe("[1]"); outputMustBe("[1,2]");
} }
TEST_F(JsonArray_PrintTo_Tests, TwoIntegers) TEST_F(JsonArray_PrintTo_Tests, OneIntegerOverCapacity) {
{ array.add(1);
array.add(1); array.add(2);
array.add(2); array.add(3);
outputMustBe("[1,2]"); outputMustBe("[1,2]");
} }
TEST_F(JsonArray_PrintTo_Tests, OneIntegerOverCapacity) TEST_F(JsonArray_PrintTo_Tests, OneTrue) {
{ array.add(true);
array.add(1);
array.add(2);
array.add(3);
outputMustBe("[1,2]"); outputMustBe("[true]");
} }
TEST_F(JsonArray_PrintTo_Tests, OneTrue) TEST_F(JsonArray_PrintTo_Tests, OneFalse) {
{ array.add(false);
array.add(true);
outputMustBe("[true]"); outputMustBe("[false]");
} }
TEST_F(JsonArray_PrintTo_Tests, OneFalse) TEST_F(JsonArray_PrintTo_Tests, TwoBooleans) {
{ array.add(false);
array.add(false); array.add(true);
outputMustBe("[false]"); outputMustBe("[false,true]");
} }
TEST_F(JsonArray_PrintTo_Tests, TwoBooleans) TEST_F(JsonArray_PrintTo_Tests, OneBooleanOverCapacity) {
{ array.add(false);
array.add(false); array.add(true);
array.add(true); array.add(false);
outputMustBe("[false,true]"); outputMustBe("[false,true]");
} }
TEST_F(JsonArray_PrintTo_Tests, OneBooleanOverCapacity) TEST_F(JsonArray_PrintTo_Tests, OneEmptyNestedArray) {
{ array.createNestedArray();
array.add(false);
array.add(true);
array.add(false);
outputMustBe("[false,true]"); outputMustBe("[[]]");
} }
TEST_F(JsonArray_PrintTo_Tests, OneEmptyNestedArray) TEST_F(JsonArray_PrintTo_Tests, OneEmptyNestedHash) {
{ array.createNestedObject();
array.createNestedArray();
outputMustBe("[[]]"); outputMustBe("[{}]");
}
TEST_F(JsonArray_PrintTo_Tests, OneEmptyNestedHash)
{
array.createNestedObject();
outputMustBe("[{}]");
} }

View File

@ -4,119 +4,105 @@
using namespace ArduinoJson; using namespace ArduinoJson;
class JsonObject_Container_Tests : public ::testing::Test class JsonObject_Container_Tests : public ::testing::Test {
{
protected: protected:
virtual void SetUp() virtual void SetUp() { object = json.createObject(); }
{
object = json.createObject();
}
StaticJsonBuffer<42> json; StaticJsonBuffer<42> json;
JsonObject object; JsonObject object;
}; };
TEST_F(JsonObject_Container_Tests, InitialSizeIsZero) TEST_F(JsonObject_Container_Tests, InitialSizeIsZero) {
{ EXPECT_EQ(0, object.size());
EXPECT_EQ(0, object.size());
} }
TEST_F(JsonObject_Container_Tests, Grow_WhenValuesAreAdded) TEST_F(JsonObject_Container_Tests, Grow_WhenValuesAreAdded) {
{ object["hello"];
object["hello"]; EXPECT_EQ(1, object.size());
EXPECT_EQ(1, object.size());
object["world"]; object["world"];
EXPECT_EQ(2, object.size()); EXPECT_EQ(2, object.size());
} }
TEST_F(JsonObject_Container_Tests, DoNotGrow_WhenSameValueIsAdded) TEST_F(JsonObject_Container_Tests, DoNotGrow_WhenSameValueIsAdded) {
{ object["hello"];
object["hello"]; EXPECT_EQ(1, object.size());
EXPECT_EQ(1, object.size());
object["hello"]; object["hello"];
EXPECT_EQ(1, object.size()); EXPECT_EQ(1, object.size());
} }
TEST_F(JsonObject_Container_Tests, Shrink_WhenValuesAreRemoved) TEST_F(JsonObject_Container_Tests, Shrink_WhenValuesAreRemoved) {
{ object["hello"];
object["hello"]; object["world"];
object["world"];
object.remove("hello"); object.remove("hello");
EXPECT_EQ(1, object.size()); EXPECT_EQ(1, object.size());
object.remove("world"); object.remove("world");
EXPECT_EQ(0, object.size()); EXPECT_EQ(0, object.size());
} }
TEST_F(JsonObject_Container_Tests, DoNotShrink_WhenRemoveIsCalledWithAWrongKey) TEST_F(JsonObject_Container_Tests,
{ DoNotShrink_WhenRemoveIsCalledWithAWrongKey) {
object["hello"]; object["hello"];
object["world"]; object["world"];
object.remove(":-P"); object.remove(":-P");
EXPECT_EQ(2, object.size()); EXPECT_EQ(2, object.size());
} }
TEST_F(JsonObject_Container_Tests, CanStoreIntegers) TEST_F(JsonObject_Container_Tests, CanStoreIntegers) {
{ object["hello"] = 123;
object["hello"] = 123; object["world"] = 456;
object["world"] = 456;
EXPECT_EQ(123, (int) object["hello"]); EXPECT_EQ(123, (int)object["hello"]);
EXPECT_EQ(456, (int) object["world"]); EXPECT_EQ(456, (int)object["world"]);
} }
TEST_F(JsonObject_Container_Tests, CanStoreDoubles) TEST_F(JsonObject_Container_Tests, CanStoreDoubles) {
{ object["hello"] = 123.45;
object["hello"] = 123.45; object["world"] = 456.78;
object["world"] = 456.78;
EXPECT_EQ(123.45, (double) object["hello"]); EXPECT_EQ(123.45, (double)object["hello"]);
EXPECT_EQ(456.78, (double) object["world"]); EXPECT_EQ(456.78, (double)object["world"]);
} }
TEST_F(JsonObject_Container_Tests, CanStoreBooleans) TEST_F(JsonObject_Container_Tests, CanStoreBooleans) {
{ object["hello"] = true;
object["hello"] = true; object["world"] = false;
object["world"] = false;
EXPECT_TRUE((bool) object["hello"]); EXPECT_TRUE((bool)object["hello"]);
EXPECT_FALSE((bool) object["world"]); EXPECT_FALSE((bool)object["world"]);
} }
TEST_F(JsonObject_Container_Tests, CanStoreStrings) TEST_F(JsonObject_Container_Tests, CanStoreStrings) {
{ object["hello"] = "h3110";
object["hello"] = "h3110"; object["world"] = "w0r1d";
object["world"] = "w0r1d";
EXPECT_STREQ("h3110", (const char*) object["hello"]); EXPECT_STREQ("h3110", (const char *)object["hello"]);
EXPECT_STREQ("w0r1d", (const char*) object["world"]); EXPECT_STREQ("w0r1d", (const char *)object["world"]);
} }
TEST_F(JsonObject_Container_Tests, CanStoreInnerArrays) TEST_F(JsonObject_Container_Tests, CanStoreInnerArrays) {
{ JsonArray innerarray1 = json.createArray();
JsonArray innerarray1 = json.createArray(); JsonArray innerarray2 = json.createArray();
JsonArray innerarray2 = json.createArray();
object["hello"] = innerarray1; object["hello"] = innerarray1;
object["world"] = innerarray2; object["world"] = innerarray2;
EXPECT_EQ(innerarray1, (JsonArray) object["hello"]); EXPECT_EQ(innerarray1, (JsonArray)object["hello"]);
EXPECT_EQ(innerarray2, (JsonArray) object["world"]); EXPECT_EQ(innerarray2, (JsonArray)object["world"]);
} }
TEST_F(JsonObject_Container_Tests, CanStoreInnerObjects) TEST_F(JsonObject_Container_Tests, CanStoreInnerObjects) {
{ JsonObject innerObject1 = json.createObject();
JsonObject innerObject1 = json.createObject(); JsonObject innerObject2 = json.createObject();
JsonObject innerObject2 = json.createObject();
object["hello"] = innerObject1; object["hello"] = innerObject1;
object["world"] = innerObject2; object["world"] = innerObject2;
EXPECT_EQ(innerObject1, (JsonObject) object["hello"]); EXPECT_EQ(innerObject1, (JsonObject)object["hello"]);
EXPECT_EQ(innerObject2, (JsonObject) object["world"]); EXPECT_EQ(innerObject2, (JsonObject)object["world"]);
} }

View File

@ -4,23 +4,23 @@
using namespace ArduinoJson; using namespace ArduinoJson;
TEST(JsonObject_Iterator_Test, SimpleTest) TEST(JsonObject_Iterator_Test, SimpleTest) {
{ StaticJsonBuffer<42> jsonBuffer;
StaticJsonBuffer<42> jsonBuffer;
JsonObject object = jsonBuffer.createObject(); JsonObject object = jsonBuffer.createObject();
object["ab"] = 12; object["ab"] = 12;
object["cd"] = 34; object["cd"] = 34;
JsonObjectIterator it = object.begin(); JsonObjectIterator it = object.begin();
JsonObjectIterator end = object.end(); JsonObjectIterator end = object.end();
EXPECT_NE(end, it); EXPECT_NE(end, it);
EXPECT_STREQ("ab", it->key()); EXPECT_STREQ("ab", it->key());
EXPECT_EQ(12, it->value().as<int>()); ++it; EXPECT_EQ(12, it->value().as<int>());
EXPECT_NE(end, it); ++it;
EXPECT_STREQ("cd", it->key()); EXPECT_NE(end, it);
EXPECT_EQ(34, it->value().as<int>()); EXPECT_STREQ("cd", it->key());
++it; EXPECT_EQ(34, it->value().as<int>());
EXPECT_EQ(object.end(), it); ++it;
EXPECT_EQ(object.end(), it);
} }

View File

@ -10,82 +10,66 @@
using namespace ArduinoJson; using namespace ArduinoJson;
class JsonObject_PrettyPrintTo_Tests : public testing::Test class JsonObject_PrettyPrintTo_Tests : public testing::Test {
{
protected: protected:
JsonObject object; JsonObject object;
StaticJsonBuffer<30> json; StaticJsonBuffer<30> json;
virtual void SetUp() virtual void SetUp() { object = json.createObject(); }
{
object = json.createObject();
}
void outputMustBe(const char* expected) void outputMustBe(const char *expected) {
{ size_t n = object.prettyPrintTo(buffer, sizeof(buffer));
size_t n = object.prettyPrintTo(buffer, sizeof(buffer)); EXPECT_STREQ(expected, buffer);
EXPECT_STREQ(expected, buffer); EXPECT_EQ(strlen(expected), n);
EXPECT_EQ(strlen(expected), n); }
}
private: private:
char buffer[256]; char buffer[256];
}; };
TEST_F(JsonObject_PrettyPrintTo_Tests, EmptyObject) TEST_F(JsonObject_PrettyPrintTo_Tests, EmptyObject) { outputMustBe("{}"); }
{
outputMustBe("{}"); TEST_F(JsonObject_PrettyPrintTo_Tests, OneMember) {
object["key"] = "value";
outputMustBe("{\r\n"
" \"key\": \"value\"\r\n"
"}");
} }
TEST_F(JsonObject_PrettyPrintTo_Tests, OneMember) TEST_F(JsonObject_PrettyPrintTo_Tests, TwoMembers) {
{ object["key1"] = "value1";
object["key"] = "value"; object["key2"] = "value2";
outputMustBe( outputMustBe("{\r\n"
"{\r\n" " \"key1\": \"value1\",\r\n"
" \"key\": \"value\"\r\n" " \"key2\": \"value2\"\r\n"
"}"); "}");
} }
TEST_F(JsonObject_PrettyPrintTo_Tests, TwoMembers) TEST_F(JsonObject_PrettyPrintTo_Tests, EmptyNestedContainers) {
{ object.createNestedObject("key1");
object["key1"] = "value1"; object.createNestedArray("key2");
object["key2"] = "value2";
outputMustBe( outputMustBe("{\r\n"
"{\r\n" " \"key1\": {},\r\n"
" \"key1\": \"value1\",\r\n" " \"key2\": []\r\n"
" \"key2\": \"value2\"\r\n" "}");
"}");
} }
TEST_F(JsonObject_PrettyPrintTo_Tests, EmptyNestedContainers) TEST_F(JsonObject_PrettyPrintTo_Tests, NestedContainers) {
{ JsonObject nested1 = object.createNestedObject("key1");
object.createNestedObject("key1"); nested1["a"] = 1;
object.createNestedArray("key2");
outputMustBe( JsonArray nested2 = object.createNestedArray("key2");
"{\r\n" nested2.add(2);
" \"key1\": {},\r\n"
" \"key2\": []\r\n"
"}");
}
TEST_F(JsonObject_PrettyPrintTo_Tests, NestedContainers) outputMustBe("{\r\n"
{ " \"key1\": {\r\n"
JsonObject nested1 = object.createNestedObject("key1"); " \"a\": 1\r\n"
nested1["a"] = 1; " },\r\n"
" \"key2\": [\r\n"
JsonArray nested2 = object.createNestedArray("key2"); " 2\r\n"
nested2.add(2); " ]\r\n"
"}");
outputMustBe(
"{\r\n"
" \"key1\": {\r\n"
" \"a\": 1\r\n"
" },\r\n"
" \"key2\": [\r\n"
" 2\r\n"
" ]\r\n"
"}");
} }

View File

@ -6,155 +6,130 @@
using namespace ArduinoJson; using namespace ArduinoJson;
class JsonObject_Serialization_Tests : public testing::Test class JsonObject_Serialization_Tests : public testing::Test {
{
protected: protected:
virtual void SetUp() virtual void SetUp() { object = json.createObject(); }
{
object = json.createObject();
}
void outputMustBe(const char* expected) void outputMustBe(const char *expected) {
{ char actual[256];
char actual[256]; int result = object.printTo(actual, sizeof(actual));
int result = object.printTo(actual, sizeof(actual));
EXPECT_STREQ(expected, actual); EXPECT_STREQ(expected, actual);
EXPECT_EQ(strlen(expected), result); EXPECT_EQ(strlen(expected), result);
} }
JsonObject object; JsonObject object;
StaticJsonBuffer<5> json; StaticJsonBuffer<5> json;
}; };
TEST_F(JsonObject_Serialization_Tests, EmptyObject) TEST_F(JsonObject_Serialization_Tests, EmptyObject) { outputMustBe("{}"); }
{
outputMustBe("{}"); TEST_F(JsonObject_Serialization_Tests, OneString) {
object["key"] = "value";
outputMustBe("{\"key\":\"value\"}");
} }
TEST_F(JsonObject_Serialization_Tests, OneString) TEST_F(JsonObject_Serialization_Tests, TwoStrings) {
{ object["key1"] = "value1";
object["key"] = "value"; object["key2"] = "value2";
outputMustBe("{\"key\":\"value\"}"); outputMustBe("{\"key1\":\"value1\",\"key2\":\"value2\"}");
} }
TEST_F(JsonObject_Serialization_Tests, TwoStrings) TEST_F(JsonObject_Serialization_Tests, RemoveFirst) {
{ object["key1"] = "value1";
object["key1"] = "value1"; object["key2"] = "value2";
object["key2"] = "value2"; object.remove("key1");
outputMustBe("{\"key1\":\"value1\",\"key2\":\"value2\"}"); outputMustBe("{\"key2\":\"value2\"}");
} }
TEST_F(JsonObject_Serialization_Tests, RemoveFirst) TEST_F(JsonObject_Serialization_Tests, RemoveLast) {
{ object["key1"] = "value1";
object["key1"] = "value1"; object["key2"] = "value2";
object["key2"] = "value2"; object.remove("key2");
object.remove("key1");
outputMustBe("{\"key2\":\"value2\"}"); outputMustBe("{\"key1\":\"value1\"}");
} }
TEST_F(JsonObject_Serialization_Tests, RemoveLast) TEST_F(JsonObject_Serialization_Tests, RemoveUnexistingKey) {
{ object["key1"] = "value1";
object["key1"] = "value1"; object["key2"] = "value2";
object["key2"] = "value2"; object.remove("key3");
object.remove("key2");
outputMustBe("{\"key1\":\"value1\"}"); outputMustBe("{\"key1\":\"value1\",\"key2\":\"value2\"}");
} }
TEST_F(JsonObject_Serialization_Tests, RemoveUnexistingKey) TEST_F(JsonObject_Serialization_Tests, ReplaceExistingKey) {
{ object["key"] = "value1";
object["key1"] = "value1"; object["key"] = "value2";
object["key2"] = "value2";
object.remove("key3");
outputMustBe("{\"key1\":\"value1\",\"key2\":\"value2\"}"); outputMustBe("{\"key\":\"value2\"}");
} }
TEST_F(JsonObject_Serialization_Tests, ReplaceExistingKey) TEST_F(JsonObject_Serialization_Tests, OneStringOverCapacity) {
{ object["key1"] = "value1";
object["key"] = "value1"; object["key2"] = "value2";
object["key"] = "value2"; object["key3"] = "value3";
outputMustBe("{\"key\":\"value2\"}"); outputMustBe("{\"key1\":\"value1\",\"key2\":\"value2\"}");
} }
TEST_F(JsonObject_Serialization_Tests, OneStringOverCapacity) TEST_F(JsonObject_Serialization_Tests, OneInteger) {
{ object["key"] = 1;
object["key1"] = "value1"; outputMustBe("{\"key\":1}");
object["key2"] = "value2";
object["key3"] = "value3";
outputMustBe("{\"key1\":\"value1\",\"key2\":\"value2\"}");
} }
TEST_F(JsonObject_Serialization_Tests, OneInteger) TEST_F(JsonObject_Serialization_Tests, OneDoubleFourDigits) {
{ object["key"].set(3.14159265358979323846, 4);
object["key"] = 1; outputMustBe("{\"key\":3.1416}");
outputMustBe("{\"key\":1}");
} }
TEST_F(JsonObject_Serialization_Tests, OneDoubleFourDigits) TEST_F(JsonObject_Serialization_Tests, OneDoubleDefaultDigits) {
{ object["key"] = 3.14159265358979323846;
object["key"].set(3.14159265358979323846, 4); outputMustBe("{\"key\":3.14}");
outputMustBe("{\"key\":3.1416}");
} }
TEST_F(JsonObject_Serialization_Tests, OneDoubleDefaultDigits) TEST_F(JsonObject_Serialization_Tests, OneNull) {
{ object["key"] = (char *)0;
object["key"] = 3.14159265358979323846; outputMustBe("{\"key\":null}");
outputMustBe("{\"key\":3.14}");
} }
TEST_F(JsonObject_Serialization_Tests, OneNull) TEST_F(JsonObject_Serialization_Tests, OneTrue) {
{ object["key"] = true;
object["key"] = (char*) 0; outputMustBe("{\"key\":true}");
outputMustBe("{\"key\":null}");
} }
TEST_F(JsonObject_Serialization_Tests, OneTrue) TEST_F(JsonObject_Serialization_Tests, OneFalse) {
{ object["key"] = false;
object["key"] = true; outputMustBe("{\"key\":false}");
outputMustBe("{\"key\":true}");
} }
TEST_F(JsonObject_Serialization_Tests, OneFalse) TEST_F(JsonObject_Serialization_Tests, OneEmptyNestedArrayViaProxy) {
{ JsonArray nestedArray = json.createArray();
object["key"] = false;
outputMustBe("{\"key\":false}"); object["key"] = nestedArray;
outputMustBe("{\"key\":[]}");
} }
TEST_F(JsonObject_Serialization_Tests, OneEmptyNestedArrayViaProxy) TEST_F(JsonObject_Serialization_Tests, OneEmptyNestedObjectViaProxy) {
{ JsonObject nestedArray = json.createObject();
JsonArray nestedArray = json.createArray();
object["key"] = nestedArray; object["key"] = nestedArray;
outputMustBe("{\"key\":[]}"); outputMustBe("{\"key\":{}}");
} }
TEST_F(JsonObject_Serialization_Tests, OneEmptyNestedObjectViaProxy) TEST_F(JsonObject_Serialization_Tests, OneEmptyNestedObject) {
{ object.createNestedObject("key");
JsonObject nestedArray = json.createObject();
object["key"] = nestedArray; outputMustBe("{\"key\":{}}");
outputMustBe("{\"key\":{}}");
} }
TEST_F(JsonObject_Serialization_Tests, OneEmptyNestedObject) TEST_F(JsonObject_Serialization_Tests, OneEmptyNestedArray) {
{ object.createNestedArray("key");
object.createNestedObject("key");
outputMustBe("{\"key\":{}}"); outputMustBe("{\"key\":[]}");
}
TEST_F(JsonObject_Serialization_Tests, OneEmptyNestedArray)
{
object.createNestedArray("key");
outputMustBe("{\"key\":[]}");
} }

View File

@ -4,164 +4,136 @@
using namespace ArduinoJson; using namespace ArduinoJson;
class JsonParser_Array_Tests : public testing::Test class JsonParser_Array_Tests : public testing::Test {
{
protected: protected:
void whenInputIs(const char *json) void whenInputIs(const char *json) {
{ strcpy(_jsonString, json);
strcpy(_jsonString, json); _array = _jsonBuffer.parseArray(_jsonString);
_array = _jsonBuffer.parseArray(_jsonString); }
}
void parseMustSucceed() void parseMustSucceed() { EXPECT_TRUE(_array.success()); }
{
EXPECT_TRUE(_array.success());
}
void parseMustFail() void parseMustFail() {
{ EXPECT_FALSE(_array.success());
EXPECT_FALSE(_array.success()); EXPECT_EQ(0, _array.size());
EXPECT_EQ(0, _array.size()); }
}
void sizeMustBe(int expected) void sizeMustBe(int expected) { EXPECT_EQ(expected, _array.size()); }
{
EXPECT_EQ(expected, _array.size());
}
template<typename T> template <typename T> void firstElementMustBe(T expected) {
void firstElementMustBe(T expected) elementAtIndexMustBe(0, expected);
{ }
elementAtIndexMustBe(0, expected);
}
template<typename T> template <typename T> void secondElementMustBe(T expected) {
void secondElementMustBe(T expected) elementAtIndexMustBe(1, expected);
{ }
elementAtIndexMustBe(1, expected);
}
template<typename T> template <typename T> void elementAtIndexMustBe(int index, T expected) {
void elementAtIndexMustBe(int index, T expected) EXPECT_EQ(expected, _array[index].as<T>());
{ }
EXPECT_EQ(expected, _array[index].as<T>());
}
void elementAtIndexMustBe(int index, const char* expected) void elementAtIndexMustBe(int index, const char *expected) {
{ EXPECT_STREQ(expected, _array[index].as<const char *>());
EXPECT_STREQ(expected, _array[index].as<const char*>()); }
}
StaticJsonBuffer<42> _jsonBuffer; StaticJsonBuffer<42> _jsonBuffer;
JsonArray _array; JsonArray _array;
char _jsonString[256]; char _jsonString[256];
}; };
TEST_F(JsonParser_Array_Tests, EmptyArray) TEST_F(JsonParser_Array_Tests, EmptyArray) {
{ whenInputIs("[]");
whenInputIs("[]");
parseMustSucceed(); parseMustSucceed();
sizeMustBe(0); sizeMustBe(0);
} }
TEST_F(JsonParser_Array_Tests, ArrayWithNoEnd) TEST_F(JsonParser_Array_Tests, ArrayWithNoEnd) {
{ whenInputIs("[");
whenInputIs("[");
parseMustFail(); parseMustFail();
} }
TEST_F(JsonParser_Array_Tests, EmptyArrayWithLeadingSpaces) TEST_F(JsonParser_Array_Tests, EmptyArrayWithLeadingSpaces) {
{ whenInputIs(" []");
whenInputIs(" []");
parseMustSucceed(); parseMustSucceed();
sizeMustBe(0); sizeMustBe(0);
} }
TEST_F(JsonParser_Array_Tests, Garbage) TEST_F(JsonParser_Array_Tests, Garbage) {
{ whenInputIs("%*$£¤");
whenInputIs("%*$£¤");
parseMustFail(); parseMustFail();
} }
TEST_F(JsonParser_Array_Tests, OneInteger) TEST_F(JsonParser_Array_Tests, OneInteger) {
{ whenInputIs("[42]");
whenInputIs("[42]");
parseMustSucceed(); parseMustSucceed();
sizeMustBe(1); sizeMustBe(1);
firstElementMustBe(42); firstElementMustBe(42);
} }
TEST_F(JsonParser_Array_Tests, OneIntegerWithSpacesBefore) TEST_F(JsonParser_Array_Tests, OneIntegerWithSpacesBefore) {
{ whenInputIs("[ \t\r\n42]");
whenInputIs("[ \t\r\n42]");
parseMustSucceed(); parseMustSucceed();
sizeMustBe(1); sizeMustBe(1);
firstElementMustBe(42); firstElementMustBe(42);
} }
TEST_F(JsonParser_Array_Tests, OneIntegerWithSpaceAfter) TEST_F(JsonParser_Array_Tests, OneIntegerWithSpaceAfter) {
{ whenInputIs("[42 \t\r\n]");
whenInputIs("[42 \t\r\n]");
parseMustSucceed(); parseMustSucceed();
sizeMustBe(1); sizeMustBe(1);
firstElementMustBe(42); firstElementMustBe(42);
} }
TEST_F(JsonParser_Array_Tests, TwoIntegers) TEST_F(JsonParser_Array_Tests, TwoIntegers) {
{ whenInputIs("[42,84]");
whenInputIs("[42,84]");
parseMustSucceed(); parseMustSucceed();
sizeMustBe(2); sizeMustBe(2);
firstElementMustBe(42); firstElementMustBe(42);
secondElementMustBe(84); secondElementMustBe(84);
} }
TEST_F(JsonParser_Array_Tests, TwoDoubles) TEST_F(JsonParser_Array_Tests, TwoDoubles) {
{ whenInputIs("[4.2,8.4]");
whenInputIs("[4.2,8.4]");
parseMustSucceed(); parseMustSucceed();
sizeMustBe(2); sizeMustBe(2);
firstElementMustBe(4.2); firstElementMustBe(4.2);
secondElementMustBe(8.4); secondElementMustBe(8.4);
} }
TEST_F(JsonParser_Array_Tests, TwoBooleans) TEST_F(JsonParser_Array_Tests, TwoBooleans) {
{ whenInputIs("[true,false]");
whenInputIs("[true,false]");
parseMustSucceed(); parseMustSucceed();
sizeMustBe(2); sizeMustBe(2);
firstElementMustBe(true); firstElementMustBe(true);
secondElementMustBe(false); secondElementMustBe(false);
} }
TEST_F(JsonParser_Array_Tests, TwoNulls) TEST_F(JsonParser_Array_Tests, TwoNulls) {
{ const char *const nullCharPtr = 0;
const char* const nullCharPtr = 0;
whenInputIs("[null,null]"); whenInputIs("[null,null]");
parseMustSucceed(); parseMustSucceed();
sizeMustBe(2); sizeMustBe(2);
firstElementMustBe(nullCharPtr); firstElementMustBe(nullCharPtr);
secondElementMustBe(nullCharPtr); secondElementMustBe(nullCharPtr);
} }
TEST_F(JsonParser_Array_Tests, TwoStrings) TEST_F(JsonParser_Array_Tests, TwoStrings) {
{ whenInputIs("[\"hello\",\"world\"]");
whenInputIs("[\"hello\",\"world\"]");
parseMustSucceed(); parseMustSucceed();
sizeMustBe(2); sizeMustBe(2);
firstElementMustBe("hello"); firstElementMustBe("hello");
secondElementMustBe("world"); secondElementMustBe("world");
} }

View File

@ -3,49 +3,48 @@
using namespace ArduinoJson; using namespace ArduinoJson;
TEST(JsonParser_Nested_Tests, ArrayNestedInObject) TEST(JsonParser_Nested_Tests, ArrayNestedInObject) {
{ StaticJsonBuffer<42> jsonBuffer;
StaticJsonBuffer<42> jsonBuffer; char jsonString[] = " { \"ab\" : [ 1 , 2 ] , \"cd\" : [ 3 , 4 ] } ";
char jsonString[] = " { \"ab\" : [ 1 , 2 ] , \"cd\" : [ 3 , 4 ] } ";
JsonObject object = jsonBuffer.parseObject(jsonString);
JsonArray array1 = object["ab"];
JsonArray array2 = object["cd"];
ASSERT_TRUE(object.success());
ASSERT_TRUE(array1.success());
ASSERT_TRUE(array2.success());
ASSERT_EQ(2, array1.size()); JsonObject object = jsonBuffer.parseObject(jsonString);
ASSERT_EQ(2, array2.size()); JsonArray array1 = object["ab"];
JsonArray array2 = object["cd"];
EXPECT_EQ(1, array1[0].as<int>());
EXPECT_EQ(2, array1[1].as<int>());
EXPECT_EQ(3, array2[0].as<int>()); ASSERT_TRUE(object.success());
EXPECT_EQ(4, array2[1].as<int>());
ASSERT_TRUE(array1.success());
ASSERT_TRUE(array2.success());
ASSERT_EQ(2, array1.size());
ASSERT_EQ(2, array2.size());
EXPECT_EQ(1, array1[0].as<int>());
EXPECT_EQ(2, array1[1].as<int>());
EXPECT_EQ(3, array2[0].as<int>());
EXPECT_EQ(4, array2[1].as<int>());
} }
TEST(JsonParser_Nested_Tests, ObjectNestedInArray) TEST(JsonParser_Nested_Tests, ObjectNestedInArray) {
{ StaticJsonBuffer<42> jsonBuffer;
StaticJsonBuffer<42> jsonBuffer; char jsonString[] =
char jsonString[] = " [ { \"a\" : 1 , \"b\" : 2 } , { \"c\" : 3 , \"d\" : 4 } ] "; " [ { \"a\" : 1 , \"b\" : 2 } , { \"c\" : 3 , \"d\" : 4 } ] ";
JsonArray array = jsonBuffer.parseArray(jsonString); JsonArray array = jsonBuffer.parseArray(jsonString);
JsonObject object1 = array[0]; JsonObject object1 = array[0];
JsonObject object2 = array[1]; JsonObject object2 = array[1];
ASSERT_TRUE(array.success()); ASSERT_TRUE(array.success());
ASSERT_TRUE(object1.success()); ASSERT_TRUE(object1.success());
ASSERT_TRUE(object2.success()); ASSERT_TRUE(object2.success());
ASSERT_EQ(2, object1.size()); ASSERT_EQ(2, object1.size());
ASSERT_EQ(2, object2.size()); ASSERT_EQ(2, object2.size());
EXPECT_EQ(1, object1["a"].as<int>()); EXPECT_EQ(1, object1["a"].as<int>());
EXPECT_EQ(2, object1["b"].as<int>()); EXPECT_EQ(2, object1["b"].as<int>());
EXPECT_EQ(3, object2["c"].as<int>()); EXPECT_EQ(3, object2["c"].as<int>());
EXPECT_EQ(4, object2["d"].as<int>()); EXPECT_EQ(4, object2["d"].as<int>());
} }

View File

@ -4,198 +4,164 @@
using namespace ArduinoJson; using namespace ArduinoJson;
class JsonParser_Object_Test : public testing::Test class JsonParser_Object_Test : public testing::Test {
{
protected: protected:
void whenInputIs(const char *jsonString) {
strcpy(_jsonString, jsonString);
_object = _jsonBuffer.parseObject(_jsonString);
}
void whenInputIs(const char* jsonString) void parseMustSucceed() { EXPECT_TRUE(_object.success()); }
{
strcpy(_jsonString, jsonString);
_object = _jsonBuffer.parseObject(_jsonString);
}
void parseMustSucceed() void parseMustFail() { EXPECT_FALSE(_object.success()); }
{
EXPECT_TRUE(_object.success());
}
void parseMustFail() void sizeMustBe(int expected) { EXPECT_EQ(expected, _object.size()); }
{
EXPECT_FALSE(_object.success());
}
void sizeMustBe(int expected) void keyMustHaveValue(const char *key, const char *expected) {
{ EXPECT_STREQ(expected, _object[key].as<const char *>());
EXPECT_EQ(expected, _object.size()); }
}
void keyMustHaveValue(const char* key, const char* expected) template <typename T> void keyMustHaveValue(const char *key, T expected) {
{ EXPECT_EQ(expected, _object[key].as<T>());
EXPECT_STREQ(expected, _object[key].as<const char*>()); }
}
template<typename T>
void keyMustHaveValue(const char* key, T expected)
{
EXPECT_EQ(expected, _object[key].as<T>());
}
private: private:
StaticJsonBuffer<10> _jsonBuffer; StaticJsonBuffer<10> _jsonBuffer;
JsonObject _object; JsonObject _object;
char _jsonString[256]; char _jsonString[256];
}; };
TEST_F(JsonParser_Object_Test, EmptyObject) TEST_F(JsonParser_Object_Test, EmptyObject) {
{ whenInputIs("{}");
whenInputIs("{}"); parseMustSucceed();
parseMustSucceed(); sizeMustBe(0);
sizeMustBe(0);
} }
TEST_F(JsonParser_Object_Test, MissingClosingBrace) TEST_F(JsonParser_Object_Test, MissingClosingBrace) {
{ whenInputIs("{");
whenInputIs("{"); parseMustFail();
parseMustFail(); sizeMustBe(0);
sizeMustBe(0);
} }
TEST_F(JsonParser_Object_Test, MissingColonAndValue) TEST_F(JsonParser_Object_Test, MissingColonAndValue) {
{ whenInputIs("{\"key\"}");
whenInputIs("{\"key\"}"); parseMustFail();
parseMustFail(); sizeMustBe(0);
sizeMustBe(0);
} }
TEST_F(JsonParser_Object_Test, MissingQuotesAndColonAndValue) TEST_F(JsonParser_Object_Test, MissingQuotesAndColonAndValue) {
{ whenInputIs("{key}");
whenInputIs("{key}"); parseMustFail();
parseMustFail(); sizeMustBe(0);
sizeMustBe(0);
} }
TEST_F(JsonParser_Object_Test, OneString) TEST_F(JsonParser_Object_Test, OneString) {
{ whenInputIs("{\"key\":\"value\"}");
whenInputIs("{\"key\":\"value\"}"); parseMustSucceed();
parseMustSucceed(); sizeMustBe(1);
sizeMustBe(1); keyMustHaveValue("key", "value");
keyMustHaveValue("key", "value");
} }
TEST_F(JsonParser_Object_Test, OneStringSingleQuotes) TEST_F(JsonParser_Object_Test, OneStringSingleQuotes) {
{ whenInputIs("{'key':'value'}");
whenInputIs("{'key':'value'}"); parseMustSucceed();
parseMustSucceed(); sizeMustBe(1);
sizeMustBe(1); keyMustHaveValue("key", "value");
keyMustHaveValue("key", "value");
} }
TEST_F(JsonParser_Object_Test, OneStringSpaceBeforeKey) TEST_F(JsonParser_Object_Test, OneStringSpaceBeforeKey) {
{ whenInputIs("{ \"key\":\"value\"}");
whenInputIs("{ \"key\":\"value\"}"); parseMustSucceed();
parseMustSucceed(); sizeMustBe(1);
sizeMustBe(1); keyMustHaveValue("key", "value");
keyMustHaveValue("key", "value");
} }
TEST_F(JsonParser_Object_Test, OneStringSpaceAfterKey) TEST_F(JsonParser_Object_Test, OneStringSpaceAfterKey) {
{ whenInputIs("{\"key\" :\"value\"}");
whenInputIs("{\"key\" :\"value\"}"); parseMustSucceed();
parseMustSucceed(); sizeMustBe(1);
sizeMustBe(1); keyMustHaveValue("key", "value");
keyMustHaveValue("key", "value");
} }
TEST_F(JsonParser_Object_Test, OneStringSpaceBeforeValue) TEST_F(JsonParser_Object_Test, OneStringSpaceBeforeValue) {
{ whenInputIs("{\"key\": \"value\"}");
whenInputIs("{\"key\": \"value\"}"); parseMustSucceed();
parseMustSucceed(); sizeMustBe(1);
sizeMustBe(1); keyMustHaveValue("key", "value");
keyMustHaveValue("key", "value");
} }
TEST_F(JsonParser_Object_Test, OneStringSpaceAfterValue) TEST_F(JsonParser_Object_Test, OneStringSpaceAfterValue) {
{ whenInputIs("{\"key\":\"value\" }");
whenInputIs("{\"key\":\"value\" }"); parseMustSucceed();
parseMustSucceed(); sizeMustBe(1);
sizeMustBe(1); keyMustHaveValue("key", "value");
keyMustHaveValue("key", "value");
} }
TEST_F(JsonParser_Object_Test, TwoStrings) TEST_F(JsonParser_Object_Test, TwoStrings) {
{ whenInputIs("{\"key1\":\"value1\",\"key2\":\"value2\"}");
whenInputIs("{\"key1\":\"value1\",\"key2\":\"value2\"}"); parseMustSucceed();
parseMustSucceed(); sizeMustBe(2);
sizeMustBe(2); keyMustHaveValue("key1", "value1");
keyMustHaveValue("key1", "value1"); keyMustHaveValue("key2", "value2");
keyMustHaveValue("key2", "value2");
} }
TEST_F(JsonParser_Object_Test, TwoStringsSpaceBeforeComma) TEST_F(JsonParser_Object_Test, TwoStringsSpaceBeforeComma) {
{ whenInputIs("{\"key1\":\"value1\" ,\"key2\":\"value2\"}");
whenInputIs("{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); parseMustSucceed();
parseMustSucceed(); sizeMustBe(2);
sizeMustBe(2); keyMustHaveValue("key1", "value1");
keyMustHaveValue("key1", "value1"); keyMustHaveValue("key2", "value2");
keyMustHaveValue("key2", "value2");
} }
TEST_F(JsonParser_Object_Test, TwoStringsSpaceAfterComma) TEST_F(JsonParser_Object_Test, TwoStringsSpaceAfterComma) {
{ whenInputIs("{\"key1\":\"value1\" ,\"key2\":\"value2\"}");
whenInputIs("{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); parseMustSucceed();
parseMustSucceed(); sizeMustBe(2);
sizeMustBe(2); keyMustHaveValue("key1", "value1");
keyMustHaveValue("key1", "value1"); keyMustHaveValue("key2", "value2");
keyMustHaveValue("key2", "value2");
} }
TEST_F(JsonParser_Object_Test, EndingWithAComma) TEST_F(JsonParser_Object_Test, EndingWithAComma) {
{ whenInputIs("{\"key1\":\"value1\",}");
whenInputIs("{\"key1\":\"value1\",}"); parseMustFail();
parseMustFail(); sizeMustBe(0);
sizeMustBe(0);
} }
TEST_F(JsonParser_Object_Test, TwoIntergers) TEST_F(JsonParser_Object_Test, TwoIntergers) {
{ whenInputIs("{\"key1\":42,\"key2\":-42}");
whenInputIs("{\"key1\":42,\"key2\":-42}"); parseMustSucceed();
parseMustSucceed(); sizeMustBe(2);
sizeMustBe(2); keyMustHaveValue("key1", 42);
keyMustHaveValue("key1", 42); keyMustHaveValue("key2", -42);
keyMustHaveValue("key2", -42);
} }
TEST_F(JsonParser_Object_Test, TwoDoubles) TEST_F(JsonParser_Object_Test, TwoDoubles) {
{ whenInputIs("{\"key1\":12.345,\"key2\":-7.89}");
whenInputIs("{\"key1\":12.345,\"key2\":-7.89}"); parseMustSucceed();
parseMustSucceed(); sizeMustBe(2);
sizeMustBe(2); keyMustHaveValue("key1", 12.345);
keyMustHaveValue("key1", 12.345); keyMustHaveValue("key2", -7.89);
keyMustHaveValue("key2", -7.89);
} }
TEST_F(JsonParser_Object_Test, TwoBooleans) TEST_F(JsonParser_Object_Test, TwoBooleans) {
{ whenInputIs("{\"key1\":true,\"key2\":false}");
whenInputIs("{\"key1\":true,\"key2\":false}"); parseMustSucceed();
parseMustSucceed(); sizeMustBe(2);
sizeMustBe(2); keyMustHaveValue("key1", true);
keyMustHaveValue("key1", true); keyMustHaveValue("key2", false);
keyMustHaveValue("key2", false);
} }
TEST_F(JsonParser_Object_Test, TwoNulls) TEST_F(JsonParser_Object_Test, TwoNulls) {
{ const char *const nullstr = 0;
const char* const nullstr = 0;
whenInputIs("{\"key1\":null,\"key2\":null}"); whenInputIs("{\"key1\":null,\"key2\":null}");
parseMustSucceed(); parseMustSucceed();
sizeMustBe(2); sizeMustBe(2);
keyMustHaveValue("key1", nullstr); keyMustHaveValue("key1", nullstr);
keyMustHaveValue("key2", nullstr); keyMustHaveValue("key2", nullstr);
} }
TEST_F(JsonParser_Object_Test, NullForKey) TEST_F(JsonParser_Object_Test, NullForKey) {
{ whenInputIs("null:\"value\"}");
whenInputIs("null:\"value\"}"); parseMustFail();
parseMustFail();
} }

View File

@ -4,118 +4,102 @@
using namespace ArduinoJson; using namespace ArduinoJson;
class JsonValueTests : public ::testing::Test class JsonValueTests : public ::testing::Test {
{
protected: protected:
virtual void SetUp() virtual void SetUp() {
{ jsonValue1 = json.createValue();
jsonValue1 = json.createValue(); jsonValue2 = json.createValue();
jsonValue2 = json.createValue(); }
}
StaticJsonBuffer<42> json; StaticJsonBuffer<42> json;
JsonValue jsonValue1; JsonValue jsonValue1;
JsonValue jsonValue2; JsonValue jsonValue2;
}; };
TEST_F(JsonValueTests, CanStoreInteger) {
jsonValue1 = 123;
TEST_F(JsonValueTests, CanStoreInteger) EXPECT_EQ(123, (int)jsonValue1);
{
jsonValue1 = 123;
EXPECT_EQ(123, (int) jsonValue1);
} }
TEST_F(JsonValueTests, CanStoreDouble) TEST_F(JsonValueTests, CanStoreDouble) {
{ jsonValue1 = 123.45;
jsonValue1 = 123.45;
EXPECT_EQ(123.45, (double) jsonValue1); EXPECT_EQ(123.45, (double)jsonValue1);
} }
TEST_F(JsonValueTests, CanStoreTrue) TEST_F(JsonValueTests, CanStoreTrue) {
{ jsonValue1 = true;
jsonValue1 = true; EXPECT_TRUE((bool)jsonValue1);
EXPECT_TRUE((bool) jsonValue1);
} }
TEST_F(JsonValueTests, CanStoreFalse) TEST_F(JsonValueTests, CanStoreFalse) {
{ jsonValue1 = false;
jsonValue1 = false; EXPECT_FALSE((bool)jsonValue1);
EXPECT_FALSE((bool) jsonValue1);
} }
TEST_F(JsonValueTests, CanStoreString) TEST_F(JsonValueTests, CanStoreString) {
{ jsonValue1 = "hello";
jsonValue1 = "hello";
EXPECT_STREQ("hello", (const char *)jsonValue1);
EXPECT_STREQ("hello", (const char*) jsonValue1);
} }
TEST_F(JsonValueTests, CanStoreObject) TEST_F(JsonValueTests, CanStoreObject) {
{ JsonObject innerObject1 = json.createObject();
JsonObject innerObject1 = json.createObject();
jsonValue1 = innerObject1; jsonValue1 = innerObject1;
EXPECT_EQ(innerObject1, (JsonObject) jsonValue1); EXPECT_EQ(innerObject1, (JsonObject)jsonValue1);
} }
TEST_F(JsonValueTests, IntegersAreCopiedByValue) TEST_F(JsonValueTests, IntegersAreCopiedByValue) {
{ jsonValue1 = 123;
jsonValue1 = 123; jsonValue2 = jsonValue1;
jsonValue2 = jsonValue1; jsonValue1 = 456;
jsonValue1 = 456;
EXPECT_EQ(123, (int) jsonValue2); EXPECT_EQ(123, (int)jsonValue2);
} }
TEST_F(JsonValueTests, DoublesAreCopiedByValue) TEST_F(JsonValueTests, DoublesAreCopiedByValue) {
{ jsonValue1 = 123.45;
jsonValue1 = 123.45; jsonValue2 = jsonValue1;
jsonValue2 = jsonValue1; jsonValue1 = 456.78;
jsonValue1 = 456.78;
EXPECT_EQ(123.45, (double) jsonValue2); EXPECT_EQ(123.45, (double)jsonValue2);
} }
TEST_F(JsonValueTests, BooleansAreCopiedByValue) TEST_F(JsonValueTests, BooleansAreCopiedByValue) {
{ jsonValue1 = true;
jsonValue1 = true; jsonValue2 = jsonValue1;
jsonValue2 = jsonValue1; jsonValue1 = false;
jsonValue1 = false;
EXPECT_TRUE((bool) jsonValue2); EXPECT_TRUE((bool)jsonValue2);
} }
TEST_F(JsonValueTests, StringsAreCopiedByValue) TEST_F(JsonValueTests, StringsAreCopiedByValue) {
{ jsonValue1 = "hello";
jsonValue1 = "hello"; jsonValue2 = jsonValue1;
jsonValue2 = jsonValue1; jsonValue1 = "world";
jsonValue1 = "world";
EXPECT_STREQ("hello", (const char*) jsonValue2); EXPECT_STREQ("hello", (const char *)jsonValue2);
} }
TEST_F(JsonValueTests, ObjectsAreCopiedByReference) {
JsonObject object = json.createObject();
TEST_F(JsonValueTests, ObjectsAreCopiedByReference) jsonValue1 = object;
{
JsonObject object = json.createObject();
jsonValue1 = object; object["hello"] = "world";
object["hello"] = "world"; EXPECT_EQ(1, ((JsonObject)jsonValue1).size());
EXPECT_EQ(1, ((JsonObject) jsonValue1).size());
} }
TEST_F(JsonValueTests, ArraysAreCopiedByReference) TEST_F(JsonValueTests, ArraysAreCopiedByReference) {
{ JsonArray array = json.createArray();
JsonArray array = json.createArray();
jsonValue1 = array; jsonValue1 = array;
array.add("world");
EXPECT_EQ(1, ((JsonObject) jsonValue1).size()); array.add("world");
EXPECT_EQ(1, ((JsonObject)jsonValue1).size());
} }

View File

@ -3,147 +3,122 @@
using namespace ArduinoJson::Internals; using namespace ArduinoJson::Internals;
class QuotedString_ExtractFrom_Tests : public testing::Test class QuotedString_ExtractFrom_Tests : public testing::Test {
{
protected: protected:
void whenInputIs(const char* json) void whenInputIs(const char *json) {
{ strcpy(_jsonString, json);
strcpy(_jsonString, json); _result = QuotedString::extractFrom(_jsonString, &_trailing);
_result = QuotedString::extractFrom(_jsonString, &_trailing); }
}
void resultMustBe(const char* expected) void resultMustBe(const char *expected) { EXPECT_STREQ(expected, _result); }
{
EXPECT_STREQ(expected, _result);
}
void trailingMustBe(const char* expected) void trailingMustBe(const char *expected) {
{ EXPECT_STREQ(expected, _trailing);
EXPECT_STREQ(expected, _trailing); }
}
private: private:
char _jsonString[256]; char _jsonString[256];
char* _result; char *_result;
char* _trailing; char *_trailing;
}; };
TEST_F(QuotedString_ExtractFrom_Tests, EmptyDoubleQuotedString) {
whenInputIs("\"\"");
TEST_F(QuotedString_ExtractFrom_Tests, EmptyDoubleQuotedString) resultMustBe("");
{ trailingMustBe("");
whenInputIs("\"\"");
resultMustBe("");
trailingMustBe("");
} }
TEST_F(QuotedString_ExtractFrom_Tests, NoQuotes) TEST_F(QuotedString_ExtractFrom_Tests, NoQuotes) {
{ whenInputIs("hello world");
whenInputIs("hello world");
resultMustBe(0); resultMustBe(0);
} }
TEST_F(QuotedString_ExtractFrom_Tests, EmptySingleQuotedString) TEST_F(QuotedString_ExtractFrom_Tests, EmptySingleQuotedString) {
{ whenInputIs("''");
whenInputIs("''");
resultMustBe(""); resultMustBe("");
trailingMustBe(""); trailingMustBe("");
} }
TEST_F(QuotedString_ExtractFrom_Tests, SimpleDoubleQuotedString) TEST_F(QuotedString_ExtractFrom_Tests, SimpleDoubleQuotedString) {
{ whenInputIs("\"hello world\"");
whenInputIs("\"hello world\"");
resultMustBe("hello world"); resultMustBe("hello world");
trailingMustBe(""); trailingMustBe("");
} }
TEST_F(QuotedString_ExtractFrom_Tests, DoubleQuotedStringWithTrailing) TEST_F(QuotedString_ExtractFrom_Tests, DoubleQuotedStringWithTrailing) {
{ whenInputIs("\"hello\" world");
whenInputIs("\"hello\" world");
resultMustBe("hello"); resultMustBe("hello");
trailingMustBe(" world"); trailingMustBe(" world");
} }
TEST_F(QuotedString_ExtractFrom_Tests, SingleQuotedStringWithTrailing) TEST_F(QuotedString_ExtractFrom_Tests, SingleQuotedStringWithTrailing) {
{ whenInputIs("'hello' world");
whenInputIs("'hello' world");
resultMustBe("hello"); resultMustBe("hello");
trailingMustBe(" world"); trailingMustBe(" world");
} }
TEST_F(QuotedString_ExtractFrom_Tests, CurlyBraces) TEST_F(QuotedString_ExtractFrom_Tests, CurlyBraces) {
{ whenInputIs("\"{hello:world}\"");
whenInputIs("\"{hello:world}\""); resultMustBe("{hello:world}");
resultMustBe("{hello:world}");
} }
TEST_F(QuotedString_ExtractFrom_Tests, SquareBraquets) TEST_F(QuotedString_ExtractFrom_Tests, SquareBraquets) {
{ whenInputIs("\"[hello,world]\"");
whenInputIs("\"[hello,world]\""); resultMustBe("[hello,world]");
resultMustBe("[hello,world]");
} }
TEST_F(QuotedString_ExtractFrom_Tests, EscapedDoubleQuote) TEST_F(QuotedString_ExtractFrom_Tests, EscapedDoubleQuote) {
{ whenInputIs("\"hello \\\"world\\\"\"");
whenInputIs("\"hello \\\"world\\\"\""); resultMustBe("hello \"world\"");
resultMustBe("hello \"world\"");
} }
TEST_F(QuotedString_ExtractFrom_Tests, EscapedSingleQuote) TEST_F(QuotedString_ExtractFrom_Tests, EscapedSingleQuote) {
{ whenInputIs("\"hello \\\'world\\\'\"");
whenInputIs("\"hello \\\'world\\\'\""); resultMustBe("hello 'world'");
resultMustBe("hello 'world'");
} }
TEST_F(QuotedString_ExtractFrom_Tests, EscapedSolidus) TEST_F(QuotedString_ExtractFrom_Tests, EscapedSolidus) {
{ whenInputIs("\"hello \\/world\\/\"");
whenInputIs("\"hello \\/world\\/\""); resultMustBe("hello /world/");
resultMustBe("hello /world/");
} }
TEST_F(QuotedString_ExtractFrom_Tests, EscapedReverseSolidus) TEST_F(QuotedString_ExtractFrom_Tests, EscapedReverseSolidus) {
{ whenInputIs("\"hello \\\\world\\\\\"");
whenInputIs("\"hello \\\\world\\\\\""); resultMustBe("hello \\world\\");
resultMustBe("hello \\world\\");
} }
TEST_F(QuotedString_ExtractFrom_Tests, EscapedBackspace) TEST_F(QuotedString_ExtractFrom_Tests, EscapedBackspace) {
{ whenInputIs("\"hello \\bworld\\b\"");
whenInputIs("\"hello \\bworld\\b\""); resultMustBe("hello \bworld\b");
resultMustBe("hello \bworld\b");
} }
TEST_F(QuotedString_ExtractFrom_Tests, EscapedFormfeed) TEST_F(QuotedString_ExtractFrom_Tests, EscapedFormfeed) {
{ whenInputIs("\"hello \\fworld\\f\"");
whenInputIs("\"hello \\fworld\\f\""); resultMustBe("hello \fworld\f");
resultMustBe("hello \fworld\f");
} }
TEST_F(QuotedString_ExtractFrom_Tests, EscapedNewline) TEST_F(QuotedString_ExtractFrom_Tests, EscapedNewline) {
{ whenInputIs("\"hello \\nworld\\n\"");
whenInputIs("\"hello \\nworld\\n\""); resultMustBe("hello \nworld\n");
resultMustBe("hello \nworld\n");
} }
TEST_F(QuotedString_ExtractFrom_Tests, EscapedCarriageReturn) TEST_F(QuotedString_ExtractFrom_Tests, EscapedCarriageReturn) {
{ whenInputIs("\"hello \\rworld\\r\"");
whenInputIs("\"hello \\rworld\\r\""); resultMustBe("hello \rworld\r");
resultMustBe("hello \rworld\r");
} }
TEST_F(QuotedString_ExtractFrom_Tests, EscapedTab) TEST_F(QuotedString_ExtractFrom_Tests, EscapedTab) {
{ whenInputIs("\"hello \\tworld\\t\"");
whenInputIs("\"hello \\tworld\\t\""); resultMustBe("hello \tworld\t");
resultMustBe("hello \tworld\t");
} }
TEST_F(QuotedString_ExtractFrom_Tests, AllEscapedCharsTogether) TEST_F(QuotedString_ExtractFrom_Tests, AllEscapedCharsTogether) {
{ whenInputIs("\"1\\\"2\\\\3\\/4\\b5\\f6\\n7\\r8\\t9\"");
whenInputIs("\"1\\\"2\\\\3\\/4\\b5\\f6\\n7\\r8\\t9\""); resultMustBe("1\"2\\3/4\b5\f6\n7\r8\t9");
resultMustBe("1\"2\\3/4\b5\f6\n7\r8\t9");
} }

View File

@ -5,82 +5,69 @@
using namespace ArduinoJson::Internals; using namespace ArduinoJson::Internals;
class QuotedString_PrintTo_Tests : public testing::Test class QuotedString_PrintTo_Tests : public testing::Test {
{
protected: protected:
void whenInputIs(const char* input) void whenInputIs(const char *input) {
{ StringBuilder sb(buffer, sizeof(buffer));
StringBuilder sb(buffer, sizeof(buffer)); returnValue = QuotedString::printTo(input, &sb);
returnValue = QuotedString::printTo(input, &sb); }
}
void outputMustBe(const char* expected) void outputMustBe(const char *expected) {
{ EXPECT_STREQ(expected, buffer);
EXPECT_STREQ(expected, buffer); EXPECT_EQ(strlen(expected), returnValue);
EXPECT_EQ(strlen(expected), returnValue); }
}
private: private:
char buffer[1024]; char buffer[1024];
size_t returnValue; size_t returnValue;
}; };
TEST_F(QuotedString_PrintTo_Tests, Null) TEST_F(QuotedString_PrintTo_Tests, Null) {
{ whenInputIs(0);
whenInputIs(0); outputMustBe("null");
outputMustBe("null");
} }
TEST_F(QuotedString_PrintTo_Tests, EmptyString) TEST_F(QuotedString_PrintTo_Tests, EmptyString) {
{ whenInputIs("");
whenInputIs(""); outputMustBe("\"\"");
outputMustBe("\"\"");
} }
TEST_F(QuotedString_PrintTo_Tests, QuotationMark) TEST_F(QuotedString_PrintTo_Tests, QuotationMark) {
{ whenInputIs("\"");
whenInputIs("\""); outputMustBe("\"\\\"\"");
outputMustBe("\"\\\"\"");
} }
TEST_F(QuotedString_PrintTo_Tests, ReverseSolidus) TEST_F(QuotedString_PrintTo_Tests, ReverseSolidus) {
{ whenInputIs("\\");
whenInputIs("\\"); outputMustBe("\"\\\\\"");
outputMustBe("\"\\\\\"");
} }
TEST_F(QuotedString_PrintTo_Tests, Solidus) TEST_F(QuotedString_PrintTo_Tests, Solidus) {
{ whenInputIs("/");
whenInputIs("/"); outputMustBe("\"/\""); // but the JSON format allows \/
outputMustBe("\"/\""); // but the JSON format allows \/
} }
TEST_F(QuotedString_PrintTo_Tests, Backspace) TEST_F(QuotedString_PrintTo_Tests, Backspace) {
{ whenInputIs("\b");
whenInputIs("\b"); outputMustBe("\"\\b\"");
outputMustBe("\"\\b\"");
} }
TEST_F(QuotedString_PrintTo_Tests, Formfeed) TEST_F(QuotedString_PrintTo_Tests, Formfeed) {
{ whenInputIs("\f");
whenInputIs("\f"); outputMustBe("\"\\f\"");
outputMustBe("\"\\f\"");
} }
TEST_F(QuotedString_PrintTo_Tests, Newline) TEST_F(QuotedString_PrintTo_Tests, Newline) {
{ whenInputIs("\n");
whenInputIs("\n"); outputMustBe("\"\\n\"");
outputMustBe("\"\\n\"");
} }
TEST_F(QuotedString_PrintTo_Tests, CarriageReturn) TEST_F(QuotedString_PrintTo_Tests, CarriageReturn) {
{ whenInputIs("\r");
whenInputIs("\r"); outputMustBe("\"\\r\"");
outputMustBe("\"\\r\"");
} }
TEST_F(QuotedString_PrintTo_Tests, HorizontalTab) TEST_F(QuotedString_PrintTo_Tests, HorizontalTab) {
{ whenInputIs("\t");
whenInputIs("\t"); outputMustBe("\"\\t\"");
outputMustBe("\"\\t\"");
} }

View File

@ -4,68 +4,66 @@
using namespace ArduinoJson; using namespace ArduinoJson;
TEST(StaticJsonBuffer, CapacityMatchTemplateParameter) TEST(StaticJsonBuffer, CapacityMatchTemplateParameter) {
{ StaticJsonBuffer<42> json;
StaticJsonBuffer<42> json; EXPECT_EQ(42, json.capacity());
EXPECT_EQ(42, json.capacity());
} }
TEST(StaticJsonBuffer, InitialSizeIsZero) TEST(StaticJsonBuffer, InitialSizeIsZero) {
{ StaticJsonBuffer<42> json;
StaticJsonBuffer<42> json; EXPECT_EQ(0, json.size());
EXPECT_EQ(0, json.size());
} }
TEST(StaticJsonBuffer, WhenCreateObjectIsCalled_ThenSizeIsIncreasedByOne) TEST(StaticJsonBuffer, WhenCreateObjectIsCalled_ThenSizeIsIncreasedByOne) {
{ StaticJsonBuffer<42> json;
StaticJsonBuffer<42> json;
json.createObject(); json.createObject();
EXPECT_EQ(1, json.size()); EXPECT_EQ(1, json.size());
json.createObject(); json.createObject();
EXPECT_EQ(2, json.size()); EXPECT_EQ(2, json.size());
} }
TEST(StaticJsonBuffer, GivenBufferIsFull_WhenCreateObjectIsCalled_ThenSizeDoesNotChange) TEST(StaticJsonBuffer,
{ GivenBufferIsFull_WhenCreateObjectIsCalled_ThenSizeDoesNotChange) {
StaticJsonBuffer<1> json; StaticJsonBuffer<1> json;
json.createObject(); json.createObject();
EXPECT_EQ(1, json.size()); EXPECT_EQ(1, json.size());
json.createObject(); json.createObject();
EXPECT_EQ(1, json.size()); EXPECT_EQ(1, json.size());
} }
TEST(StaticJsonBuffer, WhenCreateObjectIsCalled_ThenAnEmptyJsonObjectIsReturned) TEST(StaticJsonBuffer,
{ WhenCreateObjectIsCalled_ThenAnEmptyJsonObjectIsReturned) {
StaticJsonBuffer<42> json; StaticJsonBuffer<42> json;
JsonObject obj = json.createObject(); JsonObject obj = json.createObject();
EXPECT_EQ(0, obj.size()); EXPECT_EQ(0, obj.size());
} }
TEST(StaticJsonBuffer, GivenAJsonObject_WhenValuesAreAdded_ThenSizeIsIncreasedByTwo) TEST(StaticJsonBuffer,
{ GivenAJsonObject_WhenValuesAreAdded_ThenSizeIsIncreasedByTwo) {
StaticJsonBuffer<42> json; StaticJsonBuffer<42> json;
JsonObject obj = json.createObject(); JsonObject obj = json.createObject();
obj["hello"]; obj["hello"];
EXPECT_EQ(3, json.size()); EXPECT_EQ(3, json.size());
obj["world"]; obj["world"];
EXPECT_EQ(5, json.size()); EXPECT_EQ(5, json.size());
} }
TEST(StaticJsonBuffer, GivenAJsonObject_WhenSameValuesAreAddedTwice_ThenSizeIsOnlyIncreasedByTwo) TEST(
{ StaticJsonBuffer,
StaticJsonBuffer<42> json; GivenAJsonObject_WhenSameValuesAreAddedTwice_ThenSizeIsOnlyIncreasedByTwo) {
JsonObject obj = json.createObject(); StaticJsonBuffer<42> json;
JsonObject obj = json.createObject();
obj["hello"]; obj["hello"];
EXPECT_EQ(3, json.size()); EXPECT_EQ(3, json.size());
obj["hello"]; obj["hello"];
EXPECT_EQ(3, json.size()); EXPECT_EQ(3, json.size());
} }

View File

@ -3,73 +3,52 @@
using namespace ArduinoJson::Internals; using namespace ArduinoJson::Internals;
class StringBuilderTests : public testing::Test class StringBuilderTests : public testing::Test {
{
protected: protected:
virtual void SetUp() { sb = new StringBuilder(buffer, sizeof(buffer)); }
virtual void SetUp()
{
sb = new StringBuilder(buffer, sizeof(buffer));
}
void print(const char* value) void print(const char *value) { returnValue = sb->print(value); }
{
returnValue = sb->print(value);
}
void outputMustBe(const char* expected) void outputMustBe(const char *expected) { EXPECT_STREQ(expected, buffer); }
{
EXPECT_STREQ(expected, buffer);
}
void resultMustBe(size_t expected) void resultMustBe(size_t expected) { EXPECT_EQ(expected, returnValue); }
{
EXPECT_EQ(expected, returnValue);
}
private: private:
char buffer[20]; char buffer[20];
Print* sb; Print *sb;
size_t returnValue; size_t returnValue;
}; };
TEST_F(StringBuilderTests, InitialState) TEST_F(StringBuilderTests, InitialState) { outputMustBe(""); }
{
outputMustBe(""); TEST_F(StringBuilderTests, OverCapacity) {
print("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
resultMustBe(19);
print("ABC");
resultMustBe(0);
outputMustBe("ABCDEFGHIJKLMNOPQRS");
} }
TEST_F(StringBuilderTests, OverCapacity) TEST_F(StringBuilderTests, EmptyString) {
{ print("");
print("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); resultMustBe(0);
resultMustBe(19); outputMustBe("");
print("ABC");
resultMustBe(0);
outputMustBe("ABCDEFGHIJKLMNOPQRS");
} }
TEST_F(StringBuilderTests, EmptyString) TEST_F(StringBuilderTests, OneString) {
{ print("ABCD");
print(""); resultMustBe(4);
resultMustBe(0); outputMustBe("ABCD");
outputMustBe("");
} }
TEST_F(StringBuilderTests, OneString) TEST_F(StringBuilderTests, TwoStrings) {
{ print("ABCD");
print("ABCD"); resultMustBe(4);
resultMustBe(4);
outputMustBe("ABCD");
}
TEST_F(StringBuilderTests, TwoStrings) print("EFGH");
{ resultMustBe(4);
print("ABCD");
resultMustBe(4);
print("EFGH"); outputMustBe("ABCDEFGH");
resultMustBe(4);
outputMustBe("ABCDEFGH");
} }