source: josm/trunk/test/unit/org/CustomMatchers.java@ 15673

Last change on this file since 15673 was 12906, checked in by bastiK, 7 years ago

see #15273, see #15229 - add command line module for rendering

run josm render --help to see the options

  • Property svn:eol-style set to native
File size: 8.1 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org;
3
4import java.awt.geom.Point2D;
5import java.util.Collection;
6import java.util.Locale;
7import java.util.Objects;
8import java.util.function.Predicate;
9
10import org.hamcrest.CustomTypeSafeMatcher;
11import org.hamcrest.Description;
12import org.hamcrest.Matcher;
13import org.hamcrest.TypeSafeMatcher;
14import org.junit.Ignore;
15import org.openstreetmap.josm.data.Bounds;
16import org.openstreetmap.josm.data.coor.EastNorth;
17import org.openstreetmap.josm.data.coor.LatLon;
18
19/**
20 * Custom matchers for unit tests.
21 */
22@Ignore("no test")
23public final class CustomMatchers {
24
25 /**
26 * Error mode, denoting different ways to calculate the error of a number relative to an expected value.
27 */
28 public enum ErrorMode {
29 /**
30 * absolute error (difference of actual and expected value)
31 */
32 ABSOLUTE,
33
34 /**
35 * relative error (difference divided by the expected value)
36 */
37 RELATIVE
38 }
39
40 private CustomMatchers() {
41 // Hide constructor for utility classes
42 }
43
44 /**
45 * Matcher for a predicate.
46 * @param <T> type of elements
47 * @param predicate the predicate
48 * @return matcher for a predicate
49 */
50 public static <T> Matcher<? extends T> forPredicate(final Predicate<T> predicate) {
51 return new TypeSafeMatcher<T>() {
52
53 @Override
54 protected boolean matchesSafely(T item) {
55 return predicate.test(item);
56 }
57
58 @Override
59 public void describeTo(Description description) {
60 description.appendValue(predicate);
61 }
62 };
63 }
64
65 /**
66 * Matcher for a collection of a given size.
67 * @param size of collection
68 * @return matcher for a collection of a given size
69 */
70 public static Matcher<Collection<?>> hasSize(final int size) {
71 return new TypeSafeMatcher<Collection<?>>() {
72 @Override
73 protected boolean matchesSafely(Collection<?> collection) {
74 return collection != null && collection.size() == size;
75 }
76
77 @Override
78 public void describeTo(Description description) {
79 description.appendText("hasSize(").appendValue(size).appendText(")");
80 }
81 };
82 }
83
84 /**
85 * Matcher for an empty collection.
86 * @return matcher for an empty collection
87 */
88 public static Matcher<Collection<?>> isEmpty() {
89 return new TypeSafeMatcher<Collection<?>>() {
90 @Override
91 protected boolean matchesSafely(Collection<?> collection) {
92 return collection != null && collection.isEmpty();
93 }
94
95 @Override
96 public void describeTo(Description description) {
97 description.appendText("isEmpty()");
98 }
99 };
100 }
101
102 /**
103 * Matcher for a point at a given location.
104 * @param expected expected location
105 * @return matcher for a point at a given location
106 */
107 public static Matcher<? super Point2D> is(final Point2D expected) {
108 return new CustomTypeSafeMatcher<Point2D>(Objects.toString(expected)) {
109 @Override
110 protected boolean matchesSafely(Point2D actual) {
111 return expected.distance(actual) <= 0.0000001;
112 }
113 };
114 }
115
116 /**
117 * Matcher for a point at a given location.
118 * @param expected expected location
119 * @return matcher for a point at a given location
120 */
121 public static Matcher<? super LatLon> is(final LatLon expected) {
122 return new CustomTypeSafeMatcher<LatLon>(Objects.toString(expected)) {
123 @Override
124 protected boolean matchesSafely(LatLon actual) {
125 return Math.abs(expected.getX() - actual.getX()) <= LatLon.MAX_SERVER_PRECISION
126 && Math.abs(expected.getY() - actual.getY()) <= LatLon.MAX_SERVER_PRECISION;
127 }
128 };
129 }
130
131 /**
132 * Matcher for a point at a given location.
133 * @param expected expected location
134 * @return matcher for a point at a given location
135 */
136 public static Matcher<? super EastNorth> is(final EastNorth expected) {
137 return new CustomTypeSafeMatcher<EastNorth>(Objects.toString(expected)) {
138 @Override
139 protected boolean matchesSafely(EastNorth actual) {
140 return Math.abs(expected.getX() - actual.getX()) <= LatLon.MAX_SERVER_PRECISION
141 && Math.abs(expected.getY() - actual.getY()) <= LatLon.MAX_SERVER_PRECISION;
142 }
143 };
144 }
145
146 /**
147 * Matcher for a {@link Bounds} object
148 * @param expected expected bounds
149 * @param tolerance acceptable deviation (epsilon)
150 * @return Matcher for a {@link Bounds} object
151 */
152 public static Matcher<Bounds> is(final Bounds expected, double tolerance) {
153 return new TypeSafeMatcher<Bounds>() {
154 @Override
155 public void describeTo(Description description) {
156 description.appendText("is ")
157 .appendValue(expected)
158 .appendText(" (tolarance: " + tolerance + ")");
159 }
160
161 @Override
162 protected void describeMismatchSafely(Bounds bounds, Description mismatchDescription) {
163 mismatchDescription.appendText("was ").appendValue(bounds);
164 }
165
166 @Override
167 protected boolean matchesSafely(Bounds bounds) {
168 return Math.abs(expected.getMinLon() - bounds.getMinLon()) <= tolerance &&
169 Math.abs(expected.getMinLat() - bounds.getMinLat()) <= tolerance &&
170 Math.abs(expected.getMaxLon() - bounds.getMaxLon()) <= tolerance &&
171 Math.abs(expected.getMaxLat() - bounds.getMaxLat()) <= tolerance;
172 }
173 };
174 }
175
176 /**
177 * Matcher for a floating point number.
178 * @param expected expected value
179 * @param errorMode the error mode
180 * @param tolerance admissible error
181 * @return Matcher for a floating point number
182 */
183 public static Matcher<Double> isFP(final double expected, ErrorMode errorMode, double tolerance) {
184 return new TypeSafeMatcher<Double>() {
185 @Override
186 public void describeTo(Description description) {
187 description.appendText("is ")
188 .appendValue(expected)
189 .appendText(" (tolarance")
190 .appendText(errorMode == ErrorMode.RELATIVE ? ", relative:" : ":")
191 .appendText(Double.toString(tolerance))
192 .appendText(")");
193 }
194
195 @Override
196 protected void describeMismatchSafely(Double was, Description mismatchDescription) {
197 mismatchDescription.appendText("was ").appendValue(was);
198 if (errorMode == ErrorMode.RELATIVE) {
199 mismatchDescription.appendText(" (actual relative error: ")
200 .appendText(String.format(Locale.US, "%.2e", Math.abs((was - expected) / expected)))
201 .appendText(")");
202 }
203 }
204
205 @Override
206 protected boolean matchesSafely(Double x) {
207 switch (errorMode) {
208 case ABSOLUTE:
209 return Math.abs(x - expected) <= tolerance;
210 case RELATIVE:
211 return Math.abs((x - expected) / expected) <= tolerance;
212 default:
213 throw new AssertionError();
214 }
215 }
216 };
217 }
218
219 /**
220 * Matcher for a floating point number.
221 * @param expected expected value
222 * @param tolerance admissible error (absolute)
223 * @return Matcher for a floating point number
224 */
225 public static Matcher<Double> isFP(final double expected, double tolerance) {
226 return isFP(expected, ErrorMode.ABSOLUTE, tolerance);
227 }
228
229 /**
230 * Matcher for a floating point number.
231 * @param expected expected value
232 * @return Matcher for a floating point number
233 */
234 public static Matcher<Double> isFP(final double expected) {
235 return isFP(expected, 1e-8);
236 }
237}
Note: See TracBrowser for help on using the repository browser.