1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
|
# JSON Schema Test Suite
[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](https://github.com/json-schema-org/.github/blob/main/CODE_OF_CONDUCT.md)
[![Project Status: Active – The project has reached a stable, usable state and is being actively developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active)
[![Financial Contributors on Open Collective](https://opencollective.com/json-schema/all/badge.svg?label=financial+contributors)](https://opencollective.com/json-schema)
[![DOI](https://zenodo.org/badge/5952934.svg)](https://zenodo.org/badge/latestdoi/5952934)
[![Build Status](https://github.com/json-schema-org/JSON-Schema-Test-Suite/workflows/Test%20Suite%20Sanity%20Checking/badge.svg)](https://github.com/json-schema-org/JSON-Schema-Test-Suite/actions?query=workflow%3A%22Test+Suite+Sanity+Checking%22)
This repository contains a set of JSON objects that implementers of JSON Schema validation libraries can use to test their validators.
It is meant to be language agnostic and should require only a JSON parser.
The conversion of the JSON objects into tests within a specific language and test framework of choice is left to be done by the validator implementer.
## Coverage
All JSON Schema specification releases should be well covered by this suite, including drafts 2020-12, 2019-09, 07, 06, 04 and 03.
Drafts 04 and 03 are considered "frozen" in that less effort is put in to backport new tests to these versions.
Additional coverage is always welcome, particularly for bugs encountered in real-world implementations.
If you see anything missing or incorrect, please feel free to [file an issue](https://github.com/json-schema-org/JSON-Schema-Test-Suite/issues) or [submit a PR](https://github.com/json-schema-org/JSON-Schema-Test-Suite).
## Introduction to the Test Suite Structure
The tests in this suite are contained in the `tests` directory at the root of this repository.
Inside that directory is a subdirectory for each released version of the specification.
The structure and contents of each file in these directories is described below.
In addition to the version-specific subdirectories, two additional directories are present:
1. `draft-next/`: containing tests for the next version of the specification whilst it is in development
2. `latest/`: a symbolic link which points to the directory which is the most recent release (which may be useful for implementations providing specific entry points for validating against the latest version of the specification)
Inside each version directory there are a number of `.json` files each containing a collection of related tests.
Often the grouping is by property under test, but not always.
In addition to the `.json` files, each version directory contains one or more special subdirectories whose purpose is [described below](#subdirectories-within-each-draft), and which contain additional `.json` files.
Each `.json` file consists of a single JSON array of test cases.
### Terminology
For clarity, we first define this document's usage of some testing terminology:
| term | definition |
|-----------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **test suite** | the entirety of the contents of this repository, containing tests for multiple different releases of the JSON Schema specification |
| **test case** | a single schema, along with a description and an array of *test*s |
| **test** | within a *test case*, a single test example, containing a description, instance and a boolean indicating whether the instance is valid under the test case schema |
| **test runner** | a program, external to this repository and authored by a user of this suite, which is executing each of the tests in the suite |
An example illustrating this structure is immediately below, and a JSON Schema containing a formal definition of the contents of test cases can be found [alongside this README](./test-schema.json).
### Sample Test Case
Here is a single *test case*, containing one or more tests:
```json
{
"description": "The test case description",
"schema": { "type": "string" },
"tests": [
{
"description": "a test with a valid instance",
"data": "a string",
"valid": true
},
{
"description": "a test with an invalid instance",
"data": 15,
"valid": false
}
]
}
```
### Subdirectories Within Each Draft
There is currently only one additional subdirectory that may exist within each draft test directory.
This is:
1. `optional/`: Contains tests that are considered optional.
Note, the `optional/` subdirectory today conflates many reasons why a test may be optional -- it may be because tests within a particular file are indeed not required by the specification but still potentially useful to an implementer, or it may be because tests within it only apply to programming languages with particular functionality (in
which case they are not truly optional in such a language).
In the future this directory structure will be made richer to reflect these differences more clearly.
## Using the Suite to Test a Validator Implementation
The test suite structure was described [above](#introduction-to-the-test-suite-structure).
If you are authoring a new validator implementation, or adding support for an additional version of the specification, this section describes:
1. How to implement a test runner which passes tests to your validator
2. Assumptions the suite makes about how the test runner will configure your validator
3. Invariants the test suite claims to hold for its tests
### How to Implement a Test Runner
Presented here is a possible implementation of a test runner.
The precise steps described do not need to be followed exactly, but the results of your own procedure should produce the same effects.
To test a specific version:
* Load any remote references [described below](additional-assumptions) and configure your implementation to retrieve them via their URIs
* Walk the filesystem tree for that version's subdirectory and for each `.json` file found:
* if the file is located in the root of the version directory:
* for each test case present in the file:
* load the schema from the `"schema"` property
* load (or log) the test case description from the `"description"` property for debugging or outputting
* for each test in the `"tests"` property:
* load the instance to be tested from the `"data"` property
* load (or log) the individual test description from the `"description"` property for debugging or outputting
* use the schema loaded above to validate whether the instance is considered valid under your implementation
* if the result from your implementation matches the value found in the `"valid"` property, your implementation correctly implements the specific example
* if the result does not match, or your implementation errors or crashes, your implementation does not correctly implement the specific example
* otherwise it is located in a special subdirectory as described above.
Follow the additional assumptions and restrictions for the containing subdirectory, then run the test case as above.
If your implementation supports multiple versions, run the above procedure for each version supported, configuring your implementation as appropriate to call each version individually.
### Additional Assumptions
1. The suite, notably in its `refRemote.json` file in each draft, expects a number of remote references to be configured.
These are JSON documents, identified by URI, which are used by the suite to test the behavior of the `$ref` keyword (and related keywords).
Depending on your implementation, you may configure how to "register" these either by retrieving them from the `remotes/` directory at the root of the repository, *or* you may execute `bin/jsonschema_suite remotes` using the executable in the `bin/` directory, which will output a JSON object containing all of the remotes combined.
2. Test cases found within [special subdirectories](#subdirectories-within-each-draft) may require additional configuration to run.
In particular, tests within the `optional/format` subdirectory may require implementations to change the way they treat the `"format"`keyword (particularly on older drafts which did not have a notion of vocabularies).
### Invariants & Guarantees
The test suite guarantees a number of things about tests it defines.
Any deviation from the below is generally considered a bug.
If you suspect one, please [file an issue](https://github.com/json-schema-org/JSON-Schema-Test-Suite/issues/new):
1. All files containing test cases are valid JSON.
2. The contents of the `"schema"` property in a test case are always valid
JSON Schemas under the corresponding specification.
The rationale behind this is that we are testing instances in a test's `"data"` element, and not the schema itself.
A number of tests *do* test the validity of a schema itself, but do so by representing the schema as an instance inside a test, with the associated meta-schema in the `"schema"` property (via the `"$ref"` keyword):
```json
{
"description": "Test the \"type\" schema keyword",
"schema": {
"$ref": "https://json-schema.org/draft/2019-09/schema"
},
"tests": [
{
"description": "Valid: string",
"data": {
"type": "string"
},
"valid": true
},
{
"description": "Invalid: null",
"data": {
"type": null
},
"valid": false
}
]
}
```
See below for some [known limitations](#known-limitations).
## Known Limitations
This suite expresses its assertions about the behavior of an implementation *within* JSON Schema itself.
Each test is the application of a schema to a particular instance.
This means that the suite of tests can test against any behavior a schema can describe, and conversely cannot test against any behavior which a schema is incapable of representing, even if the behavior is mandated by the specification.
For example, a schema can require that a string is a _URI-reference_ and even that it matches a certain pattern, but even though the specification contains [recommendations about URIs being normalized](https://json-schema.org/draft/2020-12/json-schema-core.html#name-the-id-keyword), a JSON schema cannot today represent this assertion within the core vocabularies of the specifications, so no test covers this behavior.
## Who Uses the Test Suite
This suite is being used by:
### Clojure
* [jinx](https://github.com/juxt/jinx)
* [json-schema](https://github.com/tatut/json-schema)
### Coffeescript
* [jsck](https://github.com/pandastrike/jsck)
### Common Lisp
* [json-schema](https://github.com/fisxoj/json-schema)
### C++
* [Modern C++ JSON schema validator](https://github.com/pboettch/json-schema-validator)
### Dart
* [json\_schema](https://github.com/patefacio/json_schema)
### Elixir
* [ex\_json\_schema](https://github.com/jonasschmidt/ex_json_schema)
### Erlang
* [jesse](https://github.com/for-GET/jesse)
### Go
* [gojsonschema](https://github.com/sigu-399/gojsonschema)
* [validate-json](https://github.com/cesanta/validate-json)
### Haskell
* [aeson-schema](https://github.com/timjb/aeson-schema)
* [hjsonschema](https://github.com/seagreen/hjsonschema)
### Java
* [json-schema-validator](https://github.com/daveclayton/json-schema-validator)
* [everit-org/json-schema](https://github.com/everit-org/json-schema)
* [networknt/json-schema-validator](https://github.com/networknt/json-schema-validator)
* [Justify](https://github.com/leadpony/justify)
* [Snow](https://github.com/ssilverman/snowy-json)
* [jsonschemafriend](https://github.com/jimblackler/jsonschemafriend)
### JavaScript
* [json-schema-benchmark](https://github.com/Muscula/json-schema-benchmark)
* [direct-schema](https://github.com/IreneKnapp/direct-schema)
* [is-my-json-valid](https://github.com/mafintosh/is-my-json-valid)
* [jassi](https://github.com/iclanzan/jassi)
* [JaySchema](https://github.com/natesilva/jayschema)
* [json-schema-valid](https://github.com/ericgj/json-schema-valid)
* [Jsonary](https://github.com/jsonary-js/jsonary)
* [jsonschema](https://github.com/tdegrunt/jsonschema)
* [request-validator](https://github.com/bugventure/request-validator)
* [skeemas](https://github.com/Prestaul/skeemas)
* [tv4](https://github.com/geraintluff/tv4)
* [z-schema](https://github.com/zaggino/z-schema)
* [jsen](https://github.com/bugventure/jsen)
* [ajv](https://github.com/epoberezkin/ajv)
* [djv](https://github.com/korzio/djv)
### Node.js
For node.js developers, the suite is also available as an [npm](https://www.npmjs.com/package/@json-schema-org/tests) package.
Node-specific support is maintained in a [separate repository](https://github.com/json-schema-org/json-schema-test-suite-npm) which also welcomes your contributions!
### .NET
* [Newtonsoft.Json.Schema](https://github.com/JamesNK/Newtonsoft.Json.Schema)
* [Manatee.Json](https://github.com/gregsdennis/Manatee.Json)
### Perl
* [Test::JSON::Schema::Acceptance](https://github.com/karenetheridge/Test-JSON-Schema-Acceptance) (a wrapper of this test suite)
* [JSON::Schema::Modern](https://github.com/karenetheridge/JSON-Schema-Modern)
* [JSON::Schema::Tiny](https://github.com/karenetheridge/JSON-Schema-Tiny)
### PHP
* [opis/json-schema](https://github.com/opis/json-schema)
* [json-schema](https://github.com/justinrainbow/json-schema)
* [json-guard](https://github.com/thephpleague/json-guard)
### PostgreSQL
* [postgres-json-schema](https://github.com/gavinwahl/postgres-json-schema)
* [is\_jsonb\_valid](https://github.com/furstenheim/is_jsonb_valid)
### Python
* [jsonschema](https://github.com/Julian/jsonschema)
* [fastjsonschema](https://github.com/seznam/python-fastjsonschema)
* [hypothesis-jsonschema](https://github.com/Zac-HD/hypothesis-jsonschema)
* [jschon](https://github.com/marksparkza/jschon)
* [python-experimental, OpenAPI Generator](https://github.com/OpenAPITools/openapi-generator/blob/master/docs/generators/python-experimental.md)
### Ruby
* [json-schema](https://github.com/hoxworth/json-schema)
* [json\_schemer](https://github.com/davishmcclurg/json_schemer)
### Rust
* [jsonschema](https://github.com/Stranger6667/jsonschema-rs)
* [valico](https://github.com/rustless/valico)
### Scala
* [typed-json](https://github.com/frawa/typed-json)
### Swift
* [JSONSchema](https://github.com/kylef/JSONSchema.swift)
If you use it as well, please fork and send a pull request adding yourself to
the list :).
## Contributing
If you see something missing or incorrect, a pull request is most welcome!
There are some sanity checks in place for testing the test suite. You can run
them with `bin/jsonschema_suite check` or `tox`. They will be run automatically
by [GitHub Actions](https://github.com/json-schema-org/JSON-Schema-Test-Suite/actions?query=workflow%3A%22Test+Suite+Sanity+Checking%22)
as well.
|