Skip to content

Commit 784f5d9

Browse files
committed
Update the test suite.
1 parent 7f2950e commit 784f5d9

39 files changed

+2130
-48
lines changed

json/.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
language: python
22
python: "2.7"
33
install: pip install jsonschema
4-
script: bin/suite_sanity_check -v
4+
script: bin/jsonschema_suite check

json/README.md

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -56,41 +56,17 @@ Currently, draft 3 should have essentially full coverage for the core schema.
5656

5757
The beginnings of draft 4 are underway.
5858

59-
Optional Tests
60-
--------------
61-
62-
Tests for optional validation are available in the "optional" directory,
63-
including for bignums (large integers), and for several of the values of the
64-
"format" property.
65-
66-
Values of "format" covered are:
67-
68-
* regex
69-
* date-time
70-
* date
71-
* time
72-
* uri
73-
* email
74-
* ip-address
75-
* ipv6
76-
* host-name
77-
* color
78-
79-
Those also mentioned in draft 3, but currently omitted in the tests are:
80-
81-
* utc-millisec
82-
* style
83-
* phone
84-
8559
Who Uses the Test Suite
8660
-----------------------
8761

8862
This suite is being used by:
8963

64+
* [json-schema-validator (Java)](https://github.com/fge/json-schema-validator)
9065
* [jsonschema (python)](https://github.com/Julian/jsonschema)
9166
* [aeson-schema (haskell)](https://github.com/timjb/aeson-schema)
9267
* [direct-schema (javascript)](https://github.com/IreneKnapp/direct-schema)
9368
* [jsonschema (javascript)](https://github.com/tdegrunt/jsonschema)
69+
* [JaySchema (javascript)](https://github.com/natesilva/jayschema)
9470

9571
If you use it as well, please fork and send a pull request adding yourself to
9672
the list :).

json/bin/suite_sanity_check renamed to json/bin/jsonschema_suite

Lines changed: 61 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
#! /usr/bin/env python
2-
from unittest import TestCase, skipIf
2+
import argparse
33
import fnmatch
44
import json
55
import logging
66
import os
7+
import random
8+
import sys
9+
import unittest
710

811
try:
912
import jsonschema
@@ -37,7 +40,7 @@ TESTSUITE_SCHEMA = {
3740
}
3841
},
3942
"additionalProperties": False,
40-
"minItems": 1
43+
"minItems": 1
4144
}
4245
}
4346

@@ -67,7 +70,7 @@ def collect(root_dir):
6770
yield os.path.join(root, filename)
6871

6972

70-
class SanityTests(TestCase):
73+
class SanityTests(unittest.TestCase):
7174
@classmethod
7275
def setUpClass(cls):
7376
logging.info("Looking for tests in %s", SUITE_ROOT_DIR)
@@ -101,16 +104,22 @@ class SanityTests(TestCase):
101104
"%r contains a duplicate description" % (group,)
102105
)
103106

104-
@skipIf(jsonschema is None, "Validation library not present! Skipping.")
107+
@unittest.skipIf(jsonschema is None, "Validation library not present!")
105108
def test_all_schemas_are_valid(self):
106-
for case in cases(self.test_files):
107-
# XXX: Add the other versions for the other drafts
108-
try:
109-
jsonschema.Draft3Validator.check_schema(case["schema"])
110-
except jsonschema.SchemaError as error:
111-
self.fail("%s contains an invalid schema (%s)" % (case, error))
112-
113-
@skipIf(jsonschema is None, "Validation library not present! Skipping.")
109+
for schema in os.listdir(SUITE_ROOT_DIR):
110+
schema_validator = jsonschema.validators.get(schema)
111+
if schema_validator:
112+
test_files = collect(os.path.join(SUITE_ROOT_DIR, schema))
113+
for case in cases(test_files):
114+
try:
115+
schema_validator.check_schema(case["schema"])
116+
except jsonschema.SchemaError as error:
117+
self.fail("%s contains an invalid schema (%s)" %
118+
(case, error))
119+
else:
120+
logging.warning("No schema validator for %s" % schema)
121+
122+
@unittest.skipIf(jsonschema is None, "Validation library not present!")
114123
def test_suites_are_valid(self):
115124
validator = jsonschema.Draft3Validator(TESTSUITE_SCHEMA)
116125
for tests in files(self.test_files):
@@ -120,6 +129,44 @@ class SanityTests(TestCase):
120129
self.fail(str(error))
121130

122131

132+
def main(arguments):
133+
if arguments.command == "check":
134+
suite = unittest.TestLoader().loadTestsFromTestCase(SanityTests)
135+
result = unittest.TextTestRunner(verbosity=2).run(suite)
136+
sys.exit(not result.wasSuccessful())
137+
elif arguments.command == "flatten":
138+
selected_cases = [case for case in cases(collect(arguments.version))]
139+
140+
if arguments.randomize:
141+
random.shuffle(selected_cases)
142+
143+
json.dump(selected_cases, arguments.out, indent=4)
144+
145+
146+
parser = argparse.ArgumentParser(
147+
description="JSON Schema Test Suite utilities",
148+
)
149+
subparsers = parser.add_subparsers(help="utility commands", dest="command")
150+
151+
check = subparsers.add_parser("check", help="Sanity check the test suite.")
152+
153+
flatten = subparsers.add_parser(
154+
"flatten",
155+
help="Output a flattened file containing the test cases and any "
156+
"additionally specified optional test cases."
157+
)
158+
flatten.add_argument(
159+
"--randomize",
160+
action="store_true",
161+
help="randomize the order of the outputted cases",
162+
)
163+
flatten.add_argument(
164+
"version", help="the directory containing the version to output",
165+
)
166+
flatten.add_argument(
167+
"out", help="the output file to write to", type=argparse.FileType("w"),
168+
)
169+
170+
123171
if __name__ == "__main__":
124-
from unittest import main
125-
main()
172+
main(parser.parse_args())

json/tests/draft3/optional/bignum.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,19 @@
3131
"valid": false
3232
}
3333
]
34+
},
35+
{
36+
"description": "float comparison with high precision",
37+
"schema": {
38+
"maximum": 972783798187987123879878123.18878137,
39+
"exclusiveMaximum": true
40+
},
41+
"tests": [
42+
{
43+
"description": "comparison works for high numbers",
44+
"data": 972783798187987123879878123.188781371,
45+
"valid": false
46+
}
47+
]
3448
}
3549
]

