Merge branch 'merge-parser-and-generator' of github.com:bblanchon/ArduinoJson into merge-parser-and-generator

This commit is contained in:
Benoit Blanchon
2014-11-03 11:46:49 +01:00
9 changed files with 193 additions and 34 deletions

View File

@ -22,6 +22,7 @@ class JsonParser {
bool isEnd() { return *_ptr == '\0'; } bool isEnd() { return *_ptr == '\0'; }
bool skip(char charToSkip); bool skip(char charToSkip);
bool skip(const char *wordToSkip);
void skipSpaces(); void skipSpaces();
void parseAnythingTo(JsonValue &destination); void parseAnythingTo(JsonValue &destination);

44
scripts/run-tests.sh Normal file
View File

@ -0,0 +1,44 @@
#!/bin/bash
FILE=../bin/ArduinoJsonTests.exe
MD5=""
file_changed() {
[[ ! -f "$FILE" ]] && return 1
NEW_MD5=$(md5sum $FILE)
[[ "$MD5" == "$NEW_MD5" ]] && return 1
MD5=$NEW_MD5
return 0
}
test_succeed() {
echo -en "\007"{,}
}
test_failed() {
echo -en "\007"{,,,,,,,,,,,}
}
run_tests() {
$FILE
case $? in
0)
test_succeed
;;
1)
test_failed
;;
esac
}
while true
do
if file_changed
then
run_tests
else
sleep 2
fi
done

View File

@ -19,7 +19,7 @@ size_t Print::print(const char s[]) {
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, "%.*f", digits, value);
return print(tmp); return print(tmp);
} }

View File

@ -1,7 +0,0 @@
// Copyright Benoit Blanchon 2014
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
#include "ArduinoJson/Internals/CompactJsonWriter.hpp"

View File

