All tests passed!

This commit is contained in:
Benoit Blanchon
2014-10-30 21:51:59 +01:00
parent 45a8ed6531
commit 889f059758
17 changed files with 91 additions and 69 deletions

View File

@ -18,9 +18,6 @@ class JsonObjectNode {
JsonPair pair; JsonPair pair;
JsonObjectNode* next; JsonObjectNode* next;
// warning C4512: assignment operator could not be generated
#pragma warning( suppress : 4512 )
}; };
} }
} }

View File

@ -0,0 +1,25 @@
// Copyright Benoit Blanchon 2014
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
#pragma once
namespace ArduinoJson {
namespace Internals {
// A class that is not meant to be copied
class NonCopyable {
protected:
NonCopyable() {}
private:
// copy constructor is private
NonCopyable(const NonCopyable&);
// copy operator is private
NonCopyable& operator=(const NonCopyable&);
};
}
}

View File

@ -11,10 +11,14 @@
#include "JsonArrayConstIterator.hpp" #include "JsonArrayConstIterator.hpp"
#include "JsonPrintable.hpp" #include "JsonPrintable.hpp"
#include "JsonObject.hpp" #include "JsonObject.hpp"
#include "Internals/NonCopyable.hpp"
#define JSON_ARRAY_SIZE(NUMBER_OF_ELEMENTS) \
(sizeof(JsonArray) + (NUMBER_OF_ELEMENTS) * sizeof(Internals::JsonArrayNode))
namespace ArduinoJson { namespace ArduinoJson {
class JsonArray : public JsonPrintable { class JsonArray : public JsonPrintable, Internals::NonCopyable {
friend class JsonBuffer; friend class JsonBuffer;
public: public:
@ -56,10 +60,6 @@ class JsonArray : public JsonPrintable {
// constructor is private: instance must be created via a JsonBuffer // constructor is private: instance must be created via a JsonBuffer
JsonArray(JsonBuffer *buffer) : _buffer(buffer), _firstNode(NULL) {} JsonArray(JsonBuffer *buffer) : _buffer(buffer), _firstNode(NULL) {}
// copy is forbidden, use a reference instead
JsonArray(const JsonArray &);
JsonArray &operator=(const JsonArray &);
Internals::JsonArrayNode *createNode(); Internals::JsonArrayNode *createNode();
inline void addNode(Internals::JsonArrayNode *node); inline void addNode(Internals::JsonArrayNode *node);

View File

@ -6,15 +6,20 @@
#pragma once #pragma once
#include "Internals/JsonObjectNode.hpp"
#include "Internals/NonCopyable.hpp"
#include "JsonArray.hpp"
#include "JsonObjectConstIterator.hpp" #include "JsonObjectConstIterator.hpp"
#include "JsonObjectIterator.hpp" #include "JsonObjectIterator.hpp"
#include "JsonPrintable.hpp" #include "JsonPrintable.hpp"
#include "Internals/JsonObjectNode.hpp"
#include "JsonArray.hpp" #define JSON_OBJECT_SIZE(NUMBER_OF_ELEMENTS) \
(sizeof(JsonObject) + \
(NUMBER_OF_ELEMENTS) * sizeof(Internals::JsonObjectNode))
namespace ArduinoJson { namespace ArduinoJson {
class JsonObject : public JsonPrintable { class JsonObject : public JsonPrintable, Internals::NonCopyable {
friend class JsonBuffer; friend class JsonBuffer;
public: public:
@ -55,10 +60,6 @@ class JsonObject : public JsonPrintable {
// constructor is private, instance must be created via JsonBuffer // constructor is private, instance must be created via JsonBuffer
JsonObject(JsonBuffer *buffer) : _buffer(buffer), _firstNode(NULL) {} JsonObject(JsonBuffer *buffer) : _buffer(buffer), _firstNode(NULL) {}
JsonObject(const JsonObject &); // copy is forbidden, use a reference instead
JsonObject &operator=(
const JsonObject &); // copy is forbidden, use a reference instead
JsonValue &add(key_type key) { return (*this)[key]; } JsonValue &add(key_type key) { return (*this)[key]; }
Internals::JsonObjectNode *createNode(key_type key); Internals::JsonObjectNode *createNode(key_type key);
void addNode(Internals::JsonObjectNode *nodeToAdd); void addNode(Internals::JsonObjectNode *nodeToAdd);

View File

@ -14,10 +14,7 @@ namespace ArduinoJson {
struct JsonPair { struct JsonPair {
JsonPair(const char* k) : key(k) {} JsonPair(const char* k) : key(k) {}
const char* const key; const char* key;
JsonValue value; JsonValue value;
// warning C4512: assignment operator could not be generated
#pragma warning( suppress : 4512 )
}; };
} }

View File

@ -82,6 +82,7 @@ void JsonObject::addNode(JsonObjectNode *nodeToAdd) {
} }
void JsonObject::removeNode(JsonObjectNode *nodeToRemove) { void JsonObject::removeNode(JsonObjectNode *nodeToRemove) {
if (!nodeToRemove) return;
if (nodeToRemove == _firstNode) { if (nodeToRemove == _firstNode) {
_firstNode = nodeToRemove->next; _firstNode = nodeToRemove->next;
} else { } else {

View File

@ -38,11 +38,11 @@ class Issue10 : public testing::Test {
buffer); buffer);
} }
StaticJsonBuffer<JSON_ARRAY_SIZE(2)+2*JSON_OBJECT_SIZE(2)> json;
Person persons[2]; Person persons[2];
}; };
TEST_F(Issue10, PopulateArrayByAddingAnObject) { TEST_F(Issue10, PopulateArrayByAddingAnObject) {
StaticJsonBuffer<200> json;
JsonArray &array = json.createArray(); JsonArray &array = json.createArray();
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
@ -51,15 +51,13 @@ TEST_F(Issue10, PopulateArrayByAddingAnObject) {
object["id"] = persons[i].id; object["id"] = persons[i].id;
object["name"] = persons[i].name; object["name"] = persons[i].name;
array.add(object); // <- adds a reference to an existing objet (creates 2 array.add(object);
// extra proxy nodes)
} }
checkJsonString(array); checkJsonString(array);
} }
TEST_F(Issue10, PopulateArrayByCreatingNestedObjects) { TEST_F(Issue10, PopulateArrayByCreatingNestedObjects) {
StaticJsonBuffer<200> json;
JsonArray &array = json.createArray(); JsonArray &array = json.createArray();
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {

View File

@ -17,8 +17,8 @@ class JsonArray_PrettyPrintTo_Tests : public testing::Test {
JsonArray_PrettyPrintTo_Tests() : array(json.createArray()) {} JsonArray_PrettyPrintTo_Tests() : array(json.createArray()) {}
protected: protected:
StaticJsonBuffer<200> json;
JsonArray& array; JsonArray& array;
StaticJsonBuffer<30> json;
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));

View File

@ -16,8 +16,8 @@ class JsonArray_PrintTo_Tests : public testing::Test {
JsonArray_PrintTo_Tests() : array(json.createArray()) {} JsonArray_PrintTo_Tests() : array(json.createArray()) {}
protected: protected:
StaticJsonBuffer<JSON_ARRAY_SIZE(2)> json;
JsonArray &array; JsonArray &array;
StaticJsonBuffer<3> json;
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));

View File

@ -11,7 +11,7 @@
using namespace ArduinoJson; using namespace ArduinoJson;
TEST(JsonObject_Iterator_Test, SimpleTest) { TEST(JsonObject_Iterator_Test, SimpleTest) {
StaticJsonBuffer<42> jsonBuffer; StaticJsonBuffer<256> jsonBuffer;
JsonObject &object = jsonBuffer.createObject(); JsonObject &object = jsonBuffer.createObject();
object["ab"] = 12; object["ab"] = 12;
@ -20,11 +20,11 @@ TEST(JsonObject_Iterator_Test, SimpleTest) {
JsonObject::iterator it = object.begin(); JsonObject::iterator it = object.begin();
JsonObject::iterator end = object.end(); JsonObject::iterator end = object.end();
EXPECT_NE(end, it); ASSERT_NE(end, it);
EXPECT_STREQ("ab", it->key); EXPECT_STREQ("ab", it->key);
EXPECT_EQ(12, it->value.as<int>()); EXPECT_EQ(12, it->value.as<int>());
++it; ++it;
EXPECT_NE(end, it); ASSERT_NE(end, it);
EXPECT_STREQ("cd", it->key); EXPECT_STREQ("cd", it->key);
EXPECT_EQ(34, it->value.as<int>()); EXPECT_EQ(34, it->value.as<int>());
++it; ++it;

View File

@ -17,8 +17,8 @@ class JsonObject_PrettyPrintTo_Tests : public testing::Test {
JsonObject_PrettyPrintTo_Tests() : object(json.createObject()) {} JsonObject_PrettyPrintTo_Tests() : object(json.createObject()) {}
protected: protected:
StaticJsonBuffer<300> json;
JsonObject &object; JsonObject &object;
StaticJsonBuffer<30> json;
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));

View File

@ -10,11 +10,12 @@
#include <ArduinoJson/JsonValue.hpp> #include <ArduinoJson/JsonValue.hpp>
#include <ArduinoJson/StaticJsonBuffer.hpp> #include <ArduinoJson/StaticJsonBuffer.hpp>
using namespace ArduinoJson; using namespace ArduinoJson;
using namespace ArduinoJson::Internals;
class JsonObject_Serialization_Tests : public testing::Test { class JsonObject_PrintTo_Tests : public testing::Test {
public: public:
JsonObject_Serialization_Tests() : object(json.createObject()) {} JsonObject_PrintTo_Tests() : object(json.createObject()) {}
protected: protected:
void outputMustBe(const char *expected) { void outputMustBe(const char *expected) {
@ -25,26 +26,26 @@ class JsonObject_Serialization_Tests : public testing::Test {
EXPECT_EQ(strlen(expected), result); EXPECT_EQ(strlen(expected), result);
} }
StaticJsonBuffer<JSON_OBJECT_SIZE(2)> json;
JsonObject &object; JsonObject &object;
StaticJsonBuffer<5> json;
}; };
TEST_F(JsonObject_Serialization_Tests, EmptyObject) { outputMustBe("{}"); } TEST_F(JsonObject_PrintTo_Tests, EmptyObject) { outputMustBe("{}"); }
TEST_F(JsonObject_Serialization_Tests, OneString) { TEST_F(JsonObject_PrintTo_Tests, OneString) {
object["key"] = "value"; object["key"] = "value";
outputMustBe("{\"key\":\"value\"}"); outputMustBe("{\"key\":\"value\"}");
} }
TEST_F(JsonObject_Serialization_Tests, TwoStrings) { TEST_F(JsonObject_PrintTo_Tests, TwoStrings) {
object["key1"] = "value1"; object["key1"] = "value1";
object["key2"] = "value2"; object["key2"] = "value2";
outputMustBe("{\"key1\":\"value1\",\"key2\":\"value2\"}"); outputMustBe("{\"key1\":\"value1\",\"key2\":\"value2\"}");
} }
TEST_F(JsonObject_Serialization_Tests, RemoveFirst) { TEST_F(JsonObject_PrintTo_Tests, RemoveFirst) {
object["key1"] = "value1"; object["key1"] = "value1";
object["key2"] = "value2"; object["key2"] = "value2";
object.remove("key1"); object.remove("key1");
@ -52,7 +53,7 @@ TEST_F(JsonObject_Serialization_Tests, RemoveFirst) {
outputMustBe("{\"key2\":\"value2\"}"); outputMustBe("{\"key2\":\"value2\"}");
} }
TEST_F(JsonObject_Serialization_Tests, RemoveLast) { TEST_F(JsonObject_PrintTo_Tests, RemoveLast) {
object["key1"] = "value1"; object["key1"] = "value1";
object["key2"] = "value2"; object["key2"] = "value2";
object.remove("key2"); object.remove("key2");
@ -60,7 +61,7 @@ TEST_F(JsonObject_Serialization_Tests, RemoveLast) {
outputMustBe("{\"key1\":\"value1\"}"); outputMustBe("{\"key1\":\"value1\"}");
} }
TEST_F(JsonObject_Serialization_Tests, RemoveUnexistingKey) { TEST_F(JsonObject_PrintTo_Tests, RemoveUnexistingKey) {
object["key1"] = "value1"; object["key1"] = "value1";
object["key2"] = "value2"; object["key2"] = "value2";
object.remove("key3"); object.remove("key3");
@ -68,14 +69,14 @@ TEST_F(JsonObject_Serialization_Tests, RemoveUnexistingKey) {
outputMustBe("{\"key1\":\"value1\",\"key2\":\"value2\"}"); outputMustBe("{\"key1\":\"value1\",\"key2\":\"value2\"}");
} }
TEST_F(JsonObject_Serialization_Tests, ReplaceExistingKey) { TEST_F(JsonObject_PrintTo_Tests, ReplaceExistingKey) {
object["key"] = "value1"; object["key"] = "value1";
object["key"] = "value2"; object["key"] = "value2";
outputMustBe("{\"key\":\"value2\"}"); outputMustBe("{\"key\":\"value2\"}");
} }
TEST_F(JsonObject_Serialization_Tests, OneStringOverCapacity) { TEST_F(JsonObject_PrintTo_Tests, OneStringOverCapacity) {
object["key1"] = "value1"; object["key1"] = "value1";
object["key2"] = "value2"; object["key2"] = "value2";
object["key3"] = "value3"; object["key3"] = "value3";
@ -83,37 +84,37 @@ TEST_F(JsonObject_Serialization_Tests, OneStringOverCapacity) {
outputMustBe("{\"key1\":\"value1\",\"key2\":\"value2\"}"); outputMustBe("{\"key1\":\"value1\",\"key2\":\"value2\"}");
} }
TEST_F(JsonObject_Serialization_Tests, OneInteger) { TEST_F(JsonObject_PrintTo_Tests, OneInteger) {
object["key"] = 1; object["key"] = 1;
outputMustBe("{\"key\":1}"); outputMustBe("{\"key\":1}");
} }
TEST_F(JsonObject_Serialization_Tests, OneDoubleFourDigits) { TEST_F(JsonObject_PrintTo_Tests, OneDoubleFourDigits) {
object["key"].set(3.14159265358979323846, 4); object["key"].set(3.14159265358979323846, 4);
outputMustBe("{\"key\":3.1416}"); outputMustBe("{\"key\":3.1416}");
} }
TEST_F(JsonObject_Serialization_Tests, OneDoubleDefaultDigits) { TEST_F(JsonObject_PrintTo_Tests, OneDoubleDefaultDigits) {
object["key"] = 3.14159265358979323846; object["key"] = 3.14159265358979323846;
outputMustBe("{\"key\":3.14}"); outputMustBe("{\"key\":3.14}");
} }
TEST_F(JsonObject_Serialization_Tests, OneNull) { TEST_F(JsonObject_PrintTo_Tests, OneNull) {
object["key"] = static_cast<char *>(0); object["key"] = static_cast<char *>(0);
outputMustBe("{\"key\":null}"); outputMustBe("{\"key\":null}");
} }
TEST_F(JsonObject_Serialization_Tests, OneTrue) { TEST_F(JsonObject_PrintTo_Tests, OneTrue) {
object["key"] = true; object["key"] = true;
outputMustBe("{\"key\":true}"); outputMustBe("{\"key\":true}");
} }
TEST_F(JsonObject_Serialization_Tests, OneFalse) { TEST_F(JsonObject_PrintTo_Tests, OneFalse) {
object["key"] = false; object["key"] = false;
outputMustBe("{\"key\":false}"); outputMustBe("{\"key\":false}");
} }
TEST_F(JsonObject_Serialization_Tests, OneEmptyNestedArrayViaProxy) { TEST_F(JsonObject_PrintTo_Tests, OneEmptyNestedArrayViaProxy) {
JsonArray &nestedArray = json.createArray(); JsonArray &nestedArray = json.createArray();
object["key"] = nestedArray; object["key"] = nestedArray;
@ -121,7 +122,7 @@ TEST_F(JsonObject_Serialization_Tests, OneEmptyNestedArrayViaProxy) {
outputMustBe("{\"key\":[]}"); outputMustBe("{\"key\":[]}");
} }
TEST_F(JsonObject_Serialization_Tests, OneEmptyNestedObjectViaProxy) { TEST_F(JsonObject_PrintTo_Tests, OneEmptyNestedObjectViaProxy) {
JsonObject &nestedArray = json.createObject(); JsonObject &nestedArray = json.createObject();
object["key"] = nestedArray; object["key"] = nestedArray;
@ -129,13 +130,13 @@ TEST_F(JsonObject_Serialization_Tests, OneEmptyNestedObjectViaProxy) {
outputMustBe("{\"key\":{}}"); outputMustBe("{\"key\":{}}");
} }
TEST_F(JsonObject_Serialization_Tests, OneEmptyNestedObject) { TEST_F(JsonObject_PrintTo_Tests, OneEmptyNestedObject) {
object.createNestedObject("key"); object.createNestedObject("key");
outputMustBe("{\"key\":{}}"); outputMustBe("{\"key\":{}}");
} }
TEST_F(JsonObject_Serialization_Tests, OneEmptyNestedArray) { TEST_F(JsonObject_PrintTo_Tests, OneEmptyNestedArray) {
object.createNestedArray("key"); object.createNestedArray("key");
outputMustBe("{\"key\":[]}"); outputMustBe("{\"key\":[]}");

View File

@ -25,7 +25,7 @@ class JsonParser_Array_Tests : public testing::Test {
EXPECT_EQ(0, _array->size()); EXPECT_EQ(0, _array->size());
} }
void sizeMustBe(int expected) { EXPECT_EQ(expected, _array->size()); } void sizeMustBe(int expected) { ASSERT_EQ(expected, _array->size()); }
template <typename T> template <typename T>
void firstElementMustBe(T expected) { void firstElementMustBe(T expected) {
@ -46,7 +46,7 @@ class JsonParser_Array_Tests : public testing::Test {
EXPECT_STREQ(expected, _array->at(index).as<const char *>()); EXPECT_STREQ(expected, _array->at(index).as<const char *>());
} }
StaticJsonBuffer<42> _jsonBuffer; StaticJsonBuffer<256> _jsonBuffer;
JsonArray *_array; JsonArray *_array;
char _jsonString[256]; char _jsonString[256];
}; };

View File

@ -12,7 +12,7 @@
using namespace ArduinoJson; using namespace ArduinoJson;
TEST(JsonParser_Nested_Tests, ArrayNestedInObject) { TEST(JsonParser_Nested_Tests, ArrayNestedInObject) {
StaticJsonBuffer<42> jsonBuffer; StaticJsonBuffer<256> jsonBuffer;
char jsonString[] = " { \"ab\" : [ 1 , 2 ] , \"cd\" : [ 3 , 4 ] } "; char jsonString[] = " { \"ab\" : [ 1 , 2 ] , \"cd\" : [ 3 , 4 ] } ";
JsonObject &object = jsonBuffer.parseObject(jsonString); JsonObject &object = jsonBuffer.parseObject(jsonString);
@ -35,7 +35,7 @@ TEST(JsonParser_Nested_Tests, ArrayNestedInObject) {
} }
TEST(JsonParser_Nested_Tests, ObjectNestedInArray) { TEST(JsonParser_Nested_Tests, ObjectNestedInArray) {
StaticJsonBuffer<42> jsonBuffer; StaticJsonBuffer<256> jsonBuffer;
char jsonString[] = char jsonString[] =
" [ { \"a\" : 1 , \"b\" : 2 } , { \"c\" : 3 , \"d\" : 4 } ] "; " [ { \"a\" : 1 , \"b\" : 2 } , { \"c\" : 3 , \"d\" : 4 } ] ";

View File

@ -34,7 +34,7 @@ class JsonParser_Object_Test : public testing::Test {
} }
private: private:
StaticJsonBuffer<10> _jsonBuffer; StaticJsonBuffer<256> _jsonBuffer;
JsonObject *_object; JsonObject *_object;
char _jsonString[256]; char _jsonString[256];
}; };

View File

@ -15,7 +15,7 @@ using namespace ArduinoJson;
class JsonValueTests : public ::testing::Test { class JsonValueTests : public ::testing::Test {
protected: protected:
StaticJsonBuffer<42> json; StaticJsonBuffer<200> json;
JsonValue jsonValue1; JsonValue jsonValue1;
JsonValue jsonValue2; JsonValue jsonValue2;
}; };

View File

@ -21,25 +21,25 @@ TEST(StaticJsonBuffer, InitialSizeIsZero) {
EXPECT_EQ(0, json.size()); EXPECT_EQ(0, json.size());
} }
TEST(StaticJsonBuffer, WhenCreateObjectIsCalled_ThenSizeIsIncreasedByOne) { TEST(StaticJsonBuffer, WhenCreateObjectIsCalled_ThenSizeIsIncreasedSizeOfJsonObject) {
StaticJsonBuffer<42> json; StaticJsonBuffer<42> json;
json.createObject(); json.createObject();
EXPECT_EQ(1, json.size()); EXPECT_EQ(sizeof(JsonObject), json.size());
json.createObject(); json.createObject();
EXPECT_EQ(2, json.size()); EXPECT_EQ(sizeof(JsonObject)*2, json.size());
} }
TEST(StaticJsonBuffer, TEST(StaticJsonBuffer,
GivenBufferIsFull_WhenCreateObjectIsCalled_ThenSizeDoesNotChange) { GivenBufferIsFull_WhenCreateObjectIsCalled_ThenSizeDoesNotChange) {
StaticJsonBuffer<1> json; StaticJsonBuffer<sizeof(JsonObject)> json;
json.createObject(); json.createObject();
EXPECT_EQ(1, json.size()); EXPECT_EQ(sizeof(JsonObject), json.size());
json.createObject(); json.createObject();
EXPECT_EQ(1, json.size()); EXPECT_EQ(sizeof(JsonObject), json.size());
} }
TEST(StaticJsonBuffer, TEST(StaticJsonBuffer,
@ -51,15 +51,15 @@ TEST(StaticJsonBuffer,
} }
TEST(StaticJsonBuffer, TEST(StaticJsonBuffer,
GivenAJsonObject_WhenValuesAreAdded_ThenSizeIsIncreasedByTwo) { GivenAJsonObject_WhenValuesAreAdded_ThenSizeIsIncreasedAccordingly) {
StaticJsonBuffer<42> json; StaticJsonBuffer<200> json;
JsonObject &obj = json.createObject(); JsonObject &obj = json.createObject();
obj["hello"]; obj["hello"];
EXPECT_EQ(3, json.size()); EXPECT_EQ(sizeof(JsonObject)+sizeof(Internals::JsonObjectNode), json.size());
obj["world"]; obj["world"];
EXPECT_EQ(5, json.size()); EXPECT_EQ(sizeof(JsonObject) + sizeof(Internals::JsonObjectNode)*2, json.size());
} }
TEST( TEST(
@ -69,8 +69,10 @@ TEST(
JsonObject &obj = json.createObject(); JsonObject &obj = json.createObject();
obj["hello"]; obj["hello"];
EXPECT_EQ(3, json.size());
size_t sizeBefore = json.size();
obj["hello"]; obj["hello"];
EXPECT_EQ(3, json.size()); size_t sizeAfter = json.size();
EXPECT_EQ(sizeBefore, sizeAfter);
} }