json/tests/draft3/optional/format.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
"tests": [
2222
{
2323
"description": "a valid date-time string",
24-
"data": "1963-06-19T08:30:06.283185",
24+
"data": "1963-06-19T08:30:06.283185Z",
2525
"valid": true
2626
},
2727
{
@@ -204,4 +204,4 @@
204204
}
205205
]
206206
}
207-
]
207+
]
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
[
2+
{
3+
"description": "ECMA 262 regex dialect recognition",
4+
"schema": { "format": "pattern" },
5+
"tests": [
6+
{
7+
"description": "[^] is a valid regex",
8+
"data": "[^]",
9+
"valid": true
10+
},
11+
{
12+
"description": "ECMA 262 has no support for lookbehind",
13+
"data": "(?<=foo)bar",
14+
"valid": false
15+
}
16+
]
17+
}
18+
]
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[
2+
{
3+
"description": "some languages do not distinguish between different types of numeric value",
4+
"schema": {
5+
"type": "integer"
6+
},
7+
"tests": [
8+
{
9+
"description": "a float is not an integer even without fractional part",
10+
"data": 1.0,
11+
"valid": false
12+
}
13+
]
14+
}
15+
]

json/tests/draft3/patternProperties.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,5 +75,36 @@
7575
"valid": false
7676
}
7777
]
78+
},
79+
{
80+
"description": "regexes are not anchored by default and are case sensitive",
81+
"schema": {
82+
"patternProperties": {
83+
"[0-9]{2,}": { "type": "boolean" },
84+
"X_": { "type": "string" }
85+
}
86+
},
87+
"tests": [
88+
{
89+
"description": "non recognized members are ignored",
90+
"data": { "answer 1": "42" },
91+
"valid": true
92+
},
93+
{
94+
"description": "recognized members are accounted for",
95+
"data": { "a31b": null },
96+
"valid": false
97+
},
98+
{
99+
"description": "regexes are case sensitive",
100+
"data": { "a_x_3": 3 },
101+
"valid": true
102+
},
103+
{
104+
"description": "regexes are case sensitive, 2",
105+
"data": { "a_X_3": 3 },
106+
"valid": false
107+
}
108+
]
78109
}
79110
]

json/tests/draft3/type.json

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,6 @@
1313
"data": 1.1,
1414
"valid": false
1515
},
16-
{
17-
"description": "a float is not an integer even without fractional part",
18-
"data": 1.0,
19-
"valid": false
20-
},
2116
{
2217
"description": "a string is not an integer",
2318
"data": "foo",
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
[
2+
{
3+
"description": "additionalItems as schema",
4+
"schema": {
5+
"items": [{}],
6+
"additionalItems": {"type": "integer"}
7+
},
8+
"tests": [
9+
{
10+
"description": "additional items match schema",
11+
"data": [ null, 2, 3, 4 ],
12+
"valid": true
13+
},
14+
{
15+
"description": "additional items do not match schema",
16+
"data": [ null, 2, 3, "foo" ],
17+
"valid": false
18+
}
19+
]
20+
},
21+
{
22+
"description": "items is schema, no additionalItems",
23+
"schema": {
24+
"items": {},
25+
"additionalItems": false
26+
},
27+
"tests": [
28+
{
29+
"description": "all items match schema",
30+
"data": [ 1, 2, 3, 4, 5 ],
31+
"valid": true
32+
}
33+
]
34+
},
35+
{
36+
"description": "array of items with no additionalItems",
37+
"schema": {
38+
"items": [{}, {}, {}],
39+
"additionalItems": false
40+
},
41+
"tests": [
42+
{
43+
"description": "no additional items present",
44+
"data": [ 1, 2, 3 ],
45+
"valid": true
46+
},
47+
{
48+
"description": "additional items are not permitted",
49+
"data": [ 1, 2, 3, 4 ],
50+
"valid": false
51+
}
52+
]
53+
},
54+
{
55+
"description": "additionalItems as false without items",
56+
"schema": {"additionalItems": false},
57+
"tests": [
58+
{
59+
"description":
60+
"items defaults to empty schema so everything is valid",
61+
"data": [ 1, 2, 3, 4, 5 ],
62+
"valid": true
63+
},
64+
{
65+
"description": "ignores non-arrays",
66+
"data": {"foo" : "bar"},
67+
"valid": true
68+
}
69+
]
70+
},
71+
{
72+
"description": "additionalItems are allowed by default",
73+
"schema": {"items": [{"type": "integer"}]},
74+
"tests": [
75+
{
76+
"description": "only the first item is validated",
77+
"data": [1, "foo", false],
78+
"valid": true
79+
}
80+
]
81+
}
82+
]

0 commit comments

Comments
 (0)