Skip to content

Commit 48b9d30

Browse files
authored
Add dedicated JSON.org qualities, closes #218 (#219)
1 parent 7cbf01d commit 48b9d30

File tree

4 files changed

+342
-0
lines changed

4 files changed

+342
-0
lines changed
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/*
2+
* Copyright 2024 dmfs GmbH
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.saynotobugs.confidence.json.quality;
18+
19+
import org.dmfs.jems2.Function;
20+
import org.dmfs.jems2.iterable.Mapped;
21+
import org.dmfs.jems2.iterable.Numbered;
22+
import org.dmfs.jems2.iterable.Seq;
23+
import org.dmfs.srcless.annotations.staticfactory.StaticFactory;
24+
import org.json.JSONArray;
25+
import org.saynotobugs.confidence.Description;
26+
import org.saynotobugs.confidence.Quality;
27+
import org.saynotobugs.confidence.description.Text;
28+
import org.saynotobugs.confidence.description.bifunction.Original;
29+
import org.saynotobugs.confidence.json.JsonArrayAdapter;
30+
import org.saynotobugs.confidence.json.JsonElementAdapter;
31+
import org.saynotobugs.confidence.json.jsonstringadapter.ArrayAdapter;
32+
import org.saynotobugs.confidence.quality.composite.Has;
33+
import org.saynotobugs.confidence.quality.composite.Implied;
34+
import org.saynotobugs.confidence.quality.composite.QualityComposition;
35+
36+
import static org.saynotobugs.confidence.description.LiteralDescription.COMMA;
37+
38+
/**
39+
* {@link Quality} of a {@link JSONArray}.
40+
*/
41+
public final class JsonOrgArray extends QualityComposition<JSONArray>
42+
{
43+
44+
45+
@StaticFactory(
46+
value = "JsonOrg",
47+
methodName = "jsonArray",
48+
packageName = "org.saynotobugs.confidence.json.quality"
49+
)
50+
public JsonOrgArray(java.lang.String... strings)
51+
{
52+
this(strings.length, new Mapped<>(org.saynotobugs.confidence.json.quality.String::new, new Seq<>(strings)));
53+
}
54+
55+
56+
@StaticFactory(
57+
value = "JsonOrg",
58+
methodName = "jsonArray",
59+
packageName = "org.saynotobugs.confidence.json.quality"
60+
)
61+
public JsonOrgArray(java.lang.Number... numbers)
62+
{
63+
this(numbers.length, new Mapped<>(org.saynotobugs.confidence.json.quality.Number::new, new Seq<>(numbers)));
64+
}
65+
66+
67+
@StaticFactory(
68+
value = "JsonOrg",
69+
methodName = "jsonArray",
70+
packageName = "org.saynotobugs.confidence.json.quality"
71+
)
72+
@SafeVarargs
73+
public JsonOrgArray(Quality<? super JsonElementAdapter>... qualities)
74+
{
75+
this(qualities.length, new Seq<>(qualities));
76+
}
77+
78+
79+
@StaticFactory(
80+
value = "JsonOrg",
81+
methodName = "jsonArray",
82+
packageName = "org.saynotobugs.confidence.json.quality"
83+
)
84+
private JsonOrgArray(int count, Iterable<? extends Quality<? super JsonElementAdapter>> qualities)
85+
{
86+
super(
87+
new Has<>(
88+
(Function<Description, Description>) orig -> orig,
89+
orig -> orig,
90+
ArrayAdapter::new,
91+
92+
new Implied<>(
93+
new HasLength(count),
94+
new Conjunction<>(
95+
new Text("["),
96+
COMMA,
97+
new Text("]"),
98+
new Mapped<>(numbered -> new At(numbered.left(), numbered.right()), new Numbered<>(qualities)),
99+
new Text("[]")))));
100+
}
101+
102+
@StaticFactory(
103+
value = "JsonOrg",
104+
methodName = "jsonArray",
105+
packageName = "org.saynotobugs.confidence.json.quality"
106+
)
107+
public JsonOrgArray(Quality<? super JsonArrayAdapter> delegate)
108+
{
109+
this(new Seq<>(delegate));
110+
}
111+
112+
@StaticFactory(
113+
value = "JsonOrg",
114+
methodName = "jsonArray",
115+
packageName = "org.saynotobugs.confidence.json.quality"
116+
)
117+
public JsonOrgArray(Iterable<? extends Quality<? super JsonArrayAdapter>> delegates)
118+
{
119+
super(new Has<>(
120+
new Original<>(),
121+
orig -> orig,
122+
ArrayAdapter::new,
123+
new Conjunction<>(new Text("{"), COMMA, new Text("}"), delegates, new Text("{}"))));
124+
}
125+
126+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright 2024 dmfs GmbH
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.saynotobugs.confidence.json.quality;
18+
19+
import org.dmfs.jems2.iterable.Seq;
20+
import org.dmfs.srcless.annotations.staticfactory.StaticFactory;
21+
import org.json.JSONObject;
22+
import org.saynotobugs.confidence.Quality;
23+
import org.saynotobugs.confidence.description.Text;
24+
import org.saynotobugs.confidence.description.bifunction.Original;
25+
import org.saynotobugs.confidence.json.JsonObjectAdapter;
26+
import org.saynotobugs.confidence.json.jsonstringadapter.ObjectAdapter;
27+
import org.saynotobugs.confidence.quality.composite.Has;
28+
import org.saynotobugs.confidence.quality.composite.QualityComposition;
29+
30+
import static org.saynotobugs.confidence.description.LiteralDescription.COMMA;
31+
32+
/**
33+
* {@link Quality} of a {@link JSONObject}.
34+
*/
35+
public final class JsonOrgObject extends QualityComposition<JSONObject>
36+
{
37+
@StaticFactory(
38+
value = "JsonOrg",
39+
methodName = "jsonObject",
40+
packageName = "org.saynotobugs.confidence.json.quality"
41+
)
42+
@SafeVarargs
43+
public JsonOrgObject(Quality<? super JsonObjectAdapter>... delegates)
44+
{
45+
this(new Seq<>(delegates));
46+
}
47+
48+
@StaticFactory(
49+
value = "JsonOrg",
50+
methodName = "jsonObject",
51+
packageName = "org.saynotobugs.confidence.json.quality"
52+
)
53+
public JsonOrgObject(Iterable<? extends Quality<? super JsonObjectAdapter>> delegates)
54+
{
55+
super(new Has<>(
56+
new Original<>(),
57+
orig -> orig,
58+
ObjectAdapter::new,
59+
new Conjunction<>(new Text("{"), COMMA, new Text("}"), delegates, new Text("{}"))));
60+
}
61+
62+
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*
2+
* Copyright 2025 dmfs GmbH
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.saynotobugs.confidence.json.quality;
18+
19+
import org.dmfs.jems2.iterable.Seq;
20+
import org.json.JSONArray;
21+
import org.junit.jupiter.api.Test;
22+
import org.saynotobugs.confidence.quality.composite.AllOf;
23+
import org.saynotobugs.confidence.test.quality.Fails;
24+
import org.saynotobugs.confidence.test.quality.HasDescription;
25+
import org.saynotobugs.confidence.test.quality.Passes;
26+
27+
import static org.saynotobugs.confidence.Assertion.assertThat;
28+
29+
class JsonOrgArrayTest
30+
{
31+
@Test
32+
void testStrings()
33+
{
34+
assertThat(new JsonOrgArray("foo", "bar"),
35+
new AllOf<>(
36+
new Passes<>(new JSONArray(new Seq<>("foo", "bar")), "[\n" +
37+
" 0: \"foo\",\n" +
38+
" 1: \"bar\"\n" +
39+
"]"),
40+
41+
new Fails<>(new JSONArray(), "had length 0"),
42+
new Fails<>(new JSONArray(new Seq<>("foo")), "had length 1"),
43+
new Fails<>(new JSONArray(new Seq<>("foo", "bar", "baz")), "had length 3"),
44+
new HasDescription("[\n 0: \"foo\",\n 1: \"bar\"\n]")
45+
));
46+
}
47+
48+
@Test
49+
void testNumbers()
50+
{
51+
assertThat(new JsonOrgArray(42, 17),
52+
new AllOf<>(
53+
new Passes<>(new JSONArray(new Seq<>(42, 17)), "[\n" +
54+
" 0: 42,\n" +
55+
" 1: 17\n" +
56+
"]"),
57+
58+
new Fails<>(new JSONArray(), "had length 0"),
59+
new Fails<>(new JSONArray(new Seq<>(42)), "had length 1"),
60+
new Fails<>(new JSONArray(new Seq<>(42, 17, 1)), "had length 3"),
61+
new HasDescription("[\n 0: 42,\n 1: 17\n]")
62+
));
63+
}
64+
65+
@Test
66+
void testJsonAdapter()
67+
{
68+
assertThat(new JsonOrgArray(new Number(42), new Number(17)),
69+
new AllOf<>(
70+
new Passes<>(new JSONArray(new Seq<>(42, 17)), "[\n" +
71+
" 0: 42,\n" +
72+
" 1: 17\n" +
73+
"]"),
74+
75+
new Fails<>(new JSONArray(), "had length 0"),
76+
new Fails<>(new JSONArray(new Seq<>(42)), "had length 1"),
77+
new Fails<>(new JSONArray(new Seq<>(42, 17, 1)), "had length 3"),
78+
new HasDescription("[\n 0: 42,\n 1: 17\n]")
79+
));
80+
}
81+
82+
@Test
83+
void testArrayAdapter()
84+
{
85+
assertThat(new JsonOrgArray(
86+
new AllOf<>(
87+
new At(0, new Number(42)), new At(1, new Number(17)))),
88+
new AllOf<>(
89+
new Passes<>(new JSONArray(new Seq<>(42, 17)), "{\n" +
90+
" all of\n" +
91+
" 0: 0: 42\n" +
92+
" 1: 1: 17\n" +
93+
"}"),
94+
new Passes<>(new JSONArray(new Seq<>(42, 17, 3, 4)), "{\n" +
95+
" all of\n" +
96+
" 0: 0: 42\n" +
97+
" 1: 1: 17\n" +
98+
"}"),
99+
new Fails<>(new JSONArray(), "{\n all of\n 0: 0: missing\n 1: 1: missing\n}"),
100+
new Fails<>(new JSONArray(new Seq<>(42)), "{\n all of\n ...\n 1: 1: missing\n}"),
101+
new Fails<>(new JSONArray(new Seq<>(42, 13, 1)), "{\n all of\n ...\n 1: 1: 13\n}"),
102+
new HasDescription("{\n all of\n 0: 0: 42\n 1: 1: 17\n}")
103+
));
104+
}
105+
106+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright 2025 dmfs GmbH
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.saynotobugs.confidence.json.quality;
18+
19+
import org.json.JSONObject;
20+
import org.junit.jupiter.api.Test;
21+
import org.saynotobugs.confidence.quality.composite.AllOf;
22+
import org.saynotobugs.confidence.test.quality.Fails;
23+
import org.saynotobugs.confidence.test.quality.HasDescription;
24+
import org.saynotobugs.confidence.test.quality.Passes;
25+
26+
import static org.saynotobugs.confidence.Assertion.assertThat;
27+
28+
class JsonOrgObjectTest
29+
{
30+
@Test
31+
void test()
32+
{
33+
assertThat(new JsonOrgObject(new With("foo", "bar")),
34+
new AllOf<>(
35+
new Passes<>(new JSONObject().put("foo", "bar"), "{\n" +
36+
" \"foo\": \"bar\"\n" +
37+
"}"),
38+
new Passes<>(new JSONObject().put("foo", "bar").put("abc", "xyz"), "{\n" +
39+
" \"foo\": \"bar\"\n" +
40+
"}"),
41+
new Fails<>(new JSONObject(), "{\n \"foo\": not a member\n}"),
42+
new Fails<>(new JSONObject().put("abc", "xyz"), "{\n \"foo\": not a member\n}"),
43+
new Fails<>(new JSONObject().put("foo", "xyz"), "{\n \"foo\": \"xyz\"\n}"),
44+
new HasDescription("{\n \"foo\": \"bar\"\n}")
45+
));
46+
}
47+
48+
}

0 commit comments

Comments
 (0)