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

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

fix #15538 - add robustness to AlignInLineAction

  • Property svn:eol-style set to native
File size: 7.8 KB
RevLine 
[7937]1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.actions;
3
4import static org.junit.Assert.assertEquals;
[10347]5import static org.junit.Assert.assertNotNull;
[13108]6import static org.junit.Assert.assertNull;
[7937]7
[12110]8import org.junit.Before;
[12562]9import org.junit.Rule;
[7937]10import org.junit.Test;
[10347]11import org.openstreetmap.josm.actions.AlignInLineAction.InvalidSelection;
12import org.openstreetmap.josm.actions.AlignInLineAction.Line;
[7937]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;
[12636]18import org.openstreetmap.josm.gui.MainApplication;
[12562]19import org.openstreetmap.josm.testutils.JOSMTestRules;
[7937]20
[12562]21import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
22
[7937]23/**
[8857]24 * Unit tests for class {@link AlignInLineAction}.
[7937]25 */
26public final class AlignInLineActionTest {
27
[12562]28 /**
29 * Setup test.
30 */
31 @Rule
32 @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
[12632]33 public JOSMTestRules test = new JOSMTestRules().main().projection();
[12562]34
[7937]35 /** Class under test. */
36 private static AlignInLineAction action;
37
38 /**
39 * Setup test.
40 */
[12110]41 @Before
42 public void setUp() {
[7937]43 // Enable "Align in line" feature.
[12643]44 action = MainApplication.getMenu().alignInLine;
[7937]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.
[12562]53 * @throws InvalidSelection never
[7937]54 */
55 @Test
[12562]56 public void testNodesOpenWay() throws InvalidSelection {
[7937]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
[13108]68 // Create an open way.
69 createWay(dataSet, point1, point2, point3);
[7937]70
[13108]71 // Select nodes to align.
72 dataSet.addSelected(point1, point2, point3);
[7937]73
[13108]74 action.buildCommand(dataSet).executeCommand();
[7937]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.
[12562]85 * @throws InvalidSelection never
[7937]86 */
87 @Test
[12562]88 public void testNodesClosedWay() throws InvalidSelection {
[7937]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
[13108]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);
[7937]105
[13108]106 action.buildCommand(dataSet).executeCommand();
[7937]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.
[12562]118 * @throws InvalidSelection never
[7937]119 */
120 @Test
[12562]121 public void testNodesOpenWays() throws InvalidSelection {
[7937]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
[13108]134 // Create 2 ways.
135 createWay(dataSet, point1, point2);
136 createWay(dataSet, point3, point4);
[7937]137
[13108]138 // Select nodes to align.
139 dataSet.addSelected(point1, point2, point3, point4);
[7937]140
[13108]141 // Points must align between points 1 and 4.
142 action.buildCommand(dataSet).executeCommand();
[7937]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 /**
[13108]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 /**
[7937]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.
[13108]177 * @return created way
[7937]178 */
[13108]179 private Way createWay(DataSet dataSet, Node... nodes) {
[7937]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 }
[13108]190 return way;
[7937]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 }
[10347]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 }
[7937]239}
Note: See TracBrowser for help on using the repository browser.