Skip to content

Commit cc7b2eb

Browse files
committed
Finish revising unevaluatedItems
Signed-off-by: Juan Cruz Viotti <[email protected]>
1 parent 4a9b8e8 commit cc7b2eb

File tree

1 file changed

+66
-152
lines changed

1 file changed

+66
-152
lines changed

content/2020-12/unevaluated/unevaluatedItems.markdown

Lines changed: 66 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -79,211 +79,125 @@ dependencies, leading to schemas that are simpler to evaluate.
7979

8080
## Examples
8181

82-
{{<schema `Schema with 'unevaluatedItems' set to boolean true`>}}
82+
{{<schema `A schema that conditionally constrains array instances to contain certain items, with number additional items in both cases`>}}
8383
{
8484
"$schema": "https://json-schema.org/draft/2020-12/schema",
85-
"unevaluatedItems": true
85+
"if": { "maxItems": 3 },
86+
"then": { "prefixItems": [ { "type": "string" } ] },
87+
"else": { "contains": { "type": "boolean" } },
88+
"unevaluatedItems": { "type": "number" }
8689
}
8790
{{</schema>}}
8891

89-
{{<instance-pass `All array instances pass against the true schema`>}}
90-
[ "foo", "bar" ]
92+
{{<instance-pass `An array value that contains a string property and other number items is valid`>}}
93+
[ "foo", 1, 2 ]
9194
{{</instance-pass>}}
9295

9396
{{<instance-annotation>}}
94-
{ "keyword": "/unevaluatedItems", "instance": "", "value": "true" }
97+
{ "keyword": "/then/prefixItems", "instance": "", "value": 0 }
98+
{ "keyword": "/unevaluatedItems", "instance": "", "value": true }
9599
{{</instance-annotation>}}
96100

97-
{{<instance-pass `'unevaluatedItems' does not have any effect on instances other than an array`>}}
98-
"John Doe"
99-
{{</instance-pass>}}
100-
101-
* Here, no items are defined in the above schema. Consequently, all items in an array instance are considered unevaluated, and the `unevaluatedItems` subschema applies to them. Since the subschema here is a boolean true, an instance with unevaluated items, regardless of their value, is considered valid.
102-
103-
{{<schema `Schema with 'unevaluatedItems' set to boolean false`>}}
104-
{
105-
"$schema": "https://json-schema.org/draft/2020-12/schema",
106-
"unevaluatedItems": false
107-
}
108-
{{</schema>}}
109-
110-
{{<instance-fail `All object instances fail against the false schema`>}}
111-
[ "foo", "bar" ]
112-
{{</instance-fail>}}
113-
114-
{{<instance-pass `'unevaluatedItems' does not have any effect on instances other than an array`>}}
115-
{ "John": 46 }
116-
{{</instance-pass>}}
117-
118-
{{<schema `Schema with 'unevaluatedItems', 'prefixItems', and 'contains', with unevaluatedItems set to boolean false`>}}
119-
{
120-
"$schema": "https://json-schema.org/draft/2020-12/schema",
121-
"prefixItems": [ { "type": "string" } ],
122-
"contains": { "type": "number" },
123-
"unevaluatedItems": false
124-
}
125-
{{</schema>}}
126-
127-
{{<instance-fail `An array instance with unevaluated items is invalid`>}}
128-
[ "foo", 101, false ]
129-
{{</instance-fail>}}
130-
131-
{{<instance-pass `An array instance with no unevaluated items is valid`>}}
132-
[ "foo", 101, 77 ]
101+
{{<instance-pass `An array value that contains multiple boolean and number items is valid`>}}
102+
[ true, 1, false, 2, true, 3 ]
133103
{{</instance-pass>}}
134104

135105
{{<instance-annotation>}}
136-
{ "keyword": "/prefixItems", "instance": "", "value": 0 }
137-
{ "keyword": "/contains", "instance": "", "value": [ 1, 2 ] }
106+
{ "keyword": "/else/contains", "instance": "", "value": [ 0, 2, 4 ] }
107+
{ "keyword": "/unevaluatedItems", "instance": "", "value": true }
138108
{{</instance-annotation>}}
139109

140-
* For the first instance, the annotation result of `prefixItems` is 0, and the annotation result of `contains` is [ 1 ]. However, the item at 2nd index (i.e., `false`) remains unevaluated, so the `unevaluatedItems` subschema applies to it. This subschema fails (as any instance against a false schema is always invalid), leading to validation failure.
141-
142-
* For the second instance, the annotation result of `prefixItems` is 0, and the annotation result of contains is [ 1, 2 ]. No items remain unevaluated; hence, the instance is considered valid.
110+
{{<instance-fail `An array value that contains a string property and other non-number items is invalid`>}}
111+
[ "foo", "bar", "baz" ]
112+
{{</instance-fail>}}
143113

