| 
									
										
										
										
											2021-03-29 17:14:01 +02:00
										 |  |  | // ArduinoJson - https://arduinojson.org
 | 
					
						
							| 
									
										
										
										
											2025-02-24 15:18:26 +01:00
										 |  |  | // Copyright © 2014-2025, Benoit BLANCHON
 | 
					
						
							| 
									
										
										
										
											2017-03-19 15:23:06 +01:00
										 |  |  | // MIT License
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-19 17:46:00 +02:00
										 |  |  | #define ARDUINOJSON_ENABLE_NAN 1
 | 
					
						
							|  |  |  | #define ARDUINOJSON_ENABLE_INFINITY 1
 | 
					
						
							| 
									
										
										
										
											2019-03-06 15:31:37 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-20 14:52:47 +01:00
										 |  |  | #include <ArduinoJson.hpp>
 | 
					
						
							| 
									
										
										
										
											2017-04-18 18:22:24 +02:00
										 |  |  | #include <catch.hpp>
 | 
					
						
							| 
									
										
										
										
											2017-03-19 15:23:06 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-14 10:04:48 +01:00
										 |  |  | using namespace ArduinoJson::detail; | 
					
						
							| 
									
										
										
										
											2017-03-19 15:23:06 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-04 09:23:40 +02:00
										 |  |  | void checkFloat(const char* input, float expected) { | 
					
						
							| 
									
										
										
										
											2017-04-18 18:22:24 +02:00
										 |  |  |   CAPTURE(input); | 
					
						
							| 
									
										
										
										
											2024-09-03 19:18:32 +02:00
										 |  |  |   auto result = parseNumber(input); | 
					
						
							|  |  |  |   REQUIRE(result.type() == NumberType::Float); | 
					
						
							|  |  |  |   REQUIRE(result.asFloat() == Approx(expected)); | 
					
						
							| 
									
										
										
										
											2017-04-18 18:22:24 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-03-19 15:23:06 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-04 09:23:40 +02:00
										 |  |  | void checkFloatNaN(const char* input) { | 
					
						
							| 
									
										
										
										
											2017-04-18 18:22:24 +02:00
										 |  |  |   CAPTURE(input); | 
					
						
							| 
									
										
										
										
											2020-09-04 09:23:40 +02:00
										 |  |  |   float result = parseNumber<float>(input); | 
					
						
							| 
									
										
										
										
											2017-04-18 18:22:24 +02:00
										 |  |  |   REQUIRE(result != result); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-03-19 15:23:06 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-04 09:23:40 +02:00
										 |  |  | void checkFloatInf(const char* input, bool negative) { | 
					
						
							| 
									
										
										
										
											2017-04-18 18:22:24 +02:00
										 |  |  |   CAPTURE(input); | 
					
						
							| 
									
										
										
										
											2020-09-04 09:23:40 +02:00
										 |  |  |   float x = parseNumber<float>(input); | 
					
						
							| 
									
										
										
										
											2017-04-18 18:22:24 +02:00
										 |  |  |   if (negative) | 
					
						
							|  |  |  |     REQUIRE(x < 0); | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     REQUIRE(x > 0); | 
					
						
							|  |  |  |   REQUIRE(x == x);      // not a NaN
 | 
					
						
							|  |  |  |   REQUIRE(x * 2 == x);  // a property of infinity
 | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-03-19 15:23:06 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-04 09:23:40 +02:00
										 |  |  | TEST_CASE("parseNumber<float>()") { | 
					
						
							| 
									
										
										
										
											2017-04-18 18:22:24 +02:00
										 |  |  |   SECTION("Float_Short_NoExponent") { | 
					
						
							| 
									
										
										
										
											2020-09-04 09:23:40 +02:00
										 |  |  |     checkFloat("3.14", 3.14f); | 
					
						
							|  |  |  |     checkFloat("-3.14", -3.14f); | 
					
						
							|  |  |  |     checkFloat("+3.14", +3.14f); | 
					
						
							| 
									
										
										
										
											2017-03-19 15:23:06 +01:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-18 18:22:24 +02:00
										 |  |  |   SECTION("Short_NoDot") { | 
					
						
							| 
									
										
										
										
											2020-09-04 09:23:40 +02:00
										 |  |  |     checkFloat("1E+38", 1E+38f); | 
					
						
							|  |  |  |     checkFloat("-1E+38", -1E+38f); | 
					
						
							|  |  |  |     checkFloat("+1E-38", +1E-38f); | 
					
						
							|  |  |  |     checkFloat("+1e+38", +1e+38f); | 
					
						
							|  |  |  |     checkFloat("-1e-38", -1e-38f); | 
					
						
							| 
									
										
										
										
											2017-03-19 15:23:06 +01:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-18 18:22:24 +02:00
										 |  |  |   SECTION("Max") { | 
					
						
							| 
									
										
										
										
											2020-09-04 09:23:40 +02:00
										 |  |  |     checkFloat("340.2823e+36", 3.402823e+38f); | 
					
						
							|  |  |  |     checkFloat("34.02823e+37", 3.402823e+38f); | 
					
						
							|  |  |  |     checkFloat("3.402823e+38", 3.402823e+38f); | 
					
						
							|  |  |  |     checkFloat("0.3402823e+39", 3.402823e+38f); | 
					
						
							|  |  |  |     checkFloat("0.03402823e+40", 3.402823e+38f); | 
					
						
							|  |  |  |     checkFloat("0.003402823e+41", 3.402823e+38f); | 
					
						
							| 
									
										
										
										
											2017-04-18 18:22:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-03-19 15:23:06 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-18 18:22:24 +02:00
										 |  |  |   SECTION("VeryLong") { | 
					
						
							| 
									
										
										
										
											2020-09-04 09:23:40 +02:00
										 |  |  |     checkFloat("0.00000000000000000000000000000001", 1e-32f); | 
					
						
							| 
									
										
										
										
											2024-09-04 14:33:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // The following don't work because they have many digits so parseNumber()
 | 
					
						
							|  |  |  |     // treats them as double. But it's not an issue because JsonVariant will use
 | 
					
						
							|  |  |  |     // a float to store them.
 | 
					
						
							|  |  |  |     //
 | 
					
						
							|  |  |  |     // checkFloat("100000000000000000000000000000000.0", 1e+32f);
 | 
					
						
							|  |  |  |     // checkFloat(
 | 
					
						
							|  |  |  |     //     "100000000000000000000000000000000.00000000000000000000000000000",
 | 
					
						
							|  |  |  |     //     1e+32f);
 | 
					
						
							| 
									
										
										
										
											2017-04-18 18:22:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-03-19 15:23:06 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-18 18:22:24 +02:00
										 |  |  |   SECTION("NaN") { | 
					
						
							| 
									
										
										
										
											2020-09-04 09:23:40 +02:00
										 |  |  |     checkFloatNaN("NaN"); | 
					
						
							|  |  |  |     checkFloatNaN("nan"); | 
					
						
							| 
									
										
										
										
											2017-04-18 18:22:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-03-19 15:23:06 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-18 18:22:24 +02:00
										 |  |  |   SECTION("Infinity") { | 
					
						
							| 
									
										
										
										
											2020-09-04 09:23:40 +02:00
										 |  |  |     checkFloatInf("Infinity", false); | 
					
						
							|  |  |  |     checkFloatInf("+Infinity", false); | 
					
						
							|  |  |  |     checkFloatInf("-Infinity", true); | 
					
						
							|  |  |  |     checkFloatInf("inf", false); | 
					
						
							|  |  |  |     checkFloatInf("+inf", false); | 
					
						
							|  |  |  |     checkFloatInf("-inf", true); | 
					
						
							| 
									
										
										
										
											2017-04-18 18:22:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-03-19 15:23:06 +01:00
										 |  |  | } |