Skip to content

Commit d92eee8

Browse files
committed
Deprecate containsKey() in favor of doc["key"].is<T>()
See #2121
1 parent dd1d96e commit d92eee8

File tree

22 files changed

+263
-269
lines changed

22 files changed

+263
-269
lines changed

CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,33 @@ HEAD
99
* Reduce the slot size (see table below)
1010
* Improve message when user forgets third arg of `serializeJson()` et al.
1111
* Set `ARDUINOJSON_USE_DOUBLE` to `0` by default on 8-bit architectures
12+
* Deprecate `containsKey()` in favor of `doc["key"].is<T>()`
1213

1314
| Architecture | before | after |
1415
|--------------|----------|----------|
1516
| 8-bit | 8 bytes | 6 bytes |
1617
| 32-bit | 16 bytes | 8 bytes |
1718
| 64-bit | 24 bytes | 16 bytes |
1819

20+
> ### BREAKING CHANGES
21+
>
22+
> After being on the death row for years, the `containsKey()` method has finally been deprecated.
23+
> You should replace `doc.containsKey("key")` with `doc["key"].is<T>()`, which not only checks that the key exists but also that the value is of the expected type.
24+
>
25+
> ```cpp
26+
> // Before
27+
> if (doc.containsKey("value")) {
28+
> int value = doc["value"];
29+
> // ...
30+
> }
31+
>
32+
> // After
33+
> if (doc["value"].is<int>()) {
34+
> int value = doc["value"];
35+
> // ...
36+
> }
37+
> ```
38+
1939
v7.1.0 (2024-06-27)
2040
------
2141

extras/tests/Deprecated/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@ endif()
1616

