Compare commits

...

15 Commits
v1.0 ... v1.1

Author SHA1 Message Date
17d1f5cd2f Updated the change log 2014-02-27 19:51:24 +01:00
8c2a1fab72 Remplaced char* by char[] 2014-02-27 13:59:06 +01:00
c844db8659 Added change log 2014-02-27 13:54:34 +01:00
3661f801a5 Refactored getNestedTokenCount() 2014-02-27 13:32:50 +01:00
a35d503a02 Fixed the bug in getNestedTokenCount() 2014-02-27 13:30:03 +01:00
2ed6317135 Added more test on arrays 2014-02-27 13:20:49 +01:00
a278cd825f Added unit tests for invalid arrays 2014-02-27 13:12:52 +01:00
0eaa5e3f1b Fixed null pointer exception in JsonArray and JsonHashTable constructors 2014-02-27 13:12:10 +01:00
b35095ded1 Added unit tests on multi-dimensional arrays to isolate the bug 2014-02-27 13:03:25 +01:00
597b4c7888 Added unit tests for all members of the gbathree JSON string 2014-02-27 12:48:06 +01:00
995aa7dd40 Added unit tests of sample string given by gbatree 2014-02-26 22:29:20 +01:00
a58fb13d37 Added unit tests of the JsonArray example 2014-02-26 22:09:14 +01:00
d994178678 Added .gitignore for the tests folder 2014-02-26 22:00:35 +01:00
dc1b3f3d78 Added Unit Test for the HashTable example 2014-02-26 21:58:20 +01:00
006fc13141 Example: change the type of the json string from char* to char[] because it cause issue in memory protected environments. 2014-02-26 21:38:58 +01:00
14 changed files with 804 additions and 104 deletions

13
CHANGELOG.md Normal file
View File

@ -0,0 +1,13 @@
ArduinoJsonParser change log
============================
v1.1
----
* Example: changed `char* json` into `char json[]` so that the byes are not write protected
* Fixed parsing bug when the JSON contains multi-dimensional arrays
v1.0
----
Initial release

View File

@ -9,7 +9,7 @@
JsonArray::JsonArray(char* json, jsmntok_t* tokens) JsonArray::JsonArray(char* json, jsmntok_t* tokens)
: JsonObjectBase(json, tokens) : JsonObjectBase(json, tokens)
{ {
if (tokens[0].type != JSMN_ARRAY) if (tokens == 0 || tokens[0].type != JSMN_ARRAY)
makeInvalid(); makeInvalid();
} }

View File

@ -11,7 +11,7 @@
JsonHashTable::JsonHashTable(char* json, jsmntok_t* tokens) JsonHashTable::JsonHashTable(char* json, jsmntok_t* tokens)
: JsonObjectBase(json, tokens) : JsonObjectBase(json, tokens)
{ {
if (tokens[0].type != JSMN_OBJECT) if (tokens == 0 || tokens[0].type != JSMN_OBJECT)
makeInvalid(); makeInvalid();
} }

View File

