source: josm/trunk/test/unit/org/openstreetmap/josm/data/osm/DataSetMergerTest.java@ 8450

Last change on this file since 8450 was 8450, checked in by Don-vip, 9 years ago

unit tests - simplify assertions

  • Property svn:eol-style set to native
File size: 28.7 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.osm;
3
4import static org.junit.Assert.assertEquals;
5import static org.junit.Assert.assertFalse;
6import static org.junit.Assert.assertNotNull;
7import static org.junit.Assert.assertNotSame;
8import static org.junit.Assert.assertSame;
9import static org.junit.Assert.assertTrue;
10
11import java.io.StringWriter;
12import java.util.Arrays;
13import java.util.Calendar;
14import java.util.Date;
15import java.util.GregorianCalendar;
16
17import org.junit.After;
18import org.junit.Before;
19import org.junit.BeforeClass;
20import org.junit.Test;
21import org.openstreetmap.josm.JOSMFixture;
22import org.openstreetmap.josm.Main;
23import org.openstreetmap.josm.data.coor.LatLon;
24import org.openstreetmap.josm.data.projection.Projections;
25
26public class DataSetMergerTest {
27
28 @BeforeClass
29 public static void init() {
30 JOSMFixture.createUnitTestFixture().init();
31 }
32
33 private DataSet my;
34 private DataSet their;
35
36 /**
37 * Setup test.
38 */
39 @Before
40 public void setUp() {
41 User.clearUserMap();
42 my = new DataSet();
43 my.setVersion("0.6");
44 their = new DataSet();
45 their.setVersion("0.6");
46 Main.setProjection(Projections.getProjectionByCode("EPSG:3857")); // Mercator
47 }
48
49 private void runConsistencyTests(DataSet ds) throws Exception {
50 StringWriter writer = new StringWriter();
51 DatasetConsistencyTest test = new DatasetConsistencyTest(ds, writer);
52 test.checkReferrers();
53 test.checkCompleteWaysWithIncompleteNodes();
54 test.searchNodes();
55 test.searchWays();
56 test.referredPrimitiveNotInDataset();
57 test.checkZeroNodesWays();
58 String result = writer.toString();
59 if (result.length() > 0)
60 throw new RuntimeException(result);
61 }
62
63 @After
64 public void checkDatasets() throws Exception {
65 runConsistencyTests(my);
66 runConsistencyTests(their);
67 }
68
69 /**
70 * two identical nodes, even in id and version. No confict expected.
71 *
72 * Can happen if data is loaded in two layers and then merged from one layer
73 * on the other.
74 */
75 @Test
76 public void nodeSimple_IdenticalNoConflict() {
77 Node n = new Node(new LatLon(0,0));
78 n.setOsmId(1,1);
79 n.setModified(false);
80 n.put("key1", "value1");
81 my.addPrimitive(n);
82
83 Node n1 = new Node(new LatLon(0,0));
84 n1.setOsmId(1,1);
85 n1.setModified(false);
86 n1.put("key1", "value1");
87 their.addPrimitive(n1);
88
89
90 DataSetMerger visitor = new DataSetMerger(my,their);
91 visitor.merge();
92
93 Node n2 = (Node)my.getPrimitiveById(1, OsmPrimitiveType.NODE);
94 assertTrue(visitor.getConflicts().isEmpty());
95 assertNotSame(n1, n2); // make sure we have a clone
96 assertEquals(1, n2.getId());
97 assertEquals(1, n2.getVersion());
98 assertFalse(n2.isModified());
99 assertEquals("value1", n2.get("key1"));
100
101 // merge target not modified after merging
102 assertFalse(n2.isModified());
103 }
104
105 /**
106 * two nodes, my is unmodified, their is updated and has a higher version
107 * => their version is going to be the merged version
108 *
109 */
110 @Test
111 public void nodeSimple_locallyUnmodifiedNoConflict() {
112 Node n = new Node(new LatLon(0,0));
113 n.setOsmId(1,1);
114 n.setModified(false);
115 n.put("key1", "value1");
116 my.addPrimitive(n);
117
118 Node n1 = new Node(new LatLon(0,0));
119 n1.setOsmId(1,2);
120 n1.setModified(false);
121 n1.put("key1", "value1-new");
122 n1.put("key2", "value2");
123 their.addPrimitive(n1);
124
125
126 DataSetMerger visitor = new DataSetMerger(my,their);
127 visitor.merge();
128
129 Node n2 = (Node)my.getPrimitiveById(1, OsmPrimitiveType.NODE);
130 assertTrue(visitor.getConflicts().isEmpty());
131 assertSame(n, n2); // make sure the merged node is still the original node
132 assertSame(n2.getDataSet(), my);
133 assertEquals(1, n2.getId());
134 assertEquals(2, n2.getVersion());
135 assertFalse(n2.isModified());
136 assertEquals("value1-new", n2.get("key1"));
137 assertEquals("value2", n2.get("key2"));
138
139 // the merge target should not be modified
140 assertFalse(n2.isModified());
141 }
142
143 /**
144 * Node with same id, my is modified, their has a higher version
145 * => results in a conflict
146 *
147 * Use case: node which is modified locally and updated by another mapper on
148 * the server
149 */
150 @Test
151 public void nodeSimple_TagConflict() {
152 Node n = new Node(new LatLon(0,0));
153 n.setOsmId(1,1);
154 n.setModified(true);
155 n.put("key1", "value1");
156 n.put("key2", "value2");
157 my.addPrimitive(n);
158
159 Node n1 = new Node(new LatLon(0,0));
160 n1.setOsmId(1,2);
161 n1.setModified(false);
162 n1.put("key1", "value1-new");
163
164 their.addPrimitive(n1);
165
166
167 DataSetMerger visitor = new DataSetMerger(my,their);
168 visitor.merge();
169
170 Node n2 = (Node)my.getPrimitiveById(1, OsmPrimitiveType.NODE);
171 assertEquals(1,visitor.getConflicts().size());
172 assertSame(n, n2);
173 assertNotSame(n1, n2);
174 assertSame(n1.getDataSet(), their);
175 }
176
177 /**
178 * node with same id, my is deleted, their has a higher version
179 * => results in a conflict
180 *
181 * Use case: node which is deleted locally and updated by another mapper on
182 * the server
183 */
184 @Test
185 public void nodeSimple_DeleteConflict() {
186 Node n = new Node(1, 1);
187 n.setCoor(new LatLon(0,0));
188 n.setDeleted(true);
189 n.put("key1", "value1");
190 my.addPrimitive(n);
191
192 Node n1 = new Node(new LatLon(0,0));
193 n1.setOsmId(1,2);
194 n1.setModified(false);
195 n1.put("key1", "value1-new");
196 n1.put("key2", "value2");
197 their.addPrimitive(n1);
198
199
200 DataSetMerger visitor = new DataSetMerger(my,their);
201 visitor.merge();
202
203 Node n2 = (Node)my.getPrimitiveById(1, OsmPrimitiveType.NODE);
204 assertEquals(1,visitor.getConflicts().size());
205 assertSame(n, n2);
206 assertNotSame(n1, n2);
207 assertSame(n1.getDataSet(), their);
208 }
209
210 /**
211 * My node is deleted, their node has the same id and version and is not deleted.
212 * => mine has precedence
213 *
214 */
215 @Test
216 public void nodeSimple_DeleteConflict_2() {
217 Node n = new Node(new LatLon(0,0));
218 n.setOsmId(1,1);
219 n.setDeleted(true);
220 my.addPrimitive(n);
221
222 Node n1 = new Node(new LatLon(0,0));
223 n1.setOsmId(1,1);
224 their.addPrimitive(n1);
225
226
227 DataSetMerger visitor = new DataSetMerger(my,their);
228 visitor.merge();
229
230 Node n2 = (Node)my.getPrimitiveById(1, OsmPrimitiveType.NODE);
231 assertEquals(0,visitor.getConflicts().size());
232 assertTrue(n2.isVisible());
233 assertSame(n, n2);
234 assertSame(n.getDataSet(), my);
235 assertSame(n1.getDataSet(), their);
236 }
237
238 /**
239 * My and their node are new but semantically equal. My node is deleted.
240 *
241 * => Ignore my node, no conflict
242 */
243 @Test
244 public void nodeSimple_DeleteConflict_3() {
245 Node n = new Node(new LatLon(1,1));
246 n.setDeleted(true);
247 my.addPrimitive(n);
248
249 Node n1 = new Node(new LatLon(1,1));
250 their.addPrimitive(n1);
251
252
253 DataSetMerger visitor = new DataSetMerger(my,their);
254 visitor.merge();
255
256 assertEquals(0, visitor.getConflicts().size());
257 assertSame(n.getDataSet(), my);
258 assertSame(n1.getDataSet(), their);
259 }
260
261 /**
262 * My and their node are new but semantically equal. Both are deleted.
263 *
264 * => take mine
265 *
266 */
267 @Test
268 public void nodeSimple_DeleteConflict_4() {
269 Node n = new Node(new LatLon(1,1));
270 n.setDeleted(true);
271 my.addPrimitive(n);
272
273 Node n1 = new Node(new LatLon(1,1));
274 n1.setDeleted(true);
275 their.addPrimitive(n1);
276
277
278 DataSetMerger visitor = new DataSetMerger(my,their);
279 visitor.merge();
280
281 assertEquals(0,visitor.getConflicts().size());
282 Node n2 = (Node)my.getNodes().toArray()[0];
283 assertSame(n2, n);
284 assertTrue(n2.isDeleted());
285 }
286
287 /**
288 * their node has no assigned id (id == 0) and is semantically equal to one of my
289 * nodes with id == 0
290 *
291 * => merge it onto my node.
292 *
293 */
294 @Test
295 public void nodeSimple_NoIdSemanticallyEqual() {
296
297 Calendar cal = GregorianCalendar.getInstance();
298 User myUser = User.createOsmUser(1111, "my");
299
300 User theirUser = User.createOsmUser(222, "their");
301
302 Node n = new Node();
303 n.setCoor(new LatLon(0,0));
304 n.put("key1", "value1");
305 n.setUser(myUser);
306 n.setTimestamp(cal.getTime());
307
308 my.addPrimitive(n);
309
310 Node n1 = new Node();
311 n1.setCoor(new LatLon(0,0));
312 n1.put("key1", "value1");
313 cal.add(Calendar.HOUR, 1);
314 Date timestamp = cal.getTime();
315 n1.setTimestamp(timestamp);
316 n1.setUser(theirUser);
317 their.addPrimitive(n1);
318
319
320 DataSetMerger visitor = new DataSetMerger(my,their);
321 visitor.merge();
322
323 Node n2 = my.getNodes().iterator().next();
324 assertEquals(0,visitor.getConflicts().size());
325 assertEquals("value1",n2.get("key1"));
326 assertTrue(n1.getTimestamp().equals(n2.getTimestamp()));
327 assertEquals(theirUser,n2.getUser());
328 assertSame(n2, n);
329 assertNotSame(n2, n1);
330 assertSame(n2.getDataSet(), my);
331 }
332
333 /**
334 * my node is incomplete, their node is complete
335 *
336 * => merge it onto my node. My node becomes complete
337 *
338 */
339 @Test
340 public void nodeSimple_IncompleteNode() {
341
342 Node n = new Node(1);
343 my.addPrimitive(n);
344
345 Node n1 = new Node();
346 n1.setCoor(new LatLon(0,0));
347 n1.setOsmId(1,1);
348 n1.put("key1", "value1");
349 Date timestamp = new Date();
350 n1.setTimestamp(timestamp);
351 their.addPrimitive(n1);
352
353
354 DataSetMerger visitor = new DataSetMerger(my,their);
355 visitor.merge();
356
357 Node n2 = my.getNodes().iterator().next();
358 assertEquals(0,visitor.getConflicts().size());
359 assertEquals("value1",n2.get("key1"));
360 assertTrue(n1.getTimestamp().equals(n2.getTimestamp()));
361 assertFalse(n2.isIncomplete());
362 assertSame(n2, n);
363 }
364
365 /**
366 * their way has a higher version and different tags. the nodes are the same. My
367 * way is not modified. Merge is possible. No conflict.
368 *
369 * => merge it onto my way.
370 *
371 */
372 @Test
373 public void waySimple_IdenicalNodesDifferentTags() {
374
375 // -- the target dataset
376
377 Node n1 = new Node();
378 n1.setCoor(new LatLon(0,0));
379 n1.setOsmId(1,1);
380 my.addPrimitive(n1);
381
382 Node n2 = new Node();
383 n2.setCoor(new LatLon(0,0));
384 n2.setOsmId(2,1);
385
386 my.addPrimitive(n2);
387
388 Way myWay = new Way();
389 myWay.setOsmId(3,1);
390 myWay.put("key1", "value1");
391 myWay.addNode(n1);
392 myWay.addNode(n2);
393 my.addPrimitive(myWay);
394
395 // -- the source data set
396
397 Node n3 = new Node(new LatLon(0,0));
398 n3.setOsmId(1,1);
399 their.addPrimitive(n3);
400
401 Node n4 = new Node(new LatLon(1,1));
402 n4.setOsmId(2,1);
403 their.addPrimitive(n4);
404
405 Way theirWay = new Way();
406 theirWay.setOsmId(3,2);
407 theirWay.put("key1", "value1");
408 theirWay.put("key2", "value2");
409 theirWay.addNode(n3);
410 theirWay.addNode(n4);
411 their.addPrimitive(theirWay);
412
413
414 DataSetMerger visitor = new DataSetMerger(my,their);
415 visitor.merge();
416
417 // -- tests
418 Way merged = (Way)my.getPrimitiveById(3, OsmPrimitiveType.WAY);
419 assertEquals(0,visitor.getConflicts().size());
420 assertEquals("value1",merged.get("key1"));
421 assertEquals("value2",merged.get("key2"));
422 assertEquals(3,merged.getId());
423 assertEquals(2,merged.getVersion());
424 assertEquals(2,merged.getNodesCount());
425 assertEquals(1,merged.getNode(0).getId());
426 assertEquals(2,merged.getNode(1).getId());
427 assertSame(merged, myWay);
428 assertSame(merged.getDataSet(), my);
429
430 Node mergedNode = (Node)my.getPrimitiveById(1, OsmPrimitiveType.NODE);
431 assertSame(mergedNode, n1);
432 mergedNode = (Node)my.getPrimitiveById(2, OsmPrimitiveType.NODE);
433 assertSame(mergedNode, n2);
434
435 assertFalse(merged.isModified());
436 }
437
438 /**
439 * their way has a higher version and different tags. And it has more nodes. Two
440 * of the existing nodes are modified.
441 *
442 * => merge it onto my way, no conflict
443 *
444 */
445 @Test
446 public void waySimple_AdditionalNodesAndChangedNodes() {
447
448 // -- my data set
449
450 Node n1 = new Node(new LatLon(0,0));
451 n1.setOsmId(1,1);
452 my.addPrimitive(n1);
453
454 Node n2 = new Node(new LatLon(1,1));
455 n2.setOsmId(2,1);
456 my.addPrimitive(n2);
457
458 Way myWay = new Way();
459 myWay.setOsmId(3,1);
460 myWay.addNode(n1);
461 myWay.addNode(n2);
462 my.addPrimitive(myWay);
463
464 // --- their data set
465
466 Node n3 = new Node(new LatLon(0,0));
467 n3.setOsmId(1,1);
468 their.addPrimitive(n3);
469
470 Node n5 = new Node(new LatLon(1,1));
471 n5.setOsmId(4,1);
472
473 their.addPrimitive(n5);
474
475 Node n4 = new Node(new LatLon(2,2));
476 n4.setOsmId(2,2);
477 n4.put("key1", "value1");
478 their.addPrimitive(n4);
479
480
481 Way theirWay = new Way();
482 theirWay.setOsmId(3,2);
483 theirWay.addNode(n3);
484 theirWay.addNode(n5); // insert a node
485 theirWay.addNode(n4); // this one is updated
486 their.addPrimitive(theirWay);
487
488 DataSetMerger visitor = new DataSetMerger(my,their);
489 visitor.merge();
490
491 // -- tests
492 Way merged = (Way)my.getPrimitiveById(3, OsmPrimitiveType.WAY);
493 assertEquals(0,visitor.getConflicts().size());
494 assertEquals(3,merged.getId());
495 assertEquals(2,merged.getVersion());
496 assertEquals(3,merged.getNodesCount());
497 assertEquals(1,merged.getNode(0).getId());
498 assertEquals(4,merged.getNode(1).getId());
499 assertEquals(2,merged.getNode(2).getId());
500 assertEquals("value1",merged.getNode(2).get("key1"));
501
502 assertSame(merged.getNode(0), n1);
503 assertNotSame(merged.getNode(1), n5); // must be clone of the original node in their
504 assertSame(merged.getNode(2), n2);
505
506 assertFalse(merged.isModified()); // the target wasn't modified before merging, it mustn't be after merging
507 }
508
509 /**
510 * their way has a higher version and different nodes. My way is modified.
511 *
512 * => merge onto my way not possible, create a conflict
513 *
514 */
515 @Test
516 public void waySimple_DifferentNodesAndMyIsModified() {
517
518 // -- the target dataset
519
520 Node n1 = new Node(new LatLon(0,0));
521 n1.setOsmId(1,1);
522 my.addPrimitive(n1);
523
524 Node n2 = new Node(new LatLon(1,1));
525 n2.setOsmId(2,1);
526 my.addPrimitive(n2);
527
528 Way myWay = new Way();
529 myWay.setOsmId(3,1);
530
531 myWay.addNode(n1);
532 myWay.addNode(n2);
533 myWay.setModified(true);
534 myWay.put("key1", "value1");
535 my.addPrimitive(myWay);
536
537 // -- the source dataset
538
539 Node n3 = new Node(new LatLon(0,0));
540 n3.setOsmId(1,1);
541 their.addPrimitive(n3);
542
543 Node n5 = new Node(new LatLon(1,1));
544 n5.setOsmId(4,1);
545 their.addPrimitive(n5);
546
547 Node n4 = new Node(new LatLon(2,2));
548 n4.setOsmId(2,1);
549 n4.put("key1", "value1");
550 their.addPrimitive(n4);
551
552
553 Way theirWay = new Way();
554 theirWay.setOsmId(3,2);
555
556 theirWay.addNode(n3);
557 theirWay.addNode(n5); // insert a node
558 theirWay.addNode(n4); // this one is updated
559 their.addPrimitive(theirWay);
560
561
562 DataSetMerger visitor = new DataSetMerger(my, their);
563 visitor.merge();
564
565 Way merged = (Way)my.getPrimitiveById(3, OsmPrimitiveType.WAY);
566 assertEquals(1,visitor.getConflicts().size());
567 assertEquals(3,merged.getId());
568 assertEquals(1,merged.getVersion());
569 assertEquals(2,merged.getNodesCount());
570 assertEquals(1,merged.getNode(0).getId());
571 assertEquals(2,merged.getNode(1).getId());
572 assertEquals("value1",merged.get("key1"));
573 }
574
575
576 /**
577 * their way is not visible anymore.
578 *
579 * => conflict
580 *
581 */
582 @Test
583 public void waySimple_TheirVersionNotVisibleMyIsModified() {
584
585
586 Node mn1 = new Node(new LatLon(0,0));
587 mn1.setOsmId(1,1);
588 my.addPrimitive(mn1);
589
590 Node mn2 = new Node(new LatLon(1,1));
591 mn2.setOsmId(2,1);
592 my.addPrimitive(mn2);
593
594 Way myWay = new Way();
595 myWay.setOsmId(3,1);
596 myWay.addNode(mn1);
597 myWay.addNode(mn2);
598 myWay.setModified(true);
599 my.addPrimitive(myWay);
600
601
602 Way theirWay = new Way();
603 theirWay.setOsmId(3,2);
604 theirWay.setVisible(false);
605 /* Invisible objects fetched from the server should be marked as "deleted".
606 * Otherwise it's an error.
607 */
608 theirWay.setDeleted(true);
609 their.addPrimitive(theirWay);
610
611 DataSetMerger visitor = new DataSetMerger(my,their);
612 visitor.merge();
613
614 Way merged = (Way)my.getPrimitiveById(3, OsmPrimitiveType.WAY);
615 assertEquals(1,visitor.getConflicts().size());
616 assertTrue(visitor.getConflicts().hasConflictForMy(myWay));
617 assertTrue(visitor.getConflicts().hasConflictForTheir(theirWay));
618 assertEquals(myWay,merged);
619 }
620
621 /**
622 * my and their way have no ids, nodes they refer to have an id. but
623 * my and their way are semantically equal. so technical attributes of
624 * their way can be merged on my way. No conflict.
625 *
626 */
627 @Test
628 public void waySimple_twoWaysWithNoId_NodesWithId() {
629
630 // -- my data set
631
632 Node n1 = new Node(new LatLon(0,0));
633 n1.setOsmId(1,1);
634 my.addPrimitive(n1);
635
636 Node n2 = new Node(new LatLon(1,1));
637 n2.setOsmId(2,1);
638 my.addPrimitive(n2);
639
640 Way myWay = new Way();
641 myWay.addNode(n1);
642 myWay.addNode(n2);
643 my.addPrimitive(myWay);
644
645 // -- their data set
646
647 Node n3 = new Node(new LatLon(0,0));
648 n3.setOsmId(1,1);
649 their.addPrimitive(n3);
650
651 Node n4 = new Node(new LatLon(1,1));
652 n4.setOsmId(2,1);
653 their.addPrimitive(n4);
654
655 Way theirWay = new Way();
656 theirWay.addNode(n3);
657 theirWay.addNode(n4);
658 User user = User.createOsmUser(1111, "their");
659 theirWay.setUser(user);
660 theirWay.setTimestamp(new Date());
661 their.addPrimitive(theirWay);
662
663 DataSetMerger visitor = new DataSetMerger(my,their);
664 visitor.merge();
665
666 // -- tests
667 Way merged = (Way)my.getWays().toArray()[0];
668 assertEquals(0,visitor.getConflicts().size());
669 assertEquals("their", merged.getUser().getName());
670 assertEquals(1111, merged.getUser().getId());
671 assertEquals(theirWay.getTimestamp(), merged.getTimestamp());
672 assertSame(merged, myWay);
673 assertSame(merged.getNode(0), n1);
674 assertSame(merged.getNode(1), n2);
675
676 assertFalse(merged.isModified());
677 }
678
679 /**
680 * my and their way have no ids, neither do the nodes they refer to. but
681 * my and their way are semantically equal. so technical attributes of
682 * their way can be merged on my way. No conflict.
683 *
684 */
685 @Test
686 public void waySimple_twoWaysWithNoId_NodesWithoutId() {
687
688 // -- my data set
689
690 Node n1 = new Node(new LatLon(0,0));
691 my.addPrimitive(n1);
692
693 Node n2 = new Node(new LatLon(1,1));
694 my.addPrimitive(n2);
695
696 Way myWay = new Way();
697 myWay.addNode(n1);
698 myWay.addNode(n2);
699 my.addPrimitive(myWay);
700
701 // -- their data set
702
703 Node n3 = new Node(new LatLon(0,0));
704 their.addPrimitive(n3);
705
706 Node n4 = new Node(new LatLon(1,1));
707 their.addPrimitive(n4);
708
709 Way theirWay = new Way();
710 theirWay.addNode(n3);
711 theirWay.addNode(n4);
712 User user = User.createOsmUser(1111, "their");
713 theirWay.setUser(user);
714 theirWay.setTimestamp(new Date());
715 their.addPrimitive(theirWay);
716
717 DataSetMerger visitor = new DataSetMerger(my,their);
718 visitor.merge();
719
720 // -- tests
721 Way merged = (Way)my.getWays().toArray()[0];
722 assertEquals(0,visitor.getConflicts().size());
723 assertEquals("their", merged.getUser().getName());
724 assertEquals(1111, merged.getUser().getId());
725 assertEquals(theirWay.getTimestamp(), merged.getTimestamp());
726 assertSame(merged, myWay);
727 assertSame(merged.getNode(0), n1);
728 assertSame(merged.getNode(1), n2);
729
730 assertFalse(merged.isModified());
731 }
732
733
734 /**
735 * My dataset includes a deleted node.
736 * Their dataset includes a way with three nodes, the first one being my node.
737 *
738 * => the merged way should include all three nodes. Deleted node should have deleted=false and
739 * special conflict with isDeleted should exist
740 *
741 */
742 @Test
743 public void wayComplex_mergingADeletedNode() {
744
745 // -- my dataset
746
747 Node mn1 = new Node(new LatLon(0,0));
748 mn1.setOsmId(1,1);
749 mn1.setDeleted(true);
750 my.addPrimitive(mn1);
751
752
753 Node tn1 = new Node(new LatLon(0,0));
754 tn1.setOsmId(1,1);
755 their.addPrimitive(tn1);
756
757 Node tn2 = new Node(new LatLon(1,1));
758 tn2.setOsmId(2,1);
759 their.addPrimitive(tn2);
760
761 Node tn3 = new Node(new LatLon(2,2));
762 tn3.setOsmId(3,1);
763 their.addPrimitive(tn3);
764
765 // -- their data set
766 Way theirWay = new Way();
767 theirWay.setOsmId(4,1);
768 theirWay.addNode(tn1);
769 theirWay.addNode(tn2);
770 theirWay.addNode(tn3);
771 theirWay.setUser(User.createOsmUser(1111, "their"));
772 theirWay.setTimestamp(new Date());
773 their.addPrimitive(theirWay);
774
775 DataSetMerger visitor = new DataSetMerger(my,their);
776 visitor.merge();
777
778 assertEquals(1, visitor.getConflicts().size());
779 assertTrue(visitor.getConflicts().get(0).isMyDeleted());
780
781 Way myWay = (Way)my.getPrimitiveById(4, OsmPrimitiveType.WAY);
782 assertEquals(3, myWay.getNodesCount());
783
784 Node n = (Node)my.getPrimitiveById(1,OsmPrimitiveType.NODE);
785 assertTrue(myWay.getNodes().contains(n));
786
787 assertFalse(myWay.isModified());
788 }
789
790 /**
791 * My dataset includes a deleted node.
792 * Their dataset includes a relation with three nodes, the first one being my node.
793 *
794 * => the merged relation should include all three nodes. There should be conflict for deleted
795 * node with isMyDeleted set
796 *
797 */
798 @Test
799 public void relationComplex_mergingADeletedNode() {
800
801
802 Node mn1 = new Node(new LatLon(0,0));
803 mn1.setOsmId(1,1);
804 mn1.setDeleted(true);
805 my.addPrimitive(mn1);
806
807
808 Node tn1 = new Node(new LatLon(0,0));
809 tn1.setOsmId(1,1);
810 their.addPrimitive(tn1);
811
812 Node tn2 = new Node(new LatLon(1,1));
813 tn2.setOsmId(2,1);
814 their.addPrimitive(tn2);
815
816 Node tn3 = new Node(new LatLon(2,2));
817 tn3.setOsmId(3,1);
818 their.addPrimitive(tn3);
819
820
821 Relation theirRelation = new Relation();
822 theirRelation.setOsmId(4,1);
823
824 theirRelation.addMember(new RelationMember("", tn1));
825 theirRelation.addMember(new RelationMember("", tn2));
826 theirRelation.addMember(new RelationMember("", tn3));
827 their.addPrimitive(theirRelation);
828
829 DataSetMerger visitor = new DataSetMerger(my,their);
830 visitor.merge();
831
832 Node n = (Node)my.getPrimitiveById(1,OsmPrimitiveType.NODE);
833 assertNotNull(n);
834
835 assertEquals(1, visitor.getConflicts().size());
836 assertTrue(visitor.getConflicts().hasConflictForMy(n));
837 assertTrue(visitor.getConflicts().get(0).isMyDeleted());
838
839 Relation r = (Relation)my.getPrimitiveById(4,OsmPrimitiveType.RELATION);
840 assertEquals(3, r.getMembersCount());
841
842 assertFalse(r.isModified());
843 }
844
845 /**
846 * Merge an incomplete way with two incomplete nodes into an empty dataset.
847 *
848 * Use case: a way loaded with a multiget, i.e. GET /api/0.6/ways?ids=123456
849 */
850 @Test
851 public void newIncompleteWay() {
852
853 Node n1 = new Node(1);
854 their.addPrimitive(n1);
855
856 Node n2 = new Node(2);
857 their.addPrimitive(n2);
858
859 Way w3 = new Way(3);
860 w3.setNodes(Arrays.asList(n1,n2));
861 their.addPrimitive(w3);
862 assertTrue(w3.isIncomplete());
863
864
865 DataSetMerger visitor = new DataSetMerger(my, their);
866 visitor.merge();
867
868 assertEquals(0,visitor.getConflicts().size());
869
870 OsmPrimitive p= my.getPrimitiveById(1, OsmPrimitiveType.NODE);
871 assertNotNull(p);
872 assertTrue(p.isIncomplete());
873 p= my.getPrimitiveById(2, OsmPrimitiveType.NODE);
874 assertNotNull(p);
875 assertTrue(p.isIncomplete());
876 p= my.getPrimitiveById(3, OsmPrimitiveType.WAY);
877 assertNotNull(p);
878 assertTrue(p.isIncomplete());
879
880 Way w = (Way)my.getPrimitiveById(3, OsmPrimitiveType.WAY);
881 assertNotNull(w);
882 assertTrue(p.isIncomplete());
883 assertEquals(2, w.getNodesCount());
884 assertTrue(w.getNode(0).isIncomplete());
885 assertTrue(w.getNode(1).isIncomplete());
886 }
887
888 /**
889 * Merge an incomplete way with two incomplete nodes into a dataset where the way already exists as complete way.
890 *
891 * Use case: a way loaded with a multiget, i.e. GET /api/0.6/ways?ids=123456 after a "Update selection " of this way
892 */
893 @Test
894 public void incompleteWayOntoCompleteWay() {
895
896 // an incomplete node
897 Node n1 = new Node(1);
898 their.addPrimitive(n1);
899
900 // another incomplete node
901 Node n2 = new Node(2);
902 their.addPrimitive(n2);
903
904 // an incomplete way with two incomplete nodes
905 Way w3 = new Way(3);
906 w3.setNodes(Arrays.asList(n1,n2));
907 their.addPrimitive(w3);
908
909
910 Node n4 = new Node(new LatLon(0,0));
911 n4.setOsmId(1,1);
912 my.addPrimitive(n4);
913
914 Node n5 = new Node(new LatLon(1,1));
915 n5.setOsmId(2,1);
916 my.addPrimitive(n5);
917
918 Way w6 = new Way(3, 1);
919 w6.setNodes(Arrays.asList(n4,n5));
920 my.addPrimitive(w6);
921
922 DataSetMerger visitor = new DataSetMerger(my,their);
923 visitor.merge();
924
925 assertEquals(0,visitor.getConflicts().size());
926
927 OsmPrimitive p= my.getPrimitiveById(1, OsmPrimitiveType.NODE);
928 assertNotNull(p);
929 assertFalse(p.isIncomplete());
930 p= my.getPrimitiveById(2, OsmPrimitiveType.NODE);
931 assertNotNull(p);
932 assertFalse(p.isIncomplete());
933 p= my.getPrimitiveById(3,OsmPrimitiveType.WAY);
934 assertNotNull(p);
935 assertFalse(p.isIncomplete());
936
937 Way w = (Way)my.getPrimitiveById(3,OsmPrimitiveType.WAY);
938 assertNotNull(w);
939 assertFalse(p.isIncomplete());
940 assertEquals(2, w.getNodesCount());
941 assertFalse(w.getNode(0).isIncomplete());
942 assertFalse(w.getNode(1).isIncomplete());
943 }
944
945 /**
946 * merge to complete nodes onto an incomplete way with the same two nodes, but incomplete.
947 * => both the nodes and the way should be complete in the target dataset after merging
948 */
949 @Test
950 public void twoCompleteNodesOntoAnIncompleteWay() {
951
952 // -- source dataset
953
954 // an complete node
955 Node n1 = new Node(1, 1);
956 n1.setCoor(new LatLon(1,1));
957 their.addPrimitive(n1);
958
959 // another complete node
960 Node n2 = new Node(2, 1);
961 n2.setCoor(new LatLon(2,2));
962 their.addPrimitive(n2);
963
964 // --- target dataset
965
966 Node n4 = new Node(1);
967 my.addPrimitive(n4);
968
969 Node n5 = new Node(2);
970 my.addPrimitive(n5);
971
972 Way w6 = new Way(3, 1);
973 w6.addNode(n4);
974 w6.addNode(n5);
975 my.addPrimitive(w6);
976
977 //-- merge it
978 DataSetMerger visitor = new DataSetMerger(my, their);
979 visitor.merge();
980
981 // -- test it
982 assertEquals(0,visitor.getConflicts().size());
983
984 Node n = (Node)my.getPrimitiveById(1, OsmPrimitiveType.NODE);
985 assertNotNull(n);
986 assertFalse(n.isIncomplete());
987
988 n = (Node)my.getPrimitiveById(2, OsmPrimitiveType.NODE);
989 assertNotNull(n);
990 assertFalse(n.isIncomplete());
991
992 Way w = (Way)my.getPrimitiveById(3, OsmPrimitiveType.WAY);
993 assertNotNull(w);
994 assertFalse(w.hasIncompleteNodes());
995 assertTrue(w.isUsable());
996 assertEquals(2, w.getNodesCount());
997 assertEquals(1, w.getNode(0).getId());
998 assertEquals(2, w.getNode(1).getId());
999 }
1000}
Note: See TracBrowser for help on using the repository browser.