소스 검색

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

Benoit Blanchon 11 년 전
부모
커밋
507f809da0

+ 1 - 0
include/ArduinoJson/Internals/JsonParser.hpp

@@ -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 - 0
scripts/run-tests.sh

@@ -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
+
+

+ 1 - 1
src/Arduino/Print.cpp

@@ -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);
 }
 }
 
 

+ 0 - 7
src/Internals/CompactJsonWriter.cpp

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

+ 22 - 15
src/Internals/JsonParser.cpp

@@ -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 !!!
-
-  _ptr += value ? 4 : 5;
-  // 4 = strlen("true")
-  // 5 = strlen("false");
-
-  destination = value;
+  if (skip(value ? "true" : "false"))
+    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")
-
-  destination = static_cast<const char *>(NULL);
+  if (skip("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
 
 

+ 0 - 7
src/Internals/PrettyJsonWriter.cpp

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

+ 100 - 0
test/IntegrationTests.cpp

@@ -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\"}]}}}"));

+ 20 - 1
test/JsonParser_Array_Tests.cpp

@@ -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\"]");
 
 

+ 5 - 3
test/JsonParser_Object_Tests.cpp

@@ -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) {