1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.juneau.commons.collections;
18
19 import static org.apache.juneau.TestUtils.assertThrowsWithMessage;
20 import static org.apache.juneau.commons.utils.CollectionUtils.*;
21 import static org.apache.juneau.junit.bct.BctAssertions.*;
22 import static org.junit.jupiter.api.Assertions.*;
23
24 import java.util.*;
25
26 import org.apache.juneau.*;
27 import org.junit.jupiter.api.*;
28
29 class SimpleMap_Test extends TestBase {
30
31
32
33
34 @Test
35 void a01_nullKey_singleEntry() {
36 var keys = a((String)null);
37 var values = a("value1");
38
39 var map = new SimpleMap<>(keys, values);
40
41 assertSize(1, map);
42 assertEquals("value1", map.get(null));
43 assertTrue(map.containsKey(null));
44 }
45
46 @Test
47 void a02_nullKey_withOtherKeys() {
48 var keys = a("key1", null, "key3");
49 var values = a("value1", "value2", "value3");
50
51 var map = new SimpleMap<>(keys, values);
52
53 assertSize(3, map);
54 assertEquals("value1", map.get("key1"));
55 assertEquals("value2", map.get(null));
56 assertEquals("value3", map.get("key3"));
57 assertTrue(map.containsKey(null));
58 }
59
60 @Test
61 void a03_nullKey_cannotModify() {
62 var keys = a("key1", null);
63 var values = a("value1", "value2");
64
65 var map = new SimpleMap<>(keys, values);
66
67 assertThrows(UnsupportedOperationException.class, () -> {
68 map.put(null, "newValue");
69 });
70
71
72 assertEquals("value2", map.get(null));
73 }
74
75 @Test
76 void a04_nullKey_withNullValue() {
77 var keys = a((String)null);
78 var values = a((String)null);
79
80 SimpleMap<String,String> map = new SimpleMap<>(keys, values);
81
82 assertSize(1, map);
83 assertNull(map.get(null));
84 assertTrue(map.containsKey(null));
85 }
86
87 @Test
88 void a05_nullKey_entrySet() {
89 var keys = a("key1", null, "key3");
90 var values = a("value1", "value2", "value3");
91
92 var map = new SimpleMap<>(keys, values);
93
94 var foundNullKey = false;
95 for (var entry : map.entrySet()) {
96 if (entry.getKey() == null) {
97 foundNullKey = true;
98 assertEquals("value2", entry.getValue());
99
100
101 assertThrows(UnsupportedOperationException.class, () -> {
102 entry.setValue("modified");
103 });
104 }
105 }
106 assertTrue(foundNullKey, "Null key not found in entrySet");
107 }
108
109 @Test
110 void a06_nullKey_keySet() {
111 var keys = a("key1", null, "key3");
112 var values = a("value1", "value2", "value3");
113
114 var map = new SimpleMap<>(keys, values);
115
116 assertTrue(map.keySet().contains(null), "Null key not found in keySet");
117 assertSize(3, map.keySet());
118 }
119
120
121
122
123 @Test
124 void b01_duplicateKey_nonNullKeys() {
125 var keys = a("key1", "key2", "key1");
126 var values = a("value1", "value2", "value3");
127
128 assertThrowsWithMessage(IllegalArgumentException.class, "Duplicate key found: key1", () -> {
129 new SimpleMap<>(keys, values);
130 });
131 }
132
133 @Test
134 void b02_duplicateKey_nullKeys() {
135 var keys = a(null, "key2", null);
136 var values = a("value1", "value2", "value3");
137
138 assertThrowsWithMessage(IllegalArgumentException.class, "Duplicate key found: null", () -> {
139 new SimpleMap<>(keys, values);
140 });
141 }
142
143 @Test
144 void b03_duplicateKey_mixedNullAndNonNull() {
145 var keys = a("key1", null, "key2", "key1");
146 var values = a("value1", "value2", "value3", "value4");
147
148 assertThrowsWithMessage(IllegalArgumentException.class, "Duplicate key found: key1", () -> {
149 new SimpleMap<>(keys, values);
150 });
151 }
152
153 @Test
154 void b04_noDuplicateKeys_success() {
155 var keys = a("key1", null, "key2", "key3");
156 var values = a("value1", "value2", "value3", "value4");
157
158 var map = assertDoesNotThrow(() -> new SimpleMap<>(keys, values));
159
160 assertSize(4, map);
161 assertEquals("value1", map.get("key1"));
162 assertEquals("value2", map.get(null));
163 assertEquals("value3", map.get("key2"));
164 assertEquals("value4", map.get("key3"));
165 }
166
167
168
169
170 @Test
171 void c01_put_throwsException() {
172 var keys = a("key1");
173 var values = a("value1");
174
175 var map = new SimpleMap<>(keys, values);
176
177 assertThrows(UnsupportedOperationException.class, () -> {
178 map.put("key1", "newValue");
179 });
180
181 assertEquals("value1", map.get("key1"));
182 }
183
184 @Test
185 void c02_entrySetValues_cannotModify() {
186 var keys = a("key1", "key2");
187 var values = a("value1", "value2");
188
189 var map = new SimpleMap<>(keys, values);
190
191 for (var entry : map.entrySet()) {
192 assertThrows(UnsupportedOperationException.class, () -> {
193 entry.setValue("modified");
194 });
195 }
196 }
197
198
199
200
201 @Test
202 void d01_arrayLengthMismatch_keysLonger() {
203 var keys = a("key1", "key2", "key3");
204 var values = a("value1", "value2");
205
206 assertThrowsWithMessage(IllegalArgumentException.class, java.util.List.of("array lengths differ", "3", "2"), () -> {
207 new SimpleMap<>(keys, values);
208 });
209 }
210
211 @Test
212 void d02_arrayLengthMismatch_valuesLonger() {
213 var keys = a("key1", "key2");
214 var values = a("value1", "value2", "value3", "value4");
215
216 assertThrowsWithMessage(IllegalArgumentException.class, java.util.List.of("array lengths differ", "2", "4"), () -> {
217 new SimpleMap<>(keys, values);
218 });
219 }
220
221 @Test
222 void d03_arrayLengthMismatch_emptyKeys() {
223 var keys = new String[0];
224 var values = a("value1");
225
226 assertThrowsWithMessage(IllegalArgumentException.class, "array lengths differ", () -> {
227 new SimpleMap<>(keys, values);
228 });
229 }
230
231 @Test
232 void d04_arrayLengthMismatch_emptyValues() {
233 var keys = a("key1", "key2");
234 var values = new String[0];
235
236 assertThrowsWithMessage(IllegalArgumentException.class, "array lengths differ", () -> {
237 new SimpleMap<>(keys, values);
238 });
239 }
240
241
242
243
244 @Test
245 void e01_emptyMap_noNullKeys() {
246 var keys = new String[0];
247 var values = new String[0];
248
249 var map = new SimpleMap<>(keys, values);
250
251 assertEmpty(map);
252 assertNull(map.get(null));
253 assertFalse(map.containsKey(null));
254 }
255
256 @Test
257 void e02_getLookup_nullKeyNotInMap() {
258 var keys = a("key1", "key2");
259 var values = a("value1", "value2");
260
261 var map = new SimpleMap<>(keys, values);
262
263 assertNull(map.get(null));
264 assertFalse(map.containsKey(null));
265 }
266
267 @Test
268 void e03_complexTypes_nullKey() {
269 var keys = a(1, null, 3);
270 var values = a("one", "null-key", "three");
271
272 var map = new SimpleMap<>(keys, values);
273
274 assertEquals("one", map.get(1));
275 assertEquals("null-key", map.get(null));
276 assertEquals("three", map.get(3));
277 }
278
279
280
281
282 @Test
283 void f01_concurrentAccess_safe() throws InterruptedException {
284 var keys = a("key1", null, "key3");
285 var values = a("value1", "value2", "value3");
286
287 var map = new SimpleMap<>(keys, values);
288
289
290 var threads = new Thread[10];
291 for (var i = 0; i < threads.length; i++) {
292 threads[i] = new Thread(() -> {
293 for (var j = 0; j < 1000; j++) {
294 assertEquals("value1", map.get("key1"));
295 assertEquals("value2", map.get(null));
296 assertEquals("value3", map.get("key3"));
297 }
298 });
299 threads[i].start();
300 }
301
302
303 for (var thread : threads) {
304 thread.join();
305 }
306
307
308 assertSize(3, map);
309 assertEquals("value1", map.get("key1"));
310 assertEquals("value2", map.get(null));
311 assertEquals("value3", map.get("key3"));
312 }
313
314
315
316
317
318 @Test
319 void e01_toString_standardFormat() {
320 String[] keys = { "key1", "key2", "key3" };
321 Object[] values = { "value1", "value2", "value3" };
322 SimpleMap<String,Object> map = new SimpleMap<>(keys, values);
323
324 var result = map.toString();
325 assertTrue(result.startsWith("{"));
326 assertTrue(result.endsWith("}"));
327 assertTrue(result.contains("key1=value1"));
328 assertTrue(result.contains("key2=value2"));
329 assertTrue(result.contains("key3=value3"));
330 }
331
332 @Test
333 void e02_toString_emptyMap() {
334 String[] keys = {};
335 Object[] values = {};
336 SimpleMap<String,Object> map = new SimpleMap<>(keys, values);
337
338 assertEquals("{}", map.toString());
339 }
340
341 @Test
342 void e03_equals_sameContents() {
343 String[] keys1 = { "key1", "key2" };
344 Object[] values1 = { "value1", "value2" };
345 SimpleMap<String,Object> map1 = new SimpleMap<>(keys1, values1);
346
347 String[] keys2 = { "key1", "key2" };
348 Object[] values2 = { "value1", "value2" };
349 SimpleMap<String,Object> map2 = new SimpleMap<>(keys2, values2);
350
351 assertTrue(map1.equals(map2));
352 assertTrue(map2.equals(map1));
353 }
354
355 @Test
356 void e04_equals_differentContents() {
357 String[] keys1 = { "key1", "key2" };
358 Object[] values1 = { "value1", "value2" };
359 SimpleMap<String,Object> map1 = new SimpleMap<>(keys1, values1);
360
361 String[] keys2 = { "key1", "key2" };
362 Object[] values2 = { "value1", "value3" };
363 SimpleMap<String,Object> map2 = new SimpleMap<>(keys2, values2);
364
365 assertFalse(map1.equals(map2));
366 assertFalse(map2.equals(map1));
367 }
368
369 @Test
370 void e05_equals_regularMap() {
371 String[] keys = { "key1", "key2" };
372 Object[] values = { "value1", "value2" };
373 SimpleMap<String,Object> map = new SimpleMap<>(keys, values);
374
375 var regularMap = new LinkedHashMap<String, Object>();
376 regularMap.put("key1", "value1");
377 regularMap.put("key2", "value2");
378
379 assertTrue(map.equals(regularMap));
380 assertTrue(regularMap.equals(map));
381 }
382
383 @Test
384 void e06_equals_notAMap() {
385 String[] keys = { "key1" };
386 Object[] values = { "value1" };
387 SimpleMap<String,Object> map = new SimpleMap<>(keys, values);
388
389 assertFalse(map.equals(null));
390 }
391
392 @Test
393 void e07_hashCode_sameContents() {
394 String[] keys1 = { "key1", "key2" };
395 Object[] values1 = { "value1", "value2" };
396 SimpleMap<String,Object> map1 = new SimpleMap<>(keys1, values1);
397
398 String[] keys2 = { "key1", "key2" };
399 Object[] values2 = { "value1", "value2" };
400 SimpleMap<String,Object> map2 = new SimpleMap<>(keys2, values2);
401
402 assertEquals(map1.hashCode(), map2.hashCode());
403 }
404
405 @Test
406 void e08_hashCode_regularMap() {
407 String[] keys = { "key1", "key2" };
408 Object[] values = { "value1", "value2" };
409 SimpleMap<String,Object> map = new SimpleMap<>(keys, values);
410
411 var regularMap = new LinkedHashMap<String, Object>();
412 regularMap.put("key1", "value1");
413 regularMap.put("key2", "value2");
414
415 assertEquals(map.hashCode(), regularMap.hashCode());
416 }
417 }