source: josm/trunk/test/unit/org/openstreetmap/josm/data/gpx/GpxDataTest.java@ 18870

Last change on this file since 18870 was 18870, checked in by taylor.smock, 7 months ago

See #16567: Update to JUnit 5

This converts most tests to use @Annotations. There are also some performance
improvements as it relates to tests.

  • Property svn:eol-style set to native
File size: 18.0 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.gpx;
3
4import static org.junit.jupiter.api.Assertions.assertEquals;
5import static org.junit.jupiter.api.Assertions.assertFalse;
6import static org.junit.jupiter.api.Assertions.assertNotNull;
7import static org.junit.jupiter.api.Assertions.assertNull;
8import static org.junit.jupiter.api.Assertions.assertThrows;
9import static org.junit.jupiter.api.Assertions.assertTrue;
10
11import java.io.IOException;
12import java.time.Instant;
13import java.util.ArrayList;
14import java.util.Arrays;
15import java.util.Collection;
16import java.util.Collections;
17import java.util.List;
18import java.util.stream.Collectors;
19import java.util.stream.Stream;
20
21import org.junit.jupiter.api.BeforeEach;
22import org.junit.jupiter.api.Test;
23import org.openstreetmap.josm.TestUtils;
24import org.openstreetmap.josm.data.Bounds;
25import org.openstreetmap.josm.data.DataSource;
26import org.openstreetmap.josm.data.coor.EastNorth;
27import org.openstreetmap.josm.data.coor.ILatLon;
28import org.openstreetmap.josm.data.coor.LatLon;
29import org.openstreetmap.josm.data.gpx.GpxData.GpxDataChangeEvent;
30import org.openstreetmap.josm.data.gpx.GpxData.GpxDataChangeListener;
31import org.openstreetmap.josm.data.projection.ProjectionRegistry;
32import org.openstreetmap.josm.io.GpxReaderTest;
33import org.openstreetmap.josm.testutils.annotations.Projection;
34import org.openstreetmap.josm.tools.ListenerList;
35import org.openstreetmap.josm.tools.date.Interval;
36import org.xml.sax.SAXException;
37
38import nl.jqno.equalsverifier.EqualsVerifier;
39import nl.jqno.equalsverifier.Warning;
40
41/**
42 * Unit tests for class {@link GpxData}.
43 */
44@Projection
45class GpxDataTest {
46 private GpxData data;
47
48 /**
49 * Set up empty test data
50 */
51 @BeforeEach
52 public void setUp() {
53 data = new GpxData();
54 }
55
56 /**
57 * Test method for {@link GpxData#mergeFrom(GpxData)}.
58 */
59 @Test
60 void testMergeFrom() {
61 GpxTrack track = singleWaypointGpxTrack();
62 GpxRoute route = singleWaypointRoute();
63 WayPoint newWP = new WayPoint(LatLon.NORTH_POLE);
64 WayPoint existingWP = new WayPoint(LatLon.SOUTH_POLE);
65
66 GpxData dataToMerge = new GpxData();
67 dataToMerge.addTrack(track);
68 dataToMerge.addRoute(route);
69 dataToMerge.addWaypoint(newWP);
70
71 data.addWaypoint(existingWP);
72 data.mergeFrom(dataToMerge);
73
74 assertEquals(1, data.getTracks().size());
75 assertEquals(1, data.getRoutes().size());
76 assertEquals(2, data.getWaypoints().size());
77
78 assertTrue(data.getTracks().contains(track));
79 assertTrue(data.getRoutes().contains(route));
80 assertTrue(data.getWaypoints().contains(newWP));
81 assertTrue(data.getWaypoints().contains(existingWP));
82 }
83
84 /**
85 * Test method for {@link GpxData#mergeFrom(GpxData, boolean, boolean)} including cutting/connecting tracks using actual files.
86 * @throws Exception if the track cannot be parsed
87 */
88 @Test
89 void testMergeFromFiles() throws Exception {
90 testMerge(false, false, "Merged-all"); // regular merging
91 testMerge(true, false, "Merged-cut"); // cut overlapping tracks, but do not connect them
92 testMerge(true, true, "Merged-cut-connect"); // cut overlapping tracks and connect them
93 }
94
95 private static void testMerge(boolean cut, boolean connect, String exp) throws IOException, SAXException {
96 final GpxData own = getGpx("Layer1");
97 final GpxData other = getGpx("Layer2");
98 final GpxData expected = getGpx(exp);
99 own.mergeFrom(other, cut, connect);
100 own.put(GpxConstants.META_BOUNDS, null);
101 expected.put(GpxConstants.META_BOUNDS, null); //they are only updated by GpxWriter
102 assertEquals(expected, own, exp + " didn't match!");
103 }
104
105 private static GpxData getGpx(String file) throws IOException, SAXException {
106 return GpxReaderTest.parseGpxData(TestUtils.getTestDataRoot() + "mergelayers/" + file + ".gpx");
107 }
108
109 /**
110 * Test method for {@link GpxData#getTracks()}, {@link GpxData#addTrack(IGpxTrack)}, {@link GpxData#removeTrack(IGpxTrack)}.
111 */
112 @Test
113 void testTracks() {
114 assertEquals(0, data.getTracks().size());
115
116 GpxTrack track1 = emptyGpxTrack();
117 GpxTrack track2 = singleWaypointGpxTrack();
118 data.addTrack(track1);
119 assertEquals(1, data.getTracks().size());
120 data.addTrack(track2);
121 assertEquals(2, data.getTracks().size());
122 assertTrue(data.getTracks().contains(track1));
123 assertTrue(data.getTracks().contains(track2));
124
125 data.removeTrack(track1);
126 assertEquals(1, data.getTracks().size());
127 assertFalse(data.getTracks().contains(track1));
128 assertTrue(data.getTracks().contains(track2));
129 }
130
131 /**
132 * Test method for {@link GpxData#addTrack(IGpxTrack)}.
133 */
134 @Test
135 void testAddTrackFails() {
136 GpxTrack track1 = emptyGpxTrack();
137 data.addTrack(track1);
138 assertThrows(IllegalArgumentException.class, () -> data.addTrack(track1));
139 }
140
141 /**
142 * Test method for {@link GpxData#removeTrack(IGpxTrack)}.
143 */
144 @Test
145 void testRemoveTrackFails() {
146 GpxTrack track1 = emptyGpxTrack();
147 data.addTrack(track1);
148 data.removeTrack(track1);
149 assertThrows(IllegalArgumentException.class, () -> data.removeTrack(track1));
150 }
151
152 /**
153 * Test method for {@link GpxData#getRoutes()}, {@link GpxData#addRoute(GpxRoute)}, {@link GpxData#removeRoute(GpxRoute)}.
154 */
155 @Test
156 void testRoutes() {
157 assertEquals(0, data.getTracks().size());
158
159 GpxRoute route1 = new GpxRoute();
160 GpxRoute route2 = new GpxRoute();
161 route2.routePoints.add(new WayPoint(LatLon.NORTH_POLE));
162 data.addRoute(route1);
163 assertEquals(1, data.getRoutes().size());
164 data.addRoute(route2);
165 assertEquals(2, data.getRoutes().size());
166 assertTrue(data.getRoutes().contains(route1));
167 assertTrue(data.getRoutes().contains(route2));
168
169 data.removeRoute(route1);
170 assertEquals(1, data.getRoutes().size());
171 assertFalse(data.getRoutes().contains(route1));
172 assertTrue(data.getRoutes().contains(route2));
173 }
174
175 /**
176 * Test method for {@link GpxData#addRoute(GpxRoute)}.
177 */
178 @Test
179 void testAddRouteFails() {
180 GpxRoute route1 = new GpxRoute();
181 data.addRoute(route1);
182 assertThrows(IllegalArgumentException.class, () -> data.addRoute(route1));
183 }
184
185 /**
186 * Test method for {@link GpxData#removeRoute(GpxRoute)}.
187 */
188 @Test
189 void testRemoveRouteFails() {
190 GpxRoute route1 = new GpxRoute();
191 data.addRoute(route1);
192 data.removeRoute(route1);
193 assertThrows(IllegalArgumentException.class, () -> data.removeRoute(route1));
194 }
195
196 /**
197 * Test method for {@link GpxData#getWaypoints()}, {@link GpxData#addWaypoint(WayPoint)}, {@link GpxData#removeWaypoint(WayPoint)}.
198 */
199 @Test
200 void testWaypoints() {
201 assertEquals(0, data.getTracks().size());
202
203 WayPoint waypoint1 = new WayPoint(LatLon.ZERO);
204 WayPoint waypoint2 = new WayPoint(LatLon.NORTH_POLE);
205 data.addWaypoint(waypoint1);
206 assertEquals(1, data.getWaypoints().size());
207 data.addWaypoint(waypoint2);
208 assertEquals(2, data.getWaypoints().size());
209 assertTrue(data.getWaypoints().contains(waypoint1));
210 assertTrue(data.getWaypoints().contains(waypoint2));
211
212 data.removeWaypoint(waypoint1);
213 assertEquals(1, data.getWaypoints().size());
214 assertFalse(data.getWaypoints().contains(waypoint1));
215 assertTrue(data.getWaypoints().contains(waypoint2));
216 }
217
218 /**
219 * Test method for {@link GpxData#addWaypoint(WayPoint)}.
220 */
221 @Test
222 void testAddWaypointFails() {
223 WayPoint waypoint1 = new WayPoint(LatLon.ZERO);
224 data.addWaypoint(waypoint1);
225 assertThrows(IllegalArgumentException.class, () -> data.addWaypoint(waypoint1));
226 }
227
228 /**
229 * Test method for {@link GpxData#removeWaypoint(WayPoint)}.
230 */
231 @Test
232 void testRemoveWaypointFails() {
233 WayPoint waypoint1 = new WayPoint(LatLon.ZERO);
234 data.addWaypoint(waypoint1);
235 data.removeWaypoint(waypoint1);
236 assertThrows(IllegalArgumentException.class, () -> data.removeWaypoint(waypoint1));
237 }
238
239 /**
240 * Test method for {@link GpxData#hasTrackPoints()}.
241 */
242 @Test
243 void testHasTrackPoints() {
244 assertFalse(data.hasTrackPoints());
245 GpxTrack track1 = emptyGpxTrack();
246 data.addTrack(track1);
247 assertFalse(data.hasTrackPoints());
248 GpxTrack track2 = singleWaypointGpxTrack();
249 data.addTrack(track2);
250 assertTrue(data.hasTrackPoints());
251 }
252
253 /**
254 * Test method for {@link GpxData#getTrackPoints()}.
255 */
256 @Test
257 void testGetTrackPoints() {
258 assertEquals(0, data.getTrackPoints().count());
259 GpxTrack track1 = singleWaypointGpxTrack();
260 data.addTrack(track1);
261 assertEquals(1, data.getTrackPoints().count());
262 GpxTrack track2 = singleWaypointGpxTrack();
263 data.addTrack(track2);
264 assertEquals(2, data.getTrackPoints().count());
265 }
266
267 /**
268 * Test method for {@link GpxData#hasRoutePoints()}.
269 */
270 @Test
271 void testHasRoutePoints() {
272
273 }
274
275 /**
276 * Test method for {@link GpxData#isEmpty()}.
277 */
278 @Test
279 void testIsEmpty() {
280 GpxTrack track1 = singleWaypointGpxTrack();
281 WayPoint waypoint = new WayPoint(LatLon.ZERO);
282 GpxRoute route = singleWaypointRoute();
283
284 assertTrue(data.isEmpty());
285
286 data.addTrack(track1);
287 assertFalse(data.isEmpty());
288 data.removeTrack(track1);
289 assertTrue(data.isEmpty());
290
291 data.addWaypoint(waypoint);
292 assertFalse(data.isEmpty());
293 data.removeWaypoint(waypoint);
294 assertTrue(data.isEmpty());
295
296 data.addRoute(route);
297 assertFalse(data.isEmpty());
298 data.removeRoute(route);
299 assertTrue(data.isEmpty());
300 }
301
302 /**
303 * Test method for {@link GpxData#length()}.
304 */
305 @Test
306 void testLength() {
307 GpxTrack track1 = waypointGpxTrack(
308 new WayPoint(new LatLon(0, 0)),
309 new WayPoint(new LatLon(1, 1)),
310 new WayPoint(new LatLon(0, 2)));
311 GpxTrack track2 = waypointGpxTrack(
312 new WayPoint(new LatLon(0, 0)),
313 new WayPoint(new LatLon(-1, 1)));
314 data.addTrack(track1);
315 data.addTrack(track2);
316 assertEquals(3 * new LatLon(0, 0).greatCircleDistance((ILatLon) new LatLon(1, 1)), data.length(), 1);
317 }
318
319 /**
320 * Test method for {@link GpxData#getOrderedTracks()}.
321 */
322 @Test
323 void testGetOrderedTracks() {
324 assertTrue(data.getOrderedTracks().isEmpty());
325
326 WayPoint p1 = new WayPoint(LatLon.NORTH_POLE);
327 WayPoint p2 = new WayPoint(LatLon.NORTH_POLE);
328
329 p1.setInstant(Instant.ofEpochMilli(100020));
330 p2.setInstant(Instant.ofEpochMilli(200020));
331
332 data.addTrack(new GpxTrack(Collections.singletonList(Collections.singletonList(p2)), Collections.emptyMap()));
333 data.addTrack(new GpxTrack(Collections.singletonList(Collections.singletonList(p1)), Collections.emptyMap()));
334
335 List<IGpxTrack> tracks = data.getOrderedTracks();
336 assertEquals(2, tracks.size());
337
338 assertEquals(p1, tracks.get(0).getSegments().iterator().next().getWayPoints().iterator().next());
339 assertEquals(p2, tracks.get(1).getSegments().iterator().next().getWayPoints().iterator().next());
340 }
341
342 /**
343 * Test method for {@link GpxData#getMinMaxTimeForAllTracks()}.
344 */
345 @Test
346 void testGetMinMaxTimeForAllTracks() {
347 assertFalse(data.getMinMaxTimeForAllTracks().isPresent());
348
349 WayPoint p1 = new WayPoint(LatLon.NORTH_POLE);
350 WayPoint p2 = new WayPoint(LatLon.NORTH_POLE);
351 WayPoint p3 = new WayPoint(LatLon.NORTH_POLE);
352 WayPoint p4 = new WayPoint(LatLon.NORTH_POLE);
353 WayPoint p5 = new WayPoint(LatLon.NORTH_POLE);
354 p1.setInstant(Instant.ofEpochMilli(200020));
355 p2.setInstant(Instant.ofEpochMilli(100020));
356 p4.setInstant(Instant.ofEpochMilli(500020));
357 data.addTrack(new GpxTrack(Collections.singletonList(Arrays.asList(p1, p2)), Collections.emptyMap()));
358 data.addTrack(new GpxTrack(Collections.singletonList(Arrays.asList(p3, p4, p5)), Collections.emptyMap()));
359
360 Interval times = data.getMinMaxTimeForAllTracks().orElse(null);
361 assertEquals("1970-01-01T00:01:40.020Z/1970-01-01T00:08:20.020Z", times.toString());
362 assertEquals(Instant.ofEpochMilli(100020), times.getStart());
363 assertEquals(Instant.ofEpochMilli(500020), times.getEnd());
364 }
365
366 /**
367 * Test method for {@link GpxData#nearestPointOnTrack(org.openstreetmap.josm.data.coor.EastNorth, double)}.
368 */
369 @Test
370 void testNearestPointOnTrack() {
371 List<WayPoint> points = Stream
372 .of(new EastNorth(10, 10), new EastNorth(10, 0), new EastNorth(-1, 0))
373 .map(ProjectionRegistry.getProjection()::eastNorth2latlon)
374 .map(WayPoint::new)
375 .collect(Collectors.toList());
376 data.addTrack(new GpxTrack(Collections.singletonList(points), Collections.emptyMap()));
377
378 WayPoint closeToMiddle = data.nearestPointOnTrack(new EastNorth(10, 0), 10);
379 assertEquals(points.get(1), closeToMiddle);
380
381 WayPoint close = data.nearestPointOnTrack(new EastNorth(5, 5), 10);
382 assertEquals(10, close.getEastNorth(ProjectionRegistry.getProjection()).east(), .01);
383 assertEquals(5, close.getEastNorth(ProjectionRegistry.getProjection()).north(), .01);
384
385 close = data.nearestPointOnTrack(new EastNorth(15, 5), 10);
386 assertEquals(10, close.getEastNorth(ProjectionRegistry.getProjection()).east(), .01);
387 assertEquals(5, close.getEastNorth(ProjectionRegistry.getProjection()).north(), .01);
388
389 assertNull(data.nearestPointOnTrack(new EastNorth(5, 5), 1));
390 }
391
392 /**
393 * Test method for {@link GpxData#getDataSources()}.
394 */
395 @Test
396 void testGetDataSources() {
397 DataSource ds = new DataSource(new Bounds(0, 0, 1, 1), "test");
398 data.dataSources.add(ds);
399 assertEquals(new ArrayList<>(Collections.singletonList(ds)), new ArrayList<>(data.getDataSources()));
400 }
401
402 /**
403 * Test method for {@link GpxData#getDataSourceArea()}.
404 */
405 @Test
406 void testGetDataSourceArea() {
407 DataSource ds = new DataSource(new Bounds(0, 0, 1, 1), "test");
408 data.dataSources.add(ds);
409 assertNotNull(data.getDataSourceArea());
410 assertTrue(data.getDataSourceArea().contains(0.5, 0.5));
411 assertFalse(data.getDataSourceArea().contains(0.5, 1.5));
412 }
413
414 /**
415 * Test method for {@link GpxData#getDataSourceBounds()}.
416 */
417 @Test
418 void testGetDataSourceBounds() {
419 Bounds bounds = new Bounds(0, 0, 1, 1);
420 DataSource ds = new DataSource(bounds, "test");
421 data.dataSources.add(ds);
422 assertEquals(Collections.singletonList(bounds), data.getDataSourceBounds());
423 }
424
425 /**
426 * Test method for {@link GpxData#addChangeListener(GpxData.GpxDataChangeListener)},
427 * {@link GpxData#addWeakChangeListener(GpxData.GpxDataChangeListener)},
428 * {@link GpxData#removeChangeListener(GpxData.GpxDataChangeListener)}.
429 */
430 @Test
431 void testChangeListener() {
432 TestChangeListener cl1 = new TestChangeListener();
433 TestChangeListener cl2 = new TestChangeListener();
434
435 data.addChangeListener(cl1);
436 data.addWeakChangeListener(cl2);
437 assertNull(cl1.lastEvent);
438 assertNull(cl2.lastEvent);
439
440 data.addTrack(singleWaypointGpxTrack());
441 assertEquals(data, cl1.lastEvent.getSource());
442 assertEquals(data, cl2.lastEvent.getSource());
443 cl1.lastEvent = null;
444 cl2.lastEvent = null;
445
446 data.addRoute(singleWaypointRoute());
447 assertEquals(data, cl1.lastEvent.getSource());
448 assertEquals(data, cl2.lastEvent.getSource());
449 cl1.lastEvent = null;
450 cl2.lastEvent = null;
451
452 data.removeChangeListener(cl1);
453 data.removeChangeListener(cl2);
454 data.addTrack(singleWaypointGpxTrack());
455 assertNull(cl1.lastEvent);
456 assertNull(cl2.lastEvent);
457 }
458
459 private static class TestChangeListener implements GpxDataChangeListener {
460
461 private GpxDataChangeEvent lastEvent;
462
463 @Override
464 public void gpxDataChanged(GpxDataChangeEvent e) {
465 lastEvent = e;
466 }
467
468 }
469
470 private static GpxTrack emptyGpxTrack() {
471 return new GpxTrack(Collections.<Collection<WayPoint>>emptyList(), Collections.emptyMap());
472 }
473
474 private static GpxTrack singleWaypointGpxTrack() {
475 return new GpxTrack(Collections.singleton(Collections.singleton(new WayPoint(LatLon.ZERO))), Collections.emptyMap());
476 }
477
478 private static GpxTrack waypointGpxTrack(WayPoint... wps) {
479 return new GpxTrack(Collections.singleton(Arrays.asList(wps)), Collections.emptyMap());
480 }
481
482 private static GpxRoute singleWaypointRoute() {
483 GpxRoute route = new GpxRoute();
484 route.routePoints.add(new WayPoint(LatLon.ZERO));
485 return route;
486 }
487
488 /**
489 * Unit test of methods {@link GpxData#equals} and {@link GpxData#hashCode}.
490 */
491 @Test
492 void testEqualsContract() {
493 TestUtils.assumeWorkingEqualsVerifier();
494 GpxExtensionCollection col = new GpxExtensionCollection();
495 col.add("josm", "from-server", "true");
496 EqualsVerifier.forClass(GpxData.class).usingGetClass()
497 .suppress(Warning.NONFINAL_FIELDS)
498 .withIgnoredFields("creator", "fromServer", "fromSession", "storageFile", "initializing", "updating",
499 "suppressedInvalidate", "listeners", "tracks", "routes", "waypoints", "proxy", "segSpans", "modified")
500 .withPrefabValues(WayPoint.class, new WayPoint(LatLon.NORTH_POLE), new WayPoint(LatLon.SOUTH_POLE))
501 .withPrefabValues(ListenerList.class, ListenerList.create(), ListenerList.create())
502 .withPrefabValues(GpxExtensionCollection.class, new GpxExtensionCollection(), col)
503 .verify();
504 }
505}
Note: See TracBrowser for help on using the repository browser.