1717
add_executable(DeprecatedTests
1818
add.cpp
19+
BasicJsonDocument.cpp
20+
containsKey.cpp
1921
createNestedArray.cpp
2022
createNestedObject.cpp
21-
BasicJsonDocument.cpp
2223
DynamicJsonDocument.cpp
2324
macros.cpp
2425
memoryUsage.cpp
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
// ArduinoJson - https://arduinojson.org
2+
// Copyright © 2014-2024, Benoit BLANCHON
3+
// MIT License
4+
5+
#include <ArduinoJson.h>
6+
#include <catch.hpp>
7+
8+
#include "Literals.hpp"
9+
10+
TEST_CASE("JsonDocument::containsKey()") {
11+
JsonDocument doc;
12+
13+
SECTION("returns true on object") {
14+
doc["hello"] = "world";
15+
16+
REQUIRE(doc.containsKey("hello") == true);
17+
}
18+
19+
SECTION("returns true when value is null") {
20+
doc["hello"] = static_cast<const char*>(0);
21+
22+
REQUIRE(doc.containsKey("hello") == true);
23+
}
24+
25+
SECTION("returns true when key is a std::string") {
26+
doc["hello"] = "world";
27+
28+
REQUIRE(doc.containsKey("hello"_s) == true);
29+
}
30+
31+
SECTION("returns false on object") {
32+
doc["world"] = "hello";
33+
34+
REQUIRE(doc.containsKey("hello") == false);
35+
}
36+
37+
SECTION("returns false on array") {
38+
doc.add("hello");
39+
40+
REQUIRE(doc.containsKey("hello") == false);
41+
}
42+
43+
SECTION("returns false on null") {
44+
REQUIRE(doc.containsKey("hello") == false);
45+
}
46+
47+
SECTION("support JsonVariant") {
48+
doc["hello"] = "world";
49+
doc["key"] = "hello";
50+
51+
REQUIRE(doc.containsKey(doc["key"]) == true);
52+
REQUIRE(doc.containsKey(doc["foo"]) == false);
53+
}
54+
}
55+
56+
TEST_CASE("MemberProxy::containsKey()") {
57+
JsonDocument doc;
58+
auto mp = doc["hello"];
59+
60+
SECTION("containsKey(const char*)") {
61+
mp["key"] = "value";
62+
63+
REQUIRE(mp.containsKey("key") == true);
64+
REQUIRE(mp.containsKey("key") == true);
65+
}
66+
67+
SECTION("containsKey(std::string)") {
68+
mp["key"] = "value";
69+
70+
REQUIRE(mp.containsKey("key"_s) == true);
71+
REQUIRE(mp.containsKey("key"_s) == true);
72+
}
73+
}
74+
75+
TEST_CASE("JsonObject::containsKey()") {
76+
JsonDocument doc;
77+
JsonObject obj = doc.to<JsonObject>();
78+
obj["hello"] = 42;
79+
80+
SECTION("returns true only if key is present") {
81+
REQUIRE(false == obj.containsKey("world"));
82+
REQUIRE(true == obj.containsKey("hello"));
83+
}
84+
85+
SECTION("returns false after remove()") {
86+
obj.remove("hello");
87+
88+
REQUIRE(false == obj.containsKey("hello"));
89+
}
90+
91+
#ifdef HAS_VARIABLE_LENGTH_ARRAY
92+
SECTION("key is a VLA") {
93+
size_t i = 16;
94+
char vla[i];
95+
strcpy(vla, "hello");
96+
97+
REQUIRE(true == obj.containsKey(vla));
98+
}
99+
#endif
100+
101+
SECTION("key is a JsonVariant") {
102+
doc["key"] = "hello";
103+
REQUIRE(true == obj.containsKey(obj["key"]));
104+
REQUIRE(false == obj.containsKey(obj["hello"]));
105+
}
106+
107+
SECTION("std::string") {
108+
REQUIRE(true == obj.containsKey("hello"_s));
109+
}
110+
111+
SECTION("unsigned char[]") {
112+
unsigned char key[] = "hello";
113+
REQUIRE(true == obj.containsKey(key));
114+
}
115+
}
116+
117+
TEST_CASE("JsonObjectConst::containsKey()") {
118+
JsonDocument doc;
119+
doc["hello"] = 42;
120+
auto obj = doc.as<JsonObjectConst>();
121+
122+
SECTION("supports const char*") {
123+
REQUIRE(false == obj.containsKey("world"));
124+
REQUIRE(true == obj.containsKey("hello"));
125+
}
126+
127+
SECTION("supports std::string") {
128+
REQUIRE(false == obj.containsKey("world"_s));
129+
REQUIRE(true == obj.containsKey("hello"_s));
130+
}
131+
132+
#ifdef HAS_VARIABLE_LENGTH_ARRAY
133+
SECTION("supports VLA") {
134+
size_t i = 16;
135+
char vla[i];
136+
strcpy(vla, "hello");
137+
138+
REQUIRE(true == obj.containsKey(vla));
139+
}
140+
#endif
141+
142+
SECTION("supports JsonVariant") {
143+
doc["key"] = "hello";
144+
REQUIRE(true == obj.containsKey(obj["key"]));
145+
REQUIRE(false == obj.containsKey(obj["hello"]));
146+
}
147+
}
148+
149+
TEST_CASE("JsonVariant::containsKey()") {
150+
JsonDocument doc;
151+
JsonVariant var = doc.to<JsonVariant>();
152+
153+
SECTION("returns false is unbound") {
154+
CHECK_FALSE(JsonVariant().containsKey("hello"));
155+
}
156+
157+
SECTION("containsKey(const char*)") {
158+
var["hello"] = "world";
159+
160+
REQUIRE(var.containsKey("hello") == true);
161+
REQUIRE(var.containsKey("world") == false);
162+
}
163+
164+
SECTION("containsKey(std::string)") {
165+
var["hello"] = "world";
166+
167+
REQUIRE(var.containsKey("hello"_s) == true);
168+
REQUIRE(var.containsKey("world"_s) == false);
169+
}
170+
171+
SECTION("containsKey(JsonVariant)") {
172+
var["hello"] = "world";
173+
var["key"] = "hello";
174+
175+
REQUIRE(var.containsKey(doc["key"]) == true);
176+
REQUIRE(var.containsKey(doc["foo"]) == false);
177+
}
178+
}
179+
180+
TEST_CASE("JsonVariantConst::containsKey()") {
181+
JsonDocument doc;
182+
doc["hello"] = "world";
183+
JsonVariantConst var = doc.as<JsonVariant>();
184+
185+
SECTION("support const char*") {
186+
REQUIRE(var.containsKey("hello") == true);
187+
REQUIRE(var.containsKey("world") == false);
188+
}
189+
190+
SECTION("support std::string") {
191+
REQUIRE(var.containsKey("hello"_s) == true);
192+
REQUIRE(var.containsKey("world"_s) == false);
193+
}
194+
195+
#ifdef HAS_VARIABLE_LENGTH_ARRAY
196+
SECTION("supports VLA") {
197+
size_t i = 16;
198+
char vla[i];
199+
strcpy(vla, "hello");
200+
201+
REQUIRE(true == var.containsKey(vla));
202+
}
203+
#endif
204+
205+
SECTION("support JsonVariant") {
206+
doc["key"] = "hello";
207+
REQUIRE(var.containsKey(var["key"]) == true);
208+
REQUIRE(var.containsKey(var["foo"]) == false);
209+
}
210+
}

extras/tests/JsonDocument/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ add_executable(JsonDocumentTests
99
clear.cpp
1010
compare.cpp
1111
constructor.cpp
12-
containsKey.cpp
1312
ElementProxy.cpp
1413
isNull.cpp
1514
issue1120.cpp

extras/tests/JsonDocument/MemberProxy.cpp

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -93,25 +93,6 @@ TEST_CASE("MemberProxy::operator==()") {
9393
}
9494
}
9595

96-
TEST_CASE("MemberProxy::containsKey()") {
97-
JsonDocument doc;
98-
MemberProxy mp = doc["hello"];
99-
100-
SECTION("containsKey(const char*)") {
101-
mp["key"] = "value";
102-
103-
REQUIRE(mp.containsKey("key") == true);
104-
REQUIRE(mp.containsKey("key") == true);
105-
}
106-
107-
SECTION("containsKey(std::string)") {
108-
mp["key"] = "value";
109-
110-
REQUIRE(mp.containsKey("key"_s) == true);
111-
REQUIRE(mp.containsKey("key"_s) == true);
112-
}
113-
}
114-
11596
TEST_CASE("MemberProxy::operator|()") {
11697
JsonDocument doc;
11798

extras/tests/JsonDocument/containsKey.cpp

Lines changed: 0 additions & 54 deletions
This file was deleted.

extras/tests/JsonObject/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
add_executable(JsonObjectTests
66
clear.cpp
77
compare.cpp
8-
containsKey.cpp
98
equals.cpp
109
isNull.cpp
1110
iterator.cpp

extras/tests/JsonObject/containsKey.cpp

Lines changed: 0 additions & 39 deletions
This file was deleted.

0 commit comments

Comments
 (0)