@ -30,6 +30,15 @@ bool JsonParser::skip(char charToSkip) {
return true; return true;
} }
bool JsonParser::skip(const char *wordToSkip) {
const char *charToSkip = wordToSkip;
while (*charToSkip && *_ptr == *charToSkip) {
charToSkip++;
_ptr++;
}
return *charToSkip == '\0';
}
void JsonParser::parseAnythingTo(JsonValue &destination) { void JsonParser::parseAnythingTo(JsonValue &destination) {
skipSpaces(); skipSpaces();
@ -74,9 +83,9 @@ void JsonParser::parseAnythingTo(JsonValue &destination) {
} }
JsonArray &JsonParser::parseArray() { JsonArray &JsonParser::parseArray() {
skip('['); if (!skip('[')) return JsonArray::invalid(); // missing opening bracket
if (isEnd()) return JsonArray::invalid(); if (isEnd()) return JsonArray::invalid(); // end of stream
JsonArray &array = _buffer->createArray(); JsonArray &array = _buffer->createArray();
if (skip(']')) return array; // empty array if (skip(']')) return array; // empty array
@ -96,13 +105,10 @@ JsonArray &JsonParser::parseArray() {
void JsonParser::parseBooleanTo(JsonValue &destination) { void JsonParser::parseBooleanTo(JsonValue &destination) {
bool value = *_ptr == 't'; bool value = *_ptr == 't';
// TODO: bug if string ends here !!! if (skip(value ? "true" : "false"))
_ptr += value ? 4 : 5;
// 4 = strlen("true")
// 5 = strlen("false");
destination = value; destination = value;
else
destination = JsonValue::invalid();
} }
void JsonParser::parseNumberTo(JsonValue &destination) { void JsonParser::parseNumberTo(JsonValue &destination) {
@ -111,9 +117,9 @@ void JsonParser::parseNumberTo(JsonValue &destination) {
if (*endOfLong == '.') { if (*endOfLong == '.') {
// stopped on a decimal separator // stopped on a decimal separator
double douleValue = strtod(_ptr, &_ptr); double doubleValue = strtod(_ptr, &_ptr);
int decimals = _ptr - endOfLong - 1; int decimals = _ptr - endOfLong - 1;
destination.set(douleValue, decimals); destination.set(doubleValue, decimals);
} else { } else {
_ptr = endOfLong; _ptr = endOfLong;
destination = longValue; destination = longValue;
@ -121,13 +127,14 @@ void JsonParser::parseNumberTo(JsonValue &destination) {
} }
void JsonParser::parseNullTo(JsonValue &destination) { void JsonParser::parseNullTo(JsonValue &destination) {
_ptr += 4; // strlen("null") if (skip("null"))
destination = static_cast<const char *>(NULL); destination = static_cast<const char *>(NULL);
else
destination = JsonValue::invalid();
} }
JsonObject &JsonParser::parseObject() { JsonObject &JsonParser::parseObject() {
skip('{'); if (!skip('{')) return JsonObject::invalid(); // missing opening brace
if (isEnd()) return JsonObject::invalid(); // premature ending if (isEnd()) return JsonObject::invalid(); // premature ending

View File

@ -1,7 +0,0 @@
// Copyright Benoit Blanchon 2014
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
#include "ArduinoJson/Internals/PrettyJsonWriter.hpp"

100
test/IntegrationTests.cpp Normal file
View File

@ -0,0 +1,100 @@
// Copyright Benoit Blanchon 2014
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
#include <gtest/gtest.h>
#include <ArduinoJson/StaticJsonBuffer.hpp>
#include <ArduinoJson/JsonArray.hpp>
#include <ArduinoJson/JsonObject.hpp>
using namespace ArduinoJson;
class IntegrationTests : public testing::TestWithParam<const char*> {
protected:
virtual void SetUp() {
_input = GetParam();
strcpy(inputBuffer, _input);
}
const char* _input;
char inputBuffer[10000];
char outputBuffer[10000];
char intermediateBuffer[10000];
StaticJsonBuffer<10000> json;
};
TEST_P(IntegrationTests, ParseThenPrint) {
json.parseObject(inputBuffer).printTo(outputBuffer, sizeof(outputBuffer));
ASSERT_STREQ(_input, outputBuffer);
}
TEST_P(IntegrationTests, ParseThenPrettyPrintThenParseThenPrint) {
json.parseObject(inputBuffer)
.prettyPrintTo(intermediateBuffer, sizeof(intermediateBuffer));
json.clear();
json.parseObject(intermediateBuffer)
.printTo(outputBuffer, sizeof(outputBuffer));
ASSERT_STREQ(_input, outputBuffer);
}
INSTANTIATE_TEST_CASE_P(
OpenWeatherMap, IntegrationTests,
testing::Values(
"{\"coord\":{\"lon\":145.77,\"lat\":-16.92},\"sys\":{\"type\":1,\"id\":"
"8166,\"message\":0.1222,\"country\":\"AU\",\"sunrise\":1414784325,"
"\"sunset\":1414830137},\"weather\":[{\"id\":801,\"main\":\"Clouds\","
"\"description\":\"few clouds\",\"icon\":\"02n\"}],\"base\":\"cmc "
"stations\",\"main\":{\"temp\":296.15,\"pressure\":1014,\"humidity\":"
"83,\"temp_min\":296.15,\"temp_max\":296.15},\"wind\":{\"speed\":2.22,"
"\"deg\":114.501},\"clouds\":{\"all\":20},\"dt\":1414846800,\"id\":"
"2172797,\"name\":\"Cairns\",\"cod\":200}"));
INSTANTIATE_TEST_CASE_P(
YahooQueryLanguage, IntegrationTests,
testing::Values(
"{\"query\":{\"count\":40,\"created\":\"2014-11-01T14:16:49Z\","
"\"lang\":\"fr-FR\",\"results\":{\"item\":[{\"title\":\"Burkina army "
"backs Zida as interim leader\"},{\"title\":\"British jets intercept "
"Russian bombers\"},{\"title\":\"Doubts chip away at nation's most "
"trusted agencies\"},{\"title\":\"Cruise ship stuck off Norway, no "
"damage\"},{\"title\":\"U.S. military launches 10 air strikes in "
"Syria, Iraq\"},{\"title\":\"Blackout hits Bangladesh as line from "
"India fails\"},{\"title\":\"Burkina Faso president in Ivory Coast "
"after ouster\"},{\"title\":\"Kurds in Turkey rally to back city "
"besieged by IS\"},{\"title\":\"A majority of Scots would vote for "
"independence now:poll\"},{\"title\":\"Tunisia elections possible "
"model for region\"},{\"title\":\"Islamic State kills 85 more members "
"of Iraqi tribe\"},{\"title\":\"Iraqi officials:IS extremists line "
"up, kill 50\"},{\"title\":\"Burkina Faso army backs presidential "
"guard official to lead transition\"},{\"title\":\"Kurdish peshmerga "
"arrive with weapons in Syria's Kobani\"},{\"title\":\"Driver sought "
"in crash that killed 3 on Halloween\"},{\"title\":\"Ex-Marine arrives "
"in US after release from Mexico jail\"},{\"title\":\"UN panel "
"scrambling to finish climate report\"},{\"title\":\"Investigators, "
"Branson go to spacecraft crash site\"},{\"title\":\"Soldiers vie for "
"power after Burkina Faso president quits\"},{\"title\":\"For a man "
"without a party, turnout is big test\"},{\"title\":\"'We just had a "
"hunch':US marshals nab Eric Frein\"},{\"title\":\"Boko Haram leader "
"threatens to kill German hostage\"},{\"title\":\"Nurse free to move "
"about as restrictions eased\"},{\"title\":\"Former Burkina president "
"Compaore arrives in Ivory Coast:sources\"},{\"title\":\"Libyan port "
"rebel leader refuses to hand over oil ports to rival "
"group\"},{\"title\":\"Iraqi peshmerga fighters prepare for Syria "
"battle\"},{\"title\":\"1 Dem Senate candidate welcoming Obama's "
"help\"},{\"title\":\"Bikers cancel party after police recover "
"bar\"},{\"title\":\"New question in Texas:Can Davis survive "
"defeat?\"},{\"title\":\"Ukraine rebels to hold election, despite "
"criticism\"},{\"title\":\"Iraqi officials say Islamic State group "
"lines up, kills 50 tribesmen, women in Anbar "
"province\"},{\"title\":\"James rebounds, leads Cavaliers past "
"Bulls\"},{\"title\":\"UK warns travelers they could be terror "
"targets\"},{\"title\":\"Hello Kitty celebrates 40th "
"birthday\"},{\"title\":\"A look at people killed during space "
"missions\"},{\"title\":\"Nigeria's purported Boko Haram leader says "
"has 'married off' girls:AFP\"},{\"title\":\"Mexico orders immediate "
"release of Marine veteran\"},{\"title\":\"As election closes in, "
"Obama on center stage\"},{\"title\":\"Body of Zambian president "
"arrives home\"},{\"title\":\"South Africa arrests 2 Vietnamese for "
"poaching\"}]}}}"));

View File

@ -58,9 +58,13 @@ TEST_F(JsonParser_Array_Tests, EmptyArray) {
sizeMustBe(0); sizeMustBe(0);
} }
TEST_F(JsonParser_Array_Tests, MissingOpeningBracket) {
whenInputIs("]");
parseMustFail();
}
TEST_F(JsonParser_Array_Tests, ArrayWithNoEnd) { TEST_F(JsonParser_Array_Tests, ArrayWithNoEnd) {
whenInputIs("["); whenInputIs("[");
parseMustFail(); parseMustFail();
} }
@ -139,6 +143,21 @@ TEST_F(JsonParser_Array_Tests, TwoNulls) {
secondElementMustBe(nullCharPtr); secondElementMustBe(nullCharPtr);
} }
TEST_F(JsonParser_Array_Tests, IncompleteNull) {
whenInputIs("[nul!]");
parseMustFail();
}
TEST_F(JsonParser_Array_Tests, IncompleteTrue) {
whenInputIs("[tru!]");
parseMustFail();
}
TEST_F(JsonParser_Array_Tests, IncompleteFalse) {
whenInputIs("[fals!]");
parseMustFail();
}
TEST_F(JsonParser_Array_Tests, TwoStrings) { TEST_F(JsonParser_Array_Tests, TwoStrings) {
whenInputIs("[\"hello\",\"world\"]"); whenInputIs("[\"hello\",\"world\"]");

View File

@ -45,22 +45,24 @@ TEST_F(JsonParser_Object_Test, EmptyObject) {
sizeMustBe(0); sizeMustBe(0);
} }
TEST_F(JsonParser_Object_Test, MissingOpeningBrace) {
whenInputIs("}");
parseMustFail();
}
TEST_F(JsonParser_Object_Test, MissingClosingBrace) { TEST_F(JsonParser_Object_Test, MissingClosingBrace) {
whenInputIs("{"); whenInputIs("{");
parseMustFail(); parseMustFail();
sizeMustBe(0);
} }
TEST_F(JsonParser_Object_Test, MissingColonAndValue) { TEST_F(JsonParser_Object_Test, MissingColonAndValue) {
whenInputIs("{\"key\"}"); whenInputIs("{\"key\"}");
parseMustFail(); parseMustFail();
sizeMustBe(0);
} }
TEST_F(JsonParser_Object_Test, MissingQuotesAndColonAndValue) { TEST_F(JsonParser_Object_Test, MissingQuotesAndColonAndValue) {
whenInputIs("{key}"); whenInputIs("{key}");
parseMustFail(); parseMustFail();
sizeMustBe(0);
} }
TEST_F(JsonParser_Object_Test, OneString) { TEST_F(JsonParser_Object_Test, OneString) {