1 package org.djutils.data;
2
3 import static org.junit.Assert.assertArrayEquals;
4 import static org.junit.Assert.assertEquals;
5 import static org.junit.Assert.assertFalse;
6 import static org.junit.Assert.assertTrue;
7 import static org.junit.Assert.fail;
8
9 import java.util.ArrayList;
10 import java.util.Collection;
11 import java.util.HashMap;
12 import java.util.Iterator;
13 import java.util.LinkedHashMap;
14 import java.util.List;
15 import java.util.Map;
16 import java.util.TreeMap;
17
18 import org.djutils.immutablecollections.ImmutableList;
19 import org.djutils.immutablecollections.ImmutableMap;
20 import org.djutils.primitives.Primitive;
21 import org.junit.Test;
22
23
24
25
26
27
28
29
30
31
32
33
34 public class TestListDataTable
35 {
36
37 @Test
38 public void testListTable()
39 {
40 DataColumn<Integer> column1 = new SimpleDataColumn<>("time", "time rounded to second [s]", int.class);
41 DataColumn<Double> column2 = new SimpleDataColumn<>("value", "measured value [m]", double.class);
42 DataColumn<String> column3 = new SimpleDataColumn<>("remark", "remark about the measurement", String.class);
43
44 assertEquals("time", column1.getId());
45 assertEquals("time rounded to second [s]", column1.getDescription());
46 assertEquals(int.class, column1.getValueType());
47
48 List<DataColumn<?>> columns = new ArrayList<>();
49 columns.add(column1);
50 columns.add(column2);
51 columns.add(column3);
52 ListDataTable table = new ListDataTable("tableId", "tableDescription", columns);
53
54 assertEquals("tableId", table.getId());
55 assertEquals("tableDescription", table.getDescription());
56 assertEquals(3, table.getColumns().size());
57
58 assertArrayEquals(new String[] {"time", "value", "remark"}, table.getColumnIds());
59 assertArrayEquals(new String[] {"time rounded to second [s]", "measured value [m]", "remark about the measurement"},
60 table.getColumnDescriptions());
61 assertArrayEquals(new Class<?>[] {int.class, double.class, String.class}, table.getColumnDataTypes());
62 assertArrayEquals(new String[] {"int", "double", "java.lang.String"}, table.getColumnDataTypeStrings());
63
64
65 assertTrue(table.isEmpty());
66 table.addRecord(new Object[] {2, 5.0, "normal"});
67 assertFalse(table.isEmpty());
68 Map<DataColumn<?>, Object> cdata = new LinkedHashMap<>();
69 cdata.put(column3, "second");
70 cdata.put(column2, 7.7);
71 cdata.put(column1, 4);
72 table.addRecordByColumns(cdata);
73 Map<String, Object> idata = new TreeMap<>();
74 idata.put("time", 6);
75 idata.put("value", 9.12);
76 idata.put("remark", "third");
77 table.addRecordByColumnIds(idata);
78
79 DataRecord record = table.iterator().next();
80 assertArrayEquals(new Object[] {2, 5.0, "normal"}, record.getValues());
81
82 DataColumn<Double> c1 = new SimpleDataColumn<>("x", "x", double.class);
83 DataColumn<double[][]> c2 = new SimpleDataColumn<>("y", "y", double[][].class);
84 ListDataTable txy = new ListDataTable("xy[][]", "x, y[][]", ImmutableList.of(c1, c2));
85 assertArrayEquals(new String[] {"x", "y"}, txy.getColumnIds());
86 assertArrayEquals(new String[] {"x", "y"}, txy.getColumnDescriptions());
87 assertArrayEquals(new Class<?>[] {double.class, double[][].class}, txy.getColumnDataTypes());
88 assertArrayEquals(new String[] {"double", "[[D"}, txy.getColumnDataTypeStrings());
89
90 String tableString = table.toString();
91 assertTrue(tableString.startsWith("ListDataTable"));
92 assertTrue(tableString.contains("tableId"));
93 assertTrue(tableString.contains("tableDescription"));
94 assertTrue(tableString.contains("SimpleDataColumn"));
95
96 String recordString = table.iterator().next().toString();
97 assertTrue(recordString.startsWith("ListDataTable.ListRecord"));
98 assertTrue(recordString.contains("time = 2"));
99 assertTrue(recordString.contains("value = 5.0"));
100 }
101
102
103 @Test
104 public void testSubclassListTable()
105 {
106
107 DataColumn<Double> column = new SimpleDataColumn<>("value", "measured value", double.class);
108 List<DataColumn<?>> columns = new ArrayList<>();
109 columns.add(column);
110 ListDataTable table = new ListDataTable("tableId", "tableDescription", columns);
111
112
113 table.addRecord(new Object[] {5.0});
114 Map<DataColumn<?>, Object> cdata = new LinkedHashMap<>();
115 cdata.put(column, 7.7);
116 table.addRecordByColumns(cdata);
117 Map<String, Object> idata = new TreeMap<>();
118 idata.put("value", 9.12);
119 table.addRecordByColumnIds(idata);
120
121
122 ListDataTable table2 = new ListDataTable("tableId", "tableDescription", columns);
123 table2.addRecord(new Object[] {Double.valueOf(5.0)});
124 cdata = new LinkedHashMap<>();
125 cdata.put(column, Double.valueOf(7.7));
126 table2.addRecordByColumns(cdata);
127 idata = new TreeMap<>();
128 idata.put("value", Double.valueOf(9.12));
129 table2.addRecordByColumnIds(idata);
130
131
132 tableCompare(table, table2);
133
134
135 DataColumn<Number> nColumn = new SimpleDataColumn<>("value", "measured value", Number.class);
136 List<DataColumn<?>> nColumns = new ArrayList<>();
137 nColumns.add(nColumn);
138 ListDataTable nTable = new ListDataTable("tableId", "tableDescription", nColumns);
139
140
141 nTable.addRecord(new Object[] {5.0});
142 Map<DataColumn<?>, Object> cndata = new LinkedHashMap<>();
143 cndata.put(nColumn, 7.7);
144 nTable.addRecordByColumns(cndata);
145 Map<String, Object> indata = new TreeMap<>();
146 indata.put("value", 9.12);
147 nTable.addRecordByColumnIds(indata);
148
149
150 ListDataTable nTable2 = new ListDataTable("tableId", "tableDescription", nColumns);
151 nTable2.addRecord(new Object[] {Double.valueOf(5.0)});
152 cndata = new LinkedHashMap<>();
153 cndata.put(nColumn, Double.valueOf(7.7));
154 nTable2.addRecordByColumns(cndata);
155 indata = new TreeMap<>();
156 indata.put("value", Double.valueOf(9.12));
157 nTable2.addRecordByColumnIds(indata);
158
159
160 tableCompare(nTable, nTable2);
161 }
162
163
164
165
166
167
168
169 public static void tableCompare(final ListDataTable table1, final ListDataTable table2)
170 {
171 assertEquals(table1.getColumns().size(), table2.getColumns().size());
172 assertEquals(table1.getId(), table2.getId());
173 assertEquals(table1.getDescription(), table2.getDescription());
174 assertEquals(table1.getNumberOfColumns(), table2.getNumberOfColumns());
175 assertEquals(table1.getColumns().size(), table2.getColumns().size());
176 for (int i = 0; i < table1.getColumns().size(); i++)
177 {
178 DataColumn<?> c1 = table1.getColumns().get(i);
179 DataColumn<?> c2 = table2.getColumns().get(i);
180 assertEquals(c1.getId(), c2.getId());
181 assertEquals(c1.getDescription(), c2.getDescription());
182 assertTrue(Primitive.isPrimitiveAssignableFrom(c1.getValueType(), c2.getValueType()));
183 assertTrue(Primitive.isPrimitiveAssignableFrom(c2.getValueType(), c1.getValueType()));
184 }
185
186 Iterator<DataRecord> it2 = table2.iterator();
187 for (DataRecord r1 : table1)
188 {
189 assertTrue(it2.hasNext());
190 DataRecord r2 = it2.next();
191 for (int i = 0; i < table1.getColumns().size(); i++)
192 {
193 DataColumn<?> c1 = table1.getColumns().get(i);
194 String c2id = table2.getColumns().get(i).getId();
195 Object v1 = r1.getValue(c1);
196 Object v2 = r2.getValue(c2id);
197 assertEquals(v1.toString(), v2.toString());
198 }
199 }
200 assertFalse(it2.hasNext());
201 }
202
203
204 @Test
205 public void testIllegalColumnTable()
206 {
207 DataColumn<Integer> column1 = new SimpleDataColumn<>("time", "time, rounded to second [s]", int.class);
208 DataColumn<Double> column2 = new SimpleDataColumn<>("value", "measured value [m]", double.class);
209 DataColumn<String> column3 = new SimpleDataColumn<>("remark", "remark about the measurement", String.class);
210 List<DataColumn<?>> columns = new ArrayList<>();
211 columns.add(column1);
212 columns.add(column2);
213 columns.add(column3);
214
215
216
217
218
219 try
220 {
221 new SimpleDataColumn<>(null, "measured value [m]", double.class);
222 fail("null id should have thrown NullPointerException");
223 }
224 catch (NullPointerException npe)
225 {
226
227 }
228 try
229 {
230 new SimpleDataColumn<>("value", null, double.class);
231 fail("null description should have thrown NullPointerException");
232 }
233 catch (NullPointerException npe)
234 {
235
236 }
237 try
238 {
239 new SimpleDataColumn<>("value", "measured value [m]", null);
240 fail("null valueType should have thrown NullPointerException");
241 }
242 catch (NullPointerException npe)
243 {
244
245 }
246 try
247 {
248 new SimpleDataColumn<>("", "measured value [m]", double.class);
249 fail("empty id should have thrown IllegalArgumentException");
250 }
251 catch (IllegalArgumentException iae)
252 {
253
254 }
255
256
257
258
259
260 List<DataColumn<?>> cx = new ArrayList<>();
261 cx.add(column1);
262 cx.add(column1);
263 cx.add(column3);
264 try
265 {
266 new ListDataTable("tableId", "tableDescription", cx);
267 fail("duplicate column should have thrown IllegalArgumentException");
268 }
269 catch (IllegalArgumentException iae)
270 {
271
272 }
273
274 cx = new ArrayList<>();
275 cx.add(column1);
276 cx.add(new SimpleDataColumn<>("time", "another timestamp", double.class));
277 cx.add(column3);
278 try
279 {
280 new ListDataTable("tableId", "tableDescription", cx);
281 fail("duplicate column id should have thrown IllegalArgumentException");
282 }
283 catch (IllegalArgumentException iae)
284 {
285
286 }
287
288 try
289 {
290 new ListDataTable(null, "tableDescription", columns);
291 fail("null id should have thrown NullPointerException");
292 }
293 catch (NullPointerException iae)
294 {
295
296 }
297
298 try
299 {
300 new ListDataTable("", "tableDescription", columns);
301 fail("empty id should have thrown IllegalArgumentException");
302 }
303 catch (IllegalArgumentException iae)
304 {
305
306 }
307
308 try
309 {
310 new ListDataTable("tableId", null, columns);
311 fail("null id should have thrown NullPointerException");
312 }
313 catch (NullPointerException iae)
314 {
315
316 }
317
318 try
319 {
320 new ListDataTable("tableId", "tableDescription", (ImmutableList<DataColumn<?>>) null);
321 fail("null columns should have thrown NullPointerException");
322 }
323 catch (NullPointerException iae)
324 {
325
326 }
327
328 try
329 {
330 new ListDataTable("tableId", "tableDescription", (Collection<DataColumn<?>>) null);
331 fail("null columns should have thrown NullPointerException");
332 }
333 catch (NullPointerException iae)
334 {
335
336 }
337
338 try
339 {
340 new ListDataTable("tableId", "tableDescription", new ArrayList<DataColumn<?>>());
341 fail("zero columns should have thrown IllegalArgumentException");
342 }
343 catch (IllegalArgumentException iae)
344 {
345
346 }
347 }
348
349
350 @Test
351 public void testIllegalRecordTable()
352 {
353 DataColumn<Integer> column1 = new SimpleDataColumn<>("time", "time, rounded to second [s]", int.class);
354 DataColumn<Double> column2 = new SimpleDataColumn<>("value", "measured value [m]", double.class);
355 DataColumn<String> column3 = new SimpleDataColumn<>("remark", "remark about the measurement", String.class);
356 List<DataColumn<?>> columns = new ArrayList<>();
357 columns.add(column1);
358 columns.add(column2);
359 columns.add(column3);
360 ListDataTable table = new ListDataTable("tableId", "tableDescription", columns);
361
362
363
364
365
366 try
367 {
368 table.addRecord((Object[]) null);
369 fail("null data record should have raised exception");
370 }
371 catch (NullPointerException npe)
372 {
373
374 }
375
376 try
377 {
378 table.addRecordByColumnIds((Map<String, Object>) null);
379 fail("null data record should have raised exception");
380 }
381 catch (NullPointerException npe)
382 {
383
384 }
385
386 try
387 {
388 table.addRecordByColumns((Map<DataColumn<?>, Object>) null);
389 fail("null data record should have raised exception");
390 }
391 catch (NullPointerException npe)
392 {
393
394 }
395
396
397
398
399
400 try
401 {
402 table.addRecord(new Object[] {});
403 fail("empty data record should have raised exception");
404 }
405 catch (IllegalArgumentException iae)
406 {
407
408 }
409
410 try
411 {
412 table.addRecordByColumnIds(new HashMap<String, Object>());
413 fail("empty data record should have raised exception");
414 }
415 catch (IllegalArgumentException iae)
416 {
417
418 }
419
420 try
421 {
422 table.addRecordByColumns(new HashMap<DataColumn<?>, Object>());
423 fail("empty data record should have raised exception");
424 }
425 catch (IllegalArgumentException iae)
426 {
427
428 }
429
430
431
432
433
434 try
435 {
436 table.addRecord(new Object[] {1, 2, 3, 4});
437 fail("too long data record should have raised exception");
438 }
439 catch (IllegalArgumentException iae)
440 {
441
442 }
443
444 try
445 {
446 table.addRecordByColumnIds(ImmutableMap.of("time", 3, "value", 3.5, "remark", "none", "extra", "xx"));
447 fail("too long data record should have raised exception");
448 }
449 catch (IllegalArgumentException iae)
450 {
451
452 }
453
454 try
455 {
456 DataColumn<String> column4 = new SimpleDataColumn<>("c4", "column 4", String.class);
457 table.addRecordByColumns(ImmutableMap.of(column1, 3, column2, 3.5, column3, "remark", column4, "xx"));
458 fail("too long data record should have raised exception");
459 }
460 catch (IllegalArgumentException iae)
461 {
462
463 }
464
465
466
467
468
469 try
470 {
471 table.addRecord(new Object[] {1, 2, 3});
472 fail("wrong type data record should have raised exception");
473 }
474 catch (IllegalArgumentException iae)
475 {
476
477 }
478
479 try
480 {
481 table.addRecordByColumnIds(ImmutableMap.of("time", 3, "value", 2L, "remark", "none"));
482 fail("wrong type data record should have raised exception");
483 }
484 catch (IllegalArgumentException iae)
485 {
486
487 }
488
489 try
490 {
491 table.addRecordByColumns(ImmutableMap.of(column1, 3, column2, 3.5, column3, 2L));
492 fail("wrong type data record should have raised exception");
493 }
494 catch (IllegalArgumentException iae)
495 {
496
497 }
498
499
500
501
502
503 try
504 {
505 table.addRecordByColumnIds(ImmutableMap.of("time", 3, "remark", "none", "wrong", 3));
506 fail("wrong type data record should have raised exception");
507 }
508 catch (IllegalArgumentException iae)
509 {
510
511 }
512
513 try
514 {
515 DataColumn<String> column4 = new SimpleDataColumn<>("c4", "column 4", String.class);
516 table.addRecordByColumns(ImmutableMap.of(column1, 3, column2, 4.5, column4, "xx"));
517 fail("wrong type data record should have raised exception");
518 }
519 catch (IllegalArgumentException iae)
520 {
521
522 }
523
524 }
525
526 }