From 889f059758a45b1a3ac6b2a11bb1cb237408df44 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Thu, 30 Oct 2014 21:51:59 +0100 Subject: [PATCH] All tests passed! --- .../ArduinoJson/Internals/JsonObjectNode.hpp | 3 -- include/ArduinoJson/Internals/NonCopyable.hpp | 25 +++++++++++ include/ArduinoJson/JsonArray.hpp | 10 ++--- include/ArduinoJson/JsonObject.hpp | 15 ++++--- include/ArduinoJson/JsonPair.hpp | 5 +-- src/JsonObject.cpp | 1 + test/Issue10.cpp | 6 +-- test/JsonArray_PrettyPrintTo_Tests.cpp | 2 +- test/JsonArray_PrintTo_Tests.cpp | 2 +- test/JsonObject_Iterator_Tests.cpp | 6 +-- test/JsonObject_PrettyPrintTo_Tests.cpp | 2 +- ...Tests.cpp => JsonObject_PrintTo_Tests.cpp} | 45 ++++++++++--------- test/JsonParser_Array_Tests.cpp | 4 +- test/JsonParser_Nested_Tests.cpp | 4 +- test/JsonParser_Object_Tests.cpp | 2 +- test/JsonValueTests.cpp | 2 +- test/StaticJsonBufferTests.cpp | 26 ++++++----- 17 files changed, 91 insertions(+), 69 deletions(-) create mode 100644 include/ArduinoJson/Internals/NonCopyable.hpp rename test/{JsonObject_Serialization_Tests.cpp => JsonObject_PrintTo_Tests.cpp} (63%) diff --git a/include/ArduinoJson/Internals/JsonObjectNode.hpp b/include/ArduinoJson/Internals/JsonObjectNode.hpp index 356403a8..6ea76f7d 100644 --- a/include/ArduinoJson/Internals/JsonObjectNode.hpp +++ b/include/ArduinoJson/Internals/JsonObjectNode.hpp @@ -18,9 +18,6 @@ class JsonObjectNode { JsonPair pair; JsonObjectNode* next; - - // warning C4512: assignment operator could not be generated - #pragma warning( suppress : 4512 ) }; } } diff --git a/include/ArduinoJson/Internals/NonCopyable.hpp b/include/ArduinoJson/Internals/NonCopyable.hpp new file mode 100644 index 00000000..bdaa9721 --- /dev/null +++ b/include/ArduinoJson/Internals/NonCopyable.hpp @@ -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&); +}; +} +} diff --git a/include/ArduinoJson/JsonArray.hpp b/include/ArduinoJson/JsonArray.hpp index be60eae4..c29efec5 100644 --- a/include/ArduinoJson/JsonArray.hpp +++ b/include/ArduinoJson/JsonArray.hpp @@ -11,10 +11,14 @@ #include "JsonArrayConstIterator.hpp" #include "JsonPrintable.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 { -class JsonArray : public JsonPrintable { +class JsonArray : public JsonPrintable, Internals::NonCopyable { friend class JsonBuffer; public: @@ -56,10 +60,6 @@ class JsonArray : public JsonPrintable { // constructor is private: instance must be created via a JsonBuffer JsonArray(JsonBuffer *buffer) : _buffer(buffer), _firstNode(NULL) {} - // copy is forbidden, use a reference instead - JsonArray(const JsonArray &); - JsonArray &operator=(const JsonArray &); - Internals::JsonArrayNode *createNode(); inline void addNode(Internals::JsonArrayNode *node); diff --git a/include/ArduinoJson/JsonObject.hpp b/include/ArduinoJson/JsonObject.hpp index e2f8b3b8..d7ff4018 100644 --- a/include/ArduinoJson/JsonObject.hpp +++ b/include/ArduinoJson/JsonObject.hpp @@ -6,15 +6,20 @@ #pragma once +#include "Internals/JsonObjectNode.hpp" +#include "Internals/NonCopyable.hpp" +#include "JsonArray.hpp" #include "JsonObjectConstIterator.hpp" #include "JsonObjectIterator.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 { -class JsonObject : public JsonPrintable { +class JsonObject : public JsonPrintable, Internals::NonCopyable { friend class JsonBuffer; public: @@ -55,10 +60,6 @@ class JsonObject : public JsonPrintable { // constructor is private, instance must be created via JsonBuffer 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]; } Internals::JsonObjectNode *createNode(key_type key); void addNode(Internals::JsonObjectNode *nodeToAdd); diff --git a/include/ArduinoJson/JsonPair.hpp b/include/ArduinoJson/JsonPair.hpp index 33cf9816..7176e496 100644 --- a/include/ArduinoJson/JsonPair.hpp +++ b/include/ArduinoJson/JsonPair.hpp @@ -14,10 +14,7 @@ namespace ArduinoJson { struct JsonPair { JsonPair(const char* k) : key(k) {} - const char* const key; + const char* key; JsonValue value; - - // warning C4512: assignment operator could not be generated - #pragma warning( suppress : 4512 ) }; } \ No newline at end of file diff --git a/src/JsonObject.cpp b/src/JsonObject.cpp index 27438d31..b526352f 100644 --- a/src/JsonObject.cpp +++ b/src/JsonObject.cpp @@ -82,6 +82,7 @@ void JsonObject::addNode(JsonObjectNode *nodeToAdd) { } void JsonObject::removeNode(JsonObjectNode *nodeToRemove) { + if (!nodeToRemove) return; if (nodeToRemove == _firstNode) { _firstNode = nodeToRemove->next; } else { diff --git a/test/Issue10.cpp b/test/Issue10.cpp index 83c85341..0dc7da78 100644 --- a/test/Issue10.cpp +++ b/test/Issue10.cpp @@ -38,11 +38,11 @@ class Issue10 : public testing::Test { buffer); } + StaticJsonBuffer json; Person persons[2]; }; TEST_F(Issue10, PopulateArrayByAddingAnObject) { - StaticJsonBuffer<200> json; JsonArray &array = json.createArray(); for (int i = 0; i < 2; i++) { @@ -51,15 +51,13 @@ TEST_F(Issue10, PopulateArrayByAddingAnObject) { 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) + array.add(object); } checkJsonString(array); } TEST_F(Issue10, PopulateArrayByCreatingNestedObjects) { - StaticJsonBuffer<200> json; JsonArray &array = json.createArray(); for (int i = 0; i < 2; i++) { diff --git a/test/JsonArray_PrettyPrintTo_Tests.cpp b/test/JsonArray_PrettyPrintTo_Tests.cpp index b045bd42..bec01863 100644 --- a/test/JsonArray_PrettyPrintTo_Tests.cpp +++ b/test/JsonArray_PrettyPrintTo_Tests.cpp @@ -17,8 +17,8 @@ class JsonArray_PrettyPrintTo_Tests : public testing::Test { JsonArray_PrettyPrintTo_Tests() : array(json.createArray()) {} protected: + StaticJsonBuffer<200> json; JsonArray& array; - StaticJsonBuffer<30> json; void outputMustBe(const char* expected) { size_t n = array.prettyPrintTo(buffer, sizeof(buffer)); diff --git a/test/JsonArray_PrintTo_Tests.cpp b/test/JsonArray_PrintTo_Tests.cpp index 2b197d1e..12bc995b 100644 --- a/test/JsonArray_PrintTo_Tests.cpp +++ b/test/JsonArray_PrintTo_Tests.cpp @@ -16,8 +16,8 @@ class JsonArray_PrintTo_Tests : public testing::Test { JsonArray_PrintTo_Tests() : array(json.createArray()) {} protected: + StaticJsonBuffer json; JsonArray &array; - StaticJsonBuffer<3> json; void outputMustBe(const char *expected) { size_t n = array.printTo(buffer, sizeof(buffer)); diff --git a/test/JsonObject_Iterator_Tests.cpp b/test/JsonObject_Iterator_Tests.cpp index 02425980..9d570450 100644 --- a/test/JsonObject_Iterator_Tests.cpp +++ b/test/JsonObject_Iterator_Tests.cpp @@ -11,7 +11,7 @@ using namespace ArduinoJson; TEST(JsonObject_Iterator_Test, SimpleTest) { - StaticJsonBuffer<42> jsonBuffer; + StaticJsonBuffer<256> jsonBuffer; JsonObject &object = jsonBuffer.createObject(); object["ab"] = 12; @@ -20,11 +20,11 @@ TEST(JsonObject_Iterator_Test, SimpleTest) { JsonObject::iterator it = object.begin(); JsonObject::iterator end = object.end(); - EXPECT_NE(end, it); + ASSERT_NE(end, it); EXPECT_STREQ("ab", it->key); EXPECT_EQ(12, it->value.as()); ++it; - EXPECT_NE(end, it); + ASSERT_NE(end, it); EXPECT_STREQ("cd", it->key); EXPECT_EQ(34, it->value.as()); ++it; diff --git a/test/JsonObject_PrettyPrintTo_Tests.cpp b/test/JsonObject_PrettyPrintTo_Tests.cpp index 0ed70055..f15a3734 100644 --- a/test/JsonObject_PrettyPrintTo_Tests.cpp +++ b/test/JsonObject_PrettyPrintTo_Tests.cpp @@ -17,8 +17,8 @@ class JsonObject_PrettyPrintTo_Tests : public testing::Test { JsonObject_PrettyPrintTo_Tests() : object(json.createObject()) {} protected: + StaticJsonBuffer<300> json; JsonObject &object; - StaticJsonBuffer<30> json; void outputMustBe(const char *expected) { size_t n = object.prettyPrintTo(buffer, sizeof(buffer)); diff --git a/test/JsonObject_Serialization_Tests.cpp b/test/JsonObject_PrintTo_Tests.cpp similarity index 63% rename from test/JsonObject_Serialization_Tests.cpp rename to test/JsonObject_PrintTo_Tests.cpp index ee415221..f45b4a13 100644 --- a/test/JsonObject_Serialization_Tests.cpp +++ b/test/JsonObject_PrintTo_Tests.cpp @@ -10,11 +10,12 @@ #include #include -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: - JsonObject_Serialization_Tests() : object(json.createObject()) {} + JsonObject_PrintTo_Tests() : object(json.createObject()) {} protected: void outputMustBe(const char *expected) { @@ -25,26 +26,26 @@ class JsonObject_Serialization_Tests : public testing::Test { EXPECT_EQ(strlen(expected), result); } + StaticJsonBuffer json; 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"; outputMustBe("{\"key\":\"value\"}"); } -TEST_F(JsonObject_Serialization_Tests, TwoStrings) { +TEST_F(JsonObject_PrintTo_Tests, TwoStrings) { object["key1"] = "value1"; object["key2"] = "value2"; outputMustBe("{\"key1\":\"value1\",\"key2\":\"value2\"}"); } -TEST_F(JsonObject_Serialization_Tests, RemoveFirst) { +TEST_F(JsonObject_PrintTo_Tests, RemoveFirst) { object["key1"] = "value1"; object["key2"] = "value2"; object.remove("key1"); @@ -52,7 +53,7 @@ TEST_F(JsonObject_Serialization_Tests, RemoveFirst) { outputMustBe("{\"key2\":\"value2\"}"); } -TEST_F(JsonObject_Serialization_Tests, RemoveLast) { +TEST_F(JsonObject_PrintTo_Tests, RemoveLast) { object["key1"] = "value1"; object["key2"] = "value2"; object.remove("key2"); @@ -60,7 +61,7 @@ TEST_F(JsonObject_Serialization_Tests, RemoveLast) { outputMustBe("{\"key1\":\"value1\"}"); } -TEST_F(JsonObject_Serialization_Tests, RemoveUnexistingKey) { +TEST_F(JsonObject_PrintTo_Tests, RemoveUnexistingKey) { object["key1"] = "value1"; object["key2"] = "value2"; object.remove("key3"); @@ -68,14 +69,14 @@ TEST_F(JsonObject_Serialization_Tests, RemoveUnexistingKey) { outputMustBe("{\"key1\":\"value1\",\"key2\":\"value2\"}"); } -TEST_F(JsonObject_Serialization_Tests, ReplaceExistingKey) { +TEST_F(JsonObject_PrintTo_Tests, ReplaceExistingKey) { object["key"] = "value1"; object["key"] = "value2"; outputMustBe("{\"key\":\"value2\"}"); } -TEST_F(JsonObject_Serialization_Tests, OneStringOverCapacity) { +TEST_F(JsonObject_PrintTo_Tests, OneStringOverCapacity) { object["key1"] = "value1"; object["key2"] = "value2"; object["key3"] = "value3"; @@ -83,37 +84,37 @@ TEST_F(JsonObject_Serialization_Tests, OneStringOverCapacity) { outputMustBe("{\"key1\":\"value1\",\"key2\":\"value2\"}"); } -TEST_F(JsonObject_Serialization_Tests, OneInteger) { +TEST_F(JsonObject_PrintTo_Tests, OneInteger) { object["key"] = 1; outputMustBe("{\"key\":1}"); } -TEST_F(JsonObject_Serialization_Tests, OneDoubleFourDigits) { +TEST_F(JsonObject_PrintTo_Tests, OneDoubleFourDigits) { object["key"].set(3.14159265358979323846, 4); outputMustBe("{\"key\":3.1416}"); } -TEST_F(JsonObject_Serialization_Tests, OneDoubleDefaultDigits) { +TEST_F(JsonObject_PrintTo_Tests, OneDoubleDefaultDigits) { object["key"] = 3.14159265358979323846; outputMustBe("{\"key\":3.14}"); } -TEST_F(JsonObject_Serialization_Tests, OneNull) { +TEST_F(JsonObject_PrintTo_Tests, OneNull) { object["key"] = static_cast(0); outputMustBe("{\"key\":null}"); } -TEST_F(JsonObject_Serialization_Tests, OneTrue) { +TEST_F(JsonObject_PrintTo_Tests, OneTrue) { object["key"] = true; outputMustBe("{\"key\":true}"); } -TEST_F(JsonObject_Serialization_Tests, OneFalse) { +TEST_F(JsonObject_PrintTo_Tests, OneFalse) { object["key"] = false; outputMustBe("{\"key\":false}"); } -TEST_F(JsonObject_Serialization_Tests, OneEmptyNestedArrayViaProxy) { +TEST_F(JsonObject_PrintTo_Tests, OneEmptyNestedArrayViaProxy) { JsonArray &nestedArray = json.createArray(); object["key"] = nestedArray; @@ -121,7 +122,7 @@ TEST_F(JsonObject_Serialization_Tests, OneEmptyNestedArrayViaProxy) { outputMustBe("{\"key\":[]}"); } -TEST_F(JsonObject_Serialization_Tests, OneEmptyNestedObjectViaProxy) { +TEST_F(JsonObject_PrintTo_Tests, OneEmptyNestedObjectViaProxy) { JsonObject &nestedArray = json.createObject(); object["key"] = nestedArray; @@ -129,13 +130,13 @@ TEST_F(JsonObject_Serialization_Tests, OneEmptyNestedObjectViaProxy) { outputMustBe("{\"key\":{}}"); } -TEST_F(JsonObject_Serialization_Tests, OneEmptyNestedObject) { +TEST_F(JsonObject_PrintTo_Tests, OneEmptyNestedObject) { object.createNestedObject("key"); outputMustBe("{\"key\":{}}"); } -TEST_F(JsonObject_Serialization_Tests, OneEmptyNestedArray) { +TEST_F(JsonObject_PrintTo_Tests, OneEmptyNestedArray) { object.createNestedArray("key"); outputMustBe("{\"key\":[]}"); diff --git a/test/JsonParser_Array_Tests.cpp b/test/JsonParser_Array_Tests.cpp index 6b1b33a1..db3ef8a2 100644 --- a/test/JsonParser_Array_Tests.cpp +++ b/test/JsonParser_Array_Tests.cpp @@ -25,7 +25,7 @@ class JsonParser_Array_Tests : public testing::Test { EXPECT_EQ(0, _array->size()); } - void sizeMustBe(int expected) { EXPECT_EQ(expected, _array->size()); } + void sizeMustBe(int expected) { ASSERT_EQ(expected, _array->size()); } template void firstElementMustBe(T expected) { @@ -46,7 +46,7 @@ class JsonParser_Array_Tests : public testing::Test { EXPECT_STREQ(expected, _array->at(index).as()); } - StaticJsonBuffer<42> _jsonBuffer; + StaticJsonBuffer<256> _jsonBuffer; JsonArray *_array; char _jsonString[256]; }; diff --git a/test/JsonParser_Nested_Tests.cpp b/test/JsonParser_Nested_Tests.cpp index 4d350448..a50d437e 100644 --- a/test/JsonParser_Nested_Tests.cpp +++ b/test/JsonParser_Nested_Tests.cpp @@ -12,7 +12,7 @@ using namespace ArduinoJson; TEST(JsonParser_Nested_Tests, ArrayNestedInObject) { - StaticJsonBuffer<42> jsonBuffer; + StaticJsonBuffer<256> jsonBuffer; char jsonString[] = " { \"ab\" : [ 1 , 2 ] , \"cd\" : [ 3 , 4 ] } "; JsonObject &object = jsonBuffer.parseObject(jsonString); @@ -35,7 +35,7 @@ TEST(JsonParser_Nested_Tests, ArrayNestedInObject) { } TEST(JsonParser_Nested_Tests, ObjectNestedInArray) { - StaticJsonBuffer<42> jsonBuffer; + StaticJsonBuffer<256> jsonBuffer; char jsonString[] = " [ { \"a\" : 1 , \"b\" : 2 } , { \"c\" : 3 , \"d\" : 4 } ] "; diff --git a/test/JsonParser_Object_Tests.cpp b/test/JsonParser_Object_Tests.cpp index fd8d3607..95403610 100644 --- a/test/JsonParser_Object_Tests.cpp +++ b/test/JsonParser_Object_Tests.cpp @@ -34,7 +34,7 @@ class JsonParser_Object_Test : public testing::Test { } private: - StaticJsonBuffer<10> _jsonBuffer; + StaticJsonBuffer<256> _jsonBuffer; JsonObject *_object; char _jsonString[256]; }; diff --git a/test/JsonValueTests.cpp b/test/JsonValueTests.cpp index 6b0c754e..f07553bc 100644 --- a/test/JsonValueTests.cpp +++ b/test/JsonValueTests.cpp @@ -15,7 +15,7 @@ using namespace ArduinoJson; class JsonValueTests : public ::testing::Test { protected: - StaticJsonBuffer<42> json; + StaticJsonBuffer<200> json; JsonValue jsonValue1; JsonValue jsonValue2; }; diff --git a/test/StaticJsonBufferTests.cpp b/test/StaticJsonBufferTests.cpp index b3260a41..b7d7018c 100644 --- a/test/StaticJsonBufferTests.cpp +++ b/test/StaticJsonBufferTests.cpp @@ -21,25 +21,25 @@ TEST(StaticJsonBuffer, InitialSizeIsZero) { EXPECT_EQ(0, json.size()); } -TEST(StaticJsonBuffer, WhenCreateObjectIsCalled_ThenSizeIsIncreasedByOne) { +TEST(StaticJsonBuffer, WhenCreateObjectIsCalled_ThenSizeIsIncreasedSizeOfJsonObject) { StaticJsonBuffer<42> json; json.createObject(); - EXPECT_EQ(1, json.size()); + EXPECT_EQ(sizeof(JsonObject), json.size()); json.createObject(); - EXPECT_EQ(2, json.size()); + EXPECT_EQ(sizeof(JsonObject)*2, json.size()); } TEST(StaticJsonBuffer, GivenBufferIsFull_WhenCreateObjectIsCalled_ThenSizeDoesNotChange) { - StaticJsonBuffer<1> json; + StaticJsonBuffer json; json.createObject(); - EXPECT_EQ(1, json.size()); + EXPECT_EQ(sizeof(JsonObject), json.size()); json.createObject(); - EXPECT_EQ(1, json.size()); + EXPECT_EQ(sizeof(JsonObject), json.size()); } TEST(StaticJsonBuffer, @@ -51,15 +51,15 @@ TEST(StaticJsonBuffer, } TEST(StaticJsonBuffer, - GivenAJsonObject_WhenValuesAreAdded_ThenSizeIsIncreasedByTwo) { - StaticJsonBuffer<42> json; + GivenAJsonObject_WhenValuesAreAdded_ThenSizeIsIncreasedAccordingly) { + StaticJsonBuffer<200> json; JsonObject &obj = json.createObject(); obj["hello"]; - EXPECT_EQ(3, json.size()); + EXPECT_EQ(sizeof(JsonObject)+sizeof(Internals::JsonObjectNode), json.size()); obj["world"]; - EXPECT_EQ(5, json.size()); + EXPECT_EQ(sizeof(JsonObject) + sizeof(Internals::JsonObjectNode)*2, json.size()); } TEST( @@ -69,8 +69,10 @@ TEST( JsonObject &obj = json.createObject(); obj["hello"]; - EXPECT_EQ(3, json.size()); + size_t sizeBefore = json.size(); obj["hello"]; - EXPECT_EQ(3, json.size()); + size_t sizeAfter = json.size(); + + EXPECT_EQ(sizeBefore, sizeAfter); }