Ticket #21260: 21260.2.patch

File 21260.2.patch, 11.2 KB (added by taylor.smock, 5 years ago)

Add tests

  • src/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayer.java

    diff --git a/src/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayer.java b/src/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayer.java
    index 0813aaf25d..16e81102ee 100644
    a b implements ImageObserver, TileLoaderListener, ZoomChangeListener, FilterChangeLi  
    888888        Tile tile = getTile(x, y, zoom);
    889889        if (tile == null) {
    890890            if (coordinateConverter.requiresReprojection()) {
    891                 tile = new ReprojectionTile(tileSource, x, y, zoom);
     891                tile = new ReprojectionTile(createTile(tileSource, x, y, zoom));
    892892            } else {
    893893                tile = createTile(tileSource, x, y, zoom);
    894894            }
  • src/org/openstreetmap/josm/gui/layer/imagery/ReprojectionTile.java

    diff --git a/src/org/openstreetmap/josm/gui/layer/imagery/ReprojectionTile.java b/src/org/openstreetmap/josm/gui/layer/imagery/ReprojectionTile.java
    index 2f3d948b46..0da3cdf346 100644
    a b package org.openstreetmap.josm.gui.layer.imagery;  
    44import java.awt.Dimension;
    55import java.awt.geom.Point2D;
    66import java.awt.image.BufferedImage;
     7import java.io.IOException;
     8import java.io.InputStream;
    79
    810import org.openstreetmap.gui.jmapviewer.Tile;
    911import org.openstreetmap.gui.jmapviewer.interfaces.TileSource;
    1012import org.openstreetmap.josm.data.ProjectionBounds;
    1113import org.openstreetmap.josm.data.coor.EastNorth;
    1214import org.openstreetmap.josm.data.imagery.CoordinateConversion;
     15import org.openstreetmap.josm.data.imagery.vectortile.VectorTile;
    1316import org.openstreetmap.josm.data.projection.Projection;
    1417import org.openstreetmap.josm.data.projection.ProjectionRegistry;
    1518import org.openstreetmap.josm.data.projection.Projections;
    import org.openstreetmap.josm.tools.bugreport.BugReport;  
    2528 */
    2629public class ReprojectionTile extends Tile {
    2730
     31    private final Tile tile;
    2832    protected TileAnchor anchor;
    2933    private double nativeScale;
    3034    protected boolean maxZoomReached;
    3135
    3236    /**
    3337     * Constructs a new {@code ReprojectionTile}.
    34      * @param source sourec tile
     38     * @param source source tile
    3539     * @param xtile X coordinate
    3640     * @param ytile Y coordinate
    3741     * @param zoom zoom level
    3842     */
    3943    public ReprojectionTile(TileSource source, int xtile, int ytile, int zoom) {
    4044        super(source, xtile, ytile, zoom);
     45        this.tile = null;
     46    }
     47
     48    /**
     49     * Create a reprojection tile for a specific tile
     50     * @param tile The tile to use
     51     */
     52    public ReprojectionTile(Tile tile) {
     53        super(tile.getTileSource(), tile.getXtile(), tile.getYtile(), tile.getZoom());
     54        this.tile = tile;
    4155    }
    4256
    4357    /**
    public class ReprojectionTile extends Tile {  
    7488        return !maxZoomReached || currentScale >= nativeScale;
    7589    }
    7690
     91    @Override
     92    public void loadImage(InputStream inputStream) throws IOException {
     93        if (this.tile instanceof VectorTile) {
     94            this.tile.loadImage(inputStream);
     95        } else {
     96            super.loadImage(inputStream);
     97        }
     98    }
     99
    77100    @Override
    78101    public void setImage(BufferedImage image) {
    79102        if (image == null) {
  • new file test/unit/org/openstreetmap/josm/gui/layer/imagery/MVTLayerTest.java

    diff --git a/test/unit/org/openstreetmap/josm/gui/layer/imagery/MVTLayerTest.java b/test/unit/org/openstreetmap/josm/gui/layer/imagery/MVTLayerTest.java
    new file mode 100644
    index 0000000000..1233f9fa32
    - +  
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.gui.layer.imagery;
     3
     4import static org.junit.jupiter.api.Assertions.assertArrayEquals;
     5import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
     6import static org.junit.jupiter.api.Assertions.assertEquals;
     7import static org.junit.jupiter.api.Assertions.assertFalse;
     8import static org.junit.jupiter.api.Assertions.assertNotNull;
     9import static org.junit.jupiter.api.Assertions.assertTrue;
     10
     11import java.util.Collections;
     12
     13import org.apache.commons.jcs3.access.behavior.ICacheAccess;
     14import org.awaitility.Awaitility;
     15import org.awaitility.Durations;
     16import org.junit.jupiter.api.BeforeEach;
     17import org.junit.jupiter.api.Test;
     18import org.junit.jupiter.api.extension.RegisterExtension;
     19import org.junit.jupiter.params.ParameterizedTest;
     20import org.junit.jupiter.params.provider.ValueSource;
     21import org.openstreetmap.gui.jmapviewer.interfaces.TileLoaderListener;
     22import org.openstreetmap.josm.TestUtils;
     23import org.openstreetmap.josm.actions.ExpertToggleAction;
     24import org.openstreetmap.josm.data.Bounds;
     25import org.openstreetmap.josm.data.imagery.ImageryInfo;
     26import org.openstreetmap.josm.data.imagery.TileJobOptions;
     27import org.openstreetmap.josm.data.imagery.vectortile.mapbox.MVTFile;
     28import org.openstreetmap.josm.data.imagery.vectortile.mapbox.MVTTile;
     29import org.openstreetmap.josm.data.imagery.vectortile.mapbox.MapboxVectorCachedTileLoader;
     30import org.openstreetmap.josm.data.osm.BBox;
     31import org.openstreetmap.josm.data.projection.Projection;
     32import org.openstreetmap.josm.data.projection.ProjectionRegistry;
     33import org.openstreetmap.josm.data.projection.Projections;
     34import org.openstreetmap.josm.gui.MainApplication;
     35import org.openstreetmap.josm.testutils.FakeGraphics;
     36import org.openstreetmap.josm.testutils.JOSMTestRules;
     37import org.openstreetmap.josm.testutils.annotations.BasicPreferences;
     38
     39/**
     40 * Test class for {@link MVTLayer}
     41 */
     42@BasicPreferences
     43class MVTLayerTest {
     44    // Needed for setting HTTP factory and the main window/mapview
     45    @RegisterExtension
     46    JOSMTestRules josmTestRules = new JOSMTestRules().main().projection();
     47
     48    MVTLayer testLayer;
     49
     50    @BeforeEach
     51    void setUp() {
     52        final ImageryInfo imageryInfo = new ImageryInfo("MvtLayerTest", "file:" + TestUtils.getTestDataRoot() + "pbf/mapillary/{z}/{x}/{y}.mvt");
     53        imageryInfo.setImageryType(ImageryInfo.ImageryType.MVT);
     54        this.testLayer = new MVTLayer(imageryInfo);
     55    }
     56
     57    @Test
     58    void getTileLoaderClass() {
     59        assertEquals(MapboxVectorCachedTileLoader.class, this.testLayer.getTileLoaderClass());
     60    }
     61
     62    @Test
     63    void getCacheName() {
     64        assertEquals("MVT", this.testLayer.getCacheName());
     65    }
     66
     67    @Test
     68    void getCache() {
     69        assertNotNull(MVTLayer.getCache());
     70    }
     71
     72    @Test
     73    void getNativeProjections() {
     74        assertArrayEquals(Collections.singleton(MVTFile.DEFAULT_PROJECTION).toArray(), this.testLayer.getNativeProjections().toArray());
     75    }
     76
     77    /**
     78     * This is a non-regression test for JOSM #21260
     79     * @param projectionCode The projection code to use
     80     * @throws ReflectiveOperationException If the required method was unable to be called
     81     */
     82    @ParameterizedTest
     83    @ValueSource(strings = {"EPSG:3857" /* WGS 84 */, "EPSG:4326" /* Mercator (default) */, "EPSG:32612" /* UTM 12 N */})
     84    void ensureDifferentProjectionsAreFetched(final String projectionCode) throws ReflectiveOperationException {
     85        final Projection originalProjection = ProjectionRegistry.getProjection();
     86        try {
     87            ProjectionRegistry.setProjection(Projections.getProjectionByCode(projectionCode));
     88            // Needed to initialize mapView
     89            MainApplication.getLayerManager().addLayer(this.testLayer);
     90            final BBox tileBBox = new MVTTile(this.testLayer.getTileSource(), 3251, 6258, 14).getBBox();
     91            MainApplication.getMap().mapView.zoomTo(new Bounds(tileBBox.getMinLat(), tileBBox.getMinLon(),
     92                    tileBBox.getMaxLat(), tileBBox.getMaxLon()));
     93            final FakeGraphics graphics2D = new FakeGraphics();
     94            graphics2D.setClip(0, 0, 100, 100);
     95            this.testLayer.setZoomLevel(14);
     96            this.testLayer.getDisplaySettings().setAutoZoom(false);
     97            MainApplication.getMap().mapView.paintLayer(this.testLayer, graphics2D);
     98            Awaitility.await().atMost(Durations.ONE_SECOND).until(() -> !this.testLayer.getData().allPrimitives().isEmpty());
     99            assertFalse(this.testLayer.getData().allPrimitives().isEmpty());
     100        } finally {
     101            ProjectionRegistry.setProjection(originalProjection);
     102        }
     103    }
     104
     105    @Test
     106    void getTileSource() {
     107        assertEquals(this.testLayer.getInfo().getUrl(), this.testLayer.getTileSource().getBaseUrl());
     108    }
     109
     110    @Test
     111    void createTile() {
     112        assertNotNull(this.testLayer.createTile(this.testLayer.getTileSource(), 3251, 6258, 14));
     113    }
     114
     115    @ParameterizedTest
     116    @ValueSource(booleans = {true, false})
     117    void getMenuEntries(final boolean isExpert) {
     118        ExpertToggleAction.getInstance().setExpert(isExpert);
     119        // For now, just ensure that nothing throws on implementation
     120        MainApplication.getLayerManager().addLayer(this.testLayer);
     121        assertNotNull(assertDoesNotThrow(() -> this.testLayer.getMenuEntries()));
     122    }
     123
     124    @Test
     125    void getData() {
     126        assertNotNull(this.testLayer.getData());
     127    }
     128
     129    @Test
     130    void finishedLoading() throws ReflectiveOperationException {
     131        final MVTTile mvtTile = (MVTTile) this.testLayer.createTile(this.testLayer.getTileSource(), 3251, 6258, 14);
     132        final FinishedLoading finishedLoading = new FinishedLoading();
     133        mvtTile.addTileLoaderFinisher(finishedLoading);
     134        assertTrue(this.testLayer.getData().allPrimitives().isEmpty());
     135        this.testLayer.getTileLoaderClass().getConstructor(TileLoaderListener.class, ICacheAccess.class, TileJobOptions.class)
     136                .newInstance(this.testLayer, MVTLayer.getCache(), new TileJobOptions(50, 50, Collections.emptyMap(), 1))
     137                .createTileLoaderJob(mvtTile).submit();
     138        Awaitility.await().atMost(Durations.ONE_SECOND).until(() -> finishedLoading.finished);
     139        assertFalse(this.testLayer.getData().allPrimitives().isEmpty());
     140    }
     141
     142    /**
     143     * For some reason, lambdas get garbage collected by WeakReference's. This avoids that.
     144     */
     145    private static final class FinishedLoading implements MVTTile.TileListener {
     146        boolean finished;
     147        @Override
     148        public void finishedLoading(MVTTile tile) {
     149            this.finished = true;
     150        }
     151    }
     152}
  • test/unit/org/openstreetmap/josm/testutils/FakeGraphics.java

    diff --git a/test/unit/org/openstreetmap/josm/testutils/FakeGraphics.java b/test/unit/org/openstreetmap/josm/testutils/FakeGraphics.java
    index 6f42bac654..bab9697a35 100644
    a b import java.util.Map;  
    3131 * A fake Graphics to be used in headless mode.
    3232 */
    3333public final class FakeGraphics extends Graphics2D {
     34    // This is needed just in case someone wants to fake paint something
     35    private Rectangle bounds;
     36
    3437    @Override
    3538    public void setXORMode(Color c1) {
    3639    }
    public final class FakeGraphics extends Graphics2D {  
    4952
    5053    @Override
    5154    public void setClip(int x, int y, int width, int height) {
     55        this.bounds = new Rectangle(x, y, width, height);
    5256    }
    5357
    5458    @Override
    public final class FakeGraphics extends Graphics2D {  
    7276
    7377    @Override
    7478    public Rectangle getClipBounds() {
    75         return null;
     79        return this.bounds;
    7680    }
    7781
    7882    @Override