View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.juneau;
18  
19  import static org.apache.juneau.TestUtils.*;
20  import static org.apache.juneau.junit.bct.BctAssertions.*;
21  import static org.junit.jupiter.api.Assertions.*;
22  
23  import java.util.*;
24  
25  import org.apache.juneau.collections.*;
26  import org.apache.juneau.objecttools.*;
27  import org.junit.jupiter.api.*;
28  
29  class JsonMap_Test extends TestBase {
30  
31  	//====================================================================================================
32  	// testBasic
33  	//====================================================================================================
34  	@Test void a01_basic() throws Exception {
35  		var in = "{A:'asdf'}";
36  
37  		checkStep(1, in, JsonMap.ofJson(in).getString("A"), "asdf");
38  
39  		in = "{A:{B:'asdf'}}";
40  		checkStep(2, in, getDeepString(JsonMap.ofJson(in), "A/B"), "asdf");
41  		checkStep(3, in, JsonMap.ofJson(in).getString("A"), "{B:'asdf'}");
42  
43  		in = "{A:{B:'asdf'+\"asdf\"}}";
44  		checkStep(4, in, getDeepString(JsonMap.ofJson(in), "A/B"), "asdfasdf");
45  		checkStep(5, in, JsonMap.ofJson(in).getString("A"), "{B:'asdfasdf'}");
46  
47  		in = "{A:{B:'asdf' + \n\t \"asdf\"}}";
48  		checkStep(6, in, getDeepString(JsonMap.ofJson(in), "A/B"), "asdfasdf");
49  		checkStep(7, in, JsonMap.ofJson(in).getString("A"), "{B:'asdfasdf'}");
50  
51  		in = "{A:{B:'asdf\"asdf', C:\"asdf'asdf\", D : \"asdf\\\"asdf\", E: 'asdf\\\'asdf', F:\"asdf\\\'asdf\", G:'asdf\\\"asdf'}}";
52  		checkStep(8, in, getDeepString(JsonMap.ofJson(in), "A/B"), "asdf\"asdf");
53  		checkStep(9, in, getDeepString(JsonMap.ofJson(in), "A/C"), "asdf'asdf");
54  		checkStep(10, in, getDeepString(JsonMap.ofJson(in), "A/D"), "asdf\"asdf");
55  		checkStep(11, in, getDeepString(JsonMap.ofJson(in), "A/E"), "asdf'asdf");
56  		checkStep(12, in, getDeepString(JsonMap.ofJson(in), "A/F"), "asdf'asdf");
57  		checkStep(13, in, getDeepString(JsonMap.ofJson(in), "A/G"), "asdf\"asdf");
58  
59  		in = "{A:123, B: 123}";
60  		checkStep(16, in, JsonMap.ofJson(in).getInt("A").toString(), "123");
61  		checkStep(17, in, JsonMap.ofJson(in).getInt("B").toString(), "123");
62  
63  		in = "{A:true, B: true, C:false, D: false}";
64  		checkStep(18, in, JsonMap.ofJson(in).getBoolean("A").toString(), "true");
65  		checkStep(19, in, JsonMap.ofJson(in).getBoolean("B").toString(), "true");
66  		checkStep(20, in, JsonMap.ofJson(in).getBoolean("C").toString(), "false");
67  		checkStep(21, in, JsonMap.ofJson(in).getBoolean("D").toString(), "false");
68  
69  		in = "{'AAA':{\"BBB\":\"CCC\",'DDD':false}}";
70  		checkStep(31, in, getDeepString(JsonMap.ofJson(in), "AAA/BBB"), "CCC");
71  		checkStep(32, in, getDeepBoolean(JsonMap.ofJson(in), "AAA/DDD").toString(), "false");
72  
73  		in = " \n\n\t {  'AAA' : { \"BBB\" : \"CCC\" , 'DDD' : false } } \n\t";
74  		checkStep(33, in, getDeepString(JsonMap.ofJson(in), "AAA/BBB"), "CCC");
75  		checkStep(34, in, getDeepBoolean(JsonMap.ofJson(in), "AAA/DDD").toString(), "false");
76  
77  		in = "/*x*/{A:'B','C':1,\"E\":[1,2,3],G:['g1','g2','g3']}";
78  		checkStep(100, in, JsonMap.ofJson(in).getString("A"), "B");
79  		in = "{/*x*/A:'B','C':1,\"E\":[1,2,3],G:['g1','g2','g3']}";
80  		checkStep(101, in, JsonMap.ofJson(in).getString("A"), "B");
81  		in = "{A/*x*/:'B','C':1,\"E\":[1,2,3],G:['g1','g2','g3']}";
82  		checkStep(102, in, JsonMap.ofJson(in).getString("A"), "B");
83  		in = "{A:/*x*/'B','C':1,\"E\":[1,2,3],G:['g1','g2','g3']}";
84  		checkStep(103, in, JsonMap.ofJson(in).getString("A"), "B");
85  		in = "{A:'/*x*/B','C':1,\"E\":[1,2,3],G:['g1','g2','g3']}";
86  		checkStep(104, in, JsonMap.ofJson(in).getString("A"), "/*x*/B");
87  		in = "{A:'B/*x*/','C':1,\"E\":[1,2,3],G:['g1','g2','g3']}";
88  		checkStep(105, in, JsonMap.ofJson(in).getString("A"), "B/*x*/");
89  		in = "{A:'B'/*x*/,'C':1,\"E\":[1,2,3],G:['g1','g2','g3']}";
90  		checkStep(106, in, JsonMap.ofJson(in).getString("A"), "B");
91  		in = "{A:'B',/*x*/'C':1,\"E\":[1,2,3],G:['g1','g2','g3']}";
92  		checkStep(107, in, JsonMap.ofJson(in).getString("C"), "1");
93  		in = "{A:'B','C':/*x*/1,\"E\":[1,2,3],G:['g1','g2','g3']}";
94  		checkStep(108, in, JsonMap.ofJson(in).getString("C"), "1");
95  		in = "{A:'B','C':1/*x*/,\"E\":[1,2,3],G:['g1','g2','g3']}";
96  		checkStep(109, in, JsonMap.ofJson(in).getString("C"), "1");
97  		in = "{A:'B','C':1,/*x*/\"E\":[1,2,3],G:['g1','g2','g3']}";
98  		checkStep(110, in, JsonMap.ofJson(in).getList("E").getString(0), "1");
99  		in = "{A:'B','C':1,\"/*x*/E\":[1,2,3],G:['g1','g2','g3']}";
100 		checkStep(111, in, JsonMap.ofJson(in).getList("/*x*/E").getString(0), "1");
101 		in = "{A:'B','C':1,\"E/*x*/\":[1,2,3],G:['g1','g2','g3']}";
102 		checkStep(112, in, JsonMap.ofJson(in).getList("E/*x*/").getString(0), "1");
103 		in = "{A:'B','C':1,\"E\"/*x*/:[1,2,3],G:['g1','g2','g3']}";
104 		checkStep(113, in, JsonMap.ofJson(in).getList("E").getString(0), "1");
105 		in = "{A:'B','C':1,\"E\":/*x*/[1,2,3],G:['g1','g2','g3']}";
106 		checkStep(114, in, JsonMap.ofJson(in).getList("E").getString(0), "1");
107 		in = "{A:'B','C':1,\"E\":[/*x*/1,2,3],G:['g1','g2','g3']}";
108 		checkStep(115, in, JsonMap.ofJson(in).getList("E").getString(0), "1");
109 		in = "{A:'B','C':1,\"E\":[1/*x*/,2,3],G:['g1','g2','g3']}";
110 		checkStep(116, in, JsonMap.ofJson(in).getList("E").getString(0), "1");
111 		in = "{A:'B','C':1,\"E\":[1,/*x*/2,3],G:['g1','g2','g3']}";
112 		checkStep(117, in, JsonMap.ofJson(in).getList("E").getString(1), "2");
113 		in = "{A:'B','C':1,\"E\":[1,2/*x*/,3],G:['g1','g2','g3']}";
114 		checkStep(118, in, JsonMap.ofJson(in).getList("E").getString(1), "2");
115 		in = "{A:'B','C':1,\"E\":[1,2,/*x*/3],G:['g1','g2','g3']}";
116 		checkStep(119, in, JsonMap.ofJson(in).getList("E").getString(2), "3");
117 		in = "{A:'B','C':1,\"E\":[1,2,3]/*x*/,G:['g1','g2','g3']}";
118 		checkStep(120, in, JsonMap.ofJson(in).getList("E").getString(2), "3");
119 		in = "{A:'B','C':1,\"E\":[1,2,3],/*x*/G:['g1','g2','g3']}";
120 		checkStep(121, in, JsonMap.ofJson(in).getList("G").getString(0), "g1");
121 		in = "{A:'B','C':1,\"E\":[1,2,3],G:[/*x*/'g1','g2','g3']}";
122 		checkStep(122, in, JsonMap.ofJson(in).getList("G").getString(0), "g1");
123 		in = "{A:'B','C':1,\"E\":[1,2,3],G:['/*x*/g1','g2','g3']}";
124 		checkStep(123, in, JsonMap.ofJson(in).getList("G").getString(0), "/*x*/g1");
125 		in = "{A:'B','C':1,\"E\":[1,2,3],G:['g1'/*x*/,'g2','g3']}";
126 		checkStep(124, in, JsonMap.ofJson(in).getList("G").getString(0), "g1");
127 		in = "{A:'B','C':1,\"E\":[1,2,3],G:['g1',/*x*/'g2','g3']}";
128 		checkStep(125, in, JsonMap.ofJson(in).getList("G").getString(1), "g2");
129 		in = "{A:'B','C':1,\"E\":[1,2,3],G:['g1','g2'/*x*/,'g3']}";
130 		checkStep(126, in, JsonMap.ofJson(in).getList("G").getString(1), "g2");
131 		in = "{A:'B','C':1,\"E\":[1,2,3],G:['g1','g2',/*x*/'g3']}";
132 		checkStep(127, in, JsonMap.ofJson(in).getList("G").getString(2), "g3");
133 		in = "{A:'B','C':1,\"E\":[1,2,3],G:['g1','g2','g3'/*x*/]}";
134 		checkStep(128, in, JsonMap.ofJson(in).getList("G").getString(2), "g3");
135 		in = "{A:'B','C':1,\"E\":[1,2,3],G:['g1','g2','g3']/*x*/}";
136 		checkStep(129, in, JsonMap.ofJson(in).getList("G").getString(2), "g3");
137 		in = "{A:'B','C':1,\"E\":[1,2,3],G:['g1','g2','g3']}/*x*/";
138 		checkStep(130, in, JsonMap.ofJson(in).getList("G").getString(2), "g3");
139 
140 		in = "/*\tx\t*///\tx\t\n\t/*\tx\t*/{A:'B','C':1,\"E\":[1,2,3],G:['g1','g2','g3']}";
141 		checkStep(201, in, JsonMap.ofJson(in).getString("A"), "B");
142 		in = "{/*\tx\t*///\tx\t\n\t/*\tx\t*/A:'B','C':1,\"E\":[1,2,3],G:['g1','g2','g3']}";
143 		checkStep(202, in, JsonMap.ofJson(in).getString("A"), "B");
144 		in = "{A/*\tx\t*///\tx\t\n\t/*\tx\t*/:'B','C':1,\"E\":[1,2,3],G:['g1','g2','g3']}";
145 		checkStep(203, in, JsonMap.ofJson(in).getString("A"), "B");
146 		in = "{A:/*\tx\t*///\tx\t\n\t/*\tx\t*/'B','C':1,\"E\":[1,2,3],G:['g1','g2','g3']}";
147 		checkStep(204, in, JsonMap.ofJson(in).getString("A"), "B");
148 		in = "{A:'/*\tx\t*///\tx\t\n\t/*\tx\t*/B','C':1,\"E\":[1,2,3],G:['g1','g2','g3']}";
149 		checkStep(205, in, JsonMap.ofJson(in).getString("A"), "/*\tx\t*///\tx\t\n\t/*\tx\t*/B");
150 		in = "{A:'B/*\tx\t*///\tx\t\n\t/*\tx\t*/','C':1,\"E\":[1,2,3],G:['g1','g2','g3']}";
151 		checkStep(206, in, JsonMap.ofJson(in).getString("A"), "B/*\tx\t*///\tx\t\n\t/*\tx\t*/");
152 		in = "{A:'B'/*\tx\t*///\tx\t\n\t/*\tx\t*/,'C':1,\"E\":[1,2,3],G:['g1','g2','g3']}";
153 		checkStep(207, in, JsonMap.ofJson(in).getString("A"), "B");
154 		in = "{A:'B',/*\tx\t*///\tx\t\n\t/*\tx\t*/'C':1,\"E\":[1,2,3],G:['g1','g2','g3']}";
155 		checkStep(208, in, JsonMap.ofJson(in).getString("C"), "1");
156 		in = "{A:'B','C':/*\tx\t*///\tx\t\n\t/*\tx\t*/1,\"E\":[1,2,3],G:['g1','g2','g3']}";
157 		checkStep(209, in, JsonMap.ofJson(in).getString("C"), "1");
158 		in = "{A:'B','C':1/*\tx\t*///\tx\t\n\t/*\tx\t*/,\"E\":[1,2,3],G:['g1','g2','g3']}";
159 		checkStep(210, in, JsonMap.ofJson(in).getString("C"), "1");
160 		in = "{A:'B','C':1,/*\tx\t*///\tx\t\n\t/*\tx\t*/\"E\":[1,2,3],G:['g1','g2','g3']}";
161 		checkStep(211, in, JsonMap.ofJson(in).getList("E").getString(0), "1");
162 		in = "{A:'B','C':1,\"/*\tx\t*///\tx\t\n\t/*\tx\t*/E\":[1,2,3],G:['g1','g2','g3']}";
163 		checkStep(212, in, JsonMap.ofJson(in).getList("/*\tx\t*///\tx\t\n\t/*\tx\t*/E").getString(0), "1");
164 		in = "{A:'B','C':1,\"E/*\tx\t*///\tx\t\n\t/*\tx\t*/\":[1,2,3],G:['g1','g2','g3']}";
165 		checkStep(213, in, JsonMap.ofJson(in).getList("E/*\tx\t*///\tx\t\n\t/*\tx\t*/").getString(0), "1");
166 		in = "{A:'B','C':1,\"E\"/*\tx\t*///\tx\t\n\t/*\tx\t*/:[1,2,3],G:['g1','g2','g3']}";
167 		checkStep(214, in, JsonMap.ofJson(in).getList("E").getString(0), "1");
168 		in = "{A:'B','C':1,\"E\":/*\tx\t*///\tx\t\n\t/*\tx\t*/[1,2,3],G:['g1','g2','g3']}";
169 		checkStep(215, in, JsonMap.ofJson(in).getList("E").getString(0), "1");
170 		in = "{A:'B','C':1,\"E\":[/*\tx\t*///\tx\t\n\t/*\tx\t*/1,2,3],G:['g1','g2','g3']}";
171 		checkStep(216, in, JsonMap.ofJson(in).getList("E").getString(0), "1");
172 		in = "{A:'B','C':1,\"E\":[1/*\tx\t*///\tx\t\n\t/*\tx\t*/,2,3],G:['g1','g2','g3']}";
173 		checkStep(217, in, JsonMap.ofJson(in).getList("E").getString(0), "1");
174 		in = "{A:'B','C':1,\"E\":[1,/*\tx\t*///\tx\t\n\t/*\tx\t*/2,3],G:['g1','g2','g3']}";
175 		checkStep(218, in, JsonMap.ofJson(in).getList("E").getString(1), "2");
176 		in = "{A:'B','C':1,\"E\":[1,2/*\tx\t*///\tx\t\n\t/*\tx\t*/,3],G:['g1','g2','g3']}";
177 		checkStep(219, in, JsonMap.ofJson(in).getList("E").getString(1), "2");
178 		in = "{A:'B','C':1,\"E\":[1,2,/*\tx\t*///\tx\t\n\t/*\tx\t*/3],G:['g1','g2','g3']}";
179 		checkStep(220, in, JsonMap.ofJson(in).getList("E").getString(2), "3");
180 		in = "{A:'B','C':1,\"E\":[1,2,3]/*\tx\t*///\tx\t\n\t/*\tx\t*/,G:['g1','g2','g3']}";
181 		checkStep(221, in, JsonMap.ofJson(in).getList("E").getString(2), "3");
182 		in = "{A:'B','C':1,\"E\":[1,2,3],/*\tx\t*///\tx\t\n\t/*\tx\t*/G:['g1','g2','g3']}";
183 		checkStep(222, in, JsonMap.ofJson(in).getList("G").getString(0), "g1");
184 		in = "{A:'B','C':1,\"E\":[1,2,3],G:[/*\tx\t*///\tx\t\n\t/*\tx\t*/'g1','g2','g3']}";
185 		checkStep(223, in, JsonMap.ofJson(in).getList("G").getString(0), "g1");
186 		in = "{A:'B','C':1,\"E\":[1,2,3],G:['/*\tx\t*///\tx\t\n\t/*\tx\t*/g1','g2','g3']}";
187 		checkStep(224, in, JsonMap.ofJson(in).getList("G").getString(0), "/*\tx\t*///\tx\t\n\t/*\tx\t*/g1");
188 		in = "{A:'B','C':1,\"E\":[1,2,3],G:['g1'/*\tx\t*///\tx\t\n\t/*\tx\t*/,'g2','g3']}";
189 		checkStep(225, in, JsonMap.ofJson(in).getList("G").getString(0), "g1");
190 		in = "{A:'B','C':1,\"E\":[1,2,3],G:['g1',/*\tx\t*///\tx\t\n\t/*\tx\t*/'g2','g3']}";
191 		checkStep(226, in, JsonMap.ofJson(in).getList("G").getString(1), "g2");
192 		in = "{A:'B','C':1,\"E\":[1,2,3],G:['g1','g2'/*\tx\t*///\tx\t\n\t/*\tx\t*/,'g3']}";
193 		checkStep(227, in, JsonMap.ofJson(in).getList("G").getString(1), "g2");
194 		in = "{A:'B','C':1,\"E\":[1,2,3],G:['g1','g2',/*\tx\t*///\tx\t\n\t/*\tx\t*/'g3']}";
195 		checkStep(228, in, JsonMap.ofJson(in).getList("G").getString(2), "g3");
196 		in = "{A:'B','C':1,\"E\":[1,2,3],G:['g1','g2','g3'/*\tx\t*///\tx\t\n\t/*\tx\t*/]}";
197 		checkStep(229, in, JsonMap.ofJson(in).getList("G").getString(2), "g3");
198 		in = "{A:'B','C':1,\"E\":[1,2,3],G:['g1','g2','g3']/*\tx\t*///\tx\t\n\t/*\tx\t*/}";
199 		checkStep(230, in, JsonMap.ofJson(in).getList("G").getString(2), "g3");
200 		in = "{A:'B','C':1,\"E\":[1,2,3],G:['g1','g2','g3']}/*\tx\t*///\tx\t\n\t/*\tx\t*/";
201 		checkStep(231, in, JsonMap.ofJson(in).getList("G").getString(2), "g3");
202 
203 		in = "{  /*  x  */  //  x  \n  /*  x  */  A:'B','C':1,\"E\":[1,2,3],G:['g1','g2','g3']}";
204 		checkStep(240, in, JsonMap.ofJson(in).getString("A"), "B");
205 
206 		in = "{A:'B','C':1,\"E\":[1,2,3],G:['g1','g2','g3']}";
207 		checkStep(301, in, JsonMap.ofJson(in).getString("A", "default"), "B");
208 		in = "{/*A:'B',*/'C':1,\"E\":[1,2,3],G:['g1','g2','g3']}";
209 		checkStep(302, in, JsonMap.ofJson(in).getString("A", "default"), "default");
210 		in = "{A:'B',/*'C':1,*/\"E\":[1,2,3],G:['g1','g2','g3']}";
211 		checkStep(303, in, JsonMap.ofJson(in).getString("C", "default"), "default");
212 		in = "{A:'B','C':1,/*\"E\":[1,2,3],*/G:['g1','g2','g3']}";
213 		checkStep(304, in, JsonMap.ofJson(in).getString("E", "default"), "default");
214 		in = "{A:'B','C':1,\"E\":[/*1,*/2,3],G:['g1','g2','g3']}";
215 		checkStep(305, in, JsonMap.ofJson(in).getList("E").getString(0), "2");
216 		in = "{A:'B','C':1,\"E\":[1,/*2,*/3],G:['g1','g2','g3']}";
217 		checkStep(306, in, JsonMap.ofJson(in).getList("E").getString(1), "3");
218 		in = "{A:'B','C':1,\"E\":[1,2/*,3*/],G:['g1','g2','g3']}";
219 		checkStep(307, in, JsonMap.ofJson(in).getList("E").getString(1), "2");
220 		in = "{A:'B','C':1,\"E\":[1,2,3],G:[/*'g1',*/'g2','g3']}";
221 		checkStep(308, in, JsonMap.ofJson(in).getList("G").getString(0), "g2");
222 		in = "{A:'B','C':1,\"E\":[1,2,3],G:['g1'/*,'g2'*/,'g3']}";
223 		checkStep(309, in, JsonMap.ofJson(in).getList("G").getString(1), "g3");
224 		in = "{A:'B','C':1,\"E\":[1,2,3],G:['g1','g2'/*,'g3'*/]}";
225 		checkStep(310, in, JsonMap.ofJson(in).getList("G").getString(1), "g2");
226 		in = "{A:'B','C':1,\"E\":[1,2,3],G:['g1','g2','g3']}";
227 		checkStep(310, in, JsonMap.ofJson(in).getList("G").getString(1), "g2");
228 
229 		// Check keys that contain array indexes
230 		in = "{A:{B:[{C:'c0'},{C:'c1'},{C:'c2'}]}}";
231 		checkStep(401, in, getDeepString(JsonMap.ofJson(in), "A/B/0/C"), "c0");
232 		checkStep(402, in, getDeepString(JsonMap.ofJson(in), "A/B/1/C"), "c1");
233 		checkStep(403, in, getDeepString(JsonMap.ofJson(in), "A/B/2/C"), "c2");
234 
235 		// Check extended unicode characters.
236 		in = "{'𤭢𤭢':'𤭢𤭢'}";
237 		checkStep(1, in, JsonMap.ofJson(in).getString("𤭢𤭢"), "𤭢𤭢");
238 	}
239 
240 	private static String getDeepString(JsonMap m, String url) {
241 		var r = ObjectRest.create(m);
242 		return (String)r.get(url);
243 	}
244 
245 	private static Boolean getDeepBoolean(JsonMap m, String url) {
246 		var r = ObjectRest.create(m);
247 		return (Boolean)r.get(url);
248 	}
249 
250 	private static void checkStep(int step, String input, String output, String expectedValue) {
251 		if (!output.equals(expectedValue)) {
252 			var msg = "Step #" + step + " failed: [" + input + "]->[" + output + "]...Expected value=[" + expectedValue + "]";
253 			fail(msg);
254 		}
255 	}
256 
257 	//====================================================================================================
258 	// testComparison
259 	//====================================================================================================
260 	@Test void a02_comparison() throws Exception {
261 		var m1 = JsonMap.ofJson("{ firstName:'John', lastName:'Smith', age:123, isDeceased:false }");
262 		var m2 = JsonMap.ofJson("{ age:123, isDeceased:false, lastName:'Smith', firstName:'John' }");
263 
264 		assertEquals(m1, m2);
265 	}
266 
267 	//====================================================================================================
268 	// testParent
269 	//====================================================================================================
270 	@Test void a03_parent() throws Exception {
271 		var m1 = JsonMap.ofJson("{a:1}");
272 		var m2 = JsonMap.ofJson("{b:2}").inner(m1);
273 
274 		assertEquals(Integer.valueOf(1), m2.getInt("a"));
275 	}
276 
277 	//====================================================================================================
278 	// testUpdatability
279 	//====================================================================================================
280 	@Test void a04_updatability() throws Exception {
281 		var m = JsonMap.ofJson("{a:[{b:'c'}]}");
282 		var l = m.getList("a");
283 		var m2 = l.getMap(0);
284 		m2.put("b", "x");
285 		assertBean(m, "a", "[{b=x}]");
286 
287 		m = JsonMap.ofJson("{a:[{b:'c'}]}");
288 		for (var m3 : m.getList("a").elements(JsonMap.class))
289 			m3.put("b", "y");
290 
291 		assertBean(m, "a", "[{b=y}]");
292 	}
293 
294 	//====================================================================================================
295 	// testAtMethods
296 	//====================================================================================================
297 	@Test void a05_atMethods() throws Exception {
298 		var m = JsonMap.ofJson("{a:[{b:'c'}]}");
299 		var r = m.getAt("a/0/b", String.class);
300 
301 		assertEquals("c", r);
302 
303 		m.putAt("a/0/b", "d");
304 		r = m.getAt("a/0/b", String.class);
305 		assertEquals("d", r);
306 
307 		m.postAt("a", "e");
308 		r = m.getAt("a/1", String.class);
309 		assertEquals("e", r);
310 
311 		m.deleteAt("a/1");
312 		assertEquals("{a:[{b:'d'}]}", m.toString());
313 	}
314 
315 	//====================================================================================================
316 	// JsonMap(Reader)
317 	//====================================================================================================
318 	@Test void a06_fromReader() throws Exception {
319 		assertBean(JsonMap.ofJson(reader("{foo:'bar'}")), "foo", "bar");
320 	}
321 
322 	//====================================================================================================
323 	// testGetMap
324 	//====================================================================================================
325 	@Test void a07_getMap() throws Exception {
326 		var m = JsonMap.ofJson("{a:{1:'true',2:'false'}}");
327 		var m2 = m.getMap("a", Integer.class, Boolean.class, null);
328 		assertJson("{'1':true,'2':false}", m2);
329 		assertEquals(Integer.class, m2.keySet().iterator().next().getClass());
330 		assertEquals(Boolean.class, m2.values().iterator().next().getClass());
331 
332 		m2 = m.getMap("b", Integer.class, Boolean.class, null);
333 		assertNull(m2);
334 
335 		m2 = m.get("a", Map.class, Integer.class, Boolean.class);
336 		assertJson("{'1':true,'2':false}", m2);
337 		assertEquals(Integer.class, m2.keySet().iterator().next().getClass());
338 		assertEquals(Boolean.class, m2.values().iterator().next().getClass());
339 
340 		m2 = m.get("b", Map.class, Integer.class, Boolean.class);
341 		assertNull(m2);
342 	}
343 
344 	//====================================================================================================
345 	// testGetList
346 	//====================================================================================================
347 	@Test void a08_getList() throws Exception {
348 		var m = JsonMap.ofJson("{a:['123','456']}");
349 		var l2 = m.getList("a", Integer.class, null);
350 		assertList(l2, "123", "456");
351 		assertEquals(Integer.class, l2.iterator().next().getClass());
352 
353 		l2 = m.getList("b", Integer.class, null);
354 		assertNull(l2);
355 
356 		l2 = m.get("a", List.class, Integer.class);
357 		assertList(l2, "123", "456");
358 		assertEquals(Integer.class, l2.iterator().next().getClass());
359 
360 		l2 = m.get("b", List.class, Integer.class);
361 		assertNull(l2);
362 	}
363 }