Skip to content

Commit 095a009

Browse files
committed
Squashed 'json/' changes from cf78d97d0..f0f619d19
f0f619d19 Merge pull request #560 from json-schema-org/ether/fix-383 fa791ada9 remove tests that are not valid for draft7 0f341dca0 Merge pull request #429 from notEthan/decimal_minItems 32ec6305c test validation of keywords which expect integers when their value has a decimal 547330dd6 Tweak the markdown table syntax in the README. 28ed3022c Restructure the README further. 45d6e5e7f README: Add new content and update the structure 4de0966a7 Merge pull request #558 from yakimun/replace-definitions-with-defs aad0f350a Replace definitions with for 2019 and later drafts 0b777ffa2 Merge branch 'ether/more-anchor-and-id-tests' d593591d7 Forward port the just-added tests to 2020 and next. e157bc0b7 squash: use a unique $id to prevent namespace collisions across tests 1d5583de6 some tests of the interactions between $id, $anchor and $ref 07c45c0d7 Restore the dependencies tests as optional for 2019, 2020, and next git-subtree-dir: json git-subtree-split: f0f619d19696a81f7683116f707a51c34150d28f
1 parent aeecae3 commit 095a009

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+2065
-59
lines changed

README.md

Lines changed: 147 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,186 @@
1-
# JSON Schema Test Suite
1+
# JSON Schema Test Suite
2+
23
[![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)
34
[![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)
45
[![Financial Contributors on Open Collective](https://opencollective.com/json-schema/all/badge.svg?label=financial+contributors)](https://opencollective.com/json-schema)
56

67
[![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)
78

8-
This repository contains a set of JSON objects that implementors of JSON Schema
9-
validation libraries can use to test their validators.
9+
This repository contains a set of JSON objects that implementers of JSON Schema validation libraries can use to test their validators.
1010

1111
It is meant to be language agnostic and should require only a JSON parser.
12+
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.
13+
14+
## Coverage
15+
16+
All JSON Schema specification releases should be well covered by this suite, including drafts 2020-12, 2019-09, 07, 06, 04 and 03.
17+
Drafts 04 and 03 are considered "frozen" in that less effort is put in to backport new tests to these versions.
18+
19+
Additional coverage is always welcome, particularly for bugs encountered in real-world implementations.
20+
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).
21+
22+
## Introduction to the Test Suite Structure
23+
24+
The tests in this suite are contained in the `tests` directory at the root of this repository.
25+
Inside that directory is a subdirectory for each released version of the specification.
26+
27+
The structure and contents of each file in these directories is described below.
28+
29+
In addition to the version-specific subdirectories, two additional directories are present:
1230

13-
The conversion of the JSON objects into tests within your test framework of
14-
choice is still the job of the validator implementor.
31+
1. `draft-next/`: containing tests for the next version of the specification whilst it is in development
32+
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)
1533

16-
## Structure of a Test
34+
Inside each version directory there are a number of `.json` files each containing a collection of related tests.
35+
Often the grouping is by property under test, but not always.
36+
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.
1737

18-
The tests in this suite are contained in the `tests` directory at the root of
19-
this repository. Inside that directory is a subdirectory for each draft or
20-
version of the specification.
38+
Each `.json` file consists of a single JSON array of test cases.
2139

22-
Inside each draft directory, there are a number of `.json` files and one or more
23-
special subdirectories. The subdirectories contain `.json` files meant for a
24-
specific testing purpose, and each `.json` file logically groups a set of test
25-
cases together. Often the grouping is by property under test, but not always.
40+
### Terminology
2641

27-
The subdirectories are described in the next section.
42+
For clarity, we first define this document's usage of some testing terminology:
2843

29-
Inside each `.json` file is a single array containing objects. It's easiest to
30-
illustrate the structure of these with an example:
44+
| term | definition |
45+
|-----------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|
46+
| **test suite** | the entirety of the contents of this repository, containing tests for multiple different releases of the JSON Schema specification |
47+
| **test case** | a single schema, along with a description and an array of *test*s |
48+
| **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 |
49+
| **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 |
50+
51+
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).
52+
53+
### Sample Test Case
54+
55+
Here is a single *test case*, containing one or more tests:
3156

3257
```json
3358
{
34-
"description": "The description of the test case",
35-
"schema": {
36-
"description": "The schema against which the data in each test is validated",
37-
"type": "string"
38-
},
59+
"description": "The test case description",
60+
"schema": { "type": "string" },
3961
"tests": [
4062
{
41-
"description": "Test for a valid instance",
42-
"data": "the instance to validate",
63+
"description": "a test with a valid instance",
64+
"data": "a string",
4365
"valid": true
4466
},
4567
{
46-
"description": "Test for an invalid instance",
68+
"description": "a test with an invalid instance",
4769
"data": 15,
4870
"valid": false
4971
}
5072
]
5173
}
5274
```
5375

54-
In short: a description, a schema under test, and some tests, where each test
55-
in the `tests` array is an objects with a description of the case itself, the
56-
instance under test, and a boolean indicating whether it should be valid
57-
or invalid.
76+
### Subdirectories Within Each Draft
5877

59-
## Test Subdirectories
78+
There is currently only one additional subdirectory that may exist within each draft test directory.
6079

61-
There is currently only one subdirectory that may exist within each draft
62-
directory. This is:
80+
This is:
6381

6482
1. `optional/`: Contains tests that are considered optional.
6583

66-
## Coverage
84+
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
85+
which case they are not truly optional in such a language).
86+
In the future this directory structure will be made richer to reflect these differences more clearly.
87+
88+
## Using the Suite to Test a Validator Implementation
89+
90+
The test suite structure was described [above](#introduction-to-the-test-suite-structure).
91+
92+
If you are authoring a new validator implementation, or adding support for an additional version of the specification, this section describes:
93+
94+
1. How to implement a test runner which passes tests to your validator
95+
2. Assumptions the suite makes about how the test runner will configure your validator
96+
3. Invariants the test suite claims to hold for its tests
6797

68-
All JSON Schema specification releases should be well covered by this suite,
69-
including drafts 2020-12, 2019-09, 07, 06, 04 and 03. Additional coverage is
70-
always welcome, particularly for bugs encountered in real-world
71-
implementations.
98+
### How to Implement a Test Runner
7299

73-
Drafts 04 and 03 are considered "frozen" in that less effort is put in to
74-
backport new tests to these versions.
100+
Presented here is a possible implementation of a test runner.
101+
The precise steps described do not need to be followed exactly, but the results of your own procedure should produce the same effects.
75102

76-
Contributions are very welcome, especially from implementers as they add support
77-
to their own implementations.
103+
To test a specific version:
78104

79-
If you see anything missing from the current supported drafts, or incorrect on
80-
any draft still accepting bug fixes, please
81-
[file an issue](https://github.com/json-schema-org/JSON-Schema-Test-Suite/issues)
82-
or [submit a PR](https://github.com/json-schema-org/JSON-Schema-Test-Suite).
105+
* Load any remote references [described below](additional-assumptions) and configure your implementation to retrieve them via their URIs
106+
* Walk the filesystem tree for that version's subdirectory and for each `.json` file found:
107+
108+
* if the file is located in the root of the version directory:
109+
110+
* for each test case present in the file:
111+
112+
* load the schema from the `"schema"` property
113+
* load (or log) the test case description from the `"description"` property for debugging or outputting
114+
* for each test in the `"tests"` property:
115+
116+
* load the instance to be tested from the `"data"` property
117+
* load (or log) the individual test description from the `"description"` property for debugging or outputting
118+
119+
* use the schema loaded above to validate whether the instance is considered valid under your implementation
120+
121+
* if the result from your implementation matches the value found in the `"valid"` property, your implementation correctly implements the specific example
122+
* if the result does not match, or your implementation errors or crashes, your implementation does not correctly implement the specific example
123+
124+
* otherwise it is located in a special subdirectory as described above.
125+
Follow the additional assumptions and restrictions for the containing subdirectory, then run the test case as above.
126+
127+
If your implementation supports multiple versions, run the above procedure for each version supported, configuring your implementation as appropriate to call each version individually.
128+
129+
### Additional Assumptions
130+
131+
1. The suite, notably in its `refRemote.json` file in each draft, expects a number of remote references to be configured.
132+
These are JSON documents, identified by URI, which are used by the suite to test the behavior of the `$ref` keyword (and related keywords).
133+
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.
134+
135+
2. Test cases found within [special subdirectories](#subdirectories-within-each-draft) may require additional configuration to run.
136+
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).
137+
138+
### Invariants & Guarantees
139+
140+
The test suite guarantees a number of things about tests it defines.
141+
Any deviation from the below is generally considered a bug.
142+
If you suspect one, please [file an issue](https://github.com/json-schema-org/JSON-Schema-Test-Suite/issues/new):
143+
144+
1. All files containing test cases are valid JSON.
145+
2. The contents of the `"schema"` property in a test case are always valid
146+
JSON Schemas under the corresponding specification.
147+
148+
The rationale behind this is that we are testing instances in a test's `"data"` element, and not the schema itself.
149+
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):
150+
151+
```json
152+
{
153+
"description": "Test the \"type\" schema keyword",
154+
"schema": {
155+
"$ref": "https://json-schema.org/draft/2019-09/schema"
156+
},
157+
"tests": [
158+
{
159+
"description": "Valid: string",
160+
"data": {
161+
"type": "string"
162+
},
163+
"valid": true
164+
},
165+
{
166+
"description": "Invalid: null",
167+
"data": {
168+
"type": null
169+
},
170+
"valid": false
171+
}
172+
]
173+
}
174+
```
175+
See below for some [known limitations](#known-limitations).
176+
177+
## Known Limitations
178+
179+
This suite expresses its assertions about the behavior of an implementation *within* JSON Schema itself.
180+
Each test is the application of a schema to a particular instance.
181+
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.
182+
183+
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.
83184

84185
## Who Uses the Test Suite
85186

@@ -153,12 +254,9 @@ This suite is being used by:
153254

154255
### Node.js
155256

156-
For node.js developers, the suite is also available as an
157-
[npm](https://www.npmjs.com/package/@json-schema-org/tests) package.
257+
For node.js developers, the suite is also available as an [npm](https://www.npmjs.com/package/@json-schema-org/tests) package.
158258

159-
Node-specific support is maintained in a [separate
160-
repository](https://github.com/json-schema-org/json-schema-test-suite-npm)
161-
which also welcomes your contributions!
259+
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!
162260

163261
### .NET
164262

remotes/locationIndependentIdentifier.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"definitions": {
2+
"$defs": {
33
"refToInteger": {
44
"$ref": "#foo"
55
},

tests/draft-next/anchor.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,5 +169,36 @@
169169
"valid": false
170170
}
171171
]
172+
},
173+
{
174+
"description": "non-schema object containing an $anchor property",
175+
"schema": {
176+
"$defs": {
177+
"const_not_anchor": {
178+
"const": {
179+
"$anchor": "not_a_real_anchor"
180+
}
181+
}
182+
},
183+
"if": {
184+
"const": "skip not_a_real_anchor"
185+
},
186+
"then": true,
187+
"else" : {
188+
"$ref": "#/$defs/const_not_anchor"
189+
}
190+
},
191+
"tests": [
192+
{
193+
"description": "skip traversing definition for a valid result",
194+
"data": "skip not_a_real_anchor",
195+
"valid": true
196+
},
197+
{
198+
"description": "const at const_not_anchor does not match",
199+
"data": 1,
200+
"valid": false
201+
}
202+
]
172203
}
173204
]

tests/draft-next/id.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,5 +254,36 @@
254254
"valid": false
255255
}
256256
]
257+
},
258+
{
259+
"description": "non-schema object containing an $id property",
260+
"schema": {
261+
"$defs": {
262+
"const_not_id": {
263+
"const": {
264+
"$id": "not_a_real_id"
265+
}
266+
}
267+
},
268+
"if": {
269+
"const": "skip not_a_real_id"
270+
},
271+
"then": true,
272+
"else" : {
273+
"$ref": "#/$defs/const_not_id"
274+
}
275+
},
276+
"tests": [
277+
{
278+
"description": "skip traversing definition for a valid result",
279+
"data": "skip not_a_real_id",
280+
"valid": true
281+
},
282+
{
283+
"description": "const at const_not_id does not match",
284+
"data": 1,
285+
"valid": false
286+
}
287+
]
257288
}
258289
]

tests/draft-next/maxContains.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,25 @@
8686
}
8787
]
8888
},
89+
{
90+
"description": "maxContains with contains, value with a decimal",
91+
"schema": {
92+
"contains": {"const": 1},
93+
"maxContains": 1.0
94+
},
95+
"tests": [
96+
{
97+
"description": "one element matches, valid maxContains",
98+
"data": [ 1 ],
99+
"valid": true
100+
},
101+
{
102+
"description": "too many elements match, invalid maxContains",
103+
"data": [ 1, 1 ],
104+
"valid": false
105+
}
106+
]
107+
},
89108
{
90109
"description": "minContains < maxContains",
91110
"schema": {

tests/draft-next/maxItems.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,21 @@
2424
"valid": true
2525
}
2626
]
27+
},
28+
{
29+
"description": "maxItems validation with a decimal",
30+
"schema": {"maxItems": 2.0},
31+
"tests": [
32+
{
33+
"description": "shorter is valid",
34+
"data": [1],
35+
"valid": true
36+
},
37+
{
38+
"description": "too long is invalid",
39+
"data": [1, 2, 3],
40+
"valid": false
41+
}
42+
]
2743
}
2844
]

tests/draft-next/maxLength.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,21 @@
2929
"valid": true
3030
}
3131
]
32+
},
33+
{
34+
"description": "maxLength validation with a decimal",
35+
"schema": {"maxLength": 2.0},
36+
"tests": [
37+
{
38+
"description": "shorter is valid",
39+
"data": "f",
40+
"valid": true
41+
},
42+
{
43+
"description": "too long is invalid",
44+
"data": "foo",
45+
"valid": false
46+
}
47+
]
3248
}
3349
]

0 commit comments

Comments
 (0)