Skip to content

Commit bc605f7

Browse files
author
kalle
committed
added some hamcrest matchers
1 parent ef00f81 commit bc605f7

File tree

10 files changed

+233
-47
lines changed

10 files changed

+233
-47
lines changed

Diff for: json-path-assert/src/main/java/com/jayway/jsonassert/JsonAssert.java

+22
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@
22

33

44
import com.jayway.jsonassert.impl.JsonAsserterImpl;
5+
import com.jayway.jsonassert.impl.matcher.*;
6+
import org.hamcrest.Matcher;
57
import org.json.simple.parser.JSONParser;
68

79
import java.io.IOException;
810
import java.io.InputStream;
911
import java.io.InputStreamReader;
1012
import java.io.Reader;
1113
import java.text.ParseException;
14+
import java.util.Collection;
15+
import java.util.Map;
1216

1317
/**
1418
* User: kalle stenflo
@@ -63,4 +67,22 @@ public static JsonAsserter with(InputStream is) throws ParseException, IOExcepti
6367
return with(reader);
6468
}
6569

70+
//Matchers
71+
72+
public static CollectionMatcher collectionWithSize(Matcher<? super Integer> sizeMatcher) {
73+
return new IsCollectionWithSize(sizeMatcher);
74+
}
75+
76+
public static Matcher<Map<String, ?>> mapContainingKey(Matcher<String> keyMatcher) {
77+
return new IsMapContainingKey(keyMatcher);
78+
}
79+
80+
public static <V> Matcher<? super Map<?, V>> mapContainingValue(Matcher<? super V> valueMatcher) {
81+
return new IsMapContainingValue<V>(valueMatcher);
82+
}
83+
84+
public static Matcher<Collection<Object>> emptyCollection() {
85+
return new IsEmptyCollection<Object>();
86+
}
87+
6688
}

Diff for: json-path-assert/src/main/java/com/jayway/jsonassert/impl/JsonAsserterImpl.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.jayway.jsonassert.JsonAsserter;
55
import com.jayway.jsonpath.JsonPath;
66
import com.jayway.jsonpath.PathUtil;
7+
import org.hamcrest.Description;
78
import org.hamcrest.Matcher;
89
import org.hamcrest.MatcherAssert;
910

@@ -41,11 +42,13 @@ public JsonAsserterImpl(Object jsonObject) {
4142
@SuppressWarnings("unchecked")
4243
public <T> JsonAsserter assertThat(String path, Matcher<T> matcher) {
4344

45+
String reason = "When processing json path: " + path;
46+
4447
if(PathUtil.isPathDefinite(path)){
45-
MatcherAssert.assertThat(JsonPath.<T>readOne(jsonObject, path), matcher);
48+
MatcherAssert.assertThat(reason, JsonPath.<T>readOne(jsonObject, path), matcher);
4649
}
4750
else {
48-
MatcherAssert.assertThat((T) JsonPath.<T>read(jsonObject, path), matcher);
51+
MatcherAssert.assertThat(reason, (T) JsonPath.<T>read(jsonObject, path), matcher);
4952
}
5053
return this;
5154
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.jayway.jsonassert.impl.matcher;
2+
3+
import org.hamcrest.BaseMatcher;
4+
5+
import java.util.Collection;
6+
7+
public abstract class CollectionMatcher<C extends Collection<?>> extends BaseMatcher<C> {
8+
@SuppressWarnings("unchecked")
9+
public boolean matches(Object item) {
10+
if (!(item instanceof Collection)) {
11+
return false;
12+
}
13+
return matchesSafely((C)item);
14+
}
15+
16+
protected abstract boolean matchesSafely(C collection);
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.jayway.jsonassert.impl.matcher;
2+
3+
import static org.hamcrest.core.IsEqual.equalTo;
4+
5+
import org.hamcrest.Description;
6+
import org.hamcrest.Factory;
7+
import org.hamcrest.Matcher;
8+
9+
import java.util.Collection;
10+
11+
/**
12+
* Matches if collection size satisfies a nested matcher.
13+
*/
14+
public class IsCollectionWithSize<E> extends CollectionMatcher<Collection<? extends E>> {
15+
private final Matcher<? super Integer> sizeMatcher;
16+
17+
public IsCollectionWithSize(Matcher<? super Integer> sizeMatcher) {
18+
this.sizeMatcher = sizeMatcher;
19+
}
20+
21+
@Override
22+
public boolean matchesSafely(Collection<? extends E> item) {
23+
return sizeMatcher.matches(item.size());
24+
}
25+
26+
public void describeTo(Description description) {
27+
description.appendText("a collection with size ")
28+
.appendDescriptionOf(sizeMatcher);
29+
}
30+
31+
/**
32+
* Does collection size satisfy a given matcher?
33+
*/
34+
@Factory
35+
public static <E> Matcher<? super Collection<? extends E>> hasSize(Matcher<? super Integer> size) {
36+
return new IsCollectionWithSize<E>(size);
37+
}
38+
39+
/**
40+
* This is a shortcut to the frequently used hasSize(equalTo(x)).
41+
*
42+
* For example, assertThat(hasSize(equal_to(x)))
43+
* vs. assertThat(hasSize(x))
44+
*/
45+
@Factory
46+
public static <E> Matcher<? super Collection<? extends E>> hasSize(int size) {
47+
Matcher<? super Integer> matcher = equalTo(size);
48+
return IsCollectionWithSize.<E>hasSize(matcher);
49+
}
50+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.jayway.jsonassert.impl.matcher;
2+
3+
import org.hamcrest.Description;
4+
import org.hamcrest.Factory;
5+
import org.hamcrest.Matcher;
6+
7+
import java.util.Collection;
8+
9+
/**
10+
* Tests if collection is empty.
11+
*/
12+
public class IsEmptyCollection<E> extends CollectionMatcher<Collection<E>> {
13+
14+
@Override
15+
public boolean matchesSafely(Collection<E> item) {
16+
return item.isEmpty();
17+
}
18+
19+
public void describeTo(Description description) {
20+
description.appendText("an empty collection");
21+
}
22+
23+
/**
24+
* Matches an empty collection.
25+
*/
26+
@Factory
27+
public static <E> Matcher<Collection<E>> empty() {
28+
return new IsEmptyCollection<E>();
29+
}
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.jayway.jsonassert.impl.matcher;
2+
3+
import java.util.Map;
4+
5+
import org.hamcrest.Description;
6+
import org.hamcrest.Factory;
7+
import org.hamcrest.Matcher;
8+
import static org.hamcrest.core.IsEqual.equalTo;
9+
10+
public class IsMapContainingKey<K> extends MapTypeSafeMatcher<Map<K,?>> {
11+
private final Matcher<K> keyMatcher;
12+
13+
public IsMapContainingKey(Matcher<K> keyMatcher) {
14+
this.keyMatcher = keyMatcher;
15+
}
16+
17+
@Override
18+
public boolean matchesSafely(Map<K, ?> item) {
19+
for (K key : item.keySet()) {
20+
if (keyMatcher.matches(key)) {
21+
return true;
22+
}
23+
}
24+
return false;
25+
}
26+
27+
public void describeTo(Description description) {
28+
description.appendText("map with key ")
29+
.appendDescriptionOf(keyMatcher);
30+
}
31+
32+
@Factory
33+
public static <K> Matcher<Map<K,?>> hasKey(K key) {
34+
return hasKey(equalTo(key));
35+
}
36+
37+
@Factory
38+
public static <K> Matcher<Map<K,?>> hasKey(Matcher<K> keyMatcher) {
39+
return new IsMapContainingKey<K>(keyMatcher);
40+
}
41+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.jayway.jsonassert.impl.matcher;
2+
3+
import org.hamcrest.Description;
4+
import org.hamcrest.Factory;
5+
import org.hamcrest.Matcher;
6+
import static org.hamcrest.core.IsEqual.equalTo;
7+
import java.util.Map;
8+
9+
public class IsMapContainingValue<V> extends MapTypeSafeMatcher<Map<?,V>>{
10+
private final Matcher<? super V> valueMatcher;
11+
12+
public IsMapContainingValue(Matcher<? super V> valueMatcher) {
13+
this.valueMatcher = valueMatcher;
14+
}
15+
16+
@Override
17+
public boolean matchesSafely(Map<?, V> item) {
18+
for (V value : item.values()) {
19+
if (valueMatcher.matches(value)) {
20+
return true;
21+
}
22+
}
23+
return false;
24+
}
25+
26+
public void describeTo(Description description) {
27+
description.appendText("map with value ")
28+
.appendDescriptionOf(valueMatcher);
29+
}
30+
31+
@Factory
32+
public static <V> Matcher<? super Map<?,V>> hasValue(V value) {
33+
return IsMapContainingValue.<V>hasValue(equalTo(value));
34+
}
35+
36+
@Factory
37+
public static <V> Matcher<? super Map<?,V>> hasValue(Matcher<? super V> valueMatcher) {
38+
return new IsMapContainingValue<V>(valueMatcher);
39+
}
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.jayway.jsonassert.impl.matcher;
2+
3+
import org.hamcrest.BaseMatcher;
4+
5+
import java.util.Map;
6+
7+
public abstract class MapTypeSafeMatcher<M extends Map<?, ?>> extends BaseMatcher<M> {
8+
@SuppressWarnings("unchecked")
9+
public boolean matches(Object item) {
10+
return item instanceof Map && matchesSafely((M) item);
11+
}
12+
13+
protected abstract boolean matchesSafely(M map);
14+
}

Diff for: json-path-assert/src/test/java/com/jayway/jsonassert/JsonAssertTest.java

+14-44
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import org.junit.Test;
44

5-
import static com.jayway.jsonassert.JsonAssert.with;
5+
import static com.jayway.jsonassert.JsonAssert.*;
66
import static org.hamcrest.Matchers.*;
77

88
/**
@@ -57,7 +57,8 @@ public void list_content_can_be_asserted_with_matcher() throws Exception {
5757

5858
with(JSON).assertThat("$..book[*].author", hasItems("Nigel Rees", "Evelyn Waugh", "Herman Melville", "J. R. R. Tolkien"));
5959

60-
with(JSON).assertThat("$..author", hasItems("Nigel Rees", "Evelyn Waugh", "Herman Melville", "J. R. R. Tolkien"));
60+
with(JSON).assertThat("$..author", hasItems("Nigel Rees", "Evelyn Waugh", "Herman Melville", "J. R. R. Tolkien"))
61+
.assertThat("$..author", is(collectionWithSize(equalTo(4))));
6162
}
6263

6364
@Test
@@ -69,56 +70,25 @@ public void list_content_can_be_asserted_with_nested_matcher() throws Exception
6970
public void map_content_can_be_asserted_with_matcher() throws Exception {
7071

7172
with(JSON).assertThat("$.store.book[0]", hasEntry("category", "reference"))
72-
.assertThat("$.store.book[0]", hasEntry("title", "Sayings of the Century"));
73-
74-
with(JSON).assertThat("$..book[0]", hasItems(hasEntry("category", "reference")));
75-
}
76-
77-
@Test
78-
public void a_path_can_be_asserted_equal_to() throws Exception {
79-
80-
with(JSON).assertEquals("$.store.book[0].title", "Sayings of the Century")
81-
.assertThat("$.store.book[0].title", equalTo("Sayings of the Century"));
73+
.assertThat("$.store.book[0]", hasEntry("title", "Sayings of the Century"))
74+
.and()
75+
.assertThat("$..book[0]", hasItems(hasEntry("category", "reference")))
76+
.and()
77+
.assertThat("$.store.book[0]", mapContainingKey(equalTo("category")))
78+
.and()
79+
.assertThat("$.store.book[0]", mapContainingValue(equalTo("reference")));
8280
}
8381

84-
85-
/*
8682
@Test
87-
public void a_sub_document_can_asserted_on__by_path() throws Exception {
88-
JsonAssert.with(TEST_DOCUMENT).assertThat("subDocument.subField", is(equalTo("sub-field")));
83+
public void an_empty_collection() throws Exception {
84+
with(JSON).assertThat("$.store.book[?(@.category = 'x')]", emptyCollection());
8985
}
9086

9187
@Test
9288
public void a_path_can_be_asserted_equal_to() throws Exception {
9389

94-
JsonAssert.with(TEST_DOCUMENT).assertEquals("stringField", "string-field");
95-
}
96-
97-
@Test
98-
public void a_path_can_be_asserted_is_null() throws Exception {
99-
100-
JsonAssert.with(TEST_DOCUMENT).assertNull("nullField");
101-
}
102-
103-
@Test(expected = AssertionError.class)
104-
public void failed_assert_throws() throws Exception {
105-
106-
JsonAssert.with(TEST_DOCUMENT).assertThat("stringField", equalTo("SOME CRAP"));
107-
}
108-
109-
@Test
110-
public void multiple_asserts_can_be_chained() throws Exception {
111-
112-
JsonAssert.with(TEST_DOCUMENT)
113-
.assertThat("stringField", equalTo("string-field"))
114-
.assertThat("numberField", is(notNullValue()))
115-
.and()
116-
.assertNull("nullField")
117-
.and()
118-
.assertEquals("stringField", "string-field");
119-
90+
with(JSON).assertEquals("$.store.book[0].title", "Sayings of the Century")
91+
.assertThat("$.store.book[0].title", equalTo("Sayings of the Century"));
12092
}
121-
*/
122-
12393

12494
}

Diff for: pom.xml

-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@
7272

7373
<modules>
7474
<module>json-path</module>
75-
<module>examples</module>
7675
<module>json-path-assert</module>
7776
</modules>
7877

0 commit comments

Comments
 (0)