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

Last change on this file since 2578 was 2578, checked in by jttt, 14 years ago

Encalupse OsmPrimitive.incomplete

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