compare.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  1. // ArduinoJson - arduinojson.org
  2. // Copyright Benoit Blanchon 2014-2019
  3. // MIT License
  4. #include <ArduinoJson.h>
  5. #include <catch.hpp>
  6. static const char* null = 0;
  7. template <typename T>
  8. void checkEquals(T a, T b) {
  9. DynamicJsonDocument doc(4096);
  10. JsonVariant variant = doc.to<JsonVariant>();
  11. variant.set(a);
  12. REQUIRE(b == variant);
  13. REQUIRE(variant == b);
  14. REQUIRE(b <= variant);
  15. REQUIRE(variant <= b);
  16. REQUIRE(b >= variant);
  17. REQUIRE(variant >= b);
  18. REQUIRE_FALSE(b != variant);
  19. REQUIRE_FALSE(variant != b);
  20. REQUIRE_FALSE(b > variant);
  21. REQUIRE_FALSE(variant > b);
  22. REQUIRE_FALSE(b < variant);
  23. REQUIRE_FALSE(variant < b);
  24. }
  25. template <typename T>
  26. void checkGreater(T a, T b) {
  27. DynamicJsonDocument doc(4096);
  28. JsonVariant variant = doc.to<JsonVariant>();
  29. variant.set(a);
  30. REQUIRE(variant > b);
  31. REQUIRE(b < variant);
  32. REQUIRE(variant != b);
  33. REQUIRE(b != variant);
  34. REQUIRE_FALSE(variant < b);
  35. REQUIRE_FALSE(b > variant);
  36. REQUIRE_FALSE(variant == b);
  37. REQUIRE_FALSE(b == variant);
  38. }
  39. template <typename T>
  40. void checkLower(T a, T b) {
  41. DynamicJsonDocument doc(4096);
  42. JsonVariant variant = doc.to<JsonVariant>();
  43. variant.set(a);
  44. REQUIRE(variant < b);
  45. REQUIRE(b > variant);
  46. REQUIRE(variant != b);
  47. REQUIRE(b != variant);
  48. REQUIRE_FALSE(variant > b);
  49. REQUIRE_FALSE(b < variant);
  50. REQUIRE_FALSE(variant == b);
  51. REQUIRE_FALSE(b == variant);
  52. }
  53. template <typename T>
  54. void checkComparisons(T low, T mid, T high) {
  55. checkEquals(mid, mid);
  56. checkGreater(mid, low);
  57. checkLower(mid, high);
  58. }
  59. TEST_CASE("JsonVariant comparisons") {
  60. SECTION("Double") {
  61. checkComparisons<double>(123.44, 123.45, 123.46);
  62. }
  63. SECTION("Float") {
  64. checkComparisons<float>(123.44f, 123.45f, 123.46f);
  65. }
  66. SECTION("SChar") {
  67. checkComparisons<signed char>(122, 123, 124);
  68. }
  69. SECTION("SInt") {
  70. checkComparisons<signed int>(122, 123, 124);
  71. }
  72. SECTION("SLong") {
  73. checkComparisons<signed long>(122L, 123L, 124L);
  74. }
  75. SECTION("SShort") {
  76. checkComparisons<signed short>(122, 123, 124);
  77. }
  78. SECTION("UChar") {
  79. checkComparisons<unsigned char>(122, 123, 124);
  80. }
  81. SECTION("UInt") {
  82. checkComparisons<unsigned int>(122, 123, 124);
  83. }
  84. SECTION("ULong") {
  85. checkComparisons<unsigned long>(122L, 123L, 124L);
  86. }
  87. SECTION("UShort") {
  88. checkComparisons<unsigned short>(122, 123, 124);
  89. }
  90. SECTION("null") {
  91. DynamicJsonDocument doc(4096);
  92. JsonVariant variant = doc.to<JsonVariant>();
  93. variant.set(null);
  94. REQUIRE(variant == variant);
  95. REQUIRE_FALSE(variant != variant);
  96. REQUIRE(variant == null);
  97. REQUIRE_FALSE(variant != null);
  98. REQUIRE(variant != "null");
  99. REQUIRE_FALSE(variant == "null");
  100. }
  101. SECTION("StringLiteral") {
  102. DynamicJsonDocument doc(4096);
  103. deserializeJson(doc, "\"hello\"");
  104. JsonVariant variant = doc.as<JsonVariant>();
  105. REQUIRE(variant == variant);
  106. REQUIRE_FALSE(variant != variant);
  107. REQUIRE(variant == "hello");
  108. REQUIRE_FALSE(variant != "hello");
  109. REQUIRE(variant != "world");
  110. REQUIRE_FALSE(variant == "world");
  111. REQUIRE(variant != null);
  112. REQUIRE_FALSE(variant == null);
  113. REQUIRE("hello" == variant);
  114. REQUIRE_FALSE("hello" != variant);
  115. REQUIRE("world" != variant);
  116. REQUIRE_FALSE("world" == variant);
  117. REQUIRE(null != variant);
  118. REQUIRE_FALSE(null == variant);
  119. }
  120. SECTION("String") {
  121. DynamicJsonDocument doc(4096);
  122. JsonVariant variant = doc.to<JsonVariant>();
  123. variant.set("hello");
  124. REQUIRE(variant == variant);
  125. REQUIRE_FALSE(variant != variant);
  126. REQUIRE(variant == std::string("hello"));
  127. REQUIRE_FALSE(variant != std::string("hello"));
  128. REQUIRE(variant != std::string("world"));
  129. REQUIRE_FALSE(variant == std::string("world"));
  130. REQUIRE(variant != null);
  131. REQUIRE_FALSE(variant == null);
  132. REQUIRE(std::string("hello") == variant);
  133. REQUIRE_FALSE(std::string("hello") != variant);
  134. REQUIRE(std::string("world") != variant);
  135. REQUIRE_FALSE(std::string("world") == variant);
  136. REQUIRE(null != variant);
  137. REQUIRE_FALSE(null == variant);
  138. }
  139. #ifdef HAS_VARIABLE_LENGTH_ARRAY
  140. SECTION("VLA equals") {
  141. int i = 16;
  142. char vla[i];
  143. strcpy(vla, "hello");
  144. DynamicJsonDocument doc(4096);
  145. JsonVariant variant = doc.to<JsonVariant>();
  146. variant.set("hello");
  147. REQUIRE((vla == variant));
  148. REQUIRE((variant == vla));
  149. REQUIRE_FALSE((vla != variant));
  150. REQUIRE_FALSE((variant != vla));
  151. }
  152. SECTION("VLA differs") {
  153. int i = 16;
  154. char vla[i];
  155. strcpy(vla, "hello");
  156. DynamicJsonDocument doc(4096);
  157. JsonVariant variant = doc.to<JsonVariant>();
  158. variant.set("world");
  159. REQUIRE((vla != variant));
  160. REQUIRE((variant != vla));
  161. REQUIRE_FALSE((vla == variant));
  162. REQUIRE_FALSE((variant == vla));
  163. }
  164. #endif
  165. DynamicJsonDocument doc1(4096), doc2(4096), doc3(4096);
  166. JsonVariant variant1 = doc1.to<JsonVariant>();
  167. JsonVariant variant2 = doc2.to<JsonVariant>();
  168. JsonVariant variant3 = doc3.to<JsonVariant>();
  169. SECTION("Variants containing integers") {
  170. variant1.set(42);
  171. variant2.set(42);
  172. variant3.set(666);
  173. REQUIRE(variant1 == variant2);
  174. REQUIRE_FALSE(variant1 != variant2);
  175. REQUIRE(variant1 != variant3);
  176. REQUIRE_FALSE(variant1 == variant3);
  177. }
  178. SECTION("Variants containing linked strings") {
  179. // create two identical strings at different addresses
  180. char hello1[] = "hello";
  181. char hello2[] = "hello";
  182. REQUIRE(hello1 != hello2);
  183. variant1.set(hello1);
  184. variant2.set(hello2);
  185. variant3.set("world");
  186. REQUIRE(variant1 == variant2);
  187. REQUIRE_FALSE(variant1 != variant2);
  188. REQUIRE(variant1 != variant3);
  189. REQUIRE_FALSE(variant1 == variant3);
  190. }
  191. SECTION("Variants containing owned strings") {
  192. variant1.set(std::string("hello"));
  193. variant2.set(std::string("hello"));
  194. variant3.set(std::string("world"));
  195. REQUIRE(variant1 == variant2);
  196. REQUIRE_FALSE(variant1 != variant2);
  197. REQUIRE(variant1 != variant3);
  198. REQUIRE_FALSE(variant1 == variant3);
  199. }
  200. SECTION("Variants containing linked raws") {
  201. // create two identical strings at different addresses
  202. char hello1[] = "hello";
  203. char hello2[] = "hello";
  204. REQUIRE(hello1 != hello2);
  205. variant1.set(serialized(hello1));
  206. variant2.set(serialized(hello2));
  207. variant3.set(serialized("world"));
  208. REQUIRE(variant1 == variant2);
  209. REQUIRE_FALSE(variant1 != variant2);
  210. REQUIRE(variant1 != variant3);
  211. REQUIRE_FALSE(variant1 == variant3);
  212. }
  213. SECTION("Variants containing owned raws") {
  214. variant1.set(serialized(std::string("hello")));
  215. variant2.set(serialized(std::string("hello")));
  216. variant3.set(serialized(std::string("world")));
  217. REQUIRE(variant1 == variant2);
  218. REQUIRE_FALSE(variant1 != variant2);
  219. REQUIRE(variant1 != variant3);
  220. REQUIRE_FALSE(variant1 == variant3);
  221. }
  222. SECTION("Variants containing mixed strings (issue #1051)") {
  223. variant1.set("hello");
  224. variant2.set(std::string("hello"));
  225. REQUIRE(variant1 == variant2);
  226. REQUIRE_FALSE(variant1 != variant2);
  227. REQUIRE(variant2 == variant1);
  228. REQUIRE_FALSE(variant2 != variant1);
  229. }
  230. SECTION("Variants containing double") {
  231. variant1.set(42.0);
  232. variant2.set(42.0);
  233. variant3.set(666.0);
  234. REQUIRE(variant1 == variant2);
  235. REQUIRE_FALSE(variant1 != variant2);
  236. REQUIRE(variant1 != variant3);
  237. REQUIRE_FALSE(variant1 == variant3);
  238. }
  239. SECTION("BoolInVariant") {
  240. variant1.set(true);
  241. variant2.set(true);
  242. variant3.set(false);
  243. REQUIRE(variant1 == variant2);
  244. REQUIRE_FALSE(variant1 != variant2);
  245. REQUIRE(variant1 != variant3);
  246. REQUIRE_FALSE(variant1 == variant3);
  247. }
  248. SECTION("ArrayInVariant") {
  249. JsonArray array1 = variant1.to<JsonArray>();
  250. JsonArray array2 = variant2.to<JsonArray>();
  251. array1.add(42);
  252. array2.add(42);
  253. REQUIRE(variant1 == variant2);
  254. REQUIRE_FALSE(variant1 != variant2);
  255. REQUIRE(variant1 != variant3);
  256. REQUIRE_FALSE(variant1 == variant3);
  257. }
  258. SECTION("ObjectInVariant") {
  259. JsonObject obj1 = variant1.to<JsonObject>();
  260. JsonObject obj2 = variant2.to<JsonObject>();
  261. obj1["hello"] = "world";
  262. obj2["hello"] = "world";
  263. REQUIRE(variant1 == variant2);
  264. REQUIRE_FALSE(variant1 != variant2);
  265. REQUIRE(variant1 != variant3);
  266. REQUIRE_FALSE(variant1 == variant3);
  267. }
  268. }
  269. class VariantComparisionFixture {
  270. private:
  271. StaticJsonDocument<256> doc;
  272. JsonVariant variant;
  273. public:
  274. VariantComparisionFixture() : variant(doc.to<JsonVariant>()) {}
  275. protected:
  276. template <typename T>
  277. void setValue(const T& value) {
  278. variant.set(value);
  279. }
  280. template <typename T>
  281. void assertEqualsTo(const T& value) {
  282. REQUIRE(variant == value);
  283. REQUIRE(value == variant);
  284. REQUIRE_FALSE(variant != value);
  285. REQUIRE_FALSE(value != variant);
  286. }
  287. template <typename T>
  288. void assertDiffersFrom(const T& value) {
  289. REQUIRE(variant != value);
  290. REQUIRE(value != variant);
  291. REQUIRE_FALSE(variant == value);
  292. REQUIRE_FALSE(value == variant);
  293. }
  294. template <typename T>
  295. void assertGreaterThan(const T& value) {
  296. REQUIRE((variant > value));
  297. REQUIRE((variant >= value));
  298. REQUIRE(value < variant);
  299. REQUIRE(value <= variant);
  300. REQUIRE_FALSE((variant < value));
  301. REQUIRE_FALSE((variant <= value));
  302. REQUIRE_FALSE(value > variant);
  303. REQUIRE_FALSE(value >= variant);
  304. }
  305. template <typename T>
  306. void assertLowerThan(const T& value) {
  307. REQUIRE(variant < value);
  308. REQUIRE(variant <= value);
  309. REQUIRE(value > variant);
  310. REQUIRE(value >= variant);
  311. REQUIRE_FALSE(variant > value);
  312. REQUIRE_FALSE(variant >= value);
  313. REQUIRE_FALSE(value < variant);
  314. REQUIRE_FALSE(value <= variant);
  315. }
  316. };
  317. TEST_CASE_METHOD(VariantComparisionFixture,
  318. "Compare variant with another type") {
  319. SECTION("null") {
  320. assertDiffersFrom(3);
  321. assertDiffersFrom("world");
  322. }
  323. SECTION("string") {
  324. setValue("hello");
  325. assertEqualsTo("hello");
  326. assertDiffersFrom(3);
  327. assertDiffersFrom("world");
  328. assertGreaterThan("helln");
  329. assertLowerThan("hellp");
  330. }
  331. SECTION("positive integer") {
  332. setValue(42);
  333. assertEqualsTo(42);
  334. assertDiffersFrom(43);
  335. assertGreaterThan(41);
  336. assertLowerThan(43);
  337. assertDiffersFrom("world");
  338. }
  339. SECTION("negative integer") {
  340. setValue(-42);
  341. assertEqualsTo(-42);
  342. assertDiffersFrom(42);
  343. assertGreaterThan(-43);
  344. assertLowerThan(-41);
  345. assertDiffersFrom("world");
  346. }
  347. SECTION("double") {
  348. setValue(42.0);
  349. assertEqualsTo(42.0);
  350. assertDiffersFrom(42.1);
  351. assertGreaterThan(41.0);
  352. assertLowerThan(43.0);
  353. assertDiffersFrom("42.0");
  354. }
  355. SECTION("true") {
  356. setValue(true);
  357. assertEqualsTo(true);
  358. assertDiffersFrom(false);
  359. assertDiffersFrom(1);
  360. assertDiffersFrom("true");
  361. assertDiffersFrom(1.0);
  362. assertGreaterThan(false);
  363. }
  364. }