|
16 | 16 |
|
17 | 17 | package org.springframework.test.json;
|
18 | 18 |
|
19 |
| -import java.io.File; |
20 |
| -import java.io.InputStream; |
21 | 19 | import java.nio.charset.Charset;
|
22 |
| -import java.nio.file.Path; |
23 | 20 |
|
24 |
| -import org.assertj.core.api.AbstractAssert; |
25 |
| -import org.skyscreamer.jsonassert.JSONCompare; |
26 |
| -import org.skyscreamer.jsonassert.JSONCompareMode; |
27 |
| -import org.skyscreamer.jsonassert.JSONCompareResult; |
28 |
| -import org.skyscreamer.jsonassert.comparator.JSONComparator; |
29 |
| - |
30 |
| -import org.springframework.core.io.ByteArrayResource; |
31 |
| -import org.springframework.core.io.ClassPathResource; |
32 |
| -import org.springframework.core.io.FileSystemResource; |
33 |
| -import org.springframework.core.io.InputStreamResource; |
34 |
| -import org.springframework.core.io.Resource; |
| 21 | +import org.springframework.http.converter.GenericHttpMessageConverter; |
35 | 22 | import org.springframework.lang.Nullable;
|
36 |
| -import org.springframework.util.function.ThrowingBiFunction; |
37 | 23 |
|
38 | 24 | /**
|
39 |
| - * AssertJ {@link org.assertj.core.api.Assert assertions} that can be applied |
40 |
| - * to a {@link CharSequence} representation of a JSON document, mostly to |
41 |
| - * compare the JSON document against a target, using {@linkplain JSONCompare |
42 |
| - * JSON Assert}. |
| 25 | + * Default {@link AbstractJsonContentAssert} implementation. |
43 | 26 | *
|
44 |
| - * @author Phillip Webb |
45 |
| - * @author Andy Wilkinson |
46 |
| - * @author Diego Berrueta |
47 |
| - * @author Camille Vienot |
48 | 27 | * @author Stephane Nicoll
|
49 | 28 | * @since 6.2
|
50 | 29 | */
|
51 |
| -public class JsonContentAssert extends AbstractAssert<JsonContentAssert, CharSequence> { |
52 |
| - |
53 |
| - private final JsonLoader loader; |
54 |
| - |
55 |
| - /** |
56 |
| - * Create a new {@link JsonContentAssert} instance that will load resources |
57 |
| - * relative to the given {@code resourceLoadClass}, using the given |
58 |
| - * {@code charset}. |
59 |
| - * @param json the actual JSON content |
| 30 | +public class JsonContentAssert extends AbstractJsonContentAssert<JsonContentAssert> { |
| 31 | + |
| 32 | + /** |
| 33 | + * Create an assert for the given JSON document. |
| 34 | + * <p>Path can be converted to a value object using the given |
| 35 | + * {@linkplain GenericHttpMessageConverter json message converter}. |
| 36 | + * <p>Resources to match can be loaded relative to the given |
| 37 | + * {@code resourceLoadClass}. If not specified, resources must always be |
| 38 | + * absolute. A specific {@link Charset} can be provided if {@code UTF-8} is |
| 39 | + * not suitable. |
| 40 | + * @param json the JSON document to assert |
| 41 | + * @param jsonMessageConverter the converter to use |
60 | 42 | * @param resourceLoadClass the class used to load resources
|
61 | 43 | * @param charset the charset of the JSON resources
|
62 | 44 | */
|
63 |
| - public JsonContentAssert(@Nullable CharSequence json, @Nullable Class<?> resourceLoadClass, |
64 |
| - @Nullable Charset charset) { |
65 |
| - |
66 |
| - super(json, JsonContentAssert.class); |
67 |
| - this.loader = new JsonLoader(resourceLoadClass, charset); |
68 |
| - } |
69 |
| - |
70 |
| - /** |
71 |
| - * Create a new {@link JsonContentAssert} instance that will load resources |
72 |
| - * relative to the given {@code resourceLoadClass}, using {@code UTF-8}. |
73 |
| - * @param json the actual JSON content |
74 |
| - * @param resourceLoadClass the class used to load resources |
75 |
| - */ |
76 |
| - public JsonContentAssert(@Nullable CharSequence json, @Nullable Class<?> resourceLoadClass) { |
77 |
| - this(json, resourceLoadClass, null); |
78 |
| - } |
79 |
| - |
80 |
| - |
81 |
| - /** |
82 |
| - * Verify that the actual value is equal to the given JSON. The |
83 |
| - * {@code expected} value can contain the JSON itself or, if it ends with |
84 |
| - * {@code .json}, the name of a resource to be loaded from the classpath. |
85 |
| - * @param expected the expected JSON or the name of a resource containing |
86 |
| - * the expected JSON |
87 |
| - * @param compareMode the compare mode used when checking |
88 |
| - */ |
89 |
| - public JsonContentAssert isEqualTo(@Nullable CharSequence expected, JSONCompareMode compareMode) { |
90 |
| - String expectedJson = this.loader.getJson(expected); |
91 |
| - return assertNotFailed(compare(expectedJson, compareMode)); |
92 |
| - } |
93 |
| - |
94 |
| - /** |
95 |
| - * Verify that the actual value is equal to the given JSON {@link Resource}. |
96 |
| - * <p>The resource abstraction allows to provide several input types: |
97 |
| - * <ul> |
98 |
| - * <li>a {@code byte} array, using {@link ByteArrayResource}</li> |
99 |
| - * <li>a {@code classpath} resource, using {@link ClassPathResource}</li> |
100 |
| - * <li>a {@link File} or {@link Path}, using {@link FileSystemResource}</li> |
101 |
| - * <li>an {@link InputStream}, using {@link InputStreamResource}</li> |
102 |
| - * </ul> |
103 |
| - * @param expected a resource containing the expected JSON |
104 |
| - * @param compareMode the compare mode used when checking |
105 |
| - */ |
106 |
| - public JsonContentAssert isEqualTo(Resource expected, JSONCompareMode compareMode) { |
107 |
| - String expectedJson = this.loader.getJson(expected); |
108 |
| - return assertNotFailed(compare(expectedJson, compareMode)); |
109 |
| - } |
110 |
| - |
111 |
| - /** |
112 |
| - * Verify that the actual value is equal to the given JSON. The |
113 |
| - * {@code expected} value can contain the JSON itself or, if it ends with |
114 |
| - * {@code .json}, the name of a resource to be loaded from the classpath. |
115 |
| - * @param expected the expected JSON or the name of a resource containing |
116 |
| - * the expected JSON |
117 |
| - * @param comparator the comparator used when checking |
118 |
| - */ |
119 |
| - public JsonContentAssert isEqualTo(@Nullable CharSequence expected, JSONComparator comparator) { |
120 |
| - String expectedJson = this.loader.getJson(expected); |
121 |
| - return assertNotFailed(compare(expectedJson, comparator)); |
122 |
| - } |
123 |
| - |
124 |
| - /** |
125 |
| - * Verify that the actual value is equal to the given JSON {@link Resource}. |
126 |
| - * <p>The resource abstraction allows to provide several input types: |
127 |
| - * <ul> |
128 |
| - * <li>a {@code byte} array, using {@link ByteArrayResource}</li> |
129 |
| - * <li>a {@code classpath} resource, using {@link ClassPathResource}</li> |
130 |
| - * <li>a {@link File} or {@link Path}, using {@link FileSystemResource}</li> |
131 |
| - * <li>an {@link InputStream}, using {@link InputStreamResource}</li> |
132 |
| - * </ul> |
133 |
| - * @param expected a resource containing the expected JSON |
134 |
| - * @param comparator the comparator used when checking |
135 |
| - */ |
136 |
| - public JsonContentAssert isEqualTo(Resource expected, JSONComparator comparator) { |
137 |
| - String expectedJson = this.loader.getJson(expected); |
138 |
| - return assertNotFailed(compare(expectedJson, comparator)); |
139 |
| - } |
140 |
| - |
141 |
| - /** |
142 |
| - * Verify that the actual value is {@link JSONCompareMode#LENIENT leniently} |
143 |
| - * equal to the given JSON. The {@code expected} value can contain the JSON |
144 |
| - * itself or, if it ends with {@code .json}, the name of a resource to be |
145 |
| - * loaded from the classpath. |
146 |
| - * @param expected the expected JSON or the name of a resource containing |
147 |
| - * the expected JSON |
148 |
| - */ |
149 |
| - public JsonContentAssert isLenientlyEqualTo(@Nullable CharSequence expected) { |
150 |
| - return isEqualTo(expected, JSONCompareMode.LENIENT); |
151 |
| - } |
152 |
| - |
153 |
| - /** |
154 |
| - * Verify that the actual value is {@link JSONCompareMode#LENIENT leniently} |
155 |
| - * equal to the given JSON {@link Resource}. |
156 |
| - * <p>The resource abstraction allows to provide several input types: |
157 |
| - * <ul> |
158 |
| - * <li>a {@code byte} array, using {@link ByteArrayResource}</li> |
159 |
| - * <li>a {@code classpath} resource, using {@link ClassPathResource}</li> |
160 |
| - * <li>a {@link File} or {@link Path}, using {@link FileSystemResource}</li> |
161 |
| - * <li>an {@link InputStream}, using {@link InputStreamResource}</li> |
162 |
| - * </ul> |
163 |
| - * @param expected a resource containing the expected JSON |
164 |
| - */ |
165 |
| - public JsonContentAssert isLenientlyEqualTo(Resource expected) { |
166 |
| - return isEqualTo(expected, JSONCompareMode.LENIENT); |
167 |
| - } |
168 |
| - |
169 |
| - /** |
170 |
| - * Verify that the actual value is {@link JSONCompareMode#STRICT strictly} |
171 |
| - * equal to the given JSON. The {@code expected} value can contain the JSON |
172 |
| - * itself or, if it ends with {@code .json}, the name of a resource to be |
173 |
| - * loaded from the classpath. |
174 |
| - * @param expected the expected JSON or the name of a resource containing |
175 |
| - * the expected JSON |
176 |
| - */ |
177 |
| - public JsonContentAssert isStrictlyEqualTo(@Nullable CharSequence expected) { |
178 |
| - return isEqualTo(expected, JSONCompareMode.STRICT); |
179 |
| - } |
180 |
| - |
181 |
| - /** |
182 |
| - * Verify that the actual value is {@link JSONCompareMode#STRICT strictly} |
183 |
| - * equal to the given JSON {@link Resource}. |
184 |
| - * <p>The resource abstraction allows to provide several input types: |
185 |
| - * <ul> |
186 |
| - * <li>a {@code byte} array, using {@link ByteArrayResource}</li> |
187 |
| - * <li>a {@code classpath} resource, using {@link ClassPathResource}</li> |
188 |
| - * <li>a {@link File} or {@link Path}, using {@link FileSystemResource}</li> |
189 |
| - * <li>an {@link InputStream}, using {@link InputStreamResource}</li> |
190 |
| - * </ul> |
191 |
| - * @param expected a resource containing the expected JSON |
192 |
| - */ |
193 |
| - public JsonContentAssert isStrictlyEqualTo(Resource expected) { |
194 |
| - return isEqualTo(expected, JSONCompareMode.STRICT); |
195 |
| - } |
196 |
| - |
197 |
| - /** |
198 |
| - * Verify that the actual value is not equal to the given JSON. The |
199 |
| - * {@code expected} value can contain the JSON itself or, if it ends with |
200 |
| - * {@code .json}, the name of a resource to be loaded from the classpath. |
201 |
| - * @param expected the expected JSON or the name of a resource containing |
202 |
| - * the expected JSON |
203 |
| - * @param compareMode the compare mode used when checking |
204 |
| - */ |
205 |
| - public JsonContentAssert isNotEqualTo(@Nullable CharSequence expected, JSONCompareMode compareMode) { |
206 |
| - String expectedJson = this.loader.getJson(expected); |
207 |
| - return assertNotPassed(compare(expectedJson, compareMode)); |
208 |
| - } |
209 |
| - |
210 |
| - /** |
211 |
| - * Verify that the actual value is not equal to the given JSON {@link Resource}. |
212 |
| - * <p>The resource abstraction allows to provide several input types: |
213 |
| - * <ul> |
214 |
| - * <li>a {@code byte} array, using {@link ByteArrayResource}</li> |
215 |
| - * <li>a {@code classpath} resource, using {@link ClassPathResource}</li> |
216 |
| - * <li>a {@link File} or {@link Path}, using {@link FileSystemResource}</li> |
217 |
| - * <li>an {@link InputStream}, using {@link InputStreamResource}</li> |
218 |
| - * </ul> |
219 |
| - * @param expected a resource containing the expected JSON |
220 |
| - * @param compareMode the compare mode used when checking |
221 |
| - */ |
222 |
| - public JsonContentAssert isNotEqualTo(Resource expected, JSONCompareMode compareMode) { |
223 |
| - String expectedJson = this.loader.getJson(expected); |
224 |
| - return assertNotPassed(compare(expectedJson, compareMode)); |
225 |
| - } |
226 |
| - |
227 |
| - /** |
228 |
| - * Verify that the actual value is not equal to the given JSON. The |
229 |
| - * {@code expected} value can contain the JSON itself or, if it ends with |
230 |
| - * {@code .json}, the name of a resource to be loaded from the classpath. |
231 |
| - * @param expected the expected JSON or the name of a resource containing |
232 |
| - * the expected JSON |
233 |
| - * @param comparator the comparator used when checking |
234 |
| - */ |
235 |
| - public JsonContentAssert isNotEqualTo(@Nullable CharSequence expected, JSONComparator comparator) { |
236 |
| - String expectedJson = this.loader.getJson(expected); |
237 |
| - return assertNotPassed(compare(expectedJson, comparator)); |
238 |
| - } |
239 |
| - |
240 |
| - /** |
241 |
| - * Verify that the actual value is not equal to the given JSON {@link Resource}. |
242 |
| - * <p>The resource abstraction allows to provide several input types: |
243 |
| - * <ul> |
244 |
| - * <li>a {@code byte} array, using {@link ByteArrayResource}</li> |
245 |
| - * <li>a {@code classpath} resource, using {@link ClassPathResource}</li> |
246 |
| - * <li>a {@link File} or {@link Path}, using {@link FileSystemResource}</li> |
247 |
| - * <li>an {@link InputStream}, using {@link InputStreamResource}</li> |
248 |
| - * </ul> |
249 |
| - * @param expected a resource containing the expected JSON |
250 |
| - * @param comparator the comparator used when checking |
251 |
| - */ |
252 |
| - public JsonContentAssert isNotEqualTo(Resource expected, JSONComparator comparator) { |
253 |
| - String expectedJson = this.loader.getJson(expected); |
254 |
| - return assertNotPassed(compare(expectedJson, comparator)); |
255 |
| - } |
256 |
| - |
257 |
| - /** |
258 |
| - * Verify that the actual value is not {@link JSONCompareMode#LENIENT |
259 |
| - * leniently} equal to the given JSON. The {@code expected} value can |
260 |
| - * contain the JSON itself or, if it ends with {@code .json}, the name of a |
261 |
| - * resource to be loaded from the classpath. |
262 |
| - * @param expected the expected JSON or the name of a resource containing |
263 |
| - * the expected JSON |
264 |
| - */ |
265 |
| - public JsonContentAssert isNotLenientlyEqualTo(@Nullable CharSequence expected) { |
266 |
| - return isNotEqualTo(expected, JSONCompareMode.LENIENT); |
267 |
| - } |
268 |
| - |
269 |
| - /** |
270 |
| - * Verify that the actual value is not {@link JSONCompareMode#LENIENT |
271 |
| - * leniently} equal to the given JSON {@link Resource}. |
272 |
| - * <p>The resource abstraction allows to provide several input types: |
273 |
| - * <ul> |
274 |
| - * <li>a {@code byte} array, using {@link ByteArrayResource}</li> |
275 |
| - * <li>a {@code classpath} resource, using {@link ClassPathResource}</li> |
276 |
| - * <li>a {@link File} or {@link Path}, using {@link FileSystemResource}</li> |
277 |
| - * <li>an {@link InputStream}, using {@link InputStreamResource}</li> |
278 |
| - * </ul> |
279 |
| - * @param expected a resource containing the expected JSON |
280 |
| - */ |
281 |
| - public JsonContentAssert isNotLenientlyEqualTo(Resource expected) { |
282 |
| - return isNotEqualTo(expected, JSONCompareMode.LENIENT); |
283 |
| - } |
284 |
| - |
285 |
| - /** |
286 |
| - * Verify that the actual value is not {@link JSONCompareMode#STRICT |
287 |
| - * strictly} equal to the given JSON. The {@code expected} value can |
288 |
| - * contain the JSON itself or, if it ends with {@code .json}, the name of a |
289 |
| - * resource to be loaded from the classpath. |
290 |
| - * @param expected the expected JSON or the name of a resource containing |
291 |
| - * the expected JSON |
292 |
| - */ |
293 |
| - public JsonContentAssert isNotStrictlyEqualTo(@Nullable CharSequence expected) { |
294 |
| - return isNotEqualTo(expected, JSONCompareMode.STRICT); |
295 |
| - } |
296 |
| - |
297 |
| - /** |
298 |
| - * Verify that the actual value is not {@link JSONCompareMode#STRICT |
299 |
| - * strictly} equal to the given JSON {@link Resource}. |
300 |
| - * <p>The resource abstraction allows to provide several input types: |
301 |
| - * <ul> |
302 |
| - * <li>a {@code byte} array, using {@link ByteArrayResource}</li> |
303 |
| - * <li>a {@code classpath} resource, using {@link ClassPathResource}</li> |
304 |
| - * <li>a {@link File} or {@link Path}, using {@link FileSystemResource}</li> |
305 |
| - * <li>an {@link InputStream}, using {@link InputStreamResource}</li> |
306 |
| - * </ul> |
307 |
| - * @param expected a resource containing the expected JSON |
308 |
| - */ |
309 |
| - public JsonContentAssert isNotStrictlyEqualTo(Resource expected) { |
310 |
| - return isNotEqualTo(expected, JSONCompareMode.STRICT); |
311 |
| - } |
312 |
| - |
313 |
| - |
314 |
| - private JSONCompareResult compare(@Nullable CharSequence expectedJson, JSONCompareMode compareMode) { |
315 |
| - return compare(this.actual, expectedJson, (actualJsonString, expectedJsonString) -> |
316 |
| - JSONCompare.compareJSON(expectedJsonString, actualJsonString, compareMode)); |
317 |
| - } |
318 |
| - |
319 |
| - private JSONCompareResult compare(@Nullable CharSequence expectedJson, JSONComparator comparator) { |
320 |
| - return compare(this.actual, expectedJson, (actualJsonString, expectedJsonString) -> |
321 |
| - JSONCompare.compareJSON(expectedJsonString, actualJsonString, comparator)); |
322 |
| - } |
323 |
| - |
324 |
| - private JSONCompareResult compare(@Nullable CharSequence actualJson, @Nullable CharSequence expectedJson, |
325 |
| - ThrowingBiFunction<String, String, JSONCompareResult> comparator) { |
326 |
| - |
327 |
| - if (actualJson == null) { |
328 |
| - return compareForNull(expectedJson); |
329 |
| - } |
330 |
| - if (expectedJson == null) { |
331 |
| - return compareForNull(actualJson.toString()); |
332 |
| - } |
333 |
| - try { |
334 |
| - return comparator.applyWithException(actualJson.toString(), expectedJson.toString()); |
335 |
| - } |
336 |
| - catch (Exception ex) { |
337 |
| - if (ex instanceof RuntimeException runtimeException) { |
338 |
| - throw runtimeException; |
339 |
| - } |
340 |
| - throw new IllegalStateException(ex); |
341 |
| - } |
342 |
| - } |
343 |
| - |
344 |
| - private JSONCompareResult compareForNull(@Nullable CharSequence expectedJson) { |
345 |
| - JSONCompareResult result = new JSONCompareResult(); |
346 |
| - if (expectedJson != null) { |
347 |
| - result.fail("Expected null JSON"); |
348 |
| - } |
349 |
| - return result; |
350 |
| - } |
351 |
| - |
352 |
| - private JsonContentAssert assertNotFailed(JSONCompareResult result) { |
353 |
| - if (result.failed()) { |
354 |
| - failWithMessage("JSON comparison failure: %s", result.getMessage()); |
355 |
| - } |
356 |
| - return this; |
357 |
| - } |
| 45 | + public JsonContentAssert(@Nullable String json, @Nullable GenericHttpMessageConverter<Object> jsonMessageConverter, |
| 46 | + @Nullable Class<?> resourceLoadClass, @Nullable Charset charset) { |
358 | 47 |
|
359 |
| - private JsonContentAssert assertNotPassed(JSONCompareResult result) { |
360 |
| - if (result.passed()) { |
361 |
| - failWithMessage("JSON comparison failure: %s", result.getMessage()); |
362 |
| - } |
363 |
| - return this; |
| 48 | + super(json, jsonMessageConverter, resourceLoadClass, charset, JsonContentAssert.class); |
364 | 49 | }
|
365 | 50 |
|
366 | 51 | }
|
0 commit comments