144-
{{<schema `Schema with 'unevaluatedItems', 'prefixItems', and 'contains', with unevaluatedItems set to an object schema`>}}
145-
{
146-
"$schema": "https://json-schema.org/draft/2020-12/schema",
147-
"prefixItems": [ { "type": "string" } ],
148-
"contains": { "type": "number" },
149-
"unevaluatedItems": { "type": "boolean" }
150-
}
151-
{{</schema>}}
114+
{{<instance-fail `An array value that contains multiple boolean and number items, and string additional items is invalid`>}}
115+
[ true, 2, "foo", "bar" ]
116+
{{</instance-fail>}}
152117

153-
{{<instance-pass `An array instance with no unevaluated items is valid`>}}
154-
[ "foo", 101, 77 ]
118+
{{<instance-pass `An empty array value is valid`>}}
119+
{}
155120
{{</instance-pass>}}
156121

157-
{{<instance-annotation>}}
158-
{ "keyword": "/prefixItems", "instance": "", "value": 0 }
159-
{ "keyword": "/contains", "instance": "", "value": [ 1, 2 ] }
160-
{{</instance-annotation>}}
161-
162-
{{<instance-pass `An array instance with unevaluated items that conform to the 'unevaluatedItems' subschema is valid`>}}
163-
[ "foo", 101, false ]
122+
{{<instance-pass `A non-array value is valid`>}}
123+
"Hello World"
164124
{{</instance-pass>}}
165125

