Changeset 18963 in josm for trunk/test/unit


Ignore:
Timestamp:
2024-01-30T14:33:14+01:00 (10 months ago)
Author:
taylor.smock
Message:

Fix #23444: NPE in org.openstreetmap.josm.gui.MapViewState$MapViewEastNorthPoint.<init>

This occurs when an incomplete way is loaded into JOSM (by an .osm file, for
example). This is fixed by checking to see if the way is usable (not incomplete,
not deleted, and more importantly for this ticket, no nodes are incomplete).

This additionally fixes some pmd issues and sonarlint issues.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/test/unit/org/openstreetmap/josm/actions/mapmode/ImproveWayAccuracyActionTest.java

    r18870 r18963  
    22package org.openstreetmap.josm.actions.mapmode;
    33
     4import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
    45import static org.junit.jupiter.api.Assertions.assertEquals;
     6import static org.junit.jupiter.api.Assertions.assertFalse;
    57import static org.junit.jupiter.api.Assertions.assertTrue;
    68
     9import java.awt.Graphics2D;
     10import java.awt.Point;
     11import java.awt.event.MouseEvent;
     12import java.awt.image.BufferedImage;
     13
    714import org.junit.jupiter.api.Test;
     15import org.junit.jupiter.api.extension.RegisterExtension;
    816import org.openstreetmap.josm.TestUtils;
    917import org.openstreetmap.josm.actions.mapmode.ImproveWayAccuracyAction.State;
     18import org.openstreetmap.josm.data.Bounds;
     19import org.openstreetmap.josm.data.coor.ILatLon;
     20import org.openstreetmap.josm.data.coor.LatLon;
    1021import org.openstreetmap.josm.data.osm.DataSet;
     22import org.openstreetmap.josm.data.osm.Node;
     23import org.openstreetmap.josm.data.osm.Way;
    1124import org.openstreetmap.josm.gui.MainApplication;
    1225import org.openstreetmap.josm.gui.MapFrame;
     26import org.openstreetmap.josm.gui.MapView;
    1327import org.openstreetmap.josm.gui.layer.OsmDataLayer;
     28import org.openstreetmap.josm.gui.util.GuiHelper;
    1429import org.openstreetmap.josm.testutils.annotations.Main;
    1530import org.openstreetmap.josm.testutils.annotations.Projection;
     31import org.openstreetmap.josm.testutils.mockers.WindowlessMapViewStateMocker;
     32import org.openstreetmap.josm.testutils.mockers.WindowlessNavigatableComponentMocker;
     33
     34import mockit.Mock;
    1635
    1736/**
    1837 * Unit tests for class {@link ImproveWayAccuracyAction}.
    1938 */
    20 @Main
    2139@Projection
    2240class ImproveWayAccuracyActionTest {
     41    @RegisterExtension
     42    Main.MainExtension mainExtension = new Main.MainExtension().setMapViewMocker(SizedWindowlessMapViewStateMocker::new)
     43            .setNavigableComponentMocker(SizedWindowlessNavigatableComponentMocker::new);
     44
     45    private static final int WIDTH = 800;
     46    private static final int HEIGHT = 600;
     47    private static class SizedWindowlessMapViewStateMocker extends WindowlessMapViewStateMocker {
     48        @Mock
     49        public int getWidth() {
     50            return WIDTH;
     51        }
     52
     53        @Mock
     54        public int getHeight() {
     55            return HEIGHT;
     56        }
     57    }
     58
     59    private static class SizedWindowlessNavigatableComponentMocker extends WindowlessNavigatableComponentMocker {
     60        @Mock
     61        public int getWidth() {
     62            return WIDTH;
     63        }
     64
     65        @Mock
     66        public int getHeight() {
     67            return HEIGHT;
     68        }
     69    }
     70
     71    private static MouseEvent generateEvent(MapView mapView, ILatLon location) {
     72        final Point p = mapView.getPoint(location);
     73        return new MouseEvent(mapView, 0, 0, 0, p.x, p.y, p.x, p.y, 1, false, MouseEvent.BUTTON1);
     74    }
     75
    2376    /**
    2477     * Unit test of {@link ImproveWayAccuracyAction#enterMode} and {@link ImproveWayAccuracyAction#exitMode}.
     
    4598    @Test
    4699    void testEnumState() {
    47         TestUtils.superficialEnumCodeCoverage(State.class);
     100        assertDoesNotThrow(() -> TestUtils.superficialEnumCodeCoverage(State.class));
     101    }
     102
     103    @Test
     104    void testNonRegression23444() {
     105        final DataSet dataSet = new DataSet();
     106        final OsmDataLayer layer = new OsmDataLayer(dataSet, "ImproveWayAccuracyActionT", null);
     107        MainApplication.getLayerManager().addLayer(layer);
     108        final ImproveWayAccuracyAction mapMode = new ImproveWayAccuracyAction();
     109        final MapFrame map = MainApplication.getMap();
     110        assertTrue(map.selectMapMode(mapMode));
     111        assertEquals(mapMode, map.mapMode);
     112        final Way testWay = TestUtils.newWay("", new Node(1, 1), new Node(2, 1),
     113                new Node(3), new Node(4, 1), new Node(5, 1));
     114        testWay.firstNode().setCoor(new LatLon(0, 0));
     115        testWay.lastNode().setCoor(new LatLon(0.001, 0.001));
     116        testWay.getNode(1).setCoor(new LatLon(0.0001, 0.0001));
     117        testWay.getNode(3).setCoor(new LatLon(0.0009, 0.0009));
     118        dataSet.addPrimitiveRecursive(testWay);
     119        assertFalse(testWay.getNode(2).isLatLonKnown(), "The second node should not have valid coordinates");
     120        final Graphics2D g2d = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_ARGB).createGraphics();
     121        g2d.setClip(0, 0, WIDTH, HEIGHT);
     122        try {
     123            // If this fails, something else is wrong
     124            assertDoesNotThrow(() -> map.mapView.paint(g2d), "The mapview should be able to handle a null coordinate node");
     125            // Ensure that the test way is selected (and use the methods from the action to do so)
     126            GuiHelper.runInEDTAndWaitWithException(() -> {
     127                map.mapView.zoomTo(new Bounds(0, 0, 0.001, 0.001));
     128                // Get the target way selected (note: not selected in dataset -- use mapMode.mapReleased for that)
     129                mapMode.mouseMoved(generateEvent(map.mapView, testWay.getNode(1)));
     130            });
     131            // mouseMoved shouldn't cause the way to get selected
     132            assertFalse(dataSet.getAllSelected().contains(testWay));
     133
     134            // Now check painting (where the problem should occur; the mapMode.paint call should be called as part of the map.mapView.paint call)
     135            assertDoesNotThrow(() -> map.mapView.paint(g2d));
     136            assertDoesNotThrow(() -> mapMode.paint(g2d, map.mapView, new Bounds(0, 0, 0.001, 0.001)));
     137
     138            // Finally, check painting during selection
     139            GuiHelper.runInEDTAndWaitWithException(() -> {
     140                // Set the way as selected
     141                mapMode.mouseReleased(generateEvent(map.mapView, new LatLon(0.0001, 0.0001)));
     142                // Set the mouse location (unset in mouseReleased call)
     143                mapMode.mouseMoved(generateEvent(map.mapView, new LatLon(0.0001, 0.0001)));
     144            });
     145            // The way shouldn't be selected, since it isn't usable for the improve way tool
     146            assertFalse(dataSet.getAllSelected().contains(testWay));
     147            // Now check painting again (just in case)
     148            assertDoesNotThrow(() -> map.paint(g2d));
     149            assertDoesNotThrow(() -> mapMode.paint(g2d, map.mapView, new Bounds(0, 0, 0.001, 0.001)));
     150        } finally {
     151            g2d.dispose();
     152        }
    48153    }
    49154}
Note: See TracChangeset for help on using the changeset viewer.