Permet de lire les données de la passerelle enphase pour piloter la chauffe d'un cumulus via un relais statique.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

319 lines
8.7 KiB

// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
#include "Allocators.hpp"
using ArduinoJson::detail::sizeofArray;
TEST_CASE("deserialize JSON array") {
SpyingAllocator spy;
JsonDocument doc(&spy);
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]");
spy.clearLog();
deserializeJson(doc, "[]");
JsonArray arr = doc.as<JsonArray>();
REQUIRE(arr.size() == 0);
REQUIRE(spy.log() == AllocatorLog{
Deallocate(sizeofArray(4)),
});
}
}
TEST_CASE("deserialize JSON array under memory constraints") {
TimebombAllocator timebomb(100);
SpyingAllocator spy(&timebomb);
JsonDocument doc(&spy);
SECTION("empty array requires no allocation") {
timebomb.setCountdown(0);
char input[] = "[]";
DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == DeserializationError::Ok);
}
SECTION("allocation of pool list fails") {
timebomb.setCountdown(0);
char input[] = "[1]";
DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == DeserializationError::NoMemory);
REQUIRE(doc.as<std::string>() == "[]");
}
SECTION("allocation of pool fails") {
timebomb.setCountdown(0);
char input[] = "[1]";
DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == DeserializationError::NoMemory);
REQUIRE(doc.as<std::string>() == "[]");
}
SECTION("allocation of string fails in array") {
timebomb.setCountdown(1);
char input[] = "[0,\"hi!\"]";
DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == DeserializationError::NoMemory);
REQUIRE(doc.as<std::string>() == "[0,null]");
}
SECTION("don't store space characters") {
deserializeJson(doc, " [ \"1234567\" ] ");
REQUIRE(spy.log() ==
AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("1234567")),
Reallocate(sizeofPool(), sizeofArray(1)),
});
}
}