mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 08:42:39 +01:00 
			
		
		
		
	Added support for custom converters (closes #687)
This commit is contained in:
		| @@ -9,6 +9,7 @@ add_executable(JsonVariantTests | ||||
| 	compare.cpp | ||||
| 	containsKey.cpp | ||||
| 	copy.cpp | ||||
| 	converters.cpp | ||||
| 	createNested.cpp | ||||
| 	is.cpp | ||||
| 	isnull.cpp | ||||
|   | ||||
							
								
								
									
										144
									
								
								extras/tests/JsonVariant/converters.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								extras/tests/JsonVariant/converters.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,144 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2021 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <stdint.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| namespace { | ||||
| struct Date { | ||||
|   int day; | ||||
|   int month; | ||||
|   int year; | ||||
| }; | ||||
|  | ||||
| bool convertToJson(JsonVariant variant, const Date& date) { | ||||
|   variant["day"] = date.day; | ||||
|   variant["month"] = date.month; | ||||
|   variant["year"] = date.year; | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| void convertFromJson(Date& date, JsonVariantConst variant) { | ||||
|   date.day = variant["day"]; | ||||
|   date.month = variant["month"]; | ||||
|   date.year = variant["year"]; | ||||
| } | ||||
|  | ||||
| bool canConvertFromJson(Date&, JsonVariantConst variant) { | ||||
|   return variant["day"].is<int>() && variant["month"].is<int>() && | ||||
|          variant["year"].is<int>(); | ||||
| } | ||||
| }  // namespace | ||||
|  | ||||
| TEST_CASE("Custom converter with overloading") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
|   SECTION("convert JSON to Date") { | ||||
|     doc["date"]["day"] = 2; | ||||
|     doc["date"]["month"] = 3; | ||||
|     doc["date"]["year"] = 2021; | ||||
|  | ||||
|     Date date = doc["date"]; | ||||
|  | ||||
|     REQUIRE(date.day == 2); | ||||
|     REQUIRE(date.month == 3); | ||||
|     REQUIRE(date.year == 2021); | ||||
|   } | ||||
|  | ||||
|   SECTION("is<Date>() returns true") { | ||||
|     doc["date"]["day"] = 2; | ||||
|     doc["date"]["month"] = 3; | ||||
|     doc["date"]["year"] = 2021; | ||||
|  | ||||
|     REQUIRE(doc["date"].is<Date>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("is<Date>() returns false") { | ||||
|     doc["date"]["day"] = 2; | ||||
|     doc["date"]["month"] = 3; | ||||
|     doc["date"]["year"] = "2021"; | ||||
|  | ||||
|     REQUIRE(doc["date"].is<Date>() == false); | ||||
|   } | ||||
|  | ||||
|   SECTION("convert Date to JSON") { | ||||
|     Date date = {19, 3, 2021}; | ||||
|     doc["date"] = date; | ||||
|  | ||||
|     REQUIRE(doc["date"]["day"] == 19); | ||||
|     REQUIRE(doc["date"]["month"] == 3); | ||||
|     REQUIRE(doc["date"]["year"] == 2021); | ||||
|   } | ||||
| } | ||||
|  | ||||
| class Complex { | ||||
|  public: | ||||
|   explicit Complex(double r, double i) : _real(r), _imag(i) {} | ||||
|  | ||||
|   double real() const { | ||||
|     return _real; | ||||
|   } | ||||
|  | ||||
|   double imag() const { | ||||
|     return _imag; | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   double _real, _imag; | ||||
| }; | ||||
|  | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
| template <> | ||||
| struct Converter<Complex> { | ||||
|   static bool toJson(VariantRef variant, const Complex& value) { | ||||
|     variant["real"] = value.real(); | ||||
|     variant["imag"] = value.imag(); | ||||
|     return true; | ||||
|   } | ||||
|  | ||||
|   static Complex fromJson(VariantConstRef variant) { | ||||
|     return Complex(variant["real"], variant["imag"]); | ||||
|   } | ||||
|  | ||||
|   static bool checkJson(VariantConstRef variant) { | ||||
|     return variant["real"].is<double>() && variant["imag"].is<double>(); | ||||
|   } | ||||
| }; | ||||
| }  // namespace ARDUINOJSON_NAMESPACE | ||||
|  | ||||
| TEST_CASE("Custom converter with specialization") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
|   SECTION("convert JSON to Complex") { | ||||
|     doc["value"]["real"] = 2; | ||||
|     doc["value"]["imag"] = 3; | ||||
|  | ||||
|     Complex value = doc["value"]; | ||||
|  | ||||
|     REQUIRE(value.real() == 2); | ||||
|     REQUIRE(value.imag() == 3); | ||||
|   } | ||||
|  | ||||
|   SECTION("is<Complex>() returns true") { | ||||
|     doc["value"]["real"] = 2; | ||||
|     doc["value"]["imag"] = 3; | ||||
|  | ||||
|     REQUIRE(doc["value"].is<Complex>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("is<Complex>() returns false") { | ||||
|     doc["value"]["real"] = 2; | ||||
|     doc["value"]["imag"] = "3"; | ||||
|  | ||||
|     REQUIRE(doc["value"].is<Complex>() == false); | ||||
|   } | ||||
|  | ||||
|   SECTION("convert value to JSON") { | ||||
|     doc["value"] = Complex(19, 3); | ||||
|  | ||||
|     REQUIRE(doc["value"]["real"] == 19); | ||||
|     REQUIRE(doc["value"]["imag"] == 3); | ||||
|   } | ||||
| } | ||||
| @@ -19,7 +19,7 @@ TEST_CASE("JsonVariant::is<T>()") { | ||||
|     CHECK(variant.is<JsonVariant>() == false); | ||||
|     CHECK(variant.is<JsonVariantConst>() == false); | ||||
|     CHECK(variant.is<bool>() == false); | ||||
|     CHECK(variant.is<char *>() == false); | ||||
|     CHECK(variant.is<const char *>() == false); | ||||
|     CHECK(variant.is<int>() == false); | ||||
|     CHECK(variant.is<std::string>() == false); | ||||
|     CHECK(variant.is<float>() == false); | ||||
| @@ -32,7 +32,7 @@ TEST_CASE("JsonVariant::is<T>()") { | ||||
|     CHECK(variant.is<JsonObject>() == false); | ||||
|     CHECK(variant.is<JsonArray>() == false); | ||||
|     CHECK(variant.is<bool>() == false); | ||||
|     CHECK(variant.is<char *>() == false); | ||||
|     CHECK(variant.is<const char *>() == false); | ||||
|     CHECK(variant.is<int>() == false); | ||||
|     CHECK(variant.is<std::string>() == false); | ||||
|     CHECK(variant.is<float>() == false); | ||||
| @@ -47,7 +47,7 @@ TEST_CASE("JsonVariant::is<T>()") { | ||||
|     CHECK(variant.is<JsonVariantConst>() == true); | ||||
|     CHECK(variant.is<JsonObject>() == false); | ||||
|     CHECK(variant.is<JsonArray>() == false); | ||||
|     CHECK(variant.is<char *>() == false); | ||||
|     CHECK(variant.is<const char *>() == false); | ||||
|     CHECK(variant.is<int>() == false); | ||||
|     CHECK(variant.is<std::string>() == false); | ||||
|     CHECK(variant.is<float>() == false); | ||||
| @@ -62,7 +62,7 @@ TEST_CASE("JsonVariant::is<T>()") { | ||||
|     CHECK(variant.is<JsonVariantConst>() == true); | ||||
|     CHECK(variant.is<JsonObject>() == false); | ||||
|     CHECK(variant.is<JsonArray>() == false); | ||||
|     CHECK(variant.is<char *>() == false); | ||||
|     CHECK(variant.is<const char *>() == false); | ||||
|     CHECK(variant.is<int>() == false); | ||||
|     CHECK(variant.is<std::string>() == false); | ||||
|     CHECK(variant.is<float>() == false); | ||||
| @@ -83,7 +83,7 @@ TEST_CASE("JsonVariant::is<T>()") { | ||||
|     CHECK(variant.is<bool>() == false); | ||||
|     CHECK(variant.is<JsonObject>() == false); | ||||
|     CHECK(variant.is<JsonArray>() == false); | ||||
|     CHECK(variant.is<char *>() == false); | ||||
|     CHECK(variant.is<const char *>() == false); | ||||
|     CHECK(variant.is<std::string>() == false); | ||||
|   } | ||||
|  | ||||
| @@ -97,7 +97,7 @@ TEST_CASE("JsonVariant::is<T>()") { | ||||
|     CHECK(variant.is<bool>() == false); | ||||
|     CHECK(variant.is<JsonObject>() == false); | ||||
|     CHECK(variant.is<JsonArray>() == false); | ||||
|     CHECK(variant.is<char *>() == false); | ||||
|     CHECK(variant.is<const char *>() == false); | ||||
|     CHECK(variant.is<int>() == false); | ||||
|     CHECK(variant.is<std::string>() == false); | ||||
|     CHECK(variant.is<MYENUM2>() == false); | ||||
| @@ -106,7 +106,7 @@ TEST_CASE("JsonVariant::is<T>()") { | ||||
|   SECTION("const char*") { | ||||
|     variant.set("4.2"); | ||||
|  | ||||
|     CHECK(variant.is<char *>() == true); | ||||
|     CHECK(variant.is<const char *>() == true); | ||||
|     CHECK(variant.is<const char *>() == true); | ||||
|     CHECK(variant.is<std::string>() == true); | ||||
|     CHECK(variant.is<JsonVariant>() == true); | ||||
| @@ -132,7 +132,7 @@ TEST_CASE("JsonVariant::is<T>()") { | ||||
|     CHECK(variant.is<int>() == false); | ||||
|     CHECK(variant.is<float>() == false); | ||||
|     CHECK(variant.is<bool>() == false); | ||||
|     CHECK(variant.is<char *>() == false); | ||||
|     CHECK(variant.is<const char *>() == false); | ||||
|     CHECK(variant.is<MYENUM2>() == false); | ||||
|   } | ||||
|  | ||||
| @@ -148,7 +148,7 @@ TEST_CASE("JsonVariant::is<T>()") { | ||||
|     CHECK(variant.is<int>() == false); | ||||
|     CHECK(variant.is<float>() == false); | ||||
|     CHECK(variant.is<bool>() == false); | ||||
|     CHECK(variant.is<char *>() == false); | ||||
|     CHECK(variant.is<const char *>() == false); | ||||
|     CHECK(variant.is<MYENUM2>() == false); | ||||
|     CHECK(variant.is<JsonVariant>() == true); | ||||
|     CHECK(variant.is<JsonVariantConst>() == true); | ||||
| @@ -170,7 +170,7 @@ TEST_CASE("JsonVariantConst::is<T>()") { | ||||
|     CHECK(cvariant.is<JsonVariant>() == false); | ||||
|     CHECK(cvariant.is<JsonVariantConst>() == false); | ||||
|     CHECK(cvariant.is<bool>() == false); | ||||
|     CHECK(cvariant.is<char *>() == false); | ||||
|     CHECK(cvariant.is<const char *>() == false); | ||||
|     CHECK(cvariant.is<int>() == false); | ||||
|     CHECK(cvariant.is<std::string>() == false); | ||||
|     CHECK(cvariant.is<float>() == false); | ||||
| @@ -183,7 +183,7 @@ TEST_CASE("JsonVariantConst::is<T>()") { | ||||
|     CHECK(cvariant.is<JsonArray>() == false); | ||||
|     CHECK(cvariant.is<JsonVariant>() == false); | ||||
|     CHECK(cvariant.is<bool>() == false); | ||||
|     CHECK(cvariant.is<char *>() == false); | ||||
|     CHECK(cvariant.is<const char *>() == false); | ||||
|     CHECK(cvariant.is<int>() == false); | ||||
|     CHECK(cvariant.is<std::string>() == false); | ||||
|     CHECK(cvariant.is<float>() == false); | ||||
| @@ -198,7 +198,7 @@ TEST_CASE("JsonVariantConst::is<T>()") { | ||||
|     CHECK(cvariant.is<JsonVariant>() == false); | ||||
|     CHECK(cvariant.is<JsonObject>() == false); | ||||
|     CHECK(cvariant.is<JsonArray>() == false); | ||||
|     CHECK(cvariant.is<char *>() == false); | ||||
|     CHECK(cvariant.is<const char *>() == false); | ||||
|     CHECK(cvariant.is<int>() == false); | ||||
|     CHECK(cvariant.is<std::string>() == false); | ||||
|     CHECK(cvariant.is<float>() == false); | ||||
| @@ -213,7 +213,7 @@ TEST_CASE("JsonVariantConst::is<T>()") { | ||||
|     CHECK(cvariant.is<JsonVariant>() == false); | ||||
|     CHECK(cvariant.is<JsonObject>() == false); | ||||
|     CHECK(cvariant.is<JsonArray>() == false); | ||||
|     CHECK(cvariant.is<char *>() == false); | ||||
|     CHECK(cvariant.is<const char *>() == false); | ||||
|     CHECK(cvariant.is<int>() == false); | ||||
|     CHECK(cvariant.is<std::string>() == false); | ||||
|     CHECK(cvariant.is<float>() == false); | ||||
| @@ -234,7 +234,7 @@ TEST_CASE("JsonVariantConst::is<T>()") { | ||||
|     CHECK(cvariant.is<JsonObject>() == false); | ||||
|     CHECK(cvariant.is<JsonArray>() == false); | ||||
|     CHECK(cvariant.is<JsonVariant>() == false); | ||||
|     CHECK(cvariant.is<char *>() == false); | ||||
|     CHECK(cvariant.is<const char *>() == false); | ||||
|     CHECK(cvariant.is<std::string>() == false); | ||||
|   } | ||||
|  | ||||
| @@ -248,7 +248,7 @@ TEST_CASE("JsonVariantConst::is<T>()") { | ||||
|     CHECK(cvariant.is<JsonObject>() == false); | ||||
|     CHECK(cvariant.is<JsonArray>() == false); | ||||
|     CHECK(cvariant.is<JsonVariant>() == false); | ||||
|     CHECK(cvariant.is<char *>() == false); | ||||
|     CHECK(cvariant.is<const char *>() == false); | ||||
|     CHECK(cvariant.is<int>() == false); | ||||
|     CHECK(cvariant.is<std::string>() == false); | ||||
|     CHECK(cvariant.is<MYENUM2>() == false); | ||||
| @@ -257,7 +257,7 @@ TEST_CASE("JsonVariantConst::is<T>()") { | ||||
|   SECTION("const char*") { | ||||
|     variant.set("4.2"); | ||||
|  | ||||
|     CHECK(cvariant.is<char *>() == true); | ||||
|     CHECK(cvariant.is<const char *>() == true); | ||||
|     CHECK(cvariant.is<const char *>() == true); | ||||
|     CHECK(cvariant.is<std::string>() == true); | ||||
|     CHECK(cvariant.is<double>() == false); | ||||
| @@ -282,7 +282,7 @@ TEST_CASE("JsonVariantConst::is<T>()") { | ||||
|     CHECK(cvariant.is<int>() == false); | ||||
|     CHECK(cvariant.is<float>() == false); | ||||
|     CHECK(cvariant.is<bool>() == false); | ||||
|     CHECK(cvariant.is<char *>() == false); | ||||
|     CHECK(cvariant.is<const char *>() == false); | ||||
|     CHECK(cvariant.is<MYENUM2>() == false); | ||||
|   } | ||||
|  | ||||
| @@ -298,7 +298,7 @@ TEST_CASE("JsonVariantConst::is<T>()") { | ||||
|     CHECK(cvariant.is<int>() == false); | ||||
|     CHECK(cvariant.is<float>() == false); | ||||
|     CHECK(cvariant.is<bool>() == false); | ||||
|     CHECK(cvariant.is<char *>() == false); | ||||
|     CHECK(cvariant.is<const char *>() == false); | ||||
|     CHECK(cvariant.is<MYENUM2>() == false); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -47,8 +47,8 @@ TEST_CASE("JsonVariant undefined") { | ||||
|       REQUIRE(variant.is<unsigned>() == false); | ||||
|     } | ||||
|  | ||||
|     SECTION("char*") { | ||||
|       REQUIRE(variant.is<char*>() == false); | ||||
|     SECTION("const char*") { | ||||
|       REQUIRE(variant.is<const char*>() == false); | ||||
|     } | ||||
|  | ||||
|     SECTION("double") { | ||||
|   | ||||
| @@ -3,7 +3,7 @@ | ||||
| // MIT License | ||||
|  | ||||
| #define ARDUINOJSON_ENABLE_ARDUINO_STREAM 1 | ||||
| #include <ArduinoJson/Deserialization/Reader.hpp> | ||||
| #include <ArduinoJson.hpp> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| using namespace ARDUINOJSON_NAMESPACE; | ||||
|   | ||||
| @@ -6,8 +6,7 @@ | ||||
| #define ARDUINOJSON_ENABLE_NAN 1 | ||||
| #define ARDUINOJSON_ENABLE_INFINITY 1 | ||||
|  | ||||
| #include <ArduinoJson/Numbers/parseNumber.hpp> | ||||
| #include <ArduinoJson/Variant/VariantImpl.hpp> | ||||
| #include <ArduinoJson.hpp> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| using namespace ARDUINOJSON_NAMESPACE; | ||||
|   | ||||
| @@ -6,8 +6,7 @@ | ||||
| #define ARDUINOJSON_ENABLE_NAN 1 | ||||
| #define ARDUINOJSON_ENABLE_INFINITY 1 | ||||
|  | ||||
| #include <ArduinoJson/Numbers/parseNumber.hpp> | ||||
| #include <ArduinoJson/Variant/VariantImpl.hpp> | ||||
| #include <ArduinoJson.hpp> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| using namespace ARDUINOJSON_NAMESPACE; | ||||
|   | ||||
| @@ -3,8 +3,7 @@ | ||||
| // MIT License | ||||
|  | ||||
| #include <stdint.h> | ||||
| #include <ArduinoJson/Numbers/parseNumber.hpp> | ||||
| #include <ArduinoJson/Variant/VariantImpl.hpp> | ||||
| #include <ArduinoJson.hpp> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| using namespace ARDUINOJSON_NAMESPACE; | ||||
|   | ||||
| @@ -2,9 +2,7 @@ | ||||
| // Copyright Benoit Blanchon 2014-2021 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson/Numbers/Integer.hpp> | ||||
| #include <ArduinoJson/Numbers/parseNumber.hpp> | ||||
| #include <ArduinoJson/Variant/VariantImpl.hpp> | ||||
| #include <ArduinoJson.hpp> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| using namespace ARDUINOJSON_NAMESPACE; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user