166-
{{<instance-annotation>}}
167-
{ "keyword": "/prefixItems", "instance": "", "value": 0 }
168-
{ "keyword": "/contains", "instance": "", "value": [ 1 ] }
169-
{ "keyword": "/unevaluatedItems", "instance": "", "value": true }
170-
{{</instance-annotation>}}
171-
172-
{{<instance-fail `An array instance with unevaluated items that do not conform to the 'unevaluatedItems' subschema is invalid`>}}
173-
[ "foo", 101, [ false ] ]
174-
{{</instance-fail>}}
175-
176-
* For the first instance, there are no unevaluated items.
177-
178-
* For the second instance, the item at 2nd index (i.e., `false`) remains unevaluated, and the `unevaluatedItems` subschema applies to it. This item conforms to this subschema, and hence the instance is valid.
179-
180-
{{<schema `Schema with 'unevaluatedItems', and 'allOf' keyword`>}}
126+
{{<schema `A schema that constraints array instances to only allow a single string item using a helper`>}}
181127
{
182128
"$schema": "https://json-schema.org/draft/2020-12/schema",
183-
"prefixItems": [ { "type": "string" } ],
184-
"allOf" : [
185-
{
186-
"prefixItems": [
187-
true,
188-
{ "type": "boolean" }
189-
]
129+
"$ref": "#/$defs/string-first-item",
130+
"unevaluatedItems": false,
131+
"$defs": {
132+
"string-first-item": {
133+
"prefixItems": [ { "type": "string" } ]
190134
}
191-
],
192-
"unevaluatedItems": { "type": "number" }
135+
}
193136
}
194137
{{</schema>}}
195138

196-
{{<instance-pass `An array instance with unevaluated items that conform to the 'unevaluatedItems' subschema is valid`>}}
197-
[ "foo", false, 22 ]
139+
{{<instance-pass `An array value that only contains a string item is valid`>}}
140+
[ "foo" ]
198141
{{</instance-pass>}}
199142

200143
{{<instance-annotation>}}
201-
{ "keyword": "/prefixItems", "instance": "", "value": 0 }
202-
{ "keyword": "/allOf/0/prefixItems", "instance": "", "value": 1 }
203-
{ "keyword": "/unevaluatedItems", "instance": "", "value": true }
144+
{ "keyword": "/$defs/string-first-item/prefixItems", "instance": "", "value": 0 }
204145
{{</instance-annotation>}}
205146

206-
{{<instance-fail `An array instance with unevaluated items that do not conform to the 'unevaluatedItems' subschema is invalid`>}}
207-
[ "foo", 101, [ false ] ]
147+
{{<instance-fail `An array value that contains a string item and other items is invalid`>}}
148+
[ "foo", 2, 3 ]
208149
{{</instance-fail>}}
209150

210-
For the above two instances, the annotation result of top level `prefixItems` is 0, and the annotation result of the nested `prefixItems` is 1. The `unevaluatedItems` recognizes the annotations from top level `prefixItems` as well as nested `prefixItems` (as it can see through adjacent and nested applicators as only the produced annotations matter, not the schema structure) and ensures that the item at index 2 remains unevaluated and its subschema applies to it.
211-
212-
* The first instance passes as it conforms to the unevaluated subschema.
213-
* The second instance fails as it does not conform to the unevaluated subschema.
214-
215-
{{<schema `Schema with 'unevaluatedItems', and 'allOf' keyword`>}}
216-
{
217-
"$schema": "https://json-schema.org/draft/2020-12/schema",
218-
"prefixItems": [ { "type": "string" } ],
219-
"allOf" : [
220-
{
221-
"items": true
222-
}
223-
],
224-
"unevaluatedItems": { "type": "number" }
225-
}
226-
{{</schema>}}
227-
228-
{{<instance-pass `An array instance with no unevaluated items is valid`>}}
229-
[ "foo", false, 22 ]
151+
{{<instance-pass `An empty array value is valid`>}}
152+
{}
230153
{{</instance-pass>}}
231154

232-
{{<instance-annotation>}}
233-
{ "keyword": "/prefixItems", "instance": "", "value": 0 }
234-
{ "keyword": "/allOf/0/items", "instance": "", "value": true }
235-
{{</instance-annotation>}}
236-
237-
* Here, the nested `items` evaluated all the unevaluated items. So there's nothing left unevaluated.
155+
{{<instance-pass `A non-array value is valid`>}}
156+
"Hello World"
157+
{{</instance-pass>}}
238158

239-
{{<schema `Schema with 'unevaluatedItems' and '#ref' keyword`>}}
159+
{{<schema `A schema that constraints array instances to not define any items, as both array keywords are cousins`>}}
240160
{
241161
"$schema": "https://json-schema.org/draft/2020-12/schema",
242-
"prefixItems": [
243-
{ "type": "string" },
244-
{ "type": "boolean" }
245-
],
246-
"$ref": "#/$defs/bar",
247-
"unevaluatedItems": false,
248-
"$defs": {
249-
"bar": {
250-
"contains": { "type": "number" }
251-
}
252-
}
162+
"allOf": [
163+
{ "items": true },
164+
{ "unevaluatedItems": false }
165+
]
253166
}
254167
{{</schema>}}
255168

256-
{{<instance-pass `An instance with no unevaluated items is valid`>}}
257-
[ "foo", false, 22 ]
258-
{{</instance-pass>}}
169+
{{<instance-fail `An array value that contains any item is invalid as the schema prohibits unevaluated items`>}}
170+
[ 1, 2, 3 ]
171+
{{</instance-fail>}}
259172

260-
{{<instance-annotation>}}
261-
{ "keyword": "/prefixItems", "instance": "", "value": 1 }
262-
{ "keyword": "/$ref/contains", "instance": "", "value": [ 2 ] }
263-
{{</instance-annotation>}}
173+
{{<instance-pass `An empty array value is valid`>}}
174+
[]
175+
{{</instance-pass>}}
264176

265-
{{<instance-fail `An instance with unevaluated items is invalid`>}}
266-
[ "foo", false, "bar" ]
267-
{{</instance-fail>}}
177+
{{<instance-pass `A non-array value is valid`>}}
178+
"Hello World"
179+
{{</instance-pass>}}
268180

269-
{{<schema `Schema with nested 'unevaluatedItems' keyword`>}}
181+
{{<schema `A schema that constraints array instances to define arbitrary items`>}}
270182
{
271183
"$schema": "https://json-schema.org/draft/2020-12/schema",
272-
"prefixItems": [ { "type": "string" } ],
273-
"allOf" : [
274-
{
275-
"unevaluatedItems": true
276-
}
277-
],
184+
"allOf": [ { "unevaluatedItems": true } ],
278185
"unevaluatedItems": false
279186
}
280187
{{</schema>}}
281188

282-
{{<instance-pass `No items left unevaluated for the top level 'unevaluatedItems'`>}}
283-
[ "foo", false, "bar" ]
189+
{{<instance-pass `An array value that contains any item is valid as the nested applicator takes precedence`>}}
190+
[ 1, 2, 3 ]
284191
{{</instance-pass>}}
285192

286193
{{<instance-annotation>}}
287-
{ "keyword": "/prefixItems", "instance": "", "value": 0 }
288194
{ "keyword": "/allOf/0/unevaluatedItems", "instance": "", "value": true }
289195
{{</instance-annotation>}}
196+
197+
{{<instance-pass `An empty array value is valid`>}}
198+
{}
199+
{{</instance-pass>}}
200+
201+
{{<instance-pass `A non-array value is valid`>}}
202+
"Hello World"
203+
{{</instance-pass>}}

0 commit comments

Comments
 (0)