source: josm/trunk/test/unit/org/openstreetmap/josm/actions/AlignInLineActionTest.java@ 14138

Last change on this file since 14138 was 13108, checked in by Don-vip, 6 years ago

fix #15538 - add robustness to AlignInLineAction

  • Property svn:eol-style set to native
File size: 7.8 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.actions;
3
4import static org.junit.Assert.assertEquals;
5import static org.junit.Assert.assertNotNull;
6import static org.junit.Assert.assertNull;
7
8import org.junit.Before;
9import org.junit.Rule;
10import org.junit.Test;
11import org.openstreetmap.josm.actions.AlignInLineAction.InvalidSelection;
12import org.openstreetmap.josm.actions.AlignInLineAction.Line;
13import org.openstreetmap.josm.data.coor.EastNorth;
14import org.openstreetmap.josm.data.coor.LatLon;
15import org.openstreetmap.josm.data.osm.DataSet;
16import org.openstreetmap.josm.data.osm.Node;
17import org.openstreetmap.josm.data.osm.Way;
18import org.openstreetmap.josm.gui.MainApplication;
19import org.openstreetmap.josm.testutils.JOSMTestRules;
20
21import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
22
23/**
24 * Unit tests for class {@link AlignInLineAction}.
25 */
26public final class AlignInLineActionTest {
27
28 /**
29 * Setup test.
30 */
31 @Rule
32 @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
33 public JOSMTestRules test = new JOSMTestRules().main().projection();
34
35 /** Class under test. */
36 private static AlignInLineAction action;
37
38 /**
39 * Setup test.
40 */
41 @Before
42 public void setUp() {
43 // Enable "Align in line" feature.
44 action = MainApplication.getMenu().alignInLine;
45 action.setEnabled(true);
46 }
47
48 /**
49 * Test case: only nodes selected, part of an open way: align these nodes on the line passing through the extremity
50 * nodes (the most distant in the way sequence, not the most euclidean-distant). See
51 * https://josm.openstreetmap.de/ticket/9605#comment:3. Note that in this test, after alignment, way is overlapping
52 * itself.
53 * @throws InvalidSelection never
54 */
55 @Test
56 public void testNodesOpenWay() throws InvalidSelection {
57 DataSet dataSet = new DataSet();
58
59 // Create test points, lower left is (0,0).
60 //
61 // 1 - - -
62 // - 3 - 2
63 // - - - -
64 Node point1 = new Node(new EastNorth(0, 2));
65 Node point2 = new Node(new EastNorth(3, 1));
66 Node point3 = new Node(new EastNorth(1, 1));
67
68 // Create an open way.
69 createWay(dataSet, point1, point2, point3);
70
71 // Select nodes to align.
72 dataSet.addSelected(point1, point2, point3);
73
74 action.buildCommand(dataSet).executeCommand();
75
76 // Points 1 and 3 are the extremities and must not have moved. Only point 2 must have moved.
77 assertCoordEq(point1, 0, 2);
78 assertCoordEq(point2, 2, 0);
79 assertCoordEq(point3, 1, 1);
80 }
81
82 /**
83 * Test case: only nodes selected, part of a closed way: align these nodes on the line passing through the most
84 * distant nodes.
85 * @throws InvalidSelection never
86 */
87 @Test
88 public void testNodesClosedWay() throws InvalidSelection {
89 DataSet dataSet = new DataSet();
90
91 // Create test points, lower left is (0,0).
92 //
93 // 4 - 3
94 // - - -
95 // 1 - 2
96 Node point1 = new Node(new EastNorth(0, 0));
97 Node point2 = new Node(new EastNorth(2, 0));
98 Node point3 = new Node(new EastNorth(2, 2));
99 Node point4 = new Node(new EastNorth(0, 2));
100
101 // Create a closed way.
102 createWay(dataSet, point1, point2, point3, point4, point1);
103 // Select nodes to align (point1 must be in the second position to exhibit the bug).
104 dataSet.addSelected(point4, point1, point2);
105
106 action.buildCommand(dataSet).executeCommand();
107
108 // Only point 1 must have moved.
109 assertCoordEq(point1, 1, 1);
110 assertCoordEq(point2, 2, 0);
111 assertCoordEq(point3, 2, 2);
112 assertCoordEq(point4, 0, 2);
113 }
114
115 /**
116 * Test case: only nodes selected, part of multiple ways: align these nodes on the line passing through the most
117 * distant nodes.
118 * @throws InvalidSelection never
119 */
120 @Test
121 public void testNodesOpenWays() throws InvalidSelection {
122 DataSet dataSet = new DataSet();
123
124 // Create test points, lower left is (0,0).
125 //
126 // 1 - -
127 // 3 - 2
128 // - - 4
129 Node point1 = new Node(new EastNorth(0, 2));
130 Node point2 = new Node(new EastNorth(2, 1));
131 Node point3 = new Node(new EastNorth(0, 1));
132 Node point4 = new Node(new EastNorth(2, 0));
133
134 // Create 2 ways.
135 createWay(dataSet, point1, point2);
136 createWay(dataSet, point3, point4);
137
138 // Select nodes to align.
139 dataSet.addSelected(point1, point2, point3, point4);
140
141 // Points must align between points 1 and 4.
142 action.buildCommand(dataSet).executeCommand();
143
144 assertCoordEq(point1, 0, 2);
145 assertCoordEq(point2, 1.5, 0.5);
146 assertCoordEq(point3, 0.5, 1.5);
147 assertCoordEq(point4, 2, 0);
148 }
149
150 /**
151 * Test case: only a two-nodes way selected.
152 * @throws InvalidSelection never
153 */
154 @Test
155 public void testSimpleWay() throws InvalidSelection {
156 DataSet dataSet = new DataSet();
157
158 // Create test points, lower left is (0,0).
159 //
160 // 1 - -
161 // - - 2
162 Node point1 = new Node(new EastNorth(0, 2));
163 Node point2 = new Node(new EastNorth(2, 1));
164
165 // Creates and select a single way.
166 dataSet.addSelected(createWay(dataSet, point1, point2));
167
168 // No command must be created (nothing to do)
169 assertNull(action.buildCommand(dataSet));
170 }
171
172 /**
173 * Create a way made of the provided nodes and select nodes.
174 *
175 * @param dataSet Dataset in which adding nodes.
176 * @param nodes List of nodes to add to dataset.
177 * @return created way
178 */
179 private Way createWay(DataSet dataSet, Node... nodes) {
180 Way way = new Way();
181 dataSet.addPrimitive(way);
182
183 for (Node node : nodes) {
184 // Add primitive to dataset only if not already included.
185 if (dataSet.getPrimitiveById(node) == null)
186 dataSet.addPrimitive(node);
187
188 way.addNode(node);
189 }
190 return way;
191 }
192
193 /**
194 * Assert that the provided node has the specified coordinates. If not fail the test.
195 *
196 * @param node Node to test.
197 * @param x X coordinate.
198 * @param y Y coordinate.
199 */
200 private void assertCoordEq(Node node, double x, double y) {
201 EastNorth coordinate = node.getEastNorth();
202 assertEquals("Wrong x coordinate.", x, coordinate.getX(), LatLon.MAX_SERVER_PRECISION);
203 assertEquals("Wrong y coordinate.", y, coordinate.getY(), LatLon.MAX_SERVER_PRECISION);
204 }
205
206 /**
207 * Test that a {@link Line} can be constructed with nodes of different coordinates.
208 * @throws InvalidSelection never
209 */
210 @Test
211 public void testLineDifferentCoordinates() throws InvalidSelection {
212 assertNotNull(new Line(new Node(new EastNorth(0, 1)),
213 new Node(new EastNorth(0, 2))));
214 assertNotNull(new Line(new Node(new EastNorth(0, 1)),
215 new Node(new EastNorth(1, 1))));
216 assertNotNull(new Line(new Node(new EastNorth(0, 1)),
217 new Node(new EastNorth(0+1e-150, 1+1e-150))));
218 }
219
220 /**
221 * Test that a {@link Line} cannot be constructed with nodes of same coordinates.
222 * @throws InvalidSelection always
223 */
224 @Test(expected = InvalidSelection.class)
225 public void testLineSameCoordinates1() throws InvalidSelection {
226 new Line(new Node(new EastNorth(0, 1)),
227 new Node(new EastNorth(0, 1)));
228 }
229
230 /**
231 * Test that a {@link Line} cannot be constructed with nodes of same coordinates.
232 * @throws InvalidSelection always
233 */
234 @Test(expected = InvalidSelection.class)
235 public void testLineSameCoordinates2() throws InvalidSelection {
236 new Line(new Node(new EastNorth(0, 1)),
237 new Node(new EastNorth(0+1e-175, 1+1e-175)));
238 }
239}
Note: See TracBrowser for help on using the repository browser.