@ -10,11 +10,15 @@
int JsonObjectBase::getNestedTokenCount(jsmntok_t* token) int JsonObjectBase::getNestedTokenCount(jsmntok_t* token)
{ {
int count = 0; int end = token->end;
int count = 0;
for (int i = 0; i < token->size; i++) token++;
while (token->start < end)
{ {
count += 1 + getNestedTokenCount(token + 1 + i); token++;
count++;
} }
return count; return count;

View File

@ -21,7 +21,7 @@ Features
Example Example
------- -------
char* json = "{\"Name\":\"Blanchon\",\"Skills\":[\"C\",\"C++\",\"C#\"],\"Age\":32,\"Online\":true}"; char json[] = "{\"Name\":\"Blanchon\",\"Skills\":[\"C\",\"C++\",\"C#\"],\"Age\":32,\"Online\":true}";
JsonParser<32> parser; JsonParser<32> parser;
@ -66,7 +66,7 @@ To extract data from the JSON string, you need to create a `JsonParser`, and spe
> #### How to choose the number of tokens ? > #### How to choose the number of tokens ?
> A token is an element of the JSON object: either a key, a value, an hash-table or an array. > A token is an element of the JSON object: either a key, a value, an hash-table or an array.
> As an example the `char* json` on the top of this page contains 12 tokens (don't forget to count 1 for the whole object and 1 more for the array itself). > As an example the `char json[]` on the top of this page contains 12 tokens (don't forget to count 1 for the whole object and 1 more for the array itself).
> The more tokens you allocate, the more complex the JSON can be, but also the more memory is occupied. > The more tokens you allocate, the more complex the JSON can be, but also the more memory is occupied.
> Each token takes 8 bytes, so `sizeof(JsonParser<32>)` is 256 bytes which is quite big in an Arduino with only 2KB of RAM. > Each token takes 8 bytes, so `sizeof(JsonParser<32>)` is 256 bytes which is quite big in an Arduino with only 2KB of RAM.
@ -85,7 +85,7 @@ If you need other type, you can get the string value and parse it yourself.
#### Hash-table #### Hash-table
Consider we have a `char* json` pointing to the following JSON string: Consider we have a `char json[]` containing to the following JSON string:
{ {
"Name":"Blanchon", "Name":"Blanchon",
@ -120,7 +120,7 @@ And then extract the member you need:
#### Array #### Array
Consider we have a `char* json` pointing to the following JSON string: Consider we have a `char json[]` containing to the following JSON string:
[ [
[ 1.2, 3.4 ], [ 1.2, 3.4 ],
@ -196,7 +196,7 @@ because the local variable `parser` will be *removed* from memory when the funct
This will probably never be an issue, but you need to be aware of this feature. This will probably never be an issue, but you need to be aware of this feature.
When you pass a `char*` to `JsonParser::parseArray()` or `JsonParser::parseHashTable()`, the content of the string will be altered to add `\0` at the end of the tokens. When you pass a `char[]` to `JsonParser::parseArray()` or `JsonParser::parseHashTable()`, the content of the string will be altered to add `\0` at the end of the tokens.
This is because we want functions like `JsonArray::getString()` to return a null-terminating string without any memory allocation. This is because we want functions like `JsonArray::getString()` to return a null-terminating string without any memory allocation.

View File

@ -1,94 +1,94 @@
/* /*
* malloc-free JSON parser for Arduino * malloc-free JSON parser for Arduino
* Benoit Blanchon 2014 - MIT License * Benoit Blanchon 2014 - MIT License
*/ */
#include <JsonParser.h> #include <JsonParser.h>
void ParseAnObject() void ParseAnObject()
{ {
char* json = "{\"Name\":\"Blanchon\",\"Skills\":[\"C\",\"C++\",\"C#\"],\"Age\":32,\"Online\":true}"; char[] json = "{\"Name\":\"Blanchon\",\"Skills\":[\"C\",\"C++\",\"C#\"],\"Age\":32,\"Online\":true}";
JsonParser<32> parser; JsonParser<32> parser;
Serial.print("Parse "); Serial.print("Parse ");
Serial.println(json); Serial.println(json);
JsonHashTable hashTable = parser.parseHashTable(json); JsonHashTable hashTable = parser.parseHashTable(json);
if (!hashTable.success()) if (!hashTable.success())
{ {
Serial.println("JsonParser.parseHashTable() failed"); Serial.println("JsonParser.parseHashTable() failed");
return; return;
} }
char* name = hashTable.getString("Name"); char* name = hashTable.getString("Name");
Serial.print("name="); Serial.print("name=");
Serial.println(name); Serial.println(name);
JsonArray skills = hashTable.getArray("Skills"); JsonArray skills = hashTable.getArray("Skills");
Serial.println("skills:"); Serial.println("skills:");
for (int i = 0; i < skills.getLength(); i++) for (int i = 0; i < skills.getLength(); i++)
{ {
char* value = skills.getString(i); char* value = skills.getString(i);
Serial.print(i); Serial.print(i);
Serial.print(" "); Serial.print(" ");
Serial.println(value); Serial.println(value);
} }
int age = hashTable.getLong("Age"); int age = hashTable.getLong("Age");
Serial.print("age="); Serial.print("age=");
Serial.println(age); Serial.println(age);
bool online = hashTable.getBool("Online"); bool online = hashTable.getBool("Online");
Serial.print("online="); Serial.print("online=");
Serial.println(online); Serial.println(online);
} }
void ParseAnArray() void ParseAnArray()
{ {
char* json = "[[1.2,3.4],[5.6,7.8]]"; char[] json = "[[1.2,3.4],[5.6,7.8]]";
JsonParser<32> parser; JsonParser<32> parser;
Serial.print("Parse "); Serial.print("Parse ");
Serial.println(json); Serial.println(json);
JsonArray array = parser.parseArray(json); JsonArray array = parser.parseArray(json);
if (!array.success()) if (!array.success())
{ {
Serial.println("JsonParser.parseArray() failed"); Serial.println("JsonParser.parseArray() failed");
return; return;
} }
for (int i = 0; i < array.getLength(); i++) for (int i = 0; i < array.getLength(); i++)
{ {
Serial.println(i); Serial.println(i);
JsonArray innerArray = array.getArray(i); JsonArray innerArray = array.getArray(i);
for (int j = 0; j < innerArray.getLength(); j++) for (int j = 0; j < innerArray.getLength(); j++)
{ {
double value = innerArray.getDouble(j); double value = innerArray.getDouble(j);
Serial.print(" "); Serial.print(" ");
Serial.print(j); Serial.print(j);
Serial.print("="); Serial.print("=");
Serial.println(value); Serial.println(value);
} }
} }
} }
void setup() void setup()
{ {
Serial.begin(9600); Serial.begin(9600);
ParseAnObject(); ParseAnObject();
ParseAnArray(); ParseAnArray();
} }
void loop() void loop()
{ {
} }

5
tests/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
/*.sdf
/*.user
/*.suo
/Debug
/ipch

View File

@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ArduinoJsonParserTests", "ArduinoJsonParserTests.vcxproj", "{4DD596EF-0185-4AB4-A3C2-F20C496F7806}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{4DD596EF-0185-4AB4-A3C2-F20C496F7806}.Debug|Win32.ActiveCfg = Debug|Win32
{4DD596EF-0185-4AB4-A3C2-F20C496F7806}.Debug|Win32.Build.0 = Debug|Win32
{4DD596EF-0185-4AB4-A3C2-F20C496F7806}.Release|Win32.ActiveCfg = Release|Win32
{4DD596EF-0185-4AB4-A3C2-F20C496F7806}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,106 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{4DD596EF-0185-4AB4-A3C2-F20C496F7806}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>ArduinoJsonParserTests</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>false</UseOfMfc>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>false</UseOfMfc>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);..</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(VC_IncludePath);..</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<UseFullPaths>true</UseFullPaths>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<UseFullPaths>true</UseFullPaths>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\JsonArray.h" />
<ClInclude Include="..\JsonHashTable.h" />
<ClInclude Include="..\JsonObjectBase.h" />
<ClInclude Include="..\JsonParser.h" />
<ClInclude Include="..\utility\jsmn.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\JsonArray.cpp" />
<ClCompile Include="..\JsonHashTable.cpp" />
<ClCompile Include="..\JsonObjectBase.cpp" />
<ClCompile Include="..\utility\jsmn.cpp" />
<ClCompile Include="TestArrayExample.cpp" />
<ClCompile Include="TestArrays.cpp" />
<ClCompile Include="TestHashTableExample.cpp" />
<ClCompile Include="TestGbathreeStrings.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\JsonArray.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\JsonHashTable.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\JsonObjectBase.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\JsonParser.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\utility\jsmn.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\JsonArray.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\JsonHashTable.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\JsonObjectBase.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\utility\jsmn.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="TestHashTableExample.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="TestArrayExample.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="TestGbathreeStrings.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="TestArrays.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,50 @@
#include "CppUnitTest.h"
#include "JsonParser.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace ArduinoJsonParserTests
{
TEST_CLASS(TestArrayExample)
{
char json[128];
JsonParser<32> parser;
JsonArray array;
public:
TEST_METHOD_INITIALIZE(Initialize)
{
strcpy(json, "[[1.2,3.4],[5.6,7.8]]");
array = parser.parseArray(json);
}
TEST_METHOD(Array_Success_ReturnsTrue)
{
Assert::IsTrue(array.success());
}
TEST_METHOD(Array_GetLength_Returns2)
{
Assert::AreEqual(2, array.getLength());
}
TEST_METHOD(Array_GetArray0_ReturnsInnerArray0)
{
JsonArray innerArray = array.getArray(0);
Assert::AreEqual(2, innerArray.getLength());
Assert::AreEqual(1.2, innerArray.getDouble(0));
Assert::AreEqual(3.4, innerArray.getDouble(1));
}
TEST_METHOD(Array_GetArray1_ReturnsInnerArray1)
{
JsonArray innerArray = array.getArray(1);
Assert::AreEqual(2, innerArray.getLength());
Assert::AreEqual(5.6, innerArray.getDouble(0));
Assert::AreEqual(7.8, innerArray.getDouble(1));
}
};
}

141
tests/TestArrays.cpp Normal file
View File

@ -0,0 +1,141 @@
#include "CppUnitTest.h"
#include "JsonParser.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace ArduinoJsonParserTests
{
TEST_CLASS(TestArrays)
{
JsonParser<32> parser;
public:
TEST_METHOD(EmptyString)
{
char json[] = "";
JsonArray array = parser.parseArray(json);
Assert::IsFalse(array.success());
}
TEST_METHOD(EmptyArray)
{
char json[] = "[]";
JsonArray array = parser.parseArray(json);
Assert::IsTrue(array.success());
}
TEST_METHOD(TooFewClosingBrackets)
{
char json[] = "[[]";
JsonArray array = parser.parseArray(json);
Assert::IsFalse(array.success());
}
TEST_METHOD(TooManyClosingBrackets)
{
char json[] = "[]]";
JsonArray array = parser.parseArray(json);
Assert::IsFalse(array.success());
}
TEST_METHOD(OneDimensionArray)
{
char json [] = "[0,0]";
JsonArray array = parser.parseArray(json);
Assert::IsTrue(array.success());
Assert::AreEqual(2, array.getLength());
for (int i = 0; i < 2; i++)
{
Assert::AreEqual(0L, array.getLong(i));
}
}
TEST_METHOD(TwoDimensionsArray)
{
char json[] = "[[0,0],[0,0]]";
JsonArray array1 = parser.parseArray(json);
Assert::IsTrue(array1.success());
Assert::AreEqual(2, array1.getLength());
for (int i = 0; i < 2; i++)
{
JsonArray array2 = array1.getArray(i);
Assert::AreEqual(2, array2.getLength());
for (int j = 0; j < 2; j++)
{
Assert::AreEqual(0L, array2.getLong(j));
}
}
}
TEST_METHOD(TreeDimensionsArray)
{
char json[] = "[[[0,0],[0,0]],[[0,0],[0,0]]]";
JsonArray array1 = parser.parseArray(json);
Assert::IsTrue(array1.success());
Assert::AreEqual(2, array1.getLength());
for (int i = 0; i < 2; i++)
{
JsonArray array2 = array1.getArray(i);
Assert::AreEqual(2, array2.getLength());
for (int j = 0; j < 2; j++)
{
JsonArray array3 = array2.getArray(j);
Assert::AreEqual(2, array3.getLength());
for (int k = 0; k < 2; k++)
{
Assert::AreEqual(0L, array3.getLong(k));
}
}
}
}
TEST_METHOD(OneDimensionArrayInHashTable)
{
char json[] = "{a:[0,0],b:[0,0]}";
JsonHashTable root = parser.parseHashTable(json);
Assert::IsTrue(root.success());
JsonArray arrayA = root.getArray("a");
Assert::IsTrue(arrayA.success());
Assert::AreEqual(2, arrayA.getLength());
JsonArray arrayB = root.getArray("b");
Assert::IsTrue(arrayB.success());
Assert::AreEqual(2, arrayB.getLength());
}
TEST_METHOD(TwoDimensionsArrayInHashTable)
{
char json[] = "{a:[[0],[0]],b:[[0],[0]]}";
JsonHashTable root = parser.parseHashTable(json);
Assert::IsTrue(root.success());
JsonArray arrayA = root.getArray("a");
Assert::IsTrue(arrayA.success());
Assert::AreEqual(2, arrayA.getLength());
JsonArray arrayB = root.getArray("b");
Assert::IsTrue(arrayB.success());
Assert::AreEqual(2, arrayB.getLength());
}
};
}

View File

@ -0,0 +1,238 @@
#include "CppUnitTest.h"
#include "JsonParser.h"
#include <string>
using namespace std;
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace ArduinoJsonParserTests
{
TEST_CLASS(TestGbathreeSample1)
{
char json[1024];
JsonParser<200> parser;
JsonHashTable root;
public:
TEST_METHOD_INITIALIZE(Initialize)
{
// BUG described here:
// http://forum.arduino.cc/index.php?topic=172578.msg1608219#msg1608219
strcpy(json, "{ \"protocol_name\":\"fluorescence\",\"repeats\":1,\"wait\":0,\"averages\":1,\"measurements\":3,\"meas2_light\":15,\"meas1_baseline\":0,\"act_light\":20,\"pulsesize\":25,\"pulsedistance\":10000,\"actintensity1\":50,\"actintensity2\":255,\"measintensity\":255,\"calintensity\":255,\"pulses\":[50,50,50],\"act\":[2,1,2,2],\"red\":[2,2,2,2],\"detectors\":[[34,34,34,34],[34,34,34,34],[34,34,34,34],[34,34,34,34]],\"alta\":[2,2,2,2],\"altb\":[2,2,2,2],\"measlights\":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15,15,15]],\"measlights2\":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15,15,15]],\"altc\":[2,2,2,2],\"altd\":[2,2,2,2]}");
root = parser.parseHashTable(json);
}
TEST_METHOD(Root)
{
Assert::IsTrue(root.success());
}
TEST_METHOD(ProtocolName)
{
string protocol_name = root.getString("protocol_name");
Assert::AreEqual(string("fluorescence"), protocol_name);
}
TEST_METHOD(Repeats)
{
Assert::AreEqual(1L, root.getLong("repeats"));
}
TEST_METHOD(Wait)
{
Assert::AreEqual(0L, root.getLong("wait"));
}
TEST_METHOD(Measurements)
{
Assert::AreEqual(3L, root.getLong("measurements"));
}
TEST_METHOD(Meas2_Light)
{
Assert::AreEqual(15L, root.getLong("meas2_light"));
}
TEST_METHOD(Meas1_Baseline)
{
Assert::AreEqual(0L, root.getLong("meas1_baseline"));
}
TEST_METHOD(Act_Light)
{
Assert::AreEqual(20L, root.getLong("act_light"));
}
TEST_METHOD(Pulsesize)
{
Assert::AreEqual(25L, root.getLong("pulsesize"));
}
TEST_METHOD(Pulsedistance)
{
Assert::AreEqual(10000L, root.getLong("pulsedistance"));
}
TEST_METHOD(Actintensity1)
{
Assert::AreEqual(50L, root.getLong("actintensity1"));
}
TEST_METHOD(Actintensity2)
{
Assert::AreEqual(255L, root.getLong("actintensity2"));
}
TEST_METHOD(Measintensity)
{
Assert::AreEqual(255L, root.getLong("measintensity"));
}
TEST_METHOD(Calintensity)
{
Assert::AreEqual(255L, root.getLong("calintensity"));
}
TEST_METHOD(Pulses)
{
// "pulses":[50,50,50]
JsonArray array = root.getArray("pulses");
Assert::IsTrue(array.success());
Assert::AreEqual(3, array.getLength());
for (int i = 0; i < 3; i++)
{
Assert::AreEqual(50L, array.getLong(i));
}
}
TEST_METHOD(Act)
{
// "act":[2,1,2,2]
JsonArray array = root.getArray("act");
Assert::IsTrue(array.success());
Assert::AreEqual(4, array.getLength());
Assert::AreEqual(2L, array.getLong(0));
Assert::AreEqual(1L, array.getLong(1));
Assert::AreEqual(2L, array.getLong(2));
Assert::AreEqual(2L, array.getLong(3));
}
TEST_METHOD(Detectors)
{
// "detectors":[[34,34,34,34],[34,34,34,34],[34,34,34,34],[34,34,34,34]]
JsonArray array = root.getArray("detectors");
Assert::IsTrue(array.success());
Assert::AreEqual(4, array.getLength());
for (int i = 0; i < 4; i++)
{
Assert::AreEqual(4, array.getArray(i).getLength());
for (int j = 0; j < 4; j++)
Assert::AreEqual(34L, array.getArray(i).getLong(j));
}
}
TEST_METHOD(Alta)
{
// alta:[2,2,2,2]
JsonArray array = root.getArray("alta");
Assert::IsTrue(array.success());
Assert::AreEqual(4, array.getLength());
for (int i = 0; i < 4; i++)
{
Assert::AreEqual(2L, array.getLong(i));
}
}
TEST_METHOD(Altb)
{
// altb:[2,2,2,2]
JsonArray array = root.getArray("altb");
Assert::IsTrue(array.success());
Assert::AreEqual(4, array.getLength());
for (int i = 0; i < 4; i++)
{
Assert::AreEqual(2L, array.getLong(i));
}
}
TEST_METHOD(Measlights)
{
// "measlights":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15,15,15]]
JsonArray array = root.getArray("measlights");
Assert::IsTrue(array.success());
Assert::AreEqual(4, array.getLength());
for (int i = 0; i < 4; i++)
{
Assert::AreEqual(4, array.getArray(i).getLength());
for (int j = 0; j < 4; j++)
Assert::AreEqual(15L, array.getArray(i).getLong(j));
}
}
TEST_METHOD(Measlights2)
{
// "measlights2":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15,15,15]]
JsonArray array = root.getArray("measlights2");
Assert::IsTrue(array.success());
Assert::AreEqual(4, array.getLength());
for (int i = 0; i < 4; i++)
{
Assert::AreEqual(4, array.getArray(i).getLength());
for (int j = 0; j < 4; j++)
Assert::AreEqual(15L, array.getArray(i).getLong(j));
}
}
TEST_METHOD(Altc)
{
// altc:[2,2,2,2]
JsonArray array = root.getArray("altc");
Assert::IsTrue(array.success());
Assert::AreEqual(4, array.getLength());
for (int i = 0; i < 4; i++)
{
Assert::AreEqual(2L, array.getLong(i));
}
}
TEST_METHOD(Altd)
{
// altd:[2,2,2,2]
JsonArray array = root.getArray("altd");
Assert::IsTrue(array.success());
Assert::AreEqual(4, array.getLength());
for (int i = 0; i < 4; i++)
{
Assert::AreEqual(2L, array.getLong(i));
}
}
};
}

View File

@ -0,0 +1,61 @@
#include "CppUnitTest.h"
#include "JsonParser.h"
#include <string>
using namespace std;
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace ArduinoJsonParserTests
{
TEST_CLASS(TestHashTableExample)
{
char json[128];
JsonParser<32> parser;
JsonHashTable hashTable;
public:
TEST_METHOD_INITIALIZE(Initialize)
{
strcpy(json, "{\"Name\":\"Blanchon\",\"Skills\":[\"C\",\"C++\",\"C#\"],\"Age\":32,\"Online\":true}");
hashTable = parser.parseHashTable(json);
}
TEST_METHOD(HashTable_Success_ReturnsTrue)
{
Assert::IsTrue(hashTable.success());
}
TEST_METHOD(HashTable_GetString_ReturnsExpectedValue)
{
string name = hashTable.getString("Name");
Assert::AreEqual(name, string("Blanchon"));
}
TEST_METHOD(HashTable_GetArray_ReturnsExpectedValue)
{
JsonArray skills = hashTable.getArray("Skills");
string skill0 = skills.getString(0);
Assert::AreEqual(skill0, string("C"));
string skill1 = skills.getString(1);
Assert::AreEqual(skill1, string("C++"));
string skill2 = skills.getString(2);
Assert::AreEqual(skill2, string("C#"));
}
TEST_METHOD(HashTable_GetLong_ReturnsExpectedValue)
{
int age = hashTable.getLong("Age");
Assert::AreEqual(32, age);
}
TEST_METHOD(HashTable_GetBool_ReturnsExpectedValue)
{
bool online = hashTable.getBool("Online");
Assert::AreEqual(true, online);
}
};
}