Changeset 16984 in josm for trunk


Ignore:
Timestamp:
2020-08-30T21:27:14+02:00 (4 years ago)
Author:
simon04
Message:

see #18694 - Migrate ImageProviderTest to JUnit 5, mock bestCursorSize, compare cursors with reference images

Location:
trunk
Files:
6 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/tools/ImageProvider.java

    r16946 r16984  
    4848import java.util.concurrent.Executors;
    4949import java.util.function.Consumer;
     50import java.util.function.UnaryOperator;
    5051import java.util.regex.Matcher;
    5152import java.util.regex.Pattern;
     
    13311332
    13321333        Point hotSpot = new Point();
    1333         Image image = getCursorImage(name, overlay, hotSpot);
     1334        Image image = getCursorImage(name, overlay, dim -> Toolkit.getDefaultToolkit().getBestCursorSize(dim.width, dim.height), hotSpot);
    13341335
    13351336        return Toolkit.getDefaultToolkit().createCustomCursor(image, hotSpot, name);
     
    13481349     * @param name the cursor image filename in "cursor" directory
    13491350     * @param overlay optional overlay image
     1351     * @param bestCursorSizeFunction computes the best cursor size, see {@link Toolkit#getBestCursorSize(int, int)}
    13501352     * @param hotSpot will be set to the properly scaled hotspot of the cursor
    13511353     * @return cursor with a given file name, optionally decorated with an overlay image
    13521354     */
    1353     static Image getCursorImage(String name, String overlay, /* out */ Point hotSpot) {
     1355    static Image getCursorImage(String name, String overlay, UnaryOperator<Dimension> bestCursorSizeFunction, /* out */ Point hotSpot) {
    13541356        ImageProvider imageProvider = new ImageProvider("cursor", name);
    13551357        if (overlay != null) {
     
    13661368        // AWT will resize the cursor to bestCursorSize internally anyway, but miss to scale the hotspot as well
    13671369        // (bug JDK-8238734).  So let's do this ourselves, and also scale the hotspot accordingly.
    1368         Dimension bestCursorSize = Toolkit.getDefaultToolkit().getBestCursorSize(width, height);
     1370        Dimension bestCursorSize = bestCursorSizeFunction.apply(new Dimension(width, height));
    13691371        if (bestCursorSize.width != 0 && bestCursorSize.height != 0) {
    13701372            // In principle, we could pass the MultiResolutionImage itself to AWT, but due to bug JDK-8240568,
  • trunk/test/functional/org/openstreetmap/josm/tools/ImageProviderTest.java

    r16983 r16984  
    22package org.openstreetmap.josm.tools;
    33
    4 import static java.awt.image.BufferedImage.TYPE_INT_ARGB;
    54import static org.junit.Assert.assertEquals;
    65import static org.junit.Assert.assertFalse;
    76import static org.junit.Assert.assertNotNull;
    8 import static org.junit.Assert.assertTrue;
    97import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
    108import static org.openstreetmap.josm.gui.mappaint.MapCSSRendererTest.assertImageEquals;
    119
    1210import java.awt.Dimension;
    13 import java.awt.GraphicsEnvironment;
    1411import java.awt.Image;
    1512import java.awt.Point;
    16 import java.awt.Toolkit;
    1713import java.awt.Transparency;
    1814import java.awt.image.BufferedImage;
     
    2218import java.util.Collections;
    2319import java.util.List;
     20import java.util.function.UnaryOperator;
    2421import java.util.logging.Handler;
    2522import java.util.logging.LogRecord;
     
    2825import javax.swing.ImageIcon;
    2926
    30 import org.junit.Before;
    31 import org.junit.BeforeClass;
    32 import org.junit.Rule;
    33 import org.junit.Test;
     27import org.junit.jupiter.api.BeforeAll;
     28import org.junit.jupiter.api.BeforeEach;
     29import org.junit.jupiter.api.Test;
     30import org.junit.jupiter.api.extension.RegisterExtension;
     31import org.junit.jupiter.params.ParameterizedTest;
     32import org.junit.jupiter.params.provider.ValueSource;
    3433import org.openstreetmap.josm.JOSMFixture;
    3534import org.openstreetmap.josm.TestUtils;
     
    5453     * Setup test.
    5554     */
    56     @Rule
     55    @RegisterExtension
    5756    @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
    5857    public JOSMTestRules test = new JOSMTestRules();
     
    8079     * Setup test.
    8180     */
    82     @BeforeClass
     81    @BeforeAll
    8382    public static void setUp() {
    8483        JOSMFixture.createUnitTestFixture().init();
    8584    }
    8685
    87     @Before
     86    @BeforeEach
    8887    public void resetPixelDensity() {
    8988        GuiSizesHelper.setPixelDensity(1.0f);
     
    204203    private static void testImage(int width, int height, String reference, ImageIcon icon) throws IOException {
    205204        final BufferedImage image = (BufferedImage) icon.getImage();
    206         final File referenceFile = new File(
    207                 TestUtils.getTestDataRoot() + "/" + ImageProviderTest.class.getSimpleName() + "/" + reference + ".png");
     205        final File referenceFile = getReferenceFile(reference);
    208206        assertEquals("width", width, image.getWidth(null));
    209207        assertEquals("height", height, image.getHeight(null));
    210208        assertImageEquals(reference, referenceFile, image, 0, 0, null);
     209    }
     210
     211    private static File getReferenceFile(String reference) {
     212        return new File(TestUtils.getTestDataRoot() + "/" + ImageProviderTest.class.getSimpleName() + "/" + reference + ".png");
    211213    }
    212214
     
    237239     * Test getting an image for a crosshair cursor.
    238240     */
    239     @Test
    240     public void testGetCursorImageForCrosshair() {
    241         if (GraphicsEnvironment.isHeadless()) {
    242             // TODO mock Toolkit.getDefaultToolkit().getBestCursorSize()
    243             return;
    244         }
    245         Point hotSpot = new Point();
    246         Image image = ImageProvider.getCursorImage("crosshair", null, hotSpot);
    247         assertCursorDimensionsCorrect(new Point.Double(10.0, 10.0), image, hotSpot);
    248     }
    249 
    250     /**
    251      * Test getting an image for a custom cursor with overlay.
    252      */
    253     @Test
    254     public void testGetCursorImageWithOverlay() {
    255         testCursorImageWithOverlay(1.0f);  // normal case
    256         testCursorImageWithOverlay(1.5f);  // user has configured a GUI scale of 1.5 in the JOSM advanced preferences
    257     }
    258 
    259     private void testCursorImageWithOverlay(float guiScale) {
    260         if (GraphicsEnvironment.isHeadless()) {
    261             // TODO mock Toolkit.getDefaultToolkit().getBestCursorSize()
    262             return;
    263         }
     241    @ParameterizedTest
     242    @ValueSource(floats = {1.0f, 1.5f, 3.0f})
     243    public void testGetCursorImageForCrosshair(float guiScale) throws IOException {
    264244        GuiSizesHelper.setPixelDensity(guiScale);
    265245        Point hotSpot = new Point();
    266         Image image = ImageProvider.getCursorImage("normal", "selection", hotSpot);
    267         assertCursorDimensionsCorrect(new Point.Double(3.0, 2.0), image, hotSpot);
    268         BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getWidth(null), TYPE_INT_ARGB);
    269         bufferedImage.getGraphics().drawImage(image, 0, 0, null);
    270 
    271         // check that the square of 1/4 size right lower to the center has some non-empty pixels
    272         boolean nonEmptyPixelExistsRightLowerToCenter = false;
    273         for (int x = image.getWidth(null) / 2; x < image.getWidth(null) * 3 / 4; ++x) {
    274             for (int y = image.getHeight(null) / 2; y < image.getWidth(null) * 3 / 4; ++y) {
    275                 if (bufferedImage.getRGB(x, y) != 0)
    276                     nonEmptyPixelExistsRightLowerToCenter = true;
    277             }
    278         }
    279         assertTrue(nonEmptyPixelExistsRightLowerToCenter);
    280     }
    281 
    282     private void assertCursorDimensionsCorrect(Point.Double originalHotspot, Image image, Point hotSpot) {
     246        final UnaryOperator<Dimension> bestCursorSizeFunction = dim -> dim;
     247        Image image = ImageProvider.getCursorImage("crosshair", null, bestCursorSizeFunction, hotSpot);
     248        assertCursorDimensionsCorrect(new Point.Double(10.0, 10.0), image, bestCursorSizeFunction, hotSpot);
     249        assertImageEquals("cursor", getReferenceFile("cursor-crosshair-" + Math.round(guiScale * 10)),
     250                ((BufferedImage) image), 0, 0, null);
     251    }
     252
     253    /**
     254     * Test getting an image for a custom cursor with overlay.
     255     */
     256    @ParameterizedTest
     257    @ValueSource(floats = {1.0f, 1.5f, 3.0f})
     258    public void testGetCursorImageWithOverlay(float guiScale) throws IOException {
     259        GuiSizesHelper.setPixelDensity(guiScale);
     260        Point hotSpot = new Point();
     261        final UnaryOperator<Dimension> bestCursorSizeFunction = dim -> dim;
     262        Image image = ImageProvider.getCursorImage("normal", "selection", bestCursorSizeFunction, hotSpot);
     263        assertCursorDimensionsCorrect(new Point.Double(3.0, 2.0), image, bestCursorSizeFunction, hotSpot);
     264        assertImageEquals("cursor", getReferenceFile("cursor-normal-selection-" + Math.round(guiScale * 10)),
     265                ((BufferedImage) image), 0, 0, null);
     266    }
     267
     268    private void assertCursorDimensionsCorrect(Point.Double originalHotspot, Image image,
     269                                               UnaryOperator<Dimension> bestCursorSizeFunction, Point hotSpot) {
    283270        int originalCursorSize = ImageProvider.CURSOR_SIZE_HOTSPOT_IS_RELATIVE_TO;
    284         Dimension bestCursorSize = Toolkit.getDefaultToolkit().getBestCursorSize(originalCursorSize, originalCursorSize);
     271        Dimension bestCursorSize = bestCursorSizeFunction.apply(new Dimension(originalCursorSize, originalCursorSize));
    285272        Image bestCursorImage = HiDPISupport.getResolutionVariant(image, bestCursorSize.width, bestCursorSize.height);
    286273        int bestCursorImageWidth = bestCursorImage.getWidth(null);
Note: See TracChangeset for help on using the changeset viewer.