source: josm/trunk/test/unit/org/openstreetmap/josm/testutils/ImagePatternMatching.java@ 17275

Last change on this file since 17275 was 17275, checked in by Don-vip, 3 years ago

see #16567 - upgrade almost all tests to JUnit 5, except those depending on WiremockRule

See https://github.com/tomakehurst/wiremock/issues/684

  • Property svn:eol-style set to native
File size: 12.5 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.testutils;
3
4import static org.junit.jupiter.api.Assertions.fail;
5
6import java.awt.image.BufferedImage;
7import java.util.Arrays;
8import java.util.HashMap;
9import java.util.Map;
10import java.util.Optional;
11import java.util.function.IntFunction;
12import java.util.regex.Matcher;
13import java.util.regex.Pattern;
14import java.util.stream.Collectors;
15
16import junit.framework.AssertionFailedError;
17
18/**
19 * Utilities to aid in making assertions about images using regular expressions.
20 */
21public final class ImagePatternMatching {
22 private ImagePatternMatching() {}
23
24 private static final Map<String, Pattern> patternCache = new HashMap<>();
25
26 private static Matcher imageStripPatternMatchInner(
27 final BufferedImage image,
28 final int columnOrRowIndex,
29 IntFunction<String> paletteMapFn,
30 final Map<Integer, String> paletteMap,
31 Pattern pattern,
32 final String patternString,
33 final boolean isColumn,
34 final boolean assertMatch
35 ) {
36 paletteMapFn = Optional.ofNullable(paletteMapFn)
37 // using "#" as the default "unmapped" character as it can be used in regexes without escaping
38 .orElse(i -> paletteMap.getOrDefault(i, "#"));
39 pattern = Optional.ofNullable(pattern)
40 .orElseGet(() -> patternCache.computeIfAbsent(patternString, k -> Pattern.compile(k)));
41
42 int[] columnOrRow = isColumn
43 ? image.getRGB(columnOrRowIndex, 0, 1, image.getHeight(), null, 0, 1)
44 : image.getRGB(0, columnOrRowIndex, image.getWidth(), 1, null, 0, image.getWidth());
45
46 String stringRepr = Arrays.stream(columnOrRow).mapToObj(paletteMapFn).collect(Collectors.joining());
47 Matcher result = pattern.matcher(stringRepr);
48
49 if (assertMatch && !result.matches()) {
50 System.err.println(String.format("Full strip failing to match pattern %s: %s", pattern, stringRepr));
51 fail(String.format(
52 "%s %d failed to match pattern %s",
53 isColumn ? "Column" : "Row",
54 columnOrRowIndex,
55 pattern
56 ));
57 }
58
59 return result;
60 }
61
62 /**
63 * Attempt to match column {@code colNumber}, once translated to characters according to {@code paletteMap}
64 * against the regular expression described by {@code patternString}.
65 *
66 * @param image image to take column from
67 * @param colNumber image column number for comparison
68 * @param paletteMap {@link Map} of {@code Integer}s (denoting the color in ARGB format) to {@link String}s. It
69 * is advised to only map colors to single characters. Colors with no corresponding entry in
70 * the map are mapped to {@code #}.
71 * @param patternString string representation of regular expression to match against. These are simply used to
72 * construct a {@link Pattern} which is cached in case of re-use.
73 * @param assertMatch whether to raise an (informative) {@link AssertionFailedError} if no match is found.
74 * @return {@link Matcher} produced by matching attempt
75 */
76 public static Matcher columnMatch(
77 final BufferedImage image,
78 final int colNumber,
79 final Map<Integer, String> paletteMap,
80 final String patternString,
81 final boolean assertMatch
82 ) {
83 return imageStripPatternMatchInner(
84 image,
85 colNumber,
86 null,
87 paletteMap,
88 null,
89 patternString,
90 true,
91 true
92 );
93 }
94
95 /**
96 * Attempt to match column {@code colNumber}, once translated to characters according to {@code paletteMapFn}
97 * against the regular expression described by {@code patternString}.
98 *
99 * @param image image to take column from
100 * @param colNumber image column number for comparison
101 * @param paletteMapFn function mapping {@code Integer}s (denoting the color in ARGB format) to {@link String}s. It
102 * is advised to only map colors to single characters.
103 * @param patternString string representation of regular expression to match against. These are simply used to
104 * construct a {@link Pattern} which is cached in case of re-use.
105 * @param assertMatch whether to raise an (informative) {@link AssertionFailedError} if no match is found.
106 * @return {@link Matcher} produced by matching attempt
107 */
108 public static Matcher columnMatch(
109 final BufferedImage image,
110 final int colNumber,
111 final IntFunction<String> paletteMapFn,
112 final String patternString,
113 final boolean assertMatch
114 ) {
115 return imageStripPatternMatchInner(
116 image,
117 colNumber,
118 paletteMapFn,
119 null,
120 null,
121 patternString,
122 true,
123 true
124 );
125 }
126
127 /**
128 * Attempt to match column {@code colNumber}, once translated to characters according to {@code paletteMap}
129 * against the regular expression {@code pattern}.
130 *
131 * @param image image to take column from
132 * @param colNumber image column number for comparison
133 * @param paletteMap {@link Map} of {@code Integer}s (denoting the color in ARGB format) to {@link String}s. It
134 * is advised to only map colors to single characters. Colors with no corresponding entry in
135 * the map are mapped to {@code #}.
136 * @param pattern regular expression to match against
137 * @param assertMatch whether to raise an (informative) {@link AssertionFailedError} if no match is found.
138 * @return {@link Matcher} produced by matching attempt
139 */
140 public static Matcher columnMatch(
141 final BufferedImage image,
142 final int colNumber,
143 final Map<Integer, String> paletteMap,
144 final Pattern pattern,
145 final boolean assertMatch
146 ) {
147 return imageStripPatternMatchInner(
148 image,
149 colNumber,
150 null,
151 paletteMap,
152 pattern,
153 null,
154 true,
155 true
156 );
157 }
158
159 /**
160 * Attempt to match column {@code colNumber}, once translated to characters according to {@code paletteMapFn}
161 * against the regular expression {@code pattern}.
162 *
163 * @param image image to take column from
164 * @param colNumber image column number for comparison
165 * @param paletteMapFn function mapping {@code Integer}s (denoting the color in ARGB format) to {@link String}s. It
166 * is advised to only map colors to single characters.
167 * @param pattern regular expression to match against
168 * @param assertMatch whether to raise an (informative) {@link AssertionFailedError} if no match is found.
169 * @return {@link Matcher} produced by matching attempt
170 */
171 public static Matcher columnMatch(
172 final BufferedImage image,
173 final int colNumber,
174 final IntFunction<String> paletteMapFn,
175 final Pattern pattern,
176 final boolean assertMatch
177 ) {
178 return imageStripPatternMatchInner(
179 image,
180 colNumber,
181 paletteMapFn,
182 null,
183 pattern,
184 null,
185 true,
186 true
187 );
188 }
189
190 /**
191 * Attempt to match row {@code rowNumber}, once translated to characters according to {@code paletteMap}
192 * against the regular expression described by {@code patternString}.
193 *
194 * @param image image to take row from
195 * @param rowNumber image row number for comparison
196 * @param paletteMap {@link Map} of {@code Integer}s (denoting the or in ARGB format) to {@link String}s. It
197 * is advised to only map colors to single characters. Colors with no corresponding entry in
198 * the map are mapped to {@code #}.
199 * @param patternString string representation of regular expression to match against. These are simply used to
200 * construct a {@link Pattern} which is cached in case of re-use.
201 * @param assertMatch whether to raise an (informative) {@link AssertionFailedError} if no match is found.
202 * @return {@link Matcher} produced by matching attempt
203 */
204 public static Matcher rowMatch(
205 final BufferedImage image,
206 final int rowNumber,
207 final Map<Integer, String> paletteMap,
208 final String patternString,
209 final boolean assertMatch
210 ) {
211 return imageStripPatternMatchInner(
212 image,
213 rowNumber,
214 null,
215 paletteMap,
216 null,
217 patternString,
218 false,
219 true
220 );
221 }
222
223 /**
224 * Attempt to match row {@code rowNumber}, once translated to characters according to {@code paletteMapFn}
225 * against the regular expression described by {@code patternString}.
226 *
227 * @param image image to take row from
228 * @param rowNumber image row number for comparison
229 * @param paletteMapFn function mapping {@code Integer}s (denoting the color in ARGB format) to {@link String}s. It
230 * is advised to only map colors to single characters.
231 * @param patternString string representation of regular expression to match against. These are simply used to
232 * construct a {@link Pattern} which is cached in case of re-use.
233 * @param assertMatch whether to raise an (informative) {@link AssertionFailedError} if no match is found.
234 * @return {@link Matcher} produced by matching attempt
235 */
236 public static Matcher rowMatch(
237 final BufferedImage image,
238 final int rowNumber,
239 final IntFunction<String> paletteMapFn,
240 final String patternString,
241 final boolean assertMatch
242 ) {
243 return imageStripPatternMatchInner(
244 image,
245 rowNumber,
246 paletteMapFn,
247 null,
248 null,
249 patternString,
250 false,
251 true
252 );
253 }
254
255 /**
256 * Attempt to match row {@code rowNumber}, once translated to characters according to {@code paletteMap}
257 * against the regular expression {@code pattern}.
258 *
259 * @param image image to take row from
260 * @param rowNumber image row number for comparison
261 * @param paletteMap {@link Map} of {@code Integer}s (denoting the color in ARGB format) to {@link String}s. It
262 * is advised to only map colors to single characters. Colors with no corresponding entry in
263 * the map are mapped to {@code #}.
264 * @param pattern regular expression to match against
265 * @param assertMatch whether to raise an (informative) {@link AssertionFailedError} if no match is found.
266 * @return {@link Matcher} produced by matching attempt
267 */
268 public static Matcher rowMatch(
269 final BufferedImage image,
270 final int rowNumber,
271 final Map<Integer, String> paletteMap,
272 final Pattern pattern,
273 final boolean assertMatch
274 ) {
275 return imageStripPatternMatchInner(
276 image,
277 rowNumber,
278 null,
279 paletteMap,
280 pattern,
281 null,
282 false,
283 true
284 );
285 }
286
287 /**
288 * Attempt to match row {@code rowNumber}, once translated to characters according to {@code paletteMapFn}
289 * against the regular expression {@code pattern}.
290 *
291 * @param image image to take row from
292 * @param rowNumber image row number for comparison
293 * @param paletteMapFn function mapping {@code Integer}s (denoting the color in ARGB format) to {@link String}s. It
294 * is advised to only map colors to single characters.
295 * @param pattern regular expression to match against
296 * @param assertMatch whether to raise an (informative) {@link AssertionFailedError} if no match is found.
297 * @return {@link Matcher} produced by matching attempt
298 */
299 public static Matcher rowMatch(
300 final BufferedImage image,
301 final int rowNumber,
302 final IntFunction<String> paletteMapFn,
303 final Pattern pattern,
304 final boolean assertMatch
305 ) {
306 return imageStripPatternMatchInner(
307 image,
308 rowNumber,
309 paletteMapFn,
310 null,
311 pattern,
312 null,
313 false,
314 true
315 );
316 }
317}
Note: See TracBrowser for help on using the repository browser.