source: josm/test/org/openstreetmap/josm/data/osm/visitor/MergeVisitorTest.java@ 143

Last change on this file since 143 was 143, checked in by imi, 18 years ago

added "gpx" as flag to the external tool feature to also export raw gps data

File size: 8.9 KB
Line 
1package org.openstreetmap.josm.data.osm.visitor;
2
3import java.util.Date;
4
5import junit.framework.TestCase;
6
7import org.openstreetmap.josm.data.coor.LatLon;
8import org.openstreetmap.josm.data.osm.DataSet;
9import org.openstreetmap.josm.data.osm.Node;
10import org.openstreetmap.josm.data.osm.OsmPrimitive;
11import org.openstreetmap.josm.data.osm.Segment;
12import org.openstreetmap.josm.data.osm.Way;
13import org.openstreetmap.josm.testframework.Bug;
14import org.openstreetmap.josm.testframework.DataSetTestCaseHelper;
15
16public class MergeVisitorTest extends TestCase {
17
18
19 private DataSet ds;
20 private Node dsNode;
21 private Node n;
22 private MergeVisitor v;
23
24 @Override protected void setUp() throws Exception {
25 ds = new DataSet();
26 dsNode = DataSetTestCaseHelper.createNode(ds);
27 v = new MergeVisitor(ds);
28 n = DataSetTestCaseHelper.createNode(null);
29 }
30
31
32 public void testNodesMergeUpdate() {
33 dsNode.id = 1;
34 n.id = 1;
35 n.timestamp = new Date();
36 v.visit(n);
37 assertEquals(dsNode, n);
38 }
39 public void testNodesMergeModified() {
40 dsNode.id = 1;
41 n.id = 1;
42 n.modified = true;
43 v.visit(n);
44 assertEquals(dsNode, n);
45 }
46 public void testNodesConflictBothModified() {
47 n.modified = true;
48 dsNode.modified = true;
49 n.id = 1;
50 dsNode.id = 1;
51 v.visit(n);
52 assertEquals(1, v.conflicts.size());
53 }
54 public void testNodesConflict() {
55 dsNode.id = 1;
56 dsNode.timestamp = new Date();
57 n.id = 1;
58 n.modified = true;
59 n.timestamp = new Date(dsNode.timestamp.getTime()-1);
60 v.visit(n);
61 assertEquals(1, v.conflicts.size());
62 assertSame(dsNode, v.conflicts.keySet().iterator().next());
63 assertSame(n, v.conflicts.values().iterator().next());
64 }
65 public void testNodesConflict2() {
66 dsNode.id = 1;
67 dsNode.timestamp = new Date();
68 dsNode.modified = true;
69 n.id = 1;
70 n.timestamp = new Date(dsNode.timestamp.getTime()+1);
71 v.visit(n);
72 assertEquals(1, v.conflicts.size());
73 }
74 public void testNodesConflictModifyDelete() {
75 dsNode.id = 1;
76 dsNode.modified = true;
77 n.id = 1;
78 n.delete(true);
79 v.visit(n);
80 assertEquals(1, v.conflicts.size());
81 }
82 public void testNodesMergeSamePosition() {
83 n.id = 1; // new node comes from server
84 dsNode.modified = true; // our node is modified
85 dsNode.coor = new LatLon(n.coor.lat(), n.coor.lon());
86 v.visit(n);
87 v.fixReferences();
88 assertEquals(0, v.conflicts.size());
89 assertEquals(1, dsNode.id);
90 assertFalse("updating a new node clear the modified state", dsNode.modified);
91 }
92
93 public void testNoConflictNewNodesMerged() {
94 assertEquals(0, n.id);
95 assertEquals(0, dsNode.id);
96 v.visit(n);
97 v.fixReferences();
98 assertEquals(0,v.conflicts.size());
99 assertTrue(ds.nodes.contains(n));
100 assertEquals(2, ds.nodes.size());
101 }
102
103 /**
104 * Test that two new segments that have different from/to are not merged
105 */
106 @Bug(101)
107 public void testNewSegmentNotMerged() {
108 v.visit(n);
109 Segment s1 = new Segment(n, dsNode);
110 v.visit(s1);
111 Segment s2 = new Segment(dsNode, n);
112 v.visit(s2);
113 assertEquals(2, ds.segments.size());
114 }
115
116 public void testFixReferencesConflicts() {
117 // make two nodes mergable
118 dsNode.id = 1;
119 n.id = 1;
120 n.timestamp = new Date();
121 // have an old segment with the old node
122 Segment sold = new Segment(dsNode, dsNode);
123 sold.id = 23;
124 sold.modified = true;
125 ds.segments.add(sold);
126 // have a conflicting segment point to the new node
127 Segment s = new Segment(n,DataSetTestCaseHelper.createNode(null));
128 s.id = 23;
129 s.modified = true;
130
131 v.visit(n); // merge
132 assertEquals(n.timestamp, dsNode.timestamp);
133 v.visit(s);
134 assertEquals(1, v.conflicts.size());
135 v.fixReferences();
136 assertSame(s.from, dsNode);
137 }
138
139 public void testNoConflictForSame() {
140 dsNode.id = 1;
141 dsNode.modified = true;
142 n.cloneFrom(dsNode);
143 v.visit(n);
144 assertEquals(0, v.conflicts.size());
145 }
146
147 /**
148 * Merge of an old segment with a new one. This should
149 * be mergable (if the nodes matches).
150 */
151 public void testMergeOldSegmentsWithNew() {
152 Node[] n = createNodes(ds, 2);
153 Segment ls1 = DataSetTestCaseHelper.createSegment(ds, n[0], n[1]);
154 ls1.id = 3;
155
156 Node newnode = new Node(new LatLon(n[1].coor.lat(), n[1].coor.lon()));
157 Segment newls = new Segment(n[0], newnode);
158
159 v.visit(newls);
160 assertEquals("segment should have been merged.", 1, ds.segments.size());
161 }
162
163 /**
164 * Incomplete segments should always loose.
165 */
166 public void testImportIncomplete() throws Exception {
167 Segment s1 = DataSetTestCaseHelper.createSegment(ds, dsNode, dsNode);
168 s1.id = 1;
169 Segment s2 = new Segment(s1);
170 s1.incomplete = true;
171 s2.timestamp = new Date();
172 v.visit(s2);
173 assertTrue(s1.realEqual(s2));
174 }
175 /**
176 * Incomplete segments should extend existing ways.
177 */
178 public void testImportIncompleteExtendWays() throws Exception {
179 Segment s1 = DataSetTestCaseHelper.createSegment(ds, dsNode, dsNode);
180 Way w = DataSetTestCaseHelper.createWay(ds, new Segment[]{s1});
181 s1.id = 1;
182 Segment s2 = new Segment(s1);
183 s1.incomplete = true;
184 v.visit(s2);
185 v.fixReferences();
186 assertEquals(1, w.segments.size());
187 assertEquals(s2, w.segments.get(0));
188 assertFalse(s2.incomplete);
189 }
190
191
192 /**
193 * Nodes beeing merged are equal but should be the same.
194 */
195 @Bug(54)
196 public void testEqualNotSame() {
197 ds = new DataSet();
198 // create a dataset with segment a-b
199 Node n[] = createNodes(ds, 2);
200 Segment ls1 = DataSetTestCaseHelper.createSegment(ds, n[0], n[1]);
201 ls1.id = 1;
202
203 // create an other dataset with segment a'-c (a' is equal, but not same to a)
204 DataSet ds2 = new DataSet();
205 Node n2[] = createNodes(ds2, 2);
206 n2[0].coor = new LatLon(n[0].coor.lat(), n[0].coor.lon());
207 n2[0].id = 0;
208 n2[1].id = 42;
209
210 Segment ls2 = DataSetTestCaseHelper.createSegment(ds, n2[0], n2[1]);
211 v = new MergeVisitor(ds);
212 for (OsmPrimitive osm : ds2.allPrimitives())
213 osm.visit(v);
214 v.fixReferences();
215
216 assertSame(ls1.from, ls2.from);
217 }
218
219
220 public void testCloneWayNotIncomplete() {
221 DataSet ds = new DataSet();
222 Node[] n = createNodes(ds, 2);
223 Segment s = DataSetTestCaseHelper.createSegment(ds, n[0], n[1]);
224 Way w = DataSetTestCaseHelper.createWay(ds, s);
225 MergeVisitor v = new MergeVisitor(ds);
226 v.visit(n[0]);
227 v.visit(n[1]);
228 v.visit(s);
229 v.visit(w);
230 Way w2 = new Way(w);
231 w2.timestamp = new Date();
232 Segment s2 = new Segment(s);
233 s2.incomplete = true;
234 w2.segments.clear();
235 w2.segments.add(s2);
236 v.visit(w2);
237 assertSame("Do not import incomplete segments when merging ways.", s, w.segments.iterator().next());
238 }
239
240 /**
241 * When merging an incomplete way over a dataset that contain already all
242 * necessary segments, the way must be completed.
243 */
244 @Bug(117)
245 public void testMergeIncompleteOnExistingDoesNotComplete() {
246 // create a dataset with an segment (as base for the later incomplete way)
247 DataSet ds = new DataSet();
248 Node[] n = createNodes(ds, 2);
249 Segment s = DataSetTestCaseHelper.createSegment(ds, n[0], n[1]);
250 s.id = 23;
251 // create an incomplete way which references the former segment
252 Way w = new Way();
253 Segment incompleteSegment = new Segment(s.id);
254 w.segments.add(incompleteSegment);
255 w.id = 42;
256 // merge both
257 MergeVisitor v = new MergeVisitor(ds);
258 v.visit(w);
259 v.fixReferences();
260
261 assertTrue(ds.ways.contains(w));
262 assertEquals(1, w.segments.size());
263 assertFalse(w.segments.get(0).incomplete);
264 }
265
266 /**
267 * Deleted segments should be deleted when merged over unchanged segments.
268 */
269 public void testMergeDeletedOverUnchangedDeletes() {
270 DataSet ds = new DataSet();
271 Segment oldSegment = createSegment(ds, false, false, 23);
272 Segment s = createSegment(null, false, true, 23);
273
274 MergeVisitor v = new MergeVisitor(ds);
275 v.visit(s);
276 v.fixReferences();
277
278 assertEquals(true, oldSegment.deleted);
279 }
280
281
282 /**
283 * Deleted segments should raise an conflict when merged over changed segments.
284 */
285 public void testMergeDeletedOverChangedConflict() {
286 DataSet ds = new DataSet();
287 createSegment(ds, false, false, 23).modified = true;
288 Segment s = createSegment(null, false, true, 23);
289
290 MergeVisitor v = new MergeVisitor(ds);
291 v.visit(s);
292 v.fixReferences();
293
294 assertEquals(1, v.conflicts.size());
295 }
296
297
298 private Segment createSegment(DataSet ds, boolean incomplete, boolean deleted, int id) {
299 Node n1 = DataSetTestCaseHelper.createNode(ds);
300 Node n2 = DataSetTestCaseHelper.createNode(ds);
301 Segment s = DataSetTestCaseHelper.createSegment(ds, n1, n2);
302 s.incomplete = incomplete;
303 s.id = id;
304 s.deleted = deleted;
305 return s;
306 }
307
308 /**
309 * Create that amount of nodes and add them to the dataset. The id will be 1,2,3,4...
310 * @param amount Number of nodes to create.
311 * @return The created nodes.
312 */
313 private Node[] createNodes(DataSet ds, int amount) {
314 Node[] nodes = new Node[amount];
315 for (int i = 0; i < amount; ++i) {
316 nodes[i] = DataSetTestCaseHelper.createNode(ds);
317 nodes[i].id = i+1;
318 }
319 return nodes;
320 }
321}
Note: See TracBrowser for help on using the repository browser.