1
+ package smirnov.oleg.json.schema.assertions.`object`
2
+
3
+ import io.kotest.assertions.asClue
4
+ import io.kotest.assertions.throwables.shouldThrow
5
+ import io.kotest.core.spec.style.FunSpec
6
+ import io.kotest.matchers.collections.shouldContainExactly
7
+ import io.kotest.matchers.collections.shouldHaveSize
8
+ import io.kotest.matchers.shouldBe
9
+ import kotlinx.serialization.json.JsonPrimitive
10
+ import kotlinx.serialization.json.buildJsonObject
11
+ import smirnov.oleg.json.pointer.JsonPointer
12
+ import smirnov.oleg.json.schema.JsonSchema
13
+ import smirnov.oleg.json.schema.KEY
14
+ import smirnov.oleg.json.schema.ValidationError
15
+
16
+ @Suppress(" unused" )
17
+ class JsonSchemaDependenciesValidationTest : FunSpec () {
18
+ init {
19
+ JsonSchema .fromDescription(
20
+ """
21
+ {
22
+ "${KEY } schema": "http://json-schema.org/draft-07/schema#",
23
+ "dependencies": {
24
+ "trigger": {
25
+ "properties": {
26
+ "depend": {
27
+ "type": "number"
28
+ }
29
+ }
30
+ }
31
+ }
32
+ }
33
+ """ .trimIndent()
34
+ ).also { schema ->
35
+ test(" object without trigger JSON schema property passes validation" ) {
36
+ val jsonObject = buildJsonObject {
37
+ put(" depend" , JsonPrimitive (" test" ))
38
+ }
39
+
40
+ val errors = mutableListOf<ValidationError >()
41
+ val valid = schema.validate(jsonObject, errors::add)
42
+
43
+ jsonObject.asClue {
44
+ valid shouldBe true
45
+ errors shouldHaveSize 0
46
+ }
47
+ }
48
+
49
+ test(" object with trigger JSON schema property passes validation" ) {
50
+ val jsonObject = buildJsonObject {
51
+ put(" trigger" , JsonPrimitive (42 ))
52
+ put(" depend" , JsonPrimitive (42.5 ))
53
+ }
54
+
55
+ val errors = mutableListOf<ValidationError >()
56
+ val valid = schema.validate(jsonObject, errors::add)
57
+
58
+ jsonObject.asClue {
59
+ valid shouldBe true
60
+ errors shouldHaveSize 0
61
+ }
62
+ }
63
+
64
+ test(" object with trigger JSON schema property fails validation" ) {
65
+ val jsonObject = buildJsonObject {
66
+ put(" trigger" , JsonPrimitive (42 ))
67
+ put(" depend" , JsonPrimitive (" test" ))
68
+ }
69
+
70
+ val errors = mutableListOf<ValidationError >()
71
+ val valid = schema.validate(jsonObject, errors::add)
72
+
73
+ jsonObject.asClue {
74
+ valid shouldBe false
75
+ errors.shouldContainExactly(
76
+ ValidationError (
77
+ schemaPath = JsonPointer (" /dependencies/trigger/properties/depend/type" ),
78
+ objectPath = JsonPointer (" /depend" ),
79
+ message = " element is not a number" ,
80
+ )
81
+ )
82
+ }
83
+ }
84
+ }
85
+
86
+ JsonSchema .fromDescription(
87
+ """
88
+ {
89
+ "${KEY } schema": "http://json-schema.org/draft-07/schema#",
90
+ "dependencies": {
91
+ "trigger": ["depend"]
92
+ }
93
+ }
94
+ """ .trimIndent()
95
+ ).also { schema ->
96
+ test(" object without trigger array property passes validation" ) {
97
+ val jsonObject = buildJsonObject {
98
+ put(" depend" , JsonPrimitive (" test" ))
99
+ }
100
+
101
+ val errors = mutableListOf<ValidationError >()
102
+ val valid = schema.validate(jsonObject, errors::add)
103
+
104
+ jsonObject.asClue {
105
+ valid shouldBe true
106
+ errors shouldHaveSize 0
107
+ }
108
+ }
109
+
110
+ test(" object with trigger array property passes validation" ) {
111
+ val jsonObject = buildJsonObject {
112
+ put(" trigger" , JsonPrimitive (42 ))
113
+ put(" depend" , JsonPrimitive (42.5 ))
114
+ }
115
+
116
+ val errors = mutableListOf<ValidationError >()
117
+ val valid = schema.validate(jsonObject, errors::add)
118
+
119
+ jsonObject.asClue {
120
+ valid shouldBe true
121
+ errors shouldHaveSize 0
122
+ }
123
+ }
124
+
125
+ test(" object with trigger array property fails validation" ) {
126
+ val jsonObject = buildJsonObject {
127
+ put(" trigger" , JsonPrimitive (42 ))
128
+ put(" depend2" , JsonPrimitive (" test" ))
129
+ }
130
+
131
+ val errors = mutableListOf<ValidationError >()
132
+ val valid = schema.validate(jsonObject, errors::add)
133
+
134
+ jsonObject.asClue {
135
+ valid shouldBe false
136
+ errors.shouldContainExactly(
137
+ ValidationError (
138
+ schemaPath = JsonPointer (" /dependencies/trigger" ),
139
+ objectPath = JsonPointer .ROOT ,
140
+ message = " has 'trigger' property but missing required dependencies: [depend]" ,
141
+ )
142
+ )
143
+ }
144
+ }
145
+ }
146
+
147
+ JsonSchema .fromDescription(
148
+ """
149
+ {
150
+ "${KEY } schema": "http://json-schema.org/draft-07/schema#",
151
+ "dependencies": {
152
+ "trigger1": {
153
+ "properties": {
154
+ "depend1": {
155
+ "type": "number"
156
+ }
157
+ }
158
+ },
159
+ "trigger2": ["depend2"]
160
+ }
161
+ }
162
+ """ .trimIndent()
163
+ ).also { schema ->
164
+ notAnObjectPasses(schema)
165
+ }
166
+
167
+ JsonSchema .fromDescription(
168
+ """
169
+ {
170
+ "${KEY } schema": "http://json-schema.org/draft-07/schema#",
171
+ "dependencies": {}
172
+ }
173
+ """ .trimIndent()
174
+ ).also { schema ->
175
+ test(" object passes empty dependencies" ) {
176
+ val jsonObject = buildJsonObject {
177
+ put(" trigger" , JsonPrimitive (42 ))
178
+ put(" depend" , JsonPrimitive (42.5 ))
179
+ }
180
+
181
+ val errors = mutableListOf<ValidationError >()
182
+ val valid = schema.validate(jsonObject, errors::add)
183
+
184
+ jsonObject.asClue {
185
+ valid shouldBe true
186
+ errors shouldHaveSize 0
187
+ }
188
+ }
189
+ }
190
+
191
+ JsonSchema .fromDescription(
192
+ """
193
+ {
194
+ "${KEY } schema": "http://json-schema.org/draft-07/schema#",
195
+ "dependencies": {
196
+ "trigger": []
197
+ }
198
+ }
199
+ """ .trimIndent()
200
+ ).also { schema ->
201
+ test(" object passes empty dependencies array" ) {
202
+ val jsonObject = buildJsonObject {
203
+ put(" trigger" , JsonPrimitive (42 ))
204
+ put(" depend" , JsonPrimitive (42.5 ))
205
+ }
206
+
207
+ val errors = mutableListOf<ValidationError >()
208
+ val valid = schema.validate(jsonObject, errors::add)
209
+
210
+ jsonObject.asClue {
211
+ valid shouldBe true
212
+ errors shouldHaveSize 0
213
+ }
214
+ }
215
+ }
216
+
217
+ test(" reports if dependency is neither array or object" ) {
218
+ shouldThrow<IllegalArgumentException > {
219
+ JsonSchema .fromDescription(
220
+ """
221
+ {
222
+ "${KEY } schema": "http://json-schema.org/draft-07/schema#",
223
+ "dependencies": {
224
+ "trigger": 42
225
+ }
226
+ }
227
+ """ .trimIndent()
228
+ )
229
+ }.message shouldBe " trigger dependency must be either array of strings or valid JSON schema"
230
+ }
231
+
232
+ test(" reports if not an object" ) {
233
+ shouldThrow<IllegalArgumentException > {
234
+ JsonSchema .fromDescription(
235
+ """
236
+ {
237
+ "${KEY } schema": "http://json-schema.org/draft-07/schema#",
238
+ "dependencies": 42
239
+ }
240
+ """ .trimIndent()
241
+ )
242
+ }.message shouldBe " dependencies must be an object"
243
+ }
244
+
245
+ test(" reports not unique elements" ) {
246
+ shouldThrow<IllegalArgumentException > {
247
+ JsonSchema .fromDescription(
248
+ """
249
+ {
250
+ "${KEY } schema": "http://json-schema.org/draft-07/schema#",
251
+ "dependencies": {
252
+ "trigger": ["a","b","a"]
253
+ }
254
+ }
255
+ """ .trimIndent()
256
+ )
257
+ }.message shouldBe " trigger must consist of unique elements"
258
+ }
259
+ }
260
+ }
0 commit comments