mirror of
				https://github.com/bblanchon/ArduinoJson.git
				synced 2025-11-04 08:31:36 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			341 lines
		
	
	
		
			9.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			341 lines
		
	
	
		
			9.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// ArduinoJson - https://arduinojson.org
 | 
						|
// Copyright © 2014-2023, Benoit BLANCHON
 | 
						|
// MIT License
 | 
						|
 | 
						|
#include <ArduinoJson.h>
 | 
						|
#include <catch.hpp>
 | 
						|
 | 
						|
using ArduinoJson::detail::sizeofArray;
 | 
						|
using ArduinoJson::detail::sizeofObject;
 | 
						|
using ArduinoJson::detail::sizeofString;
 | 
						|
 | 
						|
TEST_CASE("deserialize JSON array") {
 | 
						|
  JsonDocument doc(4096);
 | 
						|
 | 
						|
  SECTION("An empty array") {
 | 
						|
    DeserializationError err = deserializeJson(doc, "[]");
 | 
						|
    JsonArray arr = doc.as<JsonArray>();
 | 
						|
 | 
						|
    REQUIRE(err == DeserializationError::Ok);
 | 
						|
    REQUIRE(0 == arr.size());
 | 
						|
  }
 | 
						|
 | 
						|
  SECTION("Spaces") {
 | 
						|
    SECTION("Before the opening bracket") {
 | 
						|
      DeserializationError err = deserializeJson(doc, "  []");
 | 
						|
      JsonArray arr = doc.as<JsonArray>();
 | 
						|
 | 
						|
      REQUIRE(err == DeserializationError::Ok);
 | 
						|
      REQUIRE(0 == arr.size());
 | 
						|
    }
 | 
						|
 | 
						|
    SECTION("Before first value") {
 | 
						|
      DeserializationError err = deserializeJson(doc, "[ \t\r\n42]");
 | 
						|
      JsonArray arr = doc.as<JsonArray>();
 | 
						|
 | 
						|
      REQUIRE(err == DeserializationError::Ok);
 | 
						|
      REQUIRE(1 == arr.size());
 | 
						|
      REQUIRE(arr[0] == 42);
 | 
						|
    }
 | 
						|
 | 
						|
    SECTION("After first value") {
 | 
						|
      DeserializationError err = deserializeJson(doc, "[42 \t\r\n]");
 | 
						|
      JsonArray arr = doc.as<JsonArray>();
 | 
						|
 | 
						|
      REQUIRE(err == DeserializationError::Ok);
 | 
						|
      REQUIRE(1 == arr.size());
 | 
						|
      REQUIRE(arr[0] == 42);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  SECTION("Values types") {
 | 
						|
    SECTION("On integer") {
 | 
						|
      DeserializationError err = deserializeJson(doc, "[42]");
 | 
						|
      JsonArray arr = doc.as<JsonArray>();
 | 
						|
 | 
						|
      REQUIRE(err == DeserializationError::Ok);
 | 
						|
      REQUIRE(1 == arr.size());
 | 
						|
      REQUIRE(arr[0] == 42);
 | 
						|
    }
 | 
						|
 | 
						|
    SECTION("Two integers") {
 | 
						|
      DeserializationError err = deserializeJson(doc, "[42,84]");
 | 
						|
      JsonArray arr = doc.as<JsonArray>();
 | 
						|
 | 
						|
      REQUIRE(err == DeserializationError::Ok);
 | 
						|
      REQUIRE(2 == arr.size());
 | 
						|
      REQUIRE(arr[0] == 42);
 | 
						|
      REQUIRE(arr[1] == 84);
 | 
						|
    }
 | 
						|
 | 
						|
    SECTION("Double") {
 | 
						|
      DeserializationError err = deserializeJson(doc, "[4.2,1e2]");
 | 
						|
      JsonArray arr = doc.as<JsonArray>();
 | 
						|
 | 
						|
      REQUIRE(err == DeserializationError::Ok);
 | 
						|
      REQUIRE(2 == arr.size());
 | 
						|
      REQUIRE(arr[0] == 4.2);
 | 
						|
      REQUIRE(arr[1] == 1e2);
 | 
						|
    }
 | 
						|
 | 
						|
    SECTION("Unsigned long") {
 | 
						|
      DeserializationError err = deserializeJson(doc, "[4294967295]");
 | 
						|
      JsonArray arr = doc.as<JsonArray>();
 | 
						|
 | 
						|
      REQUIRE(err == DeserializationError::Ok);
 | 
						|
      REQUIRE(1 == arr.size());
 | 
						|
      REQUIRE(arr[0] == 4294967295UL);
 | 
						|
    }
 | 
						|
 | 
						|
    SECTION("Boolean") {
 | 
						|
      DeserializationError err = deserializeJson(doc, "[true,false]");
 | 
						|
      JsonArray arr = doc.as<JsonArray>();
 | 
						|
 | 
						|
      REQUIRE(err == DeserializationError::Ok);
 | 
						|
      REQUIRE(2 == arr.size());
 | 
						|
      REQUIRE(arr[0] == true);
 | 
						|
      REQUIRE(arr[1] == false);
 | 
						|
    }
 | 
						|
 | 
						|
    SECTION("Null") {
 | 
						|
      DeserializationError err = deserializeJson(doc, "[null,null]");
 | 
						|
      JsonArray arr = doc.as<JsonArray>();
 | 
						|
 | 
						|
      REQUIRE(err == DeserializationError::Ok);
 | 
						|
      REQUIRE(2 == arr.size());
 | 
						|
      REQUIRE(arr[0].as<const char*>() == 0);
 | 
						|
      REQUIRE(arr[1].as<const char*>() == 0);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  SECTION("Quotes") {
 | 
						|
    SECTION("Double quotes") {
 | 
						|
      DeserializationError err =
 | 
						|
          deserializeJson(doc, "[ \"hello\" , \"world\" ]");
 | 
						|
      JsonArray arr = doc.as<JsonArray>();
 | 
						|
 | 
						|
      REQUIRE(err == DeserializationError::Ok);
 | 
						|
      REQUIRE(2 == arr.size());
 | 
						|
      REQUIRE(arr[0] == "hello");
 | 
						|
      REQUIRE(arr[1] == "world");
 | 
						|
    }
 | 
						|
 | 
						|
    SECTION("Single quotes") {
 | 
						|
      DeserializationError err = deserializeJson(doc, "[ 'hello' , 'world' ]");
 | 
						|
      JsonArray arr = doc.as<JsonArray>();
 | 
						|
 | 
						|
      REQUIRE(err == DeserializationError::Ok);
 | 
						|
      REQUIRE(2 == arr.size());
 | 
						|
      REQUIRE(arr[0] == "hello");
 | 
						|
      REQUIRE(arr[1] == "world");
 | 
						|
    }
 | 
						|
 | 
						|
    SECTION("No quotes") {
 | 
						|
      DeserializationError err = deserializeJson(doc, "[ hello , world ]");
 | 
						|
      REQUIRE(err == DeserializationError::InvalidInput);
 | 
						|
    }
 | 
						|
 | 
						|
    SECTION("Double quotes (empty strings)") {
 | 
						|
      DeserializationError err = deserializeJson(doc, "[\"\",\"\"]");
 | 
						|
      JsonArray arr = doc.as<JsonArray>();
 | 
						|
 | 
						|
      REQUIRE(err == DeserializationError::Ok);
 | 
						|
      REQUIRE(2 == arr.size());
 | 
						|
      REQUIRE(arr[0] == "");
 | 
						|
      REQUIRE(arr[1] == "");
 | 
						|
    }
 | 
						|
 | 
						|
    SECTION("Single quotes (empty strings)") {
 | 
						|
      DeserializationError err = deserializeJson(doc, "[\'\',\'\']");
 | 
						|
      JsonArray arr = doc.as<JsonArray>();
 | 
						|
 | 
						|
      REQUIRE(err == DeserializationError::Ok);
 | 
						|
      REQUIRE(2 == arr.size());
 | 
						|
      REQUIRE(arr[0] == "");
 | 
						|
      REQUIRE(arr[1] == "");
 | 
						|
    }
 | 
						|
 | 
						|
    SECTION("No quotes (empty strings)") {
 | 
						|
      DeserializationError err = deserializeJson(doc, "[,]");
 | 
						|
 | 
						|
      REQUIRE(err == DeserializationError::InvalidInput);
 | 
						|
    }
 | 
						|
 | 
						|
    SECTION("Closing single quotes missing") {
 | 
						|
      DeserializationError err = deserializeJson(doc, "[\"]");
 | 
						|
 | 
						|
      REQUIRE(err == DeserializationError::IncompleteInput);
 | 
						|
    }
 | 
						|
 | 
						|
    SECTION("Closing double quotes missing") {
 | 
						|
      DeserializationError err = deserializeJson(doc, "[\']");
 | 
						|
 | 
						|
      REQUIRE(err == DeserializationError::IncompleteInput);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  SECTION("Premature null-terminator") {
 | 
						|
    SECTION("After opening bracket") {
 | 
						|
      DeserializationError err = deserializeJson(doc, "[");
 | 
						|
 | 
						|
      REQUIRE(err == DeserializationError::IncompleteInput);
 | 
						|
    }
 | 
						|
 | 
						|
    SECTION("After value") {
 | 
						|
      DeserializationError err = deserializeJson(doc, "[1");
 | 
						|
 | 
						|
      REQUIRE(err == DeserializationError::IncompleteInput);
 | 
						|
    }
 | 
						|
 | 
						|
    SECTION("After comma") {
 | 
						|
      DeserializationError err = deserializeJson(doc, "[1,");
 | 
						|
 | 
						|
      REQUIRE(err == DeserializationError::IncompleteInput);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  SECTION("Premature end of input") {
 | 
						|
    const char* input = "[1,2]";
 | 
						|
 | 
						|
    SECTION("After opening bracket") {
 | 
						|
      DeserializationError err = deserializeJson(doc, input, 1);
 | 
						|
 | 
						|
      REQUIRE(err == DeserializationError::IncompleteInput);
 | 
						|
    }
 | 
						|
 | 
						|
    SECTION("After value") {
 | 
						|
      DeserializationError err = deserializeJson(doc, input, 2);
 | 
						|
 | 
						|
      REQUIRE(err == DeserializationError::IncompleteInput);
 | 
						|
    }
 | 
						|
 | 
						|
    SECTION("After comma") {
 | 
						|
      DeserializationError err = deserializeJson(doc, input, 3);
 | 
						|
 | 
						|
      REQUIRE(err == DeserializationError::IncompleteInput);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  SECTION("Misc") {
 | 
						|
    SECTION("Nested objects") {
 | 
						|
      char jsonString[] =
 | 
						|
          " [ { \"a\" : 1 , \"b\" : 2 } , { \"c\" : 3 , \"d\" : 4 } ] ";
 | 
						|
 | 
						|
      DeserializationError err = deserializeJson(doc, jsonString);
 | 
						|
      JsonArray arr = doc.as<JsonArray>();
 | 
						|
 | 
						|
      JsonObject object1 = arr[0];
 | 
						|
      const JsonObject object2 = arr[1];
 | 
						|
      JsonObject object3 = arr[2];
 | 
						|
 | 
						|
      REQUIRE(err == DeserializationError::Ok);
 | 
						|
 | 
						|
      REQUIRE(object1.isNull() == false);
 | 
						|
      REQUIRE(object2.isNull() == false);
 | 
						|
      REQUIRE(object3.isNull() == true);
 | 
						|
 | 
						|
      REQUIRE(2 == object1.size());
 | 
						|
      REQUIRE(2 == object2.size());
 | 
						|
      REQUIRE(0 == object3.size());
 | 
						|
 | 
						|
      REQUIRE(1 == object1["a"].as<int>());
 | 
						|
      REQUIRE(2 == object1["b"].as<int>());
 | 
						|
      REQUIRE(3 == object2["c"].as<int>());
 | 
						|
      REQUIRE(4 == object2["d"].as<int>());
 | 
						|
      REQUIRE(0 == object3["e"].as<int>());
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  SECTION("Should clear the JsonArray") {
 | 
						|
    deserializeJson(doc, "[1,2,3,4]");
 | 
						|
    deserializeJson(doc, "[]");
 | 
						|
    JsonArray arr = doc.as<JsonArray>();
 | 
						|
 | 
						|
    REQUIRE(arr.size() == 0);
 | 
						|
    REQUIRE(doc.memoryUsage() == sizeofArray(0));
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
TEST_CASE("deserialize JSON array under memory constraints") {
 | 
						|
  SECTION("buffer of the right size for an empty array") {
 | 
						|
    JsonDocument doc(sizeofArray(0));
 | 
						|
    char input[] = "[]";
 | 
						|
 | 
						|
    DeserializationError err = deserializeJson(doc, input);
 | 
						|
 | 
						|
    REQUIRE(err == DeserializationError::Ok);
 | 
						|
  }
 | 
						|
 | 
						|
  SECTION("buffer too small for an array with one element") {
 | 
						|
    JsonDocument doc(sizeofArray(0));
 | 
						|
    char input[] = "[1]";
 | 
						|
 | 
						|
    DeserializationError err = deserializeJson(doc, input);
 | 
						|
 | 
						|
    REQUIRE(err == DeserializationError::NoMemory);
 | 
						|
  }
 | 
						|
 | 
						|
  SECTION("buffer of the right size for an array with one element") {
 | 
						|
    JsonDocument doc(sizeofArray(1));
 | 
						|
    char input[] = "[1]";
 | 
						|
 | 
						|
    DeserializationError err = deserializeJson(doc, input);
 | 
						|
 | 
						|
    REQUIRE(err == DeserializationError::Ok);
 | 
						|
  }
 | 
						|
 | 
						|
  SECTION("buffer too small for an array with a nested object") {
 | 
						|
    JsonDocument doc(sizeofArray(0) + sizeofObject(0));
 | 
						|
    char input[] = "[{}]";
 | 
						|
 | 
						|
    DeserializationError err = deserializeJson(doc, input);
 | 
						|
 | 
						|
    REQUIRE(err == DeserializationError::NoMemory);
 | 
						|
  }
 | 
						|
 | 
						|
  SECTION("buffer of the right size for an array with a nested object") {
 | 
						|
    JsonDocument doc(sizeofArray(1) + sizeofObject(0));
 | 
						|
    char input[] = "[{}]";
 | 
						|
 | 
						|
    DeserializationError err = deserializeJson(doc, input);
 | 
						|
 | 
						|
    REQUIRE(err == DeserializationError::Ok);
 | 
						|
  }
 | 
						|
 | 
						|
  SECTION("don't store space characters") {
 | 
						|
    JsonDocument doc(100);
 | 
						|
 | 
						|
    deserializeJson(doc, "  [ \"1234567\" ] ");
 | 
						|
 | 
						|
    REQUIRE(sizeofArray(1) + sizeofString(7) == doc.memoryUsage());
 | 
						|
    // note: we use a string of 8 bytes to be sure that the MemoryPool
 | 
						|
    // will not insert bytes to enforce alignement
 | 
						|
  }
 | 
						|
 | 
						|
  SECTION("Should clear the JsonArray") {
 | 
						|
    JsonDocument doc(sizeofArray(4));
 | 
						|
    char input[] = "[1,2,3,4]";
 | 
						|
 | 
						|
    deserializeJson(doc, input);
 | 
						|
    deserializeJson(doc, "[]");
 | 
						|
 | 
						|
    JsonArray arr = doc.as<JsonArray>();
 | 
						|
    REQUIRE(arr.size() == 0);
 | 
						|
    REQUIRE(doc.memoryUsage() == sizeofArray(0));
 | 
						|
  }
 | 
						|
 | 
						|
  SECTION("buffer of the right size for an array with two element") {
 | 
						|
    JsonDocument doc(sizeofArray(2));
 | 
						|
    char input[] = "[1,2]";
 | 
						|
 | 
						|
    DeserializationError err = deserializeJson(doc, input);
 | 
						|
    JsonArray arr = doc.as<JsonArray>();
 | 
						|
 | 
						|
    REQUIRE(err == DeserializationError::Ok);
 | 
						|
    REQUIRE(doc.is<JsonArray>());
 | 
						|
    REQUIRE(doc.memoryUsage() == sizeofArray(2));
 | 
						|
    REQUIRE(arr[0] == 1);
 | 
						|
    REQUIRE(arr[1] == 2);
 | 
						|
  }
 | 
						|
}
 |