source: josm/trunk/test/unit/org/openstreetmap/josm/gui/NavigatableComponentTest.java@ 18690

Last change on this file since 18690 was 18690, checked in by taylor.smock, 14 months ago

See #16567: Convert all assertion calls to JUnit 5 (patch by gaben, modified)

The modifications are as follows:

  • Merge DomainValidatorTest.testIDN and DomainValidatorTest.testIDNJava6OrLater
  • Update some tests to use @ParameterizedTest (DomainValidatorTest)
  • Replace various exception blocks with assertThrows. These typically looked like
        try {
            // Something that should throw an exception here
            fail("An exception should have been thrown");
        } catch (Exception e) {
            // Verify the exception matches expectations here
        }
    
  • Replace assertTrue(val instanceof Clazz) with assertInstanceOf
  • Replace JUnit 4 @Suite with JUnit 5 @Suite

Both the original patch and the modified patch fix various lint issues.

  • Property svn:eol-style set to native
File size: 11.5 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui;
3
4import static org.hamcrest.MatcherAssert.assertThat;
5import static org.junit.jupiter.api.Assertions.assertEquals;
6import static org.junit.jupiter.api.Assertions.assertNotNull;
7import static org.junit.jupiter.api.Assertions.assertNull;
8import static org.junit.jupiter.api.Assertions.assertSame;
9
10import java.awt.Point;
11import java.awt.Rectangle;
12import java.awt.event.MouseEvent;
13import java.awt.geom.Point2D;
14import java.util.Objects;
15import java.util.concurrent.atomic.AtomicReference;
16
17import javax.swing.JPanel;
18
19import org.CustomMatchers;
20import org.hamcrest.CustomTypeSafeMatcher;
21import org.hamcrest.Matcher;
22import org.junit.jupiter.api.BeforeEach;
23import org.junit.jupiter.api.Test;
24import org.junit.jupiter.api.extension.RegisterExtension;
25import org.openstreetmap.josm.data.Bounds;
26import org.openstreetmap.josm.data.ProjectionBounds;
27import org.openstreetmap.josm.data.coor.EastNorth;
28import org.openstreetmap.josm.data.coor.LatLon;
29import org.openstreetmap.josm.data.osm.DataSet;
30import org.openstreetmap.josm.data.osm.Node;
31import org.openstreetmap.josm.data.projection.ProjectionRegistry;
32import org.openstreetmap.josm.gui.layer.OsmDataLayer;
33import org.openstreetmap.josm.gui.util.GuiHelper;
34import org.openstreetmap.josm.testutils.JOSMTestRules;
35
36import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
37
38/**
39 * Some tests for the {@link NavigatableComponent} class.
40 * @author Michael Zangl
41 *
42 */
43class NavigatableComponentTest {
44
45 private static final class NavigatableComponentMock extends NavigatableComponent {
46 @Override
47 public Point getLocationOnScreen() {
48 return new Point(30, 40);
49 }
50
51 @Override
52 protected boolean isVisibleOnScreen() {
53 return true;
54 }
55
56 @Override
57 public void processMouseMotionEvent(MouseEvent mouseEvent) {
58 super.processMouseMotionEvent(mouseEvent);
59 }
60 }
61
62 private static final int HEIGHT = 200;
63 private static final int WIDTH = 300;
64 private NavigatableComponentMock component;
65
66 /**
67 * We need the projection for coordinate conversions.
68 */
69 @RegisterExtension
70 @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
71 public JOSMTestRules test = new JOSMTestRules().preferences().projection();
72
73 /**
74 * Create a new, fresh {@link NavigatableComponent}
75 */
76 @BeforeEach
77 public void setUp() {
78 component = new NavigatableComponentMock();
79 component.setBounds(new Rectangle(WIDTH, HEIGHT));
80 // wait for the event to be propagated.
81 GuiHelper.runInEDTAndWait(() -> { /* Do nothing */ });
82 component.setVisible(true);
83 JPanel parent = new JPanel();
84 parent.add(component);
85 component.updateLocationState();
86 }
87
88 /**
89 * Test if the default scale was set correctly.
90 */
91 @Test
92 void testDefaultScale() {
93 assertEquals(ProjectionRegistry.getProjection().getDefaultZoomInPPD(), component.getScale(), 0.00001);
94 }
95
96 /**
97 * Tests {@link NavigatableComponent#getPoint2D(EastNorth)}
98 */
99 @Test
100 void testPoint2DEastNorth() {
101 assertThat(component.getPoint2D((EastNorth) null), CustomMatchers.is(new Point2D.Double()));
102 Point2D shouldBeCenter = component.getPoint2D(component.getCenter());
103 assertThat(shouldBeCenter, CustomMatchers.is(new Point2D.Double(WIDTH / 2.0, HEIGHT / 2.0)));
104
105 EastNorth testPoint = component.getCenter().add(300 * component.getScale(), 200 * component.getScale());
106 Point2D testPointConverted = component.getPoint2D(testPoint);
107 assertThat(testPointConverted, CustomMatchers.is(new Point2D.Double(WIDTH / 2.0 + 300, HEIGHT / 2.0 - 200)));
108 }
109
110 /**
111 * TODO: Implement this test.
112 */
113 @Test
114 void testPoint2DLatLon() {
115 assertThat(component.getPoint2D((LatLon) null), CustomMatchers.is(new Point2D.Double()));
116 // TODO: Really test this.
117 }
118
119 /**
120 * Tests {@link NavigatableComponent#zoomTo(LatLon)}
121 */
122 @Test
123 void testZoomToLatLon() {
124 component.zoomTo(new LatLon(10, 10));
125 Point2D shouldBeCenter = component.getPoint2D(new LatLon(10, 10));
126 // 0.5 pixel tolerance, see isAfterZoom
127 assertEquals(shouldBeCenter.getX(), WIDTH / 2., 0.5);
128 assertEquals(shouldBeCenter.getY(), HEIGHT / 2., 0.5);
129 }
130
131 /**
132 * Tests {@link NavigatableComponent#zoomToFactor(double)} and {@link NavigatableComponent#zoomToFactor(EastNorth, double)}
133 */
134 @Test
135 void testZoomToFactor() {
136 EastNorth center = component.getCenter();
137 double initialScale = component.getScale();
138
139 // zoomToFactor(double)
140 component.zoomToFactor(0.5);
141 assertEquals(initialScale / 2, component.getScale(), 0.00000001);
142 assertThat(component.getCenter(), isAfterZoom(center, component.getScale()));
143 component.zoomToFactor(2);
144 assertEquals(initialScale, component.getScale(), 0.00000001);
145 assertThat(component.getCenter(), isAfterZoom(center, component.getScale()));
146
147 // zoomToFactor(EastNorth, double)
148 EastNorth newCenter = new EastNorth(10, 20);
149 component.zoomToFactor(newCenter, 0.5);
150 assertEquals(initialScale / 2, component.getScale(), 0.00000001);
151 assertThat(component.getCenter(), isAfterZoom(newCenter, component.getScale()));
152 component.zoomToFactor(newCenter, 2);
153 assertEquals(initialScale, component.getScale(), 0.00000001);
154 assertThat(component.getCenter(), isAfterZoom(newCenter, component.getScale()));
155 }
156
157 /**
158 * Tests {@link NavigatableComponent#getEastNorth(int, int)}
159 */
160 @Test
161 void testGetEastNorth() {
162 EastNorth center = component.getCenter();
163 assertThat(component.getEastNorth(WIDTH / 2, HEIGHT / 2), CustomMatchers.is(center));
164
165 EastNorth testPoint = component.getCenter().add(WIDTH * component.getScale(), HEIGHT * component.getScale());
166 assertThat(component.getEastNorth(3 * WIDTH / 2, -HEIGHT / 2), CustomMatchers.is(testPoint));
167 }
168
169 /**
170 * Tests {@link NavigatableComponent#zoomToFactor(double, double, double)}
171 */
172 @Test
173 void testZoomToFactorCenter() {
174 // zoomToFactor(double, double, double)
175 // assumes getEastNorth works as expected
176 EastNorth testPoint1 = component.getEastNorth(0, 0);
177 EastNorth testPoint2 = component.getEastNorth(200, 150);
178 double initialScale = component.getScale();
179
180 component.zoomToFactor(0, 0, 0.5);
181 assertEquals(initialScale / 2, component.getScale(), 0.00000001);
182 assertThat(component.getEastNorth(0, 0), isAfterZoom(testPoint1, component.getScale()));
183 component.zoomToFactor(0, 0, 2);
184 assertEquals(initialScale, component.getScale(), 0.00000001);
185 assertThat(component.getEastNorth(0, 0), isAfterZoom(testPoint1, component.getScale()));
186
187 component.zoomToFactor(200, 150, 0.5);
188 assertEquals(initialScale / 2, component.getScale(), 0.00000001);
189 assertThat(component.getEastNorth(200, 150), isAfterZoom(testPoint2, component.getScale()));
190 component.zoomToFactor(200, 150, 2);
191 assertEquals(initialScale, component.getScale(), 0.00000001);
192 assertThat(component.getEastNorth(200, 150), isAfterZoom(testPoint2, component.getScale()));
193
194 }
195
196 /**
197 * Tests {@link NavigatableComponent#getProjectionBounds()}
198 */
199 @Test
200 void testGetProjectionBounds() {
201 ProjectionBounds bounds = component.getProjectionBounds();
202 assertThat(bounds.getCenter(), CustomMatchers.is(component.getCenter()));
203
204 assertThat(bounds.getMin(), CustomMatchers.is(component.getEastNorth(0, HEIGHT)));
205 assertThat(bounds.getMax(), CustomMatchers.is(component.getEastNorth(WIDTH, 0)));
206 }
207
208 /**
209 * Tests {@link NavigatableComponent#getRealBounds()}
210 */
211 @Test
212 void testGetRealBounds() {
213 Bounds bounds = component.getRealBounds();
214 assertThat(bounds.getCenter(), CustomMatchers.is(component.getLatLon(WIDTH / 2, HEIGHT / 2)));
215
216 assertThat(bounds.getMin(), CustomMatchers.is(component.getLatLon(0, HEIGHT)));
217 assertThat(bounds.getMax(), CustomMatchers.is(component.getLatLon(WIDTH, 0)));
218 }
219
220 @Test
221 void testHoverListeners() {
222 AtomicReference<PrimitiveHoverListener.PrimitiveHoverEvent> hoverEvent = new AtomicReference<>();
223 PrimitiveHoverListener testListener = hoverEvent::set;
224 assertNull(hoverEvent.get());
225 component.addNotify();
226 component.addPrimitiveHoverListener(testListener);
227 DataSet ds = new DataSet();
228 MainApplication.getLayerManager().addLayer(new OsmDataLayer(ds, "testHoverListeners", null));
229 LatLon center = component.getRealBounds().getCenter();
230 Node node1 = new Node(center);
231 ds.addPrimitive(node1);
232 double x = component.getBounds().getCenterX();
233 double y = component.getBounds().getCenterY();
234 // Check hover over primitive
235 MouseEvent node1Event = new MouseEvent(component, MouseEvent.MOUSE_MOVED, System.currentTimeMillis(),
236 0, (int) x, (int) y, 0, false, MouseEvent.NOBUTTON);
237 component.processMouseMotionEvent(node1Event);
238 GuiHelper.runInEDTAndWait(() -> { /* Sync */ });
239 PrimitiveHoverListener.PrimitiveHoverEvent event = hoverEvent.getAndSet(null);
240 assertNotNull(event);
241 assertSame(node1, event.getHoveredPrimitive());
242 assertNull(event.getPreviousPrimitive());
243 assertSame(node1Event, event.getMouseEvent());
244 // Check moving to the (same) primitive. No new mouse motion event should be called.
245 component.processMouseMotionEvent(node1Event);
246 GuiHelper.runInEDTAndWait(() -> { /* Sync */ });
247 event = hoverEvent.getAndSet(null);
248 assertNull(event);
249 // Check moving off primitive. A new mouse motion event should be called with the previous primitive and null.
250 MouseEvent noNodeEvent =
251 new MouseEvent(component, MouseEvent.MOUSE_MOVED, System.currentTimeMillis(), 0, 0, 0, 0, false, MouseEvent.NOBUTTON);
252 component.processMouseMotionEvent(noNodeEvent);
253 GuiHelper.runInEDTAndWait(() -> { /* Sync */ });
254 event = hoverEvent.getAndSet(null);
255 assertNotNull(event);
256 assertSame(node1, event.getPreviousPrimitive());
257 assertNull(event.getHoveredPrimitive());
258 assertSame(noNodeEvent, event.getMouseEvent());
259 // Check moving to area with no primitive with no previous hover primitive
260 component.processMouseMotionEvent(
261 new MouseEvent(component, MouseEvent.MOUSE_MOVED, System.currentTimeMillis(), 0, 1, 1, 0, false, MouseEvent.NOBUTTON));
262 assertNull(hoverEvent.get());
263 }
264
265 /**
266 * Check that EastNorth is the same as expected after zooming the NavigatableComponent.
267 *
268 * Adds tolerance of 0.5 pixel for pixel grid alignment, see
269 * {@link NavigatableComponent#zoomTo(EastNorth, double, boolean)}
270 * @param expected expected
271 * @param scale current scale
272 * @return Matcher object
273 */
274 private Matcher<EastNorth> isAfterZoom(EastNorth expected, double scale) {
275 return new CustomTypeSafeMatcher<EastNorth>(Objects.toString(expected)) {
276 @Override
277 protected boolean matchesSafely(EastNorth actual) {
278 // compare pixels (east/north divided by scale)
279 return Math.abs((expected.getX() - actual.getX()) / scale) <= 0.5
280 && Math.abs((expected.getY() - actual.getY()) / scale) <= 0.5;
281 }
282 };
283 }
284
285}
Note: See TracBrowser for help on using the repository browser.