Ticket #15599: v1-0006-add-ImagePatternMatching-testutil-example-use-in-.patch
| File v1-0006-add-ImagePatternMatching-testutil-example-use-in-.patch, 12.3 KB (added by , 8 years ago) |
|---|
-
test/unit/org/openstreetmap/josm/gui/dialogs/MinimapDialogTest.java
From bd836670c8280e65323d8bacbab67389ec084b6c Mon Sep 17 00:00:00 2001 From: Robert Scott <code@humanleg.org.uk> Date: Sat, 25 Nov 2017 23:55:46 +0000 Subject: [PATCH v1 6/6] add ImagePatternMatching testutil, example use in MinimapDialogTest --- .../josm/gui/dialogs/MinimapDialogTest.java | 123 ++++++++++++ .../josm/testutils/ImagePatternMatching.java | 212 +++++++++++++++++++++ 2 files changed, 335 insertions(+) create mode 100644 test/unit/org/openstreetmap/josm/testutils/ImagePatternMatching.java diff --git a/test/unit/org/openstreetmap/josm/gui/dialogs/MinimapDialogTest.java b/test/unit/org/openstreetmap/josm/gui/dialogs/MinimapDialogTest.java index 4ef49923a..cf7ad372c 100644
a b import static java.util.concurrent.TimeUnit.MILLISECONDS; 11 11 import java.awt.Color; 12 12 import java.awt.Component; 13 13 import java.awt.Graphics2D; 14 import java.awt.event.ComponentEvent; 14 15 import java.awt.image.BufferedImage; 15 16 16 17 import javax.swing.JMenuItem; 17 18 import javax.swing.JPopupMenu; 18 19 20 import java.util.Arrays; 21 import java.util.Map; 19 22 import java.util.concurrent.Callable; 23 import java.util.regex.Matcher; 20 24 21 25 import org.junit.Rule; 22 26 import org.junit.Test; 23 27 import org.openstreetmap.josm.Main; 24 28 import org.openstreetmap.josm.TestUtils; 29 import org.openstreetmap.josm.data.Bounds; 25 30 import org.openstreetmap.josm.gui.bbox.SlippyMapBBoxChooser; 26 31 import org.openstreetmap.josm.gui.bbox.SourceButton; 32 import org.openstreetmap.josm.gui.MainApplication; 33 import org.openstreetmap.josm.gui.MapView; 27 34 import org.openstreetmap.josm.gui.util.GuiHelper; 35 import org.openstreetmap.josm.testutils.ImagePatternMatching; 28 36 import org.openstreetmap.josm.testutils.JOSMTestRules; 29 37 30 38 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; 31 39 32 40 import org.awaitility.Awaitility; 33 41 42 import com.google.common.collect.ImmutableMap; 43 34 44 /** 35 45 * Unit tests of {@link MinimapDialog} class. 36 46 */ … … public class MinimapDialogTest { 251 261 252 262 assertEquals(0xffffffff, paintedSlippyMap.getRGB(0, 0)); 253 263 } 264 265 /** 266 * ... 267 * @throws Exception if any error occurs 268 */ 269 @Test 270 public void testViewportAspectRatio() throws Exception { 271 Main.pref.put("slippy_map_chooser.mapstyle", "White Tiles"); 272 273 MapView mapView = MainApplication.getMap().mapView; 274 GuiHelper.runInEDTAndWaitWithException(() -> { 275 mapView.setVisible(true); 276 mapView.addNotify(); 277 mapView.doLayout(); 278 // ensure we have a square mapView viewport 279 mapView.setBounds(0, 0, 350, 350); 280 // TODO ensure we're in the right projection 281 }); 282 283 this.setUpMiniMap(); 284 285 // attempt to set viewport to cover a non-square area 286 mapView.zoomTo(new Bounds(26.27, -18.23, 26.275, -18.229)); 287 288 // an initial paint operation is required to trigger the tile fetches 289 this.paintSlippyMap(); 290 291 Awaitility.await().atMost(1000, MILLISECONDS).until(this.slippyMapTasksFinished); 292 293 this.paintSlippyMap(); 294 295 Map<Integer, String> paletteMap = ImmutableMap.<Integer, String>builder() 296 .put(0xffffffff, "w") 297 .put(0xff000000, "b") 298 .put(0xfff0d1d1, "p") 299 .build(); 300 301 Matcher rowMatcher = ImagePatternMatching.rowMatch( 302 paintedSlippyMap, 303 paintedSlippyMap.getHeight()/2, 304 paletteMap, 305 "^(w+)b(p+)b(w+)$", 306 true 307 ); 308 309 // (within a tolerance for numerical error) the number of pixels on the left of the viewport marker 310 // should equal the number on the right 311 assertTrue( 312 "Viewport marker not horizontally centered", 313 Math.abs(rowMatcher.group(1).length() - rowMatcher.group(3).length()) < 4 314 ); 315 316 Matcher colMatcher = ImagePatternMatching.columnMatch( 317 paintedSlippyMap, 318 paintedSlippyMap.getWidth()/2, 319 paletteMap, 320 "^(w+)b(p+)b(w+)$", 321 true 322 ); 323 324 // (within a tolerance for numerical error) the number of pixels on the top of the viewport marker 325 // should equal the number on the bottom 326 assertTrue( 327 "Viewport marker not vertically centered", 328 Math.abs(colMatcher.group(1).length() - colMatcher.group(3).length()) < 4 329 ); 330 331 // (within a tolerance for numerical error) the viewport marker should be square 332 assertTrue( 333 "Viewport marker not square", 334 Math.abs(colMatcher.group(2).length() - rowMatcher.group(2).length()) < 4 335 ); 336 337 GuiHelper.runInEDTAndWaitWithException(() -> { 338 mapView.setBounds(0, 0, 150, 300); 339 Arrays.stream(mapView.getComponentListeners()).forEach( 340 cl -> cl.componentResized(new ComponentEvent(mapView, ComponentEvent.COMPONENT_RESIZED)) 341 ); 342 }); 343 // minimap doesn't (yet?) listen for component resize events to update its viewport marker, so 344 // trigger a zoom change 345 mapView.zoomTo(mapView.getCenter()); 346 this.paintSlippyMap(); 347 348 rowMatcher = ImagePatternMatching.rowMatch( 349 paintedSlippyMap, 350 paintedSlippyMap.getHeight()/2, 351 paletteMap, 352 "^(w+)b(p+)b(w+)$", 353 true 354 ); 355 assertTrue( 356 "Viewport marker not horizontally centered", 357 Math.abs(rowMatcher.group(1).length() - rowMatcher.group(3).length()) < 4 358 ); 359 360 colMatcher = ImagePatternMatching.columnMatch( 361 paintedSlippyMap, 362 paintedSlippyMap.getWidth()/2, 363 paletteMap, 364 "^(w+)b(p+)b(w+)$", 365 true 366 ); 367 assertTrue( 368 "Viewport marker not vertically centered", 369 Math.abs(colMatcher.group(1).length() - colMatcher.group(3).length()) < 4 370 ); 371 372 assertTrue( 373 "Viewport marker not 2:1 aspect ratio", 374 Math.abs(colMatcher.group(2).length() - (rowMatcher.group(2).length()*2.0)) < 5 375 ); 376 } 254 377 } -
new file test/unit/org/openstreetmap/josm/testutils/ImagePatternMatching.java
diff --git a/test/unit/org/openstreetmap/josm/testutils/ImagePatternMatching.java b/test/unit/org/openstreetmap/josm/testutils/ImagePatternMatching.java new file mode 100644 index 000000000..035627bfc
- + 1 // License: GPL. For details, see LICENSE file. 2 package org.openstreetmap.josm.testutils; 3 4 import static org.junit.Assert.fail; 5 6 import java.awt.image.BufferedImage; 7 8 import java.util.Arrays; 9 import java.util.HashMap; 10 import java.util.Map; 11 import java.util.Optional; 12 import java.util.function.IntFunction; 13 import java.util.regex.Matcher; 14 import java.util.regex.Pattern; 15 import java.util.stream.Collectors; 16 17 /** 18 * Utilities to aid in making assertions about images using regular expressions. 19 */ 20 public final class ImagePatternMatching { 21 private ImagePatternMatching() {} 22 23 private static final Map<String, Pattern> patternCache = new HashMap<String, Pattern>(); 24 25 private static Matcher imageStripPatternMatchInner( 26 final BufferedImage image, 27 final int columnOrRowIndex, 28 IntFunction<String> paletteMapFn, 29 final Map<Integer, String> paletteMap, 30 Pattern pattern, 31 final String patternString, 32 final boolean isColumn, 33 final boolean assertMatch 34 ) { 35 paletteMapFn = Optional.ofNullable(paletteMapFn) 36 // using "#" as the default "unmapped" character as it can be used in regexes without escaping 37 .orElse(i -> paletteMap.getOrDefault(i, "#")); 38 pattern = Optional.ofNullable(pattern) 39 .orElseGet(() -> patternCache.computeIfAbsent(patternString, k -> Pattern.compile(k))); 40 41 int[] columnOrRow = isColumn 42 ? image.getRGB(columnOrRowIndex, 0, 1, image.getHeight(), null, 0, 1) 43 : image.getRGB(0, columnOrRowIndex, image.getWidth(), 1, null, 0, image.getWidth()); 44 45 String stringRepr = Arrays.stream(columnOrRow).mapToObj(paletteMapFn).collect(Collectors.joining()); 46 Matcher result = pattern.matcher(stringRepr); 47 48 if (assertMatch && !result.matches()) { 49 System.err.println(String.format("Full strip failing to match pattern %s: %s", pattern, stringRepr)); 50 fail(String.format( 51 "%s %d failed to match pattern %s", 52 isColumn ? "Column" : "Row", 53 columnOrRowIndex, 54 pattern 55 )); 56 } 57 58 return result; 59 } 60 61 public static Matcher columnMatch( 62 final BufferedImage image, 63 final int rowNumber, 64 final Map<Integer, String> paletteMap, 65 final String patternString, 66 final boolean assertMatch 67 ) { 68 return imageStripPatternMatchInner( 69 image, 70 rowNumber, 71 null, 72 paletteMap, 73 null, 74 patternString, 75 true, 76 true 77 ); 78 } 79 80 public static Matcher columnMatch( 81 final BufferedImage image, 82 final int rowNumber, 83 final IntFunction<String> paletteMapFn, 84 final String patternString, 85 final boolean assertMatch 86 ) { 87 return imageStripPatternMatchInner( 88 image, 89 rowNumber, 90 paletteMapFn, 91 null, 92 null, 93 patternString, 94 true, 95 true 96 ); 97 } 98 99 public static Matcher columnMatch( 100 final BufferedImage image, 101 final int rowNumber, 102 final Map<Integer, String> paletteMap, 103 final Pattern pattern, 104 final boolean assertMatch 105 ) { 106 return imageStripPatternMatchInner( 107 image, 108 rowNumber, 109 null, 110 paletteMap, 111 pattern, 112 null, 113 true, 114 true 115 ); 116 } 117 118 public static Matcher columnMatch( 119 final BufferedImage image, 120 final int rowNumber, 121 final IntFunction<String> paletteMapFn, 122 final Pattern pattern, 123 final boolean assertMatch 124 ) { 125 return imageStripPatternMatchInner( 126 image, 127 rowNumber, 128 paletteMapFn, 129 null, 130 pattern, 131 null, 132 true, 133 true 134 ); 135 } 136 137 public static Matcher rowMatch( 138 final BufferedImage image, 139 final int rowNumber, 140 final Map<Integer, String> paletteMap, 141 final String patternString, 142 final boolean assertMatch 143 ) { 144 return imageStripPatternMatchInner( 145 image, 146 rowNumber, 147 null, 148 paletteMap, 149 null, 150 patternString, 151 false, 152 true 153 ); 154 } 155 156 public static Matcher rowMatch( 157 final BufferedImage image, 158 final int rowNumber, 159 final IntFunction<String> paletteMapFn, 160 final String patternString, 161 final boolean assertMatch 162 ) { 163 return imageStripPatternMatchInner( 164 image, 165 rowNumber, 166 paletteMapFn, 167 null, 168 null, 169 patternString, 170 false, 171 true 172 ); 173 } 174 175 public static Matcher rowMatch( 176 final BufferedImage image, 177 final int rowNumber, 178 final Map<Integer, String> paletteMap, 179 final Pattern pattern, 180 final boolean assertMatch 181 ) { 182 return imageStripPatternMatchInner( 183 image, 184 rowNumber, 185 null, 186 paletteMap, 187 pattern, 188 null, 189 false, 190 true 191 ); 192 } 193 194 public static Matcher rowMatch( 195 final BufferedImage image, 196 final int rowNumber, 197 final IntFunction<String> paletteMapFn, 198 final Pattern pattern, 199 final boolean assertMatch 200 ) { 201 return imageStripPatternMatchInner( 202 image, 203 rowNumber, 204 paletteMapFn, 205 null, 206 pattern, 207 null, 208 false, 209 true 210 ); 211 } 212 }
