git.iko.soy/typeable/hjsonschema
on db91ca2 help sign in
.travis.yml+56−67
since splitsnapshots
unifiedsplit
@@ -1,95 +1,84 @@
1−# This Travis job script has been generated by a script via
2−#
3−# make_travis_yml_2.hs 'hjsonschema.cabal'
4−#
5−# For more information, see https://github.com/hvr/multi-ghc-travis
1+# Generated by: https://github.com/hvr/multi-ghc-travis
6#
2#
3+# Removed `cabal check` because I don't want a description field.
4+
7language: c
5language: c
8sudo: false
6sudo: false
9
7
10−git:
11− submodules: false # whether to recursively clone submodules
12−
13cache:
8cache:
14 directories:
9 directories:
10+ - $HOME/.cabsnap
15 - $HOME/.cabal/packages
11 - $HOME/.cabal/packages
16− - $HOME/.cabal/store
17
12
18before_cache:
13before_cache:
19 - rm -fv $HOME/.cabal/packages/hackage.haskell.org/build-reports.log
14 - rm -fv $HOME/.cabal/packages/hackage.haskell.org/build-reports.log
20− # remove files that are regenerated by 'cabal update'
21− - rm -fv $HOME/.cabal/packages/hackage.haskell.org/00-index.*
15+ - rm -fv $HOME/.cabal/packages/hackage.haskell.org/00-index.tar
22− - rm -fv $HOME/.cabal/packages/hackage.haskell.org/*.json
23− - rm -fv $HOME/.cabal/packages/hackage.haskell.org/01-index.cache
24− - rm -fv $HOME/.cabal/packages/hackage.haskell.org/01-index.tar
25− - rm -fv $HOME/.cabal/packages/hackage.haskell.org/01-index.tar.idx
26
16
27matrix:
17matrix:
28 include:
18 include:
29− - compiler: "ghc-8.0.2"
19+ - env: CABALVER=1.18 GHCVER=7.8.4
30− # env: TEST=--disable-tests BENCH=--disable-benchmarks
20+ compiler: ": #GHC 7.8.4"
31− addons: {apt: {packages: [ghc-ppa-tools,cabal-install-head,ghc-8.0.2], sources: [hvr-ghc]}}
21+ addons: {apt: {packages: [cabal-install-1.18,ghc-7.8.4], sources: [hvr-ghc]}}
32− - compiler: "ghc-8.2.2"
22+ - env: CABALVER=1.22 GHCVER=7.10.2
33− # env: TEST=--disable-tests BENCH=--disable-benchmarks
23+ compiler: ": #GHC 7.10.2"
34− addons: {apt: {packages: [ghc-ppa-tools,cabal-install-head,ghc-8.2.2], sources: [hvr-ghc]}}
24+ addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.2], sources: [hvr-ghc]}}
35− - compiler: "ghc-8.4.1"
25+ - env: CABALVER=1.24 GHCVER=8.0.1
36− # env: TEST=--disable-tests BENCH=--disable-benchmarks
26+ compiler: ": #GHC 8.0.1"
37− addons: {apt: {packages: [ghc-ppa-tools,cabal-install-head,ghc-8.4.1], sources: [hvr-ghc]}}
27+ addons: {apt: {packages: [cabal-install-1.24,ghc-8.0.1], sources: [hvr-ghc]}}
38
28
39before_install:
29before_install:
40− - HC=${CC}
41− - HCPKG=${HC/ghc/ghc-pkg}
42 - unset CC
30 - unset CC
43− - PATH=/opt/ghc/bin:/opt/ghc-ppa-tools/bin:$PATH
31+ - export PATH=/opt/ghc/$GHCVER/bin:/opt/cabal/$CABALVER/bin:$PATH
44− - PKGNAME='hjsonschema'
45
32
46install:
33install:
47 - cabal --version
34 - cabal --version
48− - echo "$(${HC} --version) [$(${HC} --print-project-git-commit-id 2> /dev/null || echo '?')]"
35+ - echo "$(ghc --version) [$(ghc --print-project-git-commit-id 2> /dev/null || echo '?')]"
49− - BENCH=${BENCH---enable-benchmarks}
36+ - if [ -f $HOME/.cabal/packages/hackage.haskell.org/00-index.tar.gz ];
50− - TEST=${TEST---enable-tests}
37+ then
51− - HADDOCK=${HADDOCK-true}
38+ zcat $HOME/.cabal/packages/hackage.haskell.org/00-index.tar.gz >
52− - INSTALLED=${INSTALLED-true}
39+ $HOME/.cabal/packages/hackage.haskell.org/00-index.tar;
40+ fi
53 - travis_retry cabal update -v
41 - travis_retry cabal update -v
54− - sed -i.bak 's/^jobs:/-- jobs:/' ${HOME}/.cabal/config
42+ - sed -i 's/^jobs:/-- jobs:/' ${HOME}/.cabal/config
55− - rm -fv cabal.project.local
43+ - cabal install --only-dependencies --enable-tests --enable-benchmarks --dry -v > installplan.txt
56− - "echo 'packages: .' > cabal.project"
44+ - sed -i -e '1,/^Resolving /d' installplan.txt; cat installplan.txt
57− - rm -f cabal.project.freeze
45+
58− - cabal new-build -w ${HC} ${TEST} ${BENCH} --dep -j2 all
46+# check whether current requested install-plan matches cached package-db snapshot
59− - cabal new-build -w ${HC} --disable-tests --disable-benchmarks --dep -j2 all
47+ - if diff -u installplan.txt $HOME/.cabsnap/installplan.txt;
48+ then
49+ echo "cabal build-cache HIT";
50+ rm -rfv .ghc;
51+ cp -a $HOME/.cabsnap/ghc $HOME/.ghc;
52+ cp -a $HOME/.cabsnap/lib $HOME/.cabsnap/share $HOME/.cabsnap/bin $HOME/.cabal/;
53+ else
54+ echo "cabal build-cache MISS";
55+ rm -rf $HOME/.cabsnap;
56+ mkdir -p $HOME/.ghc $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin;
57+ cabal install --only-dependencies --enable-tests --enable-benchmarks;
58+ fi
59+
60+# snapshot package-db on cache miss
61+ - if [ ! -d $HOME/.cabsnap ];
62+ then
63+ echo "snapshotting package-db to build-cache";
64+ mkdir $HOME/.cabsnap;
65+ cp -a $HOME/.ghc $HOME/.cabsnap/ghc;
66+ cp -a $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin installplan.txt $HOME/.cabsnap/;
67+ fi
60
68
61# Here starts the actual work to be performed for the package under test;
69# Here starts the actual work to be performed for the package under test;
62# any command which exits with a non-zero exit code causes the build to fail.
70# any command which exits with a non-zero exit code causes the build to fail.
63script:
71script:
64 - if [ -f configure.ac ]; then autoreconf -i; fi
72 - if [ -f configure.ac ]; then autoreconf -i; fi
65− - rm -rf .ghc.environment.* dist/
73+ - cabal configure --enable-tests --enable-benchmarks -v2 # -v2 provides useful information for debugging
74+ - cabal build # this builds all libraries and executables (including tests/benchmarks)
75+ - cabal test
66− - cabal sdist # test that a source-distribution can be generated
76+ - cabal sdist # tests that a source-distribution can be generated
67− - cd dist/
68− - SRCTAR=(${PKGNAME}-*.tar.gz)
69− - SRC_BASENAME="${SRCTAR/%.tar.gz}"
70− - tar -xvf "./$SRC_BASENAME.tar.gz"
71− - cd "$SRC_BASENAME/"
72−## from here on, CWD is inside the extracted source-tarball
73− - rm -fv cabal.project.local
74− - "echo 'packages: .' > cabal.project"
75− # this builds all libraries and executables (without tests/benchmarks)
76− - rm -f cabal.project.freeze
77− - cabal new-build -w ${HC} --disable-tests --disable-benchmarks all
78− # this builds all libraries and executables (including tests/benchmarks)
79− # - rm -rf ./dist-newstyle
80−
81− # Build with installed constraints for packages in global-db
82− - if $INSTALLED; then
83− echo cabal new-build -w ${HC} --disable-tests --disable-benchmarks $(${HCPKG} list --global --simple-output --names-only | sed 's/\([a-zA-Z0-9-]\{1,\}\) */--constraint="\1 installed" /g') all | sh;
84− else echo "Not building with installed constraints"; fi
85−
86− # build & run tests, build benchmarks
87− - cabal new-build -w ${HC} ${TEST} ${BENCH} all
88− - if [ "x$TEST" = "x--enable-tests" ]; then cabal new-test -w ${HC} ${TEST} all; fi
89
77
90− # haddock
78+# Check that the resulting source distribution can be built & installed.
91− - rm -rf ./dist-newstyle
79+# If there are no other `.tar.gz` files in `dist`, this can be even simpler:
92− - if $HADDOCK; then cabal new-haddock -w ${HC} --disable-tests --disable-benchmarks all; else echo "Skipping haddock generation";fi
80+# `cabal install --force-reinstalls dist/*-*.tar.gz`
81+ - SRC_TGZ=$(cabal info . | awk '{print $2;exit}').tar.gz &&
82+ (cd dist && cabal install --force-reinstalls "$SRC_TGZ")
93
83
94−# REGENDATA ["hjsonschema.cabal"]
95# EOF
84# EOF
JSON-Schema-Test-Suite/.travis.yml+2−7
@@ -1,9 +1,4 @@
1language: python
1language: python
2python: "2.7"
2python: "2.7"
3−node_js: "6"
4−install:
5− - pip install tox
3+install: pip install tox
6− - npm install
7−script:
4+script: tox
8− - tox
9− - npm test
JSON-Schema-Test-Suite/README.md+5−26
@@ -1,4 +1,4 @@
1−JSON Schema Test Suite [![Build Status](https://travis-ci.org/json-schema-org/JSON-Schema-Test-Suite.svg?branch=master)](https://travis-ci.org/json-schema-org/JSON-Schema-Test-Suite)
1+JSON Schema Test Suite [![Build Status](https://travis-ci.org/json-schema/JSON-Schema-Test-Suite.png?branch=develop)](https://travis-ci.org/json-schema/JSON-Schema-Test-Suite)
2======================
2======================
3
3
4This repository contains a set of JSON objects that implementors of JSON Schema
4This repository contains a set of JSON objects that implementors of JSON Schema
@@ -64,18 +64,10 @@ This suite is being used by:
64
64
65* [jsck](https://github.com/pandastrike/jsck)
65* [jsck](https://github.com/pandastrike/jsck)
66
66
67−### C++ ###
68−
69−* [Modern C++ JSON schema validator](https://github.com/pboettch/json-schema-validator)
70−
71### Dart ###
67### Dart ###
72
68
73* [json_schema](https://github.com/patefacio/json_schema)
69* [json_schema](https://github.com/patefacio/json_schema)
74
70
75−### Elixir ###
76−
77−* [ex_json_schema](https://github.com/jonasschmidt/ex_json_schema)
78−
79### Erlang ###
71### Erlang ###
80
72
81* [jesse](https://github.com/klarna/jesse)
73* [jesse](https://github.com/klarna/jesse)
@@ -92,9 +84,7 @@ This suite is being used by:
92
84
93### Java ###
85### Java ###
94
86
95−* [json-schema-validator](https://github.com/daveclayton/json-schema-validator)
87+* [json-schema-validator](https://github.com/fge/json-schema-validator)
96−* [everit-org/json-schema](https://github.com/everit-org/json-schema)
97−* [networknt/json-schema-validator](https://github.com/networknt/json-schema-validator)
98
88
99### JavaScript ###
89### JavaScript ###
100
90
@@ -112,25 +102,22 @@ This suite is being used by:
112* [z-schema](https://github.com/zaggino/z-schema)
102* [z-schema](https://github.com/zaggino/z-schema)
113* [jsen](https://github.com/bugventure/jsen)
103* [jsen](https://github.com/bugventure/jsen)
114* [ajv](https://github.com/epoberezkin/ajv)
104* [ajv](https://github.com/epoberezkin/ajv)
115−* [djv](https://github.com/korzio/djv)
116
105
117### Node.js ###
106### Node.js ###
118
107
119The JSON Schema Test Suite is also available as an
108The JSON Schema Test Suite is also available as an
120[npm](https://www.npmjs.com/package/json-schema-test-suite) package.
109[npm](https://www.npmjs.com/package/json-schema-test-suite) package.
121−Node-specific support is maintained on the [node branch](https://github.com/json-schema-org/JSON-Schema-Test-Suite/tree/node).
110+Node-specific support is maintained on the [node branch](https://github.com/json-schema/JSON-Schema-Test-Suite/tree/node).
122−See [NODE-README.md](https://github.com/json-schema-org/JSON-Schema-Test-Suite/blob/node/NODE-README.md)
111+See [NODE-README.md](https://github.com/json-schema/JSON-Schema-Test-Suite/blob/node/NODE-README.md)
123for more information.
112for more information.
124
113
125### .NET ###
114### .NET ###
126
115
127* [Newtonsoft.Json.Schema](https://github.com/JamesNK/Newtonsoft.Json.Schema)
116* [Newtonsoft.Json.Schema](https://github.com/JamesNK/Newtonsoft.Json.Schema)
128−* [Manatee.Json](https://github.com/gregsdennis/Manatee.Json)
129
117
130### PHP ###
118### PHP ###
131
119
132* [json-schema](https://github.com/justinrainbow/json-schema)
120* [json-schema](https://github.com/justinrainbow/json-schema)
133−* [json-guard](https://github.com/thephpleague/json-guard)
134
121
135### Python ###
122### Python ###
136
123
@@ -148,14 +135,6 @@ for more information.
148
135
149* [JSONSchema](https://github.com/kylef/JSONSchema.swift)
136* [JSONSchema](https://github.com/kylef/JSONSchema.swift)
150
137
151−### Clojure ###
152−
153−* [json-schema](https://github.com/tatut/json-schema)
154−
155−### PostgreSQL ###
156−
157−* [postgres-json-schema](https://github.com/gavinwahl/postgres-json-schema)
158−
159If you use it as well, please fork and send a pull request adding yourself to
138If you use it as well, please fork and send a pull request adding yourself to
160the list :).
139the list :).
161
140
@@ -165,5 +144,5 @@ Contributing
165If you see something missing or incorrect, a pull request is most welcome!
144If you see something missing or incorrect, a pull request is most welcome!
166
145
167There are some sanity checks in place for testing the test suite. You can run
146There are some sanity checks in place for testing the test suite. You can run
168−them with `bin/jsonschema_suite check && npm test` or `tox && npm test`. They will be run automatically by
147+them with `bin/jsonschema_suite check` or `tox`. They will be run automatically by
169[Travis CI](https://travis-ci.org/) as well.
148[Travis CI](https://travis-ci.org/) as well.
JSON-Schema-Test-Suite/bin/jsonschema_suite+27−2
@@ -52,8 +52,33 @@ REMOTES = {
52}
52}
53REMOTES_DIR = os.path.join(ROOT_DIR, "remotes")
53REMOTES_DIR = os.path.join(ROOT_DIR, "remotes")
54
54
55−with open(os.path.join(ROOT_DIR, "test-schema.json")) as schema:
56− TESTSUITE_SCHEMA = json.load(schema)
55+TESTSUITE_SCHEMA = {
56+ "$schema": "http://json-schema.org/draft-03/schema#",
57+ "type": "array",
58+ "items": {
59+ "type": "object",
60+ "properties": {
61+ "description": {"type": "string", "required": True},
62+ "schema": {"required": True},
63+ "tests": {
64+ "type": "array",
65+ "items": {
66+ "type": "object",
67+ "properties": {
68+ "description": {"type": "string", "required": True},
69+ "data": {"required": True},
70+ "valid": {"type": "boolean", "required": True}
71+ },
72+ "additionalProperties": False
73+ },
74+ "minItems": 1
75+ }
76+ },
77+ "additionalProperties": False,
78+ "minItems": 1
79+ }
80+}
81+
57
82
58def files(paths):
83def files(paths):
59 for path in paths:
84 for path in paths:
JSON-Schema-Test-Suite/index.jsdeleted−32
@@ -1,32 +0,0 @@
1−'use strict';
2−
3−var Ajv = require('ajv');
4−var jsonSchemaTest = require('json-schema-test');
5−var assert = require('assert');
6−
7−var refs = {
8− 'http://localhost:1234/integer.json': require('./remotes/integer.json'),
9− 'http://localhost:1234/subSchemas.json': require('./remotes/subSchemas.json'),
10− 'http://localhost:1234/folder/folderInteger.json': require('./remotes/folder/folderInteger.json'),
11− 'http://localhost:1234/name.json': require('./remotes/name.json')
12−};
13−
14−runTest(4);
15−runTest(6);
16−
17−function runTest(draft) {
18− var opts = {};
19− if (draft == 4) opts.meta = false;
20− var ajv = new Ajv(opts);
21− ajv.addMetaSchema(require('ajv/lib/refs/json-schema-draft-04.json'));
22− if (draft == 4) ajv._opts.defaultMeta = 'http://json-schema.org/draft-04/schema#';
23− for (var uri in refs) ajv.addSchema(refs[uri], uri);
24−
25− jsonSchemaTest(ajv, {
26− description: 'Test suite draft-0' + draft,
27− suites: {tests: './tests/draft' + draft + '/{**/,}*.json'},
28− skip: draft == 4 ? ['optional/zeroTerminatedFloats'] : [],
29− cwd: __dirname,
30− hideFolder: 'tests/'
31− });
32−}
JSON-Schema-Test-Suite/package.jsondeleted−28
@@ -1,28 +0,0 @@
1−{
2− "name": "json-schema-test-suite",
3− "version": "0.1.0",
4− "description": "A language agnostic test suite for the JSON Schema specifications",
5− "main": "index.js",
6− "scripts": {
7− "test": "mocha index.js -R spec"
8− },
9− "repository": {
10− "type": "git",
11− "url": "git+https://github.com/json-schema-org/JSON-Schema-Test-Suite.git"
12− },
13− "keywords": [
14− "json-schema",
15− "tests"
16− ],
17− "author": "http://json-schema.org",
18− "license": "MIT",
19− "bugs": {
20− "url": "https://github.com/json-schema-org/JSON-Schema-Test-Suite/issues"
21− },
22− "homepage": "https://github.com/json-schema-org/JSON-Schema-Test-Suite#readme",
23− "devDependencies": {
24− "ajv": "^5.0.4-beta.0",
25− "json-schema-test": "^1.3.0",
26− "mocha": "^3.2.0"
27− }
28−}
JSON-Schema-Test-Suite/remotes/name.jsondeleted−11
@@ -1,11 +0,0 @@
1−{
2− "definitions": {
3− "orNull": {
4− "anyOf": [
5− {"type": "null"},
6− {"$ref": "#"}
7− ]
8− }
9− },
10− "type": "string"
11−}
JSON-Schema-Test-Suite/test-schema.jsondeleted−28
@@ -1,28 +0,0 @@
1−{
2− "$schema": "http://json-schema.org/draft-04/schema#",
3− "type": "array",
4− "items": {
5− "type": "object",
6− "required": ["description", "schema", "tests"],
7− "properties": {
8− "description": {"type": "string"},
9− "schema": {},
10− "tests": {
11− "type": "array",
12− "items": {
13− "type": "object",
14− "required": ["description", "data", "valid"],
15− "properties": {
16− "description": {"type": "string"},
17− "data": {},
18− "valid": {"type": "boolean"}
19− },
20− "additionalProperties": false
21− },
22− "minItems": 1
23− }
24− },
25− "additionalProperties": false,
26− "minItems": 1
27− }
28−}
JSON-Schema-Test-Suite/tests/draft3/optional/format.json+2−2
@@ -78,9 +78,9 @@
78 "valid": true
78 "valid": true
79 },
79 },
80 {
80 {
81− "description": "an invalid protocol-relative URI Reference",
81+ "description": "a valid protocol-relative URI",
82 "data": "//foo.bar/?baz=qux#quux",
82 "data": "//foo.bar/?baz=qux#quux",
83− "valid": false
83+ "valid": true
84 },
84 },
85 {
85 {
86 "description": "an invalid URI",
86 "description": "an invalid URI",
JSON-Schema-Test-Suite/tests/draft3/ref.json−33
@@ -140,39 +140,6 @@
140 }
140 }
141 ]
141 ]
142 },
142 },
143− {
144− "description": "ref overrides any sibling keywords",
145− "schema": {
146− "definitions": {
147− "reffed": {
148− "type": "array"
149− }
150− },
151− "properties": {
152− "foo": {
153− "$ref": "#/definitions/reffed",
154− "maxItems": 2
155− }
156− }
157− },
158− "tests": [
159− {
160− "description": "remote ref valid",
161− "data": { "foo": [] },
162− "valid": true
163− },
164− {
165− "description": "remote ref valid, maxItems ignored",
166− "data": { "foo": [ 1, 2, 3] },
167− "valid": true
168− },
169− {
170− "description": "ref invalid",
171− "data": { "foo": "string" },
172− "valid": false
173− }
174− ]
175− },
176 {
143 {
177 "description": "remote ref, containing refs itself",
144 "description": "remote ref, containing refs itself",
178 "schema": {"$ref": "http://json-schema.org/draft-03/schema#"},
145 "schema": {"$ref": "http://json-schema.org/draft-03/schema#"},
JSON-Schema-Test-Suite/tests/draft3/type.json−15
@@ -18,11 +18,6 @@
18 "data": "foo",
18 "data": "foo",
19 "valid": false
19 "valid": false
20 },
20 },
21− {
22− "description": "a string is still not an integer, even if it looks like one",
23− "data": "1",
24− "valid": false
25− },
26 {
21 {
27 "description": "an object is not an integer",
22 "description": "an object is not an integer",
28 "data": {},
23 "data": {},
@@ -64,11 +59,6 @@
64 "data": "foo",
59 "data": "foo",
65 "valid": false
60 "valid": false
66 },
61 },
67− {
68− "description": "a string is still not a number, even if it looks like one",
69− "data": "1",
70− "valid": false
71− },
72 {
62 {
73 "description": "an object is not a number",
63 "description": "an object is not a number",
74 "data": {},
64 "data": {},
@@ -110,11 +100,6 @@
110 "data": "foo",
100 "data": "foo",
111 "valid": true
101 "valid": true
112 },
102 },
113− {
114− "description": "a string is still a string, even if it looks like a number",
115− "data": "1",
116− "valid": true
117− },
118 {
103 {
119 "description": "an object is not a string",
104 "description": "an object is not a string",
120 "data": {},
105 "data": {},
JSON-Schema-Test-Suite/tests/draft4/additionalItems.json+1−6
@@ -40,12 +40,7 @@
40 },
40 },
41 "tests": [
41 "tests": [
42 {
42 {
43− "description": "fewer number of items present",
43+ "description": "no additional items present",
44− "data": [ 1, 2 ],
45− "valid": true
46− },
47− {
48− "description": "equal number of items present",
49 "data": [ 1, 2, 3 ],
44 "data": [ 1, 2, 3 ],
50 "valid": true
45 "valid": true
51 },
46 },
JSON-Schema-Test-Suite/tests/draft4/items.json−32
@@ -19,14 +19,6 @@
19 "description": "ignores non-arrays",
19 "description": "ignores non-arrays",
20 "data": {"foo" : "bar"},
20 "data": {"foo" : "bar"},
21 "valid": true
21 "valid": true
22− },
23− {
24− "description": "JavaScript pseudo-array is valid",
25− "data": {
26− "0": "invalid",
27− "length": 1
28− },
29− "valid": true
30 }
22 }
31 ]
23 ]
32 },
24 },
@@ -48,30 +40,6 @@
48 "description": "wrong types",
40 "description": "wrong types",
49 "data": [ "foo", 1 ],
41 "data": [ "foo", 1 ],
50 "valid": false
42 "valid": false
51− },
52− {
53− "description": "incomplete array of items",
54− "data": [ 1 ],
55− "valid": true
56− },
57− {
58− "description": "array with additional items",
59− "data": [ 1, "foo", true ],
60− "valid": true
61− },
62− {
63− "description": "empty array",
64− "data": [ ],
65− "valid": true
66− },
67− {
68− "description": "JavaScript pseudo-array is valid",
69− "data": {
70− "0": "invalid",
71− "1": "valid",
72− "length": 2
73− },
74− "valid": true
75 }
43 }
76 ]
44 ]
77 }
45 }
JSON-Schema-Test-Suite/tests/draft4/maximum.json−5
@@ -8,11 +8,6 @@
8 "data": 2.6,
8 "data": 2.6,
9 "valid": true
9 "valid": true
10 },
10 },
11− {
12− "description": "boundary point is valid",
13− "data": 3.0,
14− "valid": true
15− },
16 {
11 {
17 "description": "above the maximum is invalid",
12 "description": "above the maximum is invalid",
18 "data": 3.5,
13 "data": 3.5,
JSON-Schema-Test-Suite/tests/draft4/minimum.json−5
@@ -8,11 +8,6 @@
8 "data": 2.6,
8 "data": 2.6,
9 "valid": true
9 "valid": true
10 },
10 },
11− {
12− "description": "boundary point is valid",
13− "data": 1.1,
14− "valid": true
15− },
16 {
11 {
17 "description": "below the minimum is invalid",
12 "description": "below the minimum is invalid",
18 "data": 0.6,
13 "data": 0.6,
JSON-Schema-Test-Suite/tests/draft4/optional/ecmascript-regex.jsondeleted−13
@@ -1,13 +0,0 @@
1−[
2− {
3− "description": "ECMA 262 regex non-compliance",
4− "schema": { "format": "regex" },
5− "tests": [
6− {
7− "description": "ECMA 262 has no support for \\Z anchor from .NET",
8− "data": "^\\S(|(.|\\n)*\\S)\\Z",
9− "valid": false
10− }
11− ]
12− }
13−]
JSON-Schema-Test-Suite/tests/draft4/optional/format.json+2−2
@@ -30,9 +30,9 @@
30 "valid": true
30 "valid": true
31 },
31 },
32 {
32 {
33− "description": "an invalid protocol-relative URI Reference",
33+ "description": "a valid protocol-relative URI",
34 "data": "//foo.bar/?baz=qux#quux",
34 "data": "//foo.bar/?baz=qux#quux",
35− "valid": false
35+ "valid": true
36 },
36 },
37 {
37 {
38 "description": "an invalid URI",
38 "description": "an invalid URI",
JSON-Schema-Test-Suite/tests/draft4/ref.json−139
@@ -140,39 +140,6 @@
140 }
140 }
141 ]
141 ]
142 },
142 },
143− {
144− "description": "ref overrides any sibling keywords",
145− "schema": {
146− "definitions": {
147− "reffed": {
148− "type": "array"
149− }
150− },
151− "properties": {
152− "foo": {
153− "$ref": "#/definitions/reffed",
154− "maxItems": 2
155− }
156− }
157− },
158− "tests": [
159− {
160− "description": "ref valid",
161− "data": { "foo": [] },
162− "valid": true
163− },
164− {
165− "description": "ref valid, maxItems ignored",
166− "data": { "foo": [ 1, 2, 3] },
167− "valid": true
168− },
169− {
170− "description": "ref invalid",
171− "data": { "foo": "string" },
172− "valid": false
173− }
174− ]
175− },
176 {
143 {
177 "description": "remote ref, containing refs itself",
144 "description": "remote ref, containing refs itself",
178 "schema": {"$ref": "http://json-schema.org/draft-04/schema#"},
145 "schema": {"$ref": "http://json-schema.org/draft-04/schema#"},
@@ -188,111 +155,5 @@
188 "valid": false
155 "valid": false
189 }
156 }
190 ]
157 ]
191− },
192− {
193− "description": "property named $ref that is not a reference",
194− "schema": {
195− "properties": {
196− "$ref": {"type": "string"}
197− }
198− },
199− "tests": [
200− {
201− "description": "property named $ref valid",
202− "data": {"$ref": "a"},
203− "valid": true
204− },
205− {
206− "description": "property named $ref invalid",
207− "data": {"$ref": 2},
208− "valid": false
209− }
210− ]
211− },
212− {
213− "description": "Recursive references between schemas",
214− "schema": {
215− "description": "tree of nodes",
216− "type": "object",
217− "properties": {
218− "meta": {"type": "string"},
219− "nodes": {
220− "type": "array",
221− "items": {"$ref": "#/definitions/node"}
222− }
223− },
224− "required": ["meta", "nodes"],
225− "definitions": {
226− "node": {
227− "description": "node",
228− "type": "object",
229− "properties": {
230− "value": {"type": "number"},
231− "subtree": {"$ref": "#"}
232− },
233− "required": ["value"]
234− }
235− }
236− },
237− "tests": [
238− {
239− "description": "valid tree",
240− "data": {
241− "meta": "root",
242− "nodes": [
243− {
244− "value": 1,
245− "subtree": {
246− "meta": "child",
247− "nodes": [
248− {"value": 1.1},
249− {"value": 1.2}
250− ]
251− }
252− },
253− {
254− "value": 2,
255− "subtree": {
256− "meta": "child",
257− "nodes": [
258− {"value": 2.1},
259− {"value": 2.2}
260− ]
261− }
262− }
263− ]
264− },
265− "valid": true
266− },
267− {
268− "description": "invalid tree",
269− "data": {
270− "meta": "root",
271− "nodes": [
272− {
273− "value": 1,
274− "subtree": {
275− "meta": "child",
276− "nodes": [
277− {"value": "string is invalid"},
278− {"value": 1.2}
279− ]
280− }
281− },
282− {
283− "value": 2,
284− "subtree": {
285− "meta": "child",
286− "nodes": [
287− {"value": 2.1},
288− {"value": 2.2}
289− ]
290− }
291− }
292− ]
293− },
294− "valid": false
295− }
296− ]
297 }
158 }
298]
159]
JSON-Schema-Test-Suite/tests/draft4/refRemote.json+3−100
@@ -50,7 +50,7 @@
50 ]
50 ]
51 },
51 },
52 {
52 {
53− "description": "base URI change",
53+ "description": "change resolution scope",
54 "schema": {
54 "schema": {
55 "id": "http://localhost:1234/",
55 "id": "http://localhost:1234/",
56 "items": {
56 "items": {
@@ -60,112 +60,15 @@
60 },
60 },
61 "tests": [
61 "tests": [
62 {
62 {
63− "description": "base URI change ref valid",
63+ "description": "changed scope ref valid",
64 "data": [[1]],
64 "data": [[1]],
65 "valid": true
65 "valid": true
66 },
66 },
67 {
67 {
68− "description": "base URI change ref invalid",
68+ "description": "changed scope ref invalid",
69 "data": [["a"]],
69 "data": [["a"]],
70 "valid": false
70 "valid": false
71 }
71 }
72 ]
72 ]
73− },
74− {
75− "description": "base URI change - change folder",
76− "schema": {
77− "id": "http://localhost:1234/scope_change_defs1.json",
78− "type" : "object",
79− "properties": {
80− "list": {"$ref": "#/definitions/baz"}
81− },
82− "definitions": {
83− "baz": {
84− "id": "folder/",
85− "type": "array",
86− "items": {"$ref": "folderInteger.json"}
87− }
88− }
89− },
90− "tests": [
91− {
92− "description": "number is valid",
93− "data": {"list": [1]},
94− "valid": true
95− },
96− {
97− "description": "string is invalid",
98− "data": {"list": ["a"]},
99− "valid": false
100− }
101− ]
102− },
103− {
104− "description": "base URI change - change folder in subschema",
105− "schema": {
106− "id": "http://localhost:1234/scope_change_defs2.json",
107− "type" : "object",
108− "properties": {
109− "list": {"$ref": "#/definitions/baz/definitions/bar"}
110− },
111− "definitions": {
112− "baz": {
113− "id": "folder/",
114− "definitions": {
115− "bar": {
116− "type": "array",
117− "items": {"$ref": "folderInteger.json"}
118− }
119− }
120− }
121− }
122− },
123− "tests": [
124− {
125− "description": "number is valid",
126− "data": {"list": [1]},
127− "valid": true
128− },
129− {
130− "description": "string is invalid",
131− "data": {"list": ["a"]},
132− "valid": false
133− }
134− ]
135− },
136− {
137− "description": "root ref in remote ref",
138− "schema": {
139− "id": "http://localhost:1234/object",
140− "type": "object",
141− "properties": {
142− "name": {"$ref": "name.json#/definitions/orNull"}
143− }
144− },
145− "tests": [
146− {
147− "description": "string is valid",
148− "data": {
149− "name": "foo"
150− },
151− "valid": true
152− },
153− {
154− "description": "null is valid",
155− "data": {
156− "name": null
157− },
158− "valid": true
159− },
160− {
161− "description": "object is invalid",
162− "data": {
163− "name": {
164− "name": null
165− }
166− },
167− "valid": false
168− }
169− ]
170 }
73 }
171]
74]
JSON-Schema-Test-Suite/tests/draft4/required.json−5
@@ -18,11 +18,6 @@
18 "description": "non-present required property is invalid",
18 "description": "non-present required property is invalid",
19 "data": {"bar": 1},
19 "data": {"bar": 1},
20 "valid": false
20 "valid": false
21− },
22− {
23− "description": "ignores non-objects",
24− "data": 12,
25− "valid": true
26 }
21 }
27 ]
22 ]
28 },
23 },
JSON-Schema-Test-Suite/tests/draft4/type.json−15
@@ -18,11 +18,6 @@
18 "data": "foo",
18 "data": "foo",
19 "valid": false
19 "valid": false
20 },
20 },
21− {
22− "description": "a string is still not an integer, even if it looks like one",
23− "data": "1",
24− "valid": false
25− },
26 {
21 {
27 "description": "an object is not an integer",
22 "description": "an object is not an integer",
28 "data": {},
23 "data": {},
@@ -64,11 +59,6 @@
64 "data": "foo",
59 "data": "foo",
65 "valid": false
60 "valid": false
66 },
61 },
67− {
68− "description": "a string is still not a number, even if it looks like one",
69− "data": "1",
70− "valid": false
71− },
72 {
62 {
73 "description": "an object is not a number",
63 "description": "an object is not a number",
74 "data": {},
64 "data": {},
@@ -110,11 +100,6 @@
110 "data": "foo",
100 "data": "foo",
111 "valid": true
101 "valid": true
112 },
102 },
113− {
114− "description": "a string is still a string, even if it looks like a number",
115− "data": "1",
116− "valid": true
117− },
118 {
103 {
119 "description": "an object is not a string",
104 "description": "an object is not a string",
120 "data": {},
105 "data": {},
JSON-Schema-Test-Suite/tests/draft6/additionalItems.jsondeleted−87
@@ -1,87 +0,0 @@
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": "fewer number of items present",
44− "data": [ 1, 2 ],
45− "valid": true
46− },
47− {
48− "description": "equal number of items present",
49− "data": [ 1, 2, 3 ],
50− "valid": true
51− },
52− {
53− "description": "additional items are not permitted",
54− "data": [ 1, 2, 3, 4 ],
55− "valid": false
56− }
57− ]
58− },
59− {
60− "description": "additionalItems as false without items",
61− "schema": {"additionalItems": false},
62− "tests": [
63− {
64− "description":
65− "items defaults to empty schema so everything is valid",
66− "data": [ 1, 2, 3, 4, 5 ],
67− "valid": true
68− },
69− {
70− "description": "ignores non-arrays",
71− "data": {"foo" : "bar"},
72− "valid": true
73− }
74− ]
75− },
76− {
77− "description": "additionalItems are allowed by default",
78− "schema": {"items": [{"type": "integer"}]},
79− "tests": [
80− {
81− "description": "only the first item is validated",
82− "data": [1, "foo", false],
83− "valid": true
84− }
85− ]
86− }
87−]
JSON-Schema-Test-Suite/tests/draft6/additionalProperties.jsondeleted−88
@@ -1,88 +0,0 @@
1−[
2− {
3− "description":
4− "additionalProperties being false does not allow other properties",
5− "schema": {
6− "properties": {"foo": {}, "bar": {}},
7− "patternProperties": { "^v": {} },
8− "additionalProperties": false
9− },
10− "tests": [
11− {
12− "description": "no additional properties is valid",
13− "data": {"foo": 1},
14− "valid": true
15− },
16− {
17− "description": "an additional property is invalid",
18− "data": {"foo" : 1, "bar" : 2, "quux" : "boom"},
19− "valid": false
20− },
21− {
22− "description": "ignores non-objects",
23− "data": [1, 2, 3],
24− "valid": true
25− },
26− {
27− "description": "patternProperties are not additional properties",
28− "data": {"foo":1, "vroom": 2},
29− "valid": true
30− }
31− ]
32− },
33− {
34− "description":
35− "additionalProperties allows a schema which should validate",
36− "schema": {
37− "properties": {"foo": {}, "bar": {}},
38− "additionalProperties": {"type": "boolean"}
39− },
40− "tests": [
41− {
42− "description": "no additional properties is valid",
43− "data": {"foo": 1},
44− "valid": true
45− },
46− {
47− "description": "an additional valid property is valid",
48− "data": {"foo" : 1, "bar" : 2, "quux" : true},
49− "valid": true
50− },
51− {
52− "description": "an additional invalid property is invalid",
53− "data": {"foo" : 1, "bar" : 2, "quux" : 12},
54− "valid": false
55− }
56− ]
57− },
58− {
59− "description":
60− "additionalProperties can exist by itself",
61− "schema": {
62− "additionalProperties": {"type": "boolean"}
63− },
64− "tests": [
65− {
66− "description": "an additional valid property is valid",
67− "data": {"foo" : true},
68− "valid": true
69− },
70− {
71− "description": "an additional invalid property is invalid",
72− "data": {"foo" : 1},
73− "valid": false
74− }
75− ]
76− },
77− {
78− "description": "additionalProperties are allowed by default",
79− "schema": {"properties": {"foo": {}, "bar": {}}},
80− "tests": [
81− {
82− "description": "additional properties are allowed",
83− "data": {"foo": 1, "bar": 2, "quux": true},
84− "valid": true
85− }
86− ]
87− }
88−]
JSON-Schema-Test-Suite/tests/draft6/allOf.jsondeleted−145
@@ -1,145 +0,0 @@
1−[
2− {
3− "description": "allOf",
4− "schema": {
5− "allOf": [
6− {
7− "properties": {
8− "bar": {"type": "integer"}
9− },
10− "required": ["bar"]
11− },
12− {
13− "properties": {
14− "foo": {"type": "string"}
15− },
16− "required": ["foo"]
17− }
18− ]
19− },
20− "tests": [
21− {
22− "description": "allOf",
23− "data": {"foo": "baz", "bar": 2},
24− "valid": true
25− },
26− {
27− "description": "mismatch second",
28− "data": {"foo": "baz"},
29− "valid": false
30− },
31− {
32− "description": "mismatch first",
33− "data": {"bar": 2},
34− "valid": false
35− },
36− {
37− "description": "wrong type",
38− "data": {"foo": "baz", "bar": "quux"},
39− "valid": false
40− }
41− ]
42− },
43− {
44− "description": "allOf with base schema",
45− "schema": {
46− "properties": {"bar": {"type": "integer"}},
47− "required": ["bar"],
48− "allOf" : [
49− {
50− "properties": {
51− "foo": {"type": "string"}
52− },
53− "required": ["foo"]
54− },
55− {
56− "properties": {
57− "baz": {"type": "null"}
58− },
59− "required": ["baz"]
60− }
61− ]
62− },
63− "tests": [
64− {
65− "description": "valid",
66− "data": {"foo": "quux", "bar": 2, "baz": null},
67− "valid": true
68− },
69− {
70− "description": "mismatch base schema",
71− "data": {"foo": "quux", "baz": null},
72− "valid": false
73− },
74− {
75− "description": "mismatch first allOf",
76− "data": {"bar": 2, "baz": null},
77− "valid": false
78− },
79− {
80− "description": "mismatch second allOf",
81− "data": {"foo": "quux", "bar": 2},
82− "valid": false
83− },
84− {
85− "description": "mismatch both",
86− "data": {"bar": 2},
87− "valid": false
88− }
89− ]
90− },
91− {
92− "description": "allOf simple types",
93− "schema": {
94− "allOf": [
95− {"maximum": 30},
96− {"minimum": 20}
97− ]
98− },
99− "tests": [
100− {
101− "description": "valid",
102− "data": 25,
103− "valid": true
104− },
105− {
106− "description": "mismatch one",
107− "data": 35,
108− "valid": false
109− }
110− ]
111− },
112− {
113− "description": "allOf with boolean schemas, all true",
114− "schema": {"allOf": [true, true]},
115− "tests": [
116− {
117− "description": "any value is valid",
118− "data": "foo",
119− "valid": true
120− }
121− ]
122− },
123− {
124− "description": "allOf with boolean schemas, some false",
125− "schema": {"allOf": [true, false]},
126− "tests": [
127− {
128− "description": "any value is invalid",
129− "data": "foo",
130− "valid": false
131− }
132− ]
133− },
134− {
135− "description": "allOf with boolean schemas, all false",
136− "schema": {"allOf": [false, false]},
137− "tests": [
138− {
139− "description": "any value is invalid",
140− "data": "foo",
141− "valid": false
142− }
143− ]
144− }
145−]
JSON-Schema-Test-Suite/tests/draft6/anyOf.jsondeleted−101
@@ -1,101 +0,0 @@
1−[
2− {
3− "description": "anyOf",
4− "schema": {
5− "anyOf": [
6− {
7− "type": "integer"
8− },
9− {
10− "minimum": 2
11− }
12− ]
13− },
14− "tests": [
15− {
16− "description": "first anyOf valid",
17− "data": 1,
18− "valid": true
19− },
20− {
21− "description": "second anyOf valid",
22− "data": 2.5,
23− "valid": true
24− },
25− {
26− "description": "both anyOf valid",
27− "data": 3,
28− "valid": true
29− },
30− {
31− "description": "neither anyOf valid",
32− "data": 1.5,
33− "valid": false
34− }
35− ]
36− },
37− {
38− "description": "anyOf with base schema",
39− "schema": {
40− "type": "string",
41− "anyOf" : [
42− {
43− "maxLength": 2
44− },
45− {
46− "minLength": 4
47− }
48− ]
49− },
50− "tests": [
51− {
52− "description": "mismatch base schema",
53− "data": 3,
54− "valid": false
55− },
56− {
57− "description": "one anyOf valid",
58− "data": "foobar",
59− "valid": true
60− },
61− {
62− "description": "both anyOf invalid",
63− "data": "foo",
64− "valid": false
65− }
66− ]
67− },
68− {
69− "description": "anyOf with boolean schemas, all true",
70− "schema": {"anyOf": [true, true]},
71− "tests": [
72− {
73− "description": "any value is valid",
74− "data": "foo",
75− "valid": true
76− }
77− ]
78− },
79− {
80− "description": "anyOf with boolean schemas, some true",
81− "schema": {"anyOf": [true, false]},
82− "tests": [
83− {
84− "description": "any value is valid",
85− "data": "foo",
86− "valid": true
87− }
88− ]
89− },
90− {
91− "description": "anyOf with boolean schemas, all false",
92− "schema": {"anyOf": [false, false]},
93− "tests": [
94− {
95− "description": "any value is invalid",
96− "data": "foo",
97− "valid": false
98− }
99− ]
100− }
101−]
JSON-Schema-Test-Suite/tests/draft6/boolean_schema.jsondeleted−104
@@ -1,104 +0,0 @@
1−[
2− {
3− "description": "boolean schema 'true'",
4− "schema": true,
5− "tests": [
6− {
7− "description": "number is valid",
8− "data": 1,
9− "valid": true
10− },
11− {
12− "description": "string is valid",
13− "data": "foo",
14− "valid": true
15− },
16− {
17− "description": "boolean true is valid",
18− "data": true,
19− "valid": true
20− },
21− {
22− "description": "boolean false is valid",
23− "data": false,
24− "valid": true
25− },
26− {
27− "description": "null is valid",
28− "data": null,
29− "valid": true
30− },
31− {
32− "description": "object is valid",
33− "data": {"foo": "bar"},
34− "valid": true
35− },
36− {
37− "description": "empty object is valid",
38− "data": {},
39− "valid": true
40− },
41− {
42− "description": "array is valid",
43− "data": ["foo"],
44− "valid": true
45− },
46− {
47− "description": "empty array is valid",
48− "data": [],
49− "valid": true
50− }
51− ]
52− },
53− {
54− "description": "boolean schema 'false'",
55− "schema": false,
56− "tests": [
57− {
58− "description": "number is invalid",
59− "data": 1,
60− "valid": false
61− },
62− {
63− "description": "string is invalid",
64− "data": "foo",
65− "valid": false
66− },
67− {
68− "description": "boolean true is invalid",
69− "data": true,
70− "valid": false
71− },
72− {
73− "description": "boolean false is invalid",
74− "data": false,
75− "valid": false
76− },
77− {
78− "description": "null is invalid",
79− "data": null,
80− "valid": false
81− },
82− {
83− "description": "object is invalid",
84− "data": {"foo": "bar"},
85− "valid": false
86− },
87− {
88− "description": "empty object is invalid",
89− "data": {},
90− "valid": false
91− },
92− {
93− "description": "array is invalid",
94− "data": ["foo"],
95− "valid": false
96− },
97− {
98− "description": "empty array is invalid",
99− "data": [],
100− "valid": false
101− }
102− ]
103− }
104−]
JSON-Schema-Test-Suite/tests/draft6/const.jsondeleted−65
@@ -1,65 +0,0 @@
1−[
2− {
3− "description": "const validation",
4− "schema": {"const": 2},
5− "tests": [
6− {
7− "description": "same value is valid",
8− "data": 2,
9− "valid": true
10− },
11− {
12− "description": "another value is invalid",
13− "data": 5,
14− "valid": false
15− },
16− {
17− "description": "another type is invalid",
18− "data": "a",
19− "valid": false
20− }
21− ]
22− },
23− {
24− "description": "const with object",
25− "schema": {"const": {"foo": "bar", "baz": "bax"}},
26− "tests": [
27− {
28− "description": "same object is valid",
29− "data": {"foo": "bar", "baz": "bax"},
30− "valid": true
31− },
32− {
33− "description": "same object with different property order is valid",
34− "data": {"baz": "bax", "foo": "bar"},
35− "valid": true
36− },
37− {
38− "description": "another object is invalid",
39− "data": {"foo": "bar"},
40− "valid": false
41− },
42− {
43− "description": "another type is invalid",
44− "data": [1, 2],
45− "valid": false
46− }
47− ]
48− },
49− {
50− "description": "const with null",
51− "schema": {"const": null},
52− "tests": [
53− {
54− "description": "null is valid",
55− "data": null,
56− "valid": true
57− },
58− {
59− "description": "not null is invalid",
60− "data": 0,
61− "valid": false
62− }
63− ]
64− }
65−]
JSON-Schema-Test-Suite/tests/draft6/contains.jsondeleted−95
@@ -1,95 +0,0 @@
1−[
2− {
3− "description": "contains keyword validation",
4− "schema": {
5− "contains": {"minimum": 5}
6− },
7− "tests": [
8− {
9− "description": "array with item matching schema (5) is valid",
10− "data": [3, 4, 5],
11− "valid": true
12− },
13− {
14− "description": "array with item matching schema (6) is valid",
15− "data": [3, 4, 6],
16− "valid": true
17− },
18− {
19− "description": "array with two items matching schema (5, 6) is valid",
20− "data": [3, 4, 5, 6],
21− "valid": true
22− },
23− {
24− "description": "array without items matching schema is invalid",
25− "data": [2, 3, 4],
26− "valid": false
27− },
28− {
29− "description": "empty array is invalid",
30− "data": [],
31− "valid": false
32− },
33− {
34− "description": "not array is valid",
35− "data": {},
36− "valid": true
37− }
38− ]
39− },
40− {
41− "description": "contains keyword with const keyword",
42− "schema": {
43− "contains": { "const": 5 }
44− },
45− "tests": [
46− {
47− "description": "array with item 5 is valid",
48− "data": [3, 4, 5],
49− "valid": true
50− },
51− {
52− "description": "array with two items 5 is valid",
53− "data": [3, 4, 5, 5],
54− "valid": true
55− },
56− {
57− "description": "array without item 5 is invalid",
58− "data": [1, 2, 3, 4],
59− "valid": false
60− }
61− ]
62− },
63− {
64− "description": "contains keyword with boolean schema true",
65− "schema": {"contains": true},
66− "tests": [
67− {
68− "description": "any non-empty array is valid",
69− "data": ["foo"],
70− "valid": true
71− },
72− {
73− "description": "empty array is invalid",
74− "data": [],
75− "valid": false
76− }
77− ]
78− },
79− {
80− "description": "contains keyword with boolean schema false",
81− "schema": {"contains": false},
82− "tests": [
83− {
84− "description": "any non-empty array is invalid",
85− "data": ["foo"],
86− "valid": false
87− },
88− {
89− "description": "empty array is invalid",
90− "data": [],
91− "valid": false
92− }
93− ]
94− }
95−]
JSON-Schema-Test-Suite/tests/draft6/default.jsondeleted−49
@@ -1,49 +0,0 @@
1−[
2− {
3− "description": "invalid type for default",
4− "schema": {
5− "properties": {
6− "foo": {
7− "type": "integer",
8− "default": []
9− }
10− }
11− },
12− "tests": [
13− {
14− "description": "valid when property is specified",
15− "data": {"foo": 13},
16− "valid": true
17− },
18− {
19− "description": "still valid when the invalid default is used",
20− "data": {},
21− "valid": true
22− }
23− ]
24− },
25− {
26− "description": "invalid string value for default",
27− "schema": {
28− "properties": {
29− "bar": {
30− "type": "string",
31− "minLength": 4,
32− "default": "bad"
33− }
34− }
35− },
36− "tests": [
37− {
38− "description": "valid when property is specified",
39− "data": {"bar": "good"},
40− "valid": true
41− },
42− {
43− "description": "still valid when the invalid default is used",
44− "data": {},
45− "valid": true
46− }
47− ]
48− }
49−]
JSON-Schema-Test-Suite/tests/draft6/definitions.jsondeleted−32
@@ -1,32 +0,0 @@
1−[
2− {
3− "description": "valid definition",
4− "schema": {"$ref": "http://json-schema.org/draft-04/schema#"},
5− "tests": [
6− {
7− "description": "valid definition schema",
8− "data": {
9− "definitions": {
10− "foo": {"type": "integer"}
11− }
12− },
13− "valid": true
14− }
15− ]
16− },
17− {
18− "description": "invalid definition",
19− "schema": {"$ref": "http://json-schema.org/draft-04/schema#"},
20− "tests": [
21− {
22− "description": "invalid definition schema",
23− "data": {
24− "definitions": {
25− "foo": {"type": 1}
26− }
27− },
28− "valid": false
29− }
30− ]
31− }
32−]
JSON-Schema-Test-Suite/tests/draft6/dependencies.jsondeleted−162
@@ -1,162 +0,0 @@
1−[
2− {
3− "description": "dependencies",
4− "schema": {
5− "dependencies": {"bar": ["foo"]}
6− },
7− "tests": [
8− {
9− "description": "neither",
10− "data": {},
11− "valid": true
12− },
13− {
14− "description": "nondependant",
15− "data": {"foo": 1},
16− "valid": true
17− },
18− {
19− "description": "with dependency",
20− "data": {"foo": 1, "bar": 2},
21− "valid": true
22− },
23− {
24− "description": "missing dependency",
25− "data": {"bar": 2},
26− "valid": false
27− },
28− {
29− "description": "ignores non-objects",
30− "data": "foo",
31− "valid": true
32− }
33− ]
34− },
35− {
36− "description": "dependencies with empty array",
37− "schema": {
38− "dependencies": {"bar": []}
39− },
40− "tests": [
41− {
42− "description": "empty object",
43− "data": {},
44− "valid": true
45− },
46− {
47− "description": "object with one property",
48− "data": {"bar": 2},
49− "valid": true
50− }
51− ]
52− },
53− {
54− "description": "multiple dependencies",
55− "schema": {
56− "dependencies": {"quux": ["foo", "bar"]}
57− },
58− "tests": [
59− {
60− "description": "neither",
61− "data": {},
62− "valid": true
63− },
64− {
65− "description": "nondependants",
66− "data": {"foo": 1, "bar": 2},
67− "valid": true
68− },
69− {
70− "description": "with dependencies",
71− "data": {"foo": 1, "bar": 2, "quux": 3},
72− "valid": true
73− },
74− {
75− "description": "missing dependency",
76− "data": {"foo": 1, "quux": 2},
77− "valid": false
78− },
79− {
80− "description": "missing other dependency",
81− "data": {"bar": 1, "quux": 2},
82− "valid": false
83− },
84− {
85− "description": "missing both dependencies",
86− "data": {"quux": 1},
87− "valid": false
88− }
89− ]
90− },
91− {
92− "description": "multiple dependencies subschema",
93− "schema": {
94− "dependencies": {
95− "bar": {
96− "properties": {
97− "foo": {"type": "integer"},
98− "bar": {"type": "integer"}
99− }
100− }
101− }
102− },
103− "tests": [
104− {
105− "description": "valid",
106− "data": {"foo": 1, "bar": 2},
107− "valid": true
108− },
109− {
110− "description": "no dependency",
111− "data": {"foo": "quux"},
112− "valid": true
113− },
114− {
115− "description": "wrong type",
116− "data": {"foo": "quux", "bar": 2},
117− "valid": false
118− },
119− {
120− "description": "wrong type other",
121− "data": {"foo": 2, "bar": "quux"},
122− "valid": false
123− },
124− {
125− "description": "wrong type both",
126− "data": {"foo": "quux", "bar": "quux"},
127− "valid": false
128− }
129− ]
130− },
131− {
132− "description": "dependencies with boolean subschemas",
133− "schema": {
134− "dependencies": {
135− "foo": true,
136− "bar": false
137− }
138− },
139− "tests": [
140− {
141− "description": "object with property having schema true is valid",
142− "data": {"foo": 1},
143− "valid": true
144− },
145− {
146− "description": "object with property having schema false is invalid",
147− "data": {"bar": 2},
148− "valid": false
149− },
150− {
151− "description": "object with both properties is invalid",
152− "data": {"foo": 1, "bar": 2},
153− "valid": false
154− },
155− {
156− "description": "empty object is valid",
157− "data": {},
158− "valid": true
159− }
160− ]
161− }
162−]
JSON-Schema-Test-Suite/tests/draft6/enum.jsondeleted−72
@@ -1,72 +0,0 @@
1−[
2− {
3− "description": "simple enum validation",
4− "schema": {"enum": [1, 2, 3]},
5− "tests": [
6− {
7− "description": "one of the enum is valid",
8− "data": 1,
9− "valid": true
10− },
11− {
12− "description": "something else is invalid",
13− "data": 4,
14− "valid": false
15− }
16− ]
17− },
18− {
19− "description": "heterogeneous enum validation",
20− "schema": {"enum": [6, "foo", [], true, {"foo": 12}]},
21− "tests": [
22− {
23− "description": "one of the enum is valid",
24− "data": [],
25− "valid": true
26− },
27− {
28− "description": "something else is invalid",
29− "data": null,
30− "valid": false
31− },
32− {
33− "description": "objects are deep compared",
34− "data": {"foo": false},
35− "valid": false
36− }
37− ]
38− },
39− {
40− "description": "enums in properties",
41− "schema": {
42− "type":"object",
43− "properties": {
44− "foo": {"enum":["foo"]},
45− "bar": {"enum":["bar"]}
46− },
47− "required": ["bar"]
48− },
49− "tests": [
50− {
51− "description": "both properties are valid",
52− "data": {"foo":"foo", "bar":"bar"},
53− "valid": true
54− },
55− {
56− "description": "missing optional property is valid",
57− "data": {"bar":"bar"},
58− "valid": true
59− },
60− {
61− "description": "missing required property is invalid",
62− "data": {"foo":"foo"},
63− "valid": false
64− },
65− {
66− "description": "missing all properties is invalid",
67− "data": {},
68− "valid": false
69− }
70− ]
71− }
72−]
JSON-Schema-Test-Suite/tests/draft6/exclusiveMaximum.jsondeleted−30
@@ -1,30 +0,0 @@
1−[
2− {
3− "description": "exclusiveMaximum validation",
4− "schema": {
5− "exclusiveMaximum": 3.0
6− },
7− "tests": [
8− {
9− "description": "below the exclusiveMaximum is valid",
10− "data": 2.2,
11− "valid": true
12− },
13− {
14− "description": "boundary point is invalid",
15− "data": 3.0,
16− "valid": false
17− },
18− {
19− "description": "above the exclusiveMaximum is invalid",
20− "data": 3.5,
21− "valid": false
22− },
23− {
24− "description": "ignores non-numbers",
25− "data": "x",
26− "valid": true
27− }
28− ]
29− }
30−]
JSON-Schema-Test-Suite/tests/draft6/exclusiveMinimum.jsondeleted−30
@@ -1,30 +0,0 @@
1−[
2− {
3− "description": "exclusiveMinimum validation",
4− "schema": {
5− "exclusiveMinimum": 1.1
6− },
7− "tests": [
8− {
9− "description": "above the exclusiveMinimum is valid",
10− "data": 1.2,
11− "valid": true
12− },
13− {
14− "description": "boundary point is invalid",
15− "data": 1.1,
16− "valid": false
17− },
18− {
19− "description": "below the exclusiveMinimum is invalid",
20− "data": 0.6,
21− "valid": false
22− },
23− {
24− "description": "ignores non-numbers",
25− "data": "x",
26− "valid": true
27− }
28− ]
29− }
30−]
JSON-Schema-Test-Suite/tests/draft6/items.jsondeleted−133
@@ -1,133 +0,0 @@
1−[
2− {
3− "description": "a schema given for items",
4− "schema": {
5− "items": {"type": "integer"}
6− },
7− "tests": [
8− {
9− "description": "valid items",
10− "data": [ 1, 2, 3 ],
11− "valid": true
12− },
13− {
14− "description": "wrong type of items",
15− "data": [1, "x"],
16− "valid": false
17− },
18− {
19− "description": "ignores non-arrays",
20− "data": {"foo" : "bar"},
21− "valid": true
22− },
23− {
24− "description": "JavaScript pseudo-array is valid",
25− "data": {
26− "0": "invalid",
27− "length": 1
28− },
29− "valid": true
30− }
31− ]
32− },
33− {
34− "description": "an array of schemas for items",
35− "schema": {
36− "items": [
37− {"type": "integer"},
38− {"type": "string"}
39− ]
40− },
41− "tests": [
42− {
43− "description": "correct types",
44− "data": [ 1, "foo" ],
45− "valid": true
46− },
47− {
48− "description": "wrong types",
49− "data": [ "foo", 1 ],
50− "valid": false
51− },
52− {
53− "description": "incomplete array of items",
54− "data": [ 1 ],
55− "valid": true
56− },
57− {
58− "description": "array with additional items",
59− "data": [ 1, "foo", true ],
60− "valid": true
61− },
62− {
63− "description": "empty array",
64− "data": [ ],
65− "valid": true
66− },
67− {
68− "description": "JavaScript pseudo-array is valid",
69− "data": {
70− "0": "invalid",
71− "1": "valid",
72− "length": 2
73− },
74− "valid": true
75− }
76− ]
77− },
78− {
79− "description": "items with boolean schema (true)",
80− "schema": {"items": true},
81− "tests": [
82− {
83− "description": "any array is valid",
84− "data": [ 1, "foo", true ],
85− "valid": true
86− },
87− {
88− "description": "empty array is valid",
89− "data": [],
90− "valid": true
91− }
92− ]
93− },
94− {
95− "description": "items with boolean schema (false)",
96− "schema": {"items": false},
97− "tests": [
98− {
99− "description": "any non-empty array is invalid",
100− "data": [ 1, "foo", true ],
101− "valid": false
102− },
103− {
104− "description": "empty array is valid",
105− "data": [],
106− "valid": true
107− }
108− ]
109− },
110− {
111− "description": "items with boolean schemas",
112− "schema": {
113− "items": [true, false]
114− },
115− "tests": [
116− {
117− "description": "array with one item is valid",
118− "data": [ 1 ],
119− "valid": true
120− },
121− {
122− "description": "array with two items is invalid",
123− "data": [ 1, "foo" ],
124− "valid": false
125− },
126− {
127− "description": "empty array is valid",
128− "data": [],
129− "valid": true
130− }
131− ]
132− }
133−]
JSON-Schema-Test-Suite/tests/draft6/maxItems.jsondeleted−28
@@ -1,28 +0,0 @@
1−[
2− {
3− "description": "maxItems validation",
4− "schema": {"maxItems": 2},
5− "tests": [
6− {
7− "description": "shorter is valid",
8− "data": [1],
9− "valid": true
10− },
11− {
12− "description": "exact length is valid",
13− "data": [1, 2],
14− "valid": true
15− },
16− {
17− "description": "too long is invalid",
18− "data": [1, 2, 3],
19− "valid": false
20− },
21− {
22− "description": "ignores non-arrays",
23− "data": "foobar",
24− "valid": true
25− }
26− ]
27− }
28−]
JSON-Schema-Test-Suite/tests/draft6/maxLength.jsondeleted−33
@@ -1,33 +0,0 @@
1−[
2− {
3− "description": "maxLength validation",
4− "schema": {"maxLength": 2},
5− "tests": [
6− {
7− "description": "shorter is valid",
8− "data": "f",
9− "valid": true
10− },
11− {
12− "description": "exact length is valid",
13− "data": "fo",
14− "valid": true
15− },
16− {
17− "description": "too long is invalid",
18− "data": "foo",
19− "valid": false
20− },
21− {
22− "description": "ignores non-strings",
23− "data": 100,
24− "valid": true
25− },
26− {
27− "description": "two supplementary Unicode code points is long enough",
28− "data": "\uD83D\uDCA9\uD83D\uDCA9",
29− "valid": true
30− }
31− ]
32− }
33−]
JSON-Schema-Test-Suite/tests/draft6/maxProperties.jsondeleted−28
@@ -1,28 +0,0 @@
1−[
2− {
3− "description": "maxProperties validation",
4− "schema": {"maxProperties": 2},
5− "tests": [
6− {
7− "description": "shorter is valid",
8− "data": {"foo": 1},
9− "valid": true
10− },
11− {
12− "description": "exact length is valid",
13− "data": {"foo": 1, "bar": 2},
14− "valid": true
15− },
16− {
17− "description": "too long is invalid",
18− "data": {"foo": 1, "bar": 2, "baz": 3},
19− "valid": false
20− },
21− {
22− "description": "ignores non-objects",
23− "data": "foobar",
24− "valid": true
25− }
26− ]
27− }
28−]
JSON-Schema-Test-Suite/tests/draft6/maximum.jsondeleted−28
@@ -1,28 +0,0 @@
1−[
2− {
3− "description": "maximum validation",
4− "schema": {"maximum": 3.0},
5− "tests": [
6− {
7− "description": "below the maximum is valid",
8− "data": 2.6,
9− "valid": true
10− },
11− {
12− "description": "boundary point is valid",
13− "data": 3.0,
14− "valid": true
15− },
16− {
17− "description": "above the maximum is invalid",
18− "data": 3.5,
19− "valid": false
20− },
21− {
22− "description": "ignores non-numbers",
23− "data": "x",
24− "valid": true
25− }
26− ]
27− }
28−]
JSON-Schema-Test-Suite/tests/draft6/minItems.jsondeleted−28
@@ -1,28 +0,0 @@
1−[
2− {
3− "description": "minItems validation",
4− "schema": {"minItems": 1},
5− "tests": [
6− {
7− "description": "longer is valid",
8− "data": [1, 2],
9− "valid": true
10− },
11− {
12− "description": "exact length is valid",
13− "data": [1],
14− "valid": true
15− },
16− {
17− "description": "too short is invalid",
18− "data": [],
19− "valid": false
20− },
21− {
22− "description": "ignores non-arrays",
23− "data": "",
24− "valid": true
25− }
26− ]
27− }
28−]
JSON-Schema-Test-Suite/tests/draft6/minLength.jsondeleted−33
@@ -1,33 +0,0 @@
1−[
2− {
3− "description": "minLength validation",
4− "schema": {"minLength": 2},
5− "tests": [
6− {
7− "description": "longer is valid",
8− "data": "foo",
9− "valid": true
10− },
11− {
12− "description": "exact length is valid",
13− "data": "fo",
14− "valid": true
15− },
16− {
17− "description": "too short is invalid",
18− "data": "f",
19− "valid": false
20− },
21− {
22− "description": "ignores non-strings",
23− "data": 1,
24− "valid": true
25− },
26− {
27− "description": "one supplementary Unicode code point is not long enough",
28− "data": "\uD83D\uDCA9",
29− "valid": false
30− }
31− ]
32− }
33−]
JSON-Schema-Test-Suite/tests/draft6/minProperties.jsondeleted−28
@@ -1,28 +0,0 @@
1−[
2− {
3− "description": "minProperties validation",
4− "schema": {"minProperties": 1},
5− "tests": [
6− {
7− "description": "longer is valid",
8− "data": {"foo": 1, "bar": 2},
9− "valid": true
10− },
11− {
12− "description": "exact length is valid",
13− "data": {"foo": 1},
14− "valid": true
15− },
16− {
17− "description": "too short is invalid",
18− "data": {},
19− "valid": false
20− },
21− {
22− "description": "ignores non-objects",
23− "data": "",
24− "valid": true
25− }
26− ]
27− }
28−]
JSON-Schema-Test-Suite/tests/draft6/minimum.jsondeleted−28
@@ -1,28 +0,0 @@
1−[
2− {
3− "description": "minimum validation",
4− "schema": {"minimum": 1.1},
5− "tests": [
6− {
7− "description": "above the minimum is valid",
8− "data": 2.6,
9− "valid": true
10− },
11− {
12− "description": "boundary point is valid",
13− "data": 1.1,
14− "valid": true
15− },
16− {
17− "description": "below the minimum is invalid",
18− "data": 0.6,
19− "valid": false
20− },
21− {
22− "description": "ignores non-numbers",
23− "data": "x",
24− "valid": true
25− }
26− ]
27− }
28−]
JSON-Schema-Test-Suite/tests/draft6/multipleOf.jsondeleted−60
@@ -1,60 +0,0 @@
1−[
2− {
3− "description": "by int",
4− "schema": {"multipleOf": 2},
5− "tests": [
6− {
7− "description": "int by int",
8− "data": 10,
9− "valid": true
10− },
11− {
12− "description": "int by int fail",
13− "data": 7,
14− "valid": false
15− },
16− {
17− "description": "ignores non-numbers",
18− "data": "foo",
19− "valid": true
20− }
21− ]
22− },
23− {
24− "description": "by number",
25− "schema": {"multipleOf": 1.5},
26− "tests": [
27− {
28− "description": "zero is multiple of anything",
29− "data": 0,
30− "valid": true
31− },
32− {
33− "description": "4.5 is multiple of 1.5",
34− "data": 4.5,
35− "valid": true
36− },
37− {
38− "description": "35 is not multiple of 1.5",
39− "data": 35,
40− "valid": false
41− }
42− ]
43− },
44− {
45− "description": "by small number",
46− "schema": {"multipleOf": 0.0001},
47− "tests": [
48− {
49− "description": "0.0075 is multiple of 0.0001",
50− "data": 0.0075,
51− "valid": true
52− },
53− {
54− "description": "0.00751 is not multiple of 0.0001",
55− "data": 0.00751,
56− "valid": false
57− }
58− ]
59− }
60−]
JSON-Schema-Test-Suite/tests/draft6/not.jsondeleted−117
@@ -1,117 +0,0 @@
1−[
2− {
3− "description": "not",
4− "schema": {
5− "not": {"type": "integer"}
6− },
7− "tests": [
8− {
9− "description": "allowed",
10− "data": "foo",
11− "valid": true
12− },
13− {
14− "description": "disallowed",
15− "data": 1,
16− "valid": false
17− }
18− ]
19− },
20− {
21− "description": "not multiple types",
22− "schema": {
23− "not": {"type": ["integer", "boolean"]}
24− },
25− "tests": [
26− {
27− "description": "valid",
28− "data": "foo",
29− "valid": true
30− },
31− {
32− "description": "mismatch",
33− "data": 1,
34− "valid": false
35− },
36− {
37− "description": "other mismatch",
38− "data": true,
39− "valid": false
40− }
41− ]
42− },
43− {
44− "description": "not more complex schema",
45− "schema": {
46− "not": {
47− "type": "object",
48− "properties": {
49− "foo": {
50− "type": "string"
51− }
52− }
53− }
54− },
55− "tests": [
56− {
57− "description": "match",
58− "data": 1,
59− "valid": true
60− },
61− {
62− "description": "other match",
63− "data": {"foo": 1},
64− "valid": true
65− },
66− {
67− "description": "mismatch",
68− "data": {"foo": "bar"},
69− "valid": false
70− }
71− ]
72− },
73− {
74− "description": "forbidden property",
75− "schema": {
76− "properties": {
77− "foo": {
78− "not": {}
79− }
80− }
81− },
82− "tests": [
83− {
84− "description": "property present",
85− "data": {"foo": 1, "bar": 2},
86− "valid": false
87− },
88− {
89− "description": "property absent",
90− "data": {"bar": 1, "baz": 2},
91− "valid": true
92− }
93− ]
94− },
95− {
96− "description": "not with boolean schema true",
97− "schema": {"not": true},
98− "tests": [
99− {
100− "description": "any value is invalid",
101− "data": "foo",
102− "valid": false
103− }
104− ]
105− },
106− {
107− "description": "not with boolean schema false",
108− "schema": {"not": false},
109− "tests": [
110− {
111− "description": "any value is valid",
112− "data": "foo",
113− "valid": true
114− }
115− ]
116− }
117−]
JSON-Schema-Test-Suite/tests/draft6/oneOf.jsondeleted−112
@@ -1,112 +0,0 @@
1−[
2− {
3− "description": "oneOf",
4− "schema": {
5− "oneOf": [
6− {
7− "type": "integer"
8− },
9− {
10− "minimum": 2
11− }
12− ]
13− },
14− "tests": [
15− {
16− "description": "first oneOf valid",
17− "data": 1,
18− "valid": true
19− },
20− {
21− "description": "second oneOf valid",
22− "data": 2.5,
23− "valid": true
24− },
25− {
26− "description": "both oneOf valid",
27− "data": 3,
28− "valid": false
29− },
30− {
31− "description": "neither oneOf valid",
32− "data": 1.5,
33− "valid": false
34− }
35− ]
36− },
37− {
38− "description": "oneOf with base schema",
39− "schema": {
40− "type": "string",
41− "oneOf" : [
42− {
43− "minLength": 2
44− },
45− {
46− "maxLength": 4
47− }
48− ]
49− },
50− "tests": [
51− {
52− "description": "mismatch base schema",
53− "data": 3,
54− "valid": false
55− },
56− {
57− "description": "one oneOf valid",
58− "data": "foobar",
59− "valid": true
60− },
61− {
62− "description": "both oneOf valid",
63− "data": "foo",
64− "valid": false
65− }
66− ]
67− },
68− {
69− "description": "oneOf with boolean schemas, all true",
70− "schema": {"oneOf": [true, true, true]},
71− "tests": [
72− {
73− "description": "any value is invalid",
74− "data": "foo",
75− "valid": false
76− }
77− ]
78− },
79− {
80− "description": "oneOf with boolean schemas, one true",
81− "schema": {"oneOf": [true, false, false]},
82− "tests": [
83− {
84− "description": "any value is valid",
85− "data": "foo",
86− "valid": true
87− }
88− ]
89− },
90− {
91− "description": "oneOf with boolean schemas, more than one true",
92− "schema": {"oneOf": [true, true, false]},
93− "tests": [
94− {
95− "description": "any value is invalid",
96− "data": "foo",
97− "valid": false
98− }
99− ]
100− },
101− {
102− "description": "oneOf with boolean schemas, all false",
103− "schema": {"oneOf": [false, false, false]},
104− "tests": [
105− {
106− "description": "any value is invalid",
107− "data": "foo",
108− "valid": false
109− }
110− ]
111− }
112−]
JSON-Schema-Test-Suite/tests/draft6/optional/bignum.jsondeleted−105
@@ -1,105 +0,0 @@
1−[
2− {
3− "description": "integer",
4− "schema": {"type": "integer"},
5− "tests": [
6− {
7− "description": "a bignum is an integer",
8− "data": 12345678910111213141516171819202122232425262728293031,
9− "valid": true
10− }
11− ]
12− },
13− {
14− "description": "number",
15− "schema": {"type": "number"},
16− "tests": [
17− {
18− "description": "a bignum is a number",
19− "data": 98249283749234923498293171823948729348710298301928331,
20− "valid": true
21− }
22− ]
23− },
24− {
25− "description": "integer",
26− "schema": {"type": "integer"},
27− "tests": [
28− {
29− "description": "a negative bignum is an integer",
30− "data": -12345678910111213141516171819202122232425262728293031,
31− "valid": true
32− }
33− ]
34− },
35− {
36− "description": "number",
37− "schema": {"type": "number"},
38− "tests": [
39− {
40− "description": "a negative bignum is a number",
41− "data": -98249283749234923498293171823948729348710298301928331,
42− "valid": true
43− }
44− ]
45− },
46− {
47− "description": "string",
48− "schema": {"type": "string"},
49− "tests": [
50− {
51− "description": "a bignum is not a string",
52− "data": 98249283749234923498293171823948729348710298301928331,
53− "valid": false
54− }
55− ]
56− },
57− {
58− "description": "integer comparison",
59− "schema": {"maximum": 18446744073709551615},
60− "tests": [
61− {
62− "description": "comparison works for high numbers",
63− "data": 18446744073709551600,
64− "valid": true
65− }
66− ]
67− },
68− {
69− "description": "float comparison with high precision",
70− "schema": {
71− "exclusiveMaximum": 972783798187987123879878123.18878137
72− },
73− "tests": [
74− {
75− "description": "comparison works for high numbers",
76− "data": 972783798187987123879878123.188781371,
77− "valid": false
78− }
79− ]
80− },
81− {
82− "description": "integer comparison",
83− "schema": {"minimum": -18446744073709551615},
84− "tests": [
85− {
86− "description": "comparison works for very negative numbers",
87− "data": -18446744073709551600,
88− "valid": true
89− }
90− ]
91− },
92− {
93− "description": "float comparison with high precision on negative numbers",
94− "schema": {
95− "exclusiveMinimum": -972783798187987123879878123.18878137
96− },
97− "tests": [
98− {
99− "description": "comparison works for very negative numbers",
100− "data": -972783798187987123879878123.188781371,
101− "valid": false
102− }
103− ]
104− }
105−]
JSON-Schema-Test-Suite/tests/draft6/optional/ecmascript-regex.jsondeleted−13
@@ -1,13 +0,0 @@
1−[
2− {
3− "description": "ECMA 262 regex non-compliance",
4− "schema": { "format": "regex" },
5− "tests": [
6− {
7− "description": "ECMA 262 has no support for \\Z anchor from .NET",
8− "data": "^\\S(|(.|\\n)*\\S)\\Z",
9− "valid": false
10− }
11− ]
12− }
13−]
JSON-Schema-Test-Suite/tests/draft6/optional/format.jsondeleted−148
@@ -1,148 +0,0 @@
1−[
2− {
3− "description": "validation of date-time strings",
4− "schema": {"format": "date-time"},
5− "tests": [
6− {
7− "description": "a valid date-time string",
8− "data": "1963-06-19T08:30:06.283185Z",
9− "valid": true
10− },
11− {
12− "description": "an invalid date-time string",
13− "data": "06/19/1963 08:30:06 PST",
14− "valid": false
15− },
16− {
17− "description": "only RFC3339 not all of ISO 8601 are valid",
18− "data": "2013-350T01:01:01",
19− "valid": false
20− }
21− ]
22− },
23− {
24− "description": "validation of URIs",
25− "schema": {"format": "uri"},
26− "tests": [
27− {
28− "description": "a valid URI",
29− "data": "http://foo.bar/?baz=qux#quux",
30− "valid": true
31− },
32− {
33− "description": "an invalid protocol-relative URI Reference",
34− "data": "//foo.bar/?baz=qux#quux",
35− "valid": false
36− },
37− {
38− "description": "an invalid URI",
39− "data": "\\\\WINDOWS\\fileshare",
40− "valid": false
41− },
42− {
43− "description": "an invalid URI though valid URI reference",
44− "data": "abc",
45− "valid": false
46− }
47− ]
48− },
49− {
50− "description": "validation of e-mail addresses",
51− "schema": {"format": "email"},
52− "tests": [
53− {
54− "description": "a valid e-mail address",
55− "data": "joe.bloggs@example.com",
56− "valid": true
57− },
58− {
59− "description": "an invalid e-mail address",
60− "data": "2962",
61− "valid": false
62− }
63− ]
64− },
65− {
66− "description": "validation of IP addresses",
67− "schema": {"format": "ipv4"},
68− "tests": [
69− {
70− "description": "a valid IP address",
71− "data": "192.168.0.1",
72− "valid": true
73− },
74− {
75− "description": "an IP address with too many components",
76− "data": "127.0.0.0.1",
77− "valid": false
78− },
79− {
80− "description": "an IP address with out-of-range values",
81− "data": "256.256.256.256",
82− "valid": false
83− },
84− {
85− "description": "an IP address without 4 components",
86− "data": "127.0",
87− "valid": false
88− },
89− {
90− "description": "an IP address as an integer",
91− "data": "0x7f000001",
92− "valid": false
93− }
94− ]
95− },
96− {
97− "description": "validation of IPv6 addresses",
98− "schema": {"format": "ipv6"},
99− "tests": [
100− {
101− "description": "a valid IPv6 address",
102− "data": "::1",
103− "valid": true
104− },
105− {
106− "description": "an IPv6 address with out-of-range values",
107− "data": "12345::",
108− "valid": false
109− },
110− {
111− "description": "an IPv6 address with too many components",
112− "data": "1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1",
113− "valid": false
114− },
115− {
116− "description": "an IPv6 address containing illegal characters",
117− "data": "::laptop",
118− "valid": false
119− }
120− ]
121− },
122− {
123− "description": "validation of host names",
124− "schema": {"format": "hostname"},
125− "tests": [
126− {
127− "description": "a valid host name",
128− "data": "www.example.com",
129− "valid": true
130− },
131− {
132− "description": "a host name starting with an illegal character",
133− "data": "-a-host-name-that-starts-with--",
134− "valid": false
135− },
136− {
137− "description": "a host name containing illegal characters",
138− "data": "not_a_valid_host_name",
139− "valid": false
140− },
141− {
142− "description": "a host name with a component too long",
143− "data": "a-vvvvvvvvvvvvvvvveeeeeeeeeeeeeeeerrrrrrrrrrrrrrrryyyyyyyyyyyyyyyy-long-host-name-component",
144− "valid": false
145− }
146− ]
147− }
148−]
JSON-Schema-Test-Suite/tests/draft6/optional/zeroTerminatedFloats.jsondeleted−15
@@ -1,15 +0,0 @@
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": true
12− }
13− ]
14− }
15−]
JSON-Schema-Test-Suite/tests/draft6/pattern.jsondeleted−34
@@ -1,34 +0,0 @@
1−[
2− {
3− "description": "pattern validation",
4− "schema": {"pattern": "^a*$"},
5− "tests": [
6− {
7− "description": "a matching pattern is valid",
8− "data": "aaa",
9− "valid": true
10− },
11− {
12− "description": "a non-matching pattern is invalid",
13− "data": "abc",
14− "valid": false
15− },
16− {
17− "description": "ignores non-strings",
18− "data": true,
19− "valid": true
20− }
21− ]
22− },
23− {
24− "description": "pattern is not anchored",
25− "schema": {"pattern": "a+"},
26− "tests": [
27− {
28− "description": "matches a substring",
29− "data": "xxaayy",
30− "valid": true
31− }
32− ]
33− }
34−]
JSON-Schema-Test-Suite/tests/draft6/patternProperties.jsondeleted−141
@@ -1,141 +0,0 @@
1−[
2− {
3− "description":
4− "patternProperties validates properties matching a regex",
5− "schema": {
6− "patternProperties": {
7− "f.*o": {"type": "integer"}
8− }
9− },
10− "tests": [
11− {
12− "description": "a single valid match is valid",
13− "data": {"foo": 1},
14− "valid": true
15− },
16− {
17− "description": "multiple valid matches is valid",
18− "data": {"foo": 1, "foooooo" : 2},
19− "valid": true
20− },
21− {
22− "description": "a single invalid match is invalid",
23− "data": {"foo": "bar", "fooooo": 2},
24− "valid": false
25− },
26− {
27− "description": "multiple invalid matches is invalid",
28− "data": {"foo": "bar", "foooooo" : "baz"},
29− "valid": false
30− },
31− {
32− "description": "ignores non-objects",
33− "data": 12,
34− "valid": true
35− }
36− ]
37− },
38− {
39− "description": "multiple simultaneous patternProperties are validated",
40− "schema": {
41− "patternProperties": {
42− "a*": {"type": "integer"},
43− "aaa*": {"maximum": 20}
44− }
45− },
46− "tests": [
47− {
48− "description": "a single valid match is valid",
49− "data": {"a": 21},
50− "valid": true
51− },
52− {
53− "description": "a simultaneous match is valid",
54− "data": {"aaaa": 18},
55− "valid": true
56− },
57− {
58− "description": "multiple matches is valid",
59− "data": {"a": 21, "aaaa": 18},
60− "valid": true
61− },
62− {
63− "description": "an invalid due to one is invalid",
64− "data": {"a": "bar"},
65− "valid": false
66− },
67− {
68− "description": "an invalid due to the other is invalid",
69− "data": {"aaaa": 31},
70− "valid": false
71− },
72− {
73− "description": "an invalid due to both is invalid",
74− "data": {"aaa": "foo", "aaaa": 31},
75− "valid": false
76− }
77− ]
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− ]
109− },
110− {
111− "description": "patternProperties with boolean schemas",
112− "schema": {
113− "patternProperties": {
114− "f.*": true,
115− "b.*": false
116− }
117− },
118− "tests": [
119− {
120− "description": "object with property matching schema true is valid",
121− "data": {"foo": 1},
122− "valid": true
123− },
124− {
125− "description": "object with property matching schema false is invalid",
126− "data": {"bar": 2},
127− "valid": false
128− },
129− {
130− "description": "object with both properties is invalid",
131− "data": {"foo": 1, "bar": 2},
132− "valid": false
133− },
134− {
135− "description": "empty object is valid",
136− "data": {},
137− "valid": true
138− }
139− ]
140− }
141−]
JSON-Schema-Test-Suite/tests/draft6/properties.jsondeleted−123
@@ -1,123 +0,0 @@
1−[
2− {
3− "description": "object properties validation",
4− "schema": {
5− "properties": {
6− "foo": {"type": "integer"},
7− "bar": {"type": "string"}
8− }
9− },
10− "tests": [
11− {
12− "description": "both properties present and valid is valid",
13− "data": {"foo": 1, "bar": "baz"},
14− "valid": true
15− },
16− {
17− "description": "one property invalid is invalid",
18− "data": {"foo": 1, "bar": {}},
19− "valid": false
20− },
21− {
22− "description": "both properties invalid is invalid",
23− "data": {"foo": [], "bar": {}},
24− "valid": false
25− },
26− {
27− "description": "doesn't invalidate other properties",
28− "data": {"quux": []},
29− "valid": true
30− },
31− {
32− "description": "ignores non-objects",
33− "data": [],
34− "valid": true
35− }
36− ]
37− },
38− {
39− "description":
40− "properties, patternProperties, additionalProperties interaction",
41− "schema": {
42− "properties": {
43− "foo": {"type": "array", "maxItems": 3},
44− "bar": {"type": "array"}
45− },
46− "patternProperties": {"f.o": {"minItems": 2}},
47− "additionalProperties": {"type": "integer"}
48− },
49− "tests": [
50− {
51− "description": "property validates property",
52− "data": {"foo": [1, 2]},
53− "valid": true
54− },
55− {
56− "description": "property invalidates property",
57− "data": {"foo": [1, 2, 3, 4]},
58− "valid": false
59− },
60− {
61− "description": "patternProperty invalidates property",
62− "data": {"foo": []},
63− "valid": false
64− },
65− {
66− "description": "patternProperty validates nonproperty",
67− "data": {"fxo": [1, 2]},
68− "valid": true
69− },
70− {
71− "description": "patternProperty invalidates nonproperty",
72− "data": {"fxo": []},
73− "valid": false
74− },
75− {
76− "description": "additionalProperty ignores property",
77− "data": {"bar": []},
78− "valid": true
79− },
80− {
81− "description": "additionalProperty validates others",
82− "data": {"quux": 3},
83− "valid": true
84− },
85− {
86− "description": "additionalProperty invalidates others",
87− "data": {"quux": "foo"},
88− "valid": false
89− }
90− ]
91− },
92− {
93− "description": "properties with boolean schema",
94− "schema": {
95− "properties": {
96− "foo": true,
97− "bar": false
98− }
99− },
100− "tests": [
101− {
102− "description": "no property present is valid",
103− "data": {},
104− "valid": true
105− },
106− {
107− "description": "only 'true' property present is valid",
108− "data": {"foo": 1},
109− "valid": true
110− },
111− {
112− "description": "only 'false' property present is invalid",
113− "data": {"bar": 2},
114− "valid": false
115− },
116− {
117− "description": "both properties present is invalid",
118− "data": {"foo": 1, "bar": 2},
119− "valid": false
120− }
121− ]
122− }
123−]
JSON-Schema-Test-Suite/tests/draft6/propertyNames.jsondeleted−68
@@ -1,68 +0,0 @@
1−[
2− {
3− "description": "propertyNames validation",
4− "schema": {
5− "propertyNames": {"maxLength": 3}
6− },
7− "tests": [
8− {
9− "description": "all property names valid",
10− "data": {
11− "f": {},
12− "foo": {}
13− },
14− "valid": true
15− },
16− {
17− "description": "some property names invalid",
18− "data": {
19− "foo": {},
20− "foobar": {}
21− },
22− "valid": false
23− },
24− {
25− "description": "object without properties is valid",
26− "data": {},
27− "valid": true
28− },
29− {
30− "description": "non-object is valid",
31− "data": [],
32− "valid": true
33− }
34− ]
35− },
36− {
37− "description": "propertyNames with boolean schema true",
38− "schema": {"propertyNames": true},
39− "tests": [
40− {
41− "description": "object with any properties is valid",
42− "data": {"foo": 1},
43− "valid": true
44− },
45− {
46− "description": "empty object is valid",
47− "data": {},
48− "valid": true
49− }
50− ]
51− },
52− {
53− "description": "propertyNames with boolean schema false",
54− "schema": {"propertyNames": false},
55− "tests": [
56− {
57− "description": "object with any properties is invalid",
58− "data": {"foo": 1},
59− "valid": false
60− },
61− {
62− "description": "empty object is valid",
63− "data": {},
64− "valid": true
65− }
66− ]
67− }
68−]
JSON-Schema-Test-Suite/tests/draft6/ref.jsondeleted−332
@@ -1,332 +0,0 @@
1−[
2− {
3− "description": "root pointer ref",
4− "schema": {
5− "properties": {
6− "foo": {"$ref": "#"}
7− },
8− "additionalProperties": false
9− },
10− "tests": [
11− {
12− "description": "match",
13− "data": {"foo": false},
14− "valid": true
15− },
16− {
17− "description": "recursive match",
18− "data": {"foo": {"foo": false}},
19− "valid": true
20− },
21− {
22− "description": "mismatch",
23− "data": {"bar": false},
24− "valid": false
25− },
26− {
27− "description": "recursive mismatch",
28− "data": {"foo": {"bar": false}},
29− "valid": false
30− }
31− ]
32− },
33− {
34− "description": "relative pointer ref to object",
35− "schema": {
36− "properties": {
37− "foo": {"type": "integer"},
38− "bar": {"$ref": "#/properties/foo"}
39− }
40− },
41− "tests": [
42− {
43− "description": "match",
44− "data": {"bar": 3},
45− "valid": true
46− },
47− {
48− "description": "mismatch",
49− "data": {"bar": true},
50− "valid": false
51− }
52− ]
53− },
54− {
55− "description": "relative pointer ref to array",
56− "schema": {
57− "items": [
58− {"type": "integer"},
59− {"$ref": "#/items/0"}
60− ]
61− },
62− "tests": [
63− {
64− "description": "match array",
65− "data": [1, 2],
66− "valid": true
67− },
68− {
69− "description": "mismatch array",
70− "data": [1, "foo"],
71− "valid": false
72− }
73− ]
74− },
75− {
76− "description": "escaped pointer ref",
77− "schema": {
78− "tilda~field": {"type": "integer"},
79− "slash/field": {"type": "integer"},
80− "percent%field": {"type": "integer"},
81− "properties": {
82− "tilda": {"$ref": "#/tilda~0field"},
83− "slash": {"$ref": "#/slash~1field"},
84− "percent": {"$ref": "#/percent%25field"}
85− }
86− },
87− "tests": [
88− {
89− "description": "slash invalid",
90− "data": {"slash": "aoeu"},
91− "valid": false
92− },
93− {
94− "description": "tilda invalid",
95− "data": {"tilda": "aoeu"},
96− "valid": false
97− },
98− {
99− "description": "percent invalid",
100− "data": {"percent": "aoeu"},
101− "valid": false
102− },
103− {
104− "description": "slash valid",
105− "data": {"slash": 123},
106− "valid": true
107− },
108− {
109− "description": "tilda valid",
110− "data": {"tilda": 123},
111− "valid": true
112− },
113− {
114− "description": "percent valid",
115− "data": {"percent": 123},
116− "valid": true
117− }
118− ]
119− },
120− {
121− "description": "nested refs",
122− "schema": {
123− "definitions": {
124− "a": {"type": "integer"},
125− "b": {"$ref": "#/definitions/a"},
126− "c": {"$ref": "#/definitions/b"}
127− },
128− "$ref": "#/definitions/c"
129− },
130− "tests": [
131− {
132− "description": "nested ref valid",
133− "data": 5,
134− "valid": true
135− },
136− {
137− "description": "nested ref invalid",
138− "data": "a",
139− "valid": false
140− }
141− ]
142− },
143− {
144− "description": "ref overrides any sibling keywords",
145− "schema": {
146− "definitions": {
147− "reffed": {
148− "type": "array"
149− }
150− },
151− "properties": {
152− "foo": {
153− "$ref": "#/definitions/reffed",
154− "maxItems": 2
155− }
156− }
157− },
158− "tests": [
159− {
160− "description": "ref valid",
161− "data": { "foo": [] },
162− "valid": true
163− },
164− {
165− "description": "ref valid, maxItems ignored",
166− "data": { "foo": [ 1, 2, 3] },
167− "valid": true
168− },
169− {
170− "description": "ref invalid",
171− "data": { "foo": "string" },
172− "valid": false
173− }
174− ]
175− },
176− {
177− "description": "remote ref, containing refs itself",
178− "schema": {"$ref": "http://json-schema.org/draft-04/schema#"},
179− "tests": [
180− {
181− "description": "remote ref valid",
182− "data": {"minLength": 1},
183− "valid": true
184− },
185− {
186− "description": "remote ref invalid",
187− "data": {"minLength": -1},
188− "valid": false
189− }
190− ]
191− },
192− {
193− "description": "property named $ref that is not a reference",
194− "schema": {
195− "properties": {
196− "$ref": {"type": "string"}
197− }
198− },
199− "tests": [
200− {
201− "description": "property named $ref valid",
202− "data": {"$ref": "a"},
203− "valid": true
204− },
205− {
206− "description": "property named $ref invalid",
207− "data": {"$ref": 2},
208− "valid": false
209− }
210− ]
211− },
212− {
213− "description": "$ref to boolean schema true",
214− "schema": {
215− "$ref": "#/definitions/bool",
216− "definitions": {
217− "bool": true
218− }
219− },
220− "tests": [
221− {
222− "description": "any value is valid",
223− "data": "foo",
224− "valid": true
225− }
226− ]
227− },
228− {
229− "description": "$ref to boolean schema false",
230− "schema": {
231− "$ref": "#/definitions/bool",
232− "definitions": {
233− "bool": false
234− }
235− },
236− "tests": [
237− {
238− "description": "any value is invalid",
239− "data": "foo",
240− "valid": false
241− }
242− ]
243− },
244− {
245− "description": "Recursive references between schemas",
246− "schema": {
247− "$id": "http://localhost:1234/tree",
248− "description": "tree of nodes",
249− "type": "object",
250− "properties": {
251− "meta": {"type": "string"},
252− "nodes": {
253− "type": "array",
254− "items": {"$ref": "node"}
255− }
256− },
257− "required": ["meta", "nodes"],
258− "definitions": {
259− "node": {
260− "$id": "http://localhost:1234/node",
261− "description": "node",
262− "type": "object",
263− "properties": {
264− "value": {"type": "number"},
265− "subtree": {"$ref": "tree"}
266− },
267− "required": ["value"]
268− }
269− }
270− },
271− "tests": [
272− {
273− "description": "valid tree",
274− "data": {
275− "meta": "root",
276− "nodes": [
277− {
278− "value": 1,
279− "subtree": {
280− "meta": "child",
281− "nodes": [
282− {"value": 1.1},
283− {"value": 1.2}
284− ]
285− }
286− },
287− {
288− "value": 2,
289− "subtree": {
290− "meta": "child",
291− "nodes": [
292− {"value": 2.1},
293− {"value": 2.2}
294− ]
295− }
296− }
297− ]
298− },
299− "valid": true
300− },
301− {
302− "description": "invalid tree",
303− "data": {
304− "meta": "root",
305− "nodes": [
306− {
307− "value": 1,
308− "subtree": {
309− "meta": "child",
310− "nodes": [
311− {"value": "string is invalid"},
312− {"value": 1.2}
313− ]
314− }
315− },
316− {
317− "value": 2,
318− "subtree": {
319− "meta": "child",
320− "nodes": [
321− {"value": 2.1},
322− {"value": 2.2}
323− ]
324− }
325− }
326− ]
327− },
328− "valid": false
329− }
330− ]
331− }
332−]
JSON-Schema-Test-Suite/tests/draft6/refRemote.jsondeleted−171
@@ -1,171 +0,0 @@
1−[
2− {
3− "description": "remote ref",
4− "schema": {"$ref": "http://localhost:1234/integer.json"},
5− "tests": [
6− {
7− "description": "remote ref valid",
8− "data": 1,
9− "valid": true
10− },
11− {
12− "description": "remote ref invalid",
13− "data": "a",
14− "valid": false
15− }
16− ]
17− },
18− {
19− "description": "fragment within remote ref",
20− "schema": {"$ref": "http://localhost:1234/subSchemas.json#/integer"},
21− "tests": [
22− {
23− "description": "remote fragment valid",
24− "data": 1,
25− "valid": true
26− },
27− {
28− "description": "remote fragment invalid",
29− "data": "a",
30− "valid": false
31− }
32− ]
33− },
34− {
35− "description": "ref within remote ref",
36− "schema": {
37− "$ref": "http://localhost:1234/subSchemas.json#/refToInteger"
38− },
39− "tests": [
40− {
41− "description": "ref within ref valid",
42− "data": 1,
43− "valid": true
44− },
45− {
46− "description": "ref within ref invalid",
47− "data": "a",
48− "valid": false
49− }
50− ]
51− },
52− {
53− "description": "base URI change",
54− "schema": {
55− "$id": "http://localhost:1234/",
56− "items": {
57− "$id": "folder/",
58− "items": {"$ref": "folderInteger.json"}
59− }
60− },
61− "tests": [
62− {
63− "description": "base URI change ref valid",
64− "data": [[1]],
65− "valid": true
66− },
67− {
68− "description": "base URI change ref invalid",
69− "data": [["a"]],
70− "valid": false
71− }
72− ]
73− },
74− {
75− "description": "base URI change - change folder",
76− "schema": {
77− "$id": "http://localhost:1234/scope_change_defs1.json",
78− "type" : "object",
79− "properties": {
80− "list": {"$ref": "#/definitions/baz"}
81− },
82− "definitions": {
83− "baz": {
84− "$id": "folder/",
85− "type": "array",
86− "items": {"$ref": "folderInteger.json"}
87− }
88− }
89− },
90− "tests": [
91− {
92− "description": "number is valid",
93− "data": {"list": [1]},
94− "valid": true
95− },
96− {
97− "description": "string is invalid",
98− "data": {"list": ["a"]},
99− "valid": false
100− }
101− ]
102− },
103− {
104− "description": "base URI change - change folder in subschema",
105− "schema": {
106− "$id": "http://localhost:1234/scope_change_defs2.json",
107− "type" : "object",
108− "properties": {
109− "list": {"$ref": "#/definitions/baz/definitions/bar"}
110− },
111− "definitions": {
112− "baz": {
113− "$id": "folder/",
114− "definitions": {
115− "bar": {
116− "type": "array",
117− "items": {"$ref": "folderInteger.json"}
118− }
119− }
120− }
121− }
122− },
123− "tests": [
124− {
125− "description": "number is valid",
126− "data": {"list": [1]},
127− "valid": true
128− },
129− {
130− "description": "string is invalid",
131− "data": {"list": ["a"]},
132− "valid": false
133− }
134− ]
135− },
136− {
137− "description": "root ref in remote ref",
138− "schema": {
139− "$id": "http://localhost:1234/object",
140− "type": "object",
141− "properties": {
142− "name": {"$ref": "name.json#/definitions/orNull"}
143− }
144− },
145− "tests": [
146− {
147− "description": "string is valid",
148− "data": {
149− "name": "foo"
150− },
151− "valid": true
152− },
153− {
154− "description": "null is valid",
155− "data": {
156− "name": null
157− },
158− "valid": true
159− },
160− {
161− "description": "object is invalid",
162− "data": {
163− "name": {
164− "name": null
165− }
166− },
167− "valid": false
168− }
169− ]
170− }
171−]
JSON-Schema-Test-Suite/tests/draft6/required.jsondeleted−60
@@ -1,60 +0,0 @@
1−[
2− {
3− "description": "required validation",
4− "schema": {
5− "properties": {
6− "foo": {},
7− "bar": {}
8− },
9− "required": ["foo"]
10− },
11− "tests": [
12− {
13− "description": "present required property is valid",
14− "data": {"foo": 1},
15− "valid": true
16− },
17− {
18− "description": "non-present required property is invalid",
19− "data": {"bar": 1},
20− "valid": false
21− },
22− {
23− "description": "ignores non-objects",
24− "data": 12,
25− "valid": true
26− }
27− ]
28− },
29− {
30− "description": "required default validation",
31− "schema": {
32− "properties": {
33− "foo": {}
34− }
35− },
36− "tests": [
37− {
38− "description": "not required by default",
39− "data": {},
40− "valid": true
41− }
42− ]
43− },
44− {
45− "description": "required with empty array",
46− "schema": {
47− "properties": {
48− "foo": {}
49− },
50− "required": []
51− },
52− "tests": [
53− {
54− "description": "property not required",
55− "data": {},
56− "valid": true
57− }
58− ]
59− }
60−]
JSON-Schema-Test-Suite/tests/draft6/type.jsondeleted−345
@@ -1,345 +0,0 @@
1−[
2− {
3− "description": "integer type matches integers",
4− "schema": {"type": "integer"},
5− "tests": [
6− {
7− "description": "an integer is an integer",
8− "data": 1,
9− "valid": true
10− },
11− {
12− "description": "a float is not an integer",
13− "data": 1.1,
14− "valid": false
15− },
16− {
17− "description": "a string is not an integer",
18− "data": "foo",
19− "valid": false
20− },
21− {
22− "description": "a string is still not an integer, even if it looks like one",
23− "data": "1",
24− "valid": false
25− },
26− {
27− "description": "an object is not an integer",
28− "data": {},
29− "valid": false
30− },
31− {
32− "description": "an array is not an integer",
33− "data": [],
34− "valid": false
35− },
36− {
37− "description": "a boolean is not an integer",
38− "data": true,
39− "valid": false
40− },
41− {
42− "description": "null is not an integer",
43− "data": null,
44− "valid": false
45− }
46− ]
47− },
48− {
49− "description": "number type matches numbers",
50− "schema": {"type": "number"},
51− "tests": [
52− {
53− "description": "an integer is a number",
54− "data": 1,
55− "valid": true
56− },
57− {
58− "description": "a float is a number",
59− "data": 1.1,
60− "valid": true
61− },
62− {
63− "description": "a string is not a number",
64− "data": "foo",
65− "valid": false
66− },
67− {
68− "description": "a string is still not a number, even if it looks like one",
69− "data": "1",
70− "valid": false
71− },
72− {
73− "description": "an object is not a number",
74− "data": {},
75− "valid": false
76− },
77− {
78− "description": "an array is not a number",
79− "data": [],
80− "valid": false
81− },
82− {
83− "description": "a boolean is not a number",
84− "data": true,
85− "valid": false
86− },
87− {
88− "description": "null is not a number",
89− "data": null,
90− "valid": false
91− }
92− ]
93− },
94− {
95− "description": "string type matches strings",
96− "schema": {"type": "string"},
97− "tests": [
98− {
99− "description": "1 is not a string",
100− "data": 1,
101− "valid": false
102− },
103− {
104− "description": "a float is not a string",
105− "data": 1.1,
106− "valid": false
107− },
108− {
109− "description": "a string is a string",
110− "data": "foo",
111− "valid": true
112− },
113− {
114− "description": "a string is still a string, even if it looks like a number",
115− "data": "1",
116− "valid": true
117− },
118− {
119− "description": "an object is not a string",
120− "data": {},
121− "valid": false
122− },
123− {
124− "description": "an array is not a string",
125− "data": [],
126− "valid": false
127− },
128− {
129− "description": "a boolean is not a string",
130− "data": true,
131− "valid": false
132− },
133− {
134− "description": "null is not a string",
135− "data": null,
136− "valid": false
137− }
138− ]
139− },
140− {
141− "description": "object type matches objects",
142− "schema": {"type": "object"},
143− "tests": [
144− {
145− "description": "an integer is not an object",
146− "data": 1,
147− "valid": false
148− },
149− {
150− "description": "a float is not an object",
151− "data": 1.1,
152− "valid": false
153− },
154− {
155− "description": "a string is not an object",
156− "data": "foo",
157− "valid": false
158− },
159− {
160− "description": "an object is an object",
161− "data": {},
162− "valid": true
163− },
164− {
165− "description": "an array is not an object",
166− "data": [],
167− "valid": false
168− },
169− {
170− "description": "a boolean is not an object",
171− "data": true,
172− "valid": false
173− },
174− {
175− "description": "null is not an object",
176− "data": null,
177− "valid": false
178− }
179− ]
180− },
181− {
182− "description": "array type matches arrays",
183− "schema": {"type": "array"},
184− "tests": [
185− {
186− "description": "an integer is not an array",
187− "data": 1,
188− "valid": false
189− },
190− {
191− "description": "a float is not an array",
192− "data": 1.1,
193− "valid": false
194− },
195− {
196− "description": "a string is not an array",
197− "data": "foo",
198− "valid": false
199− },
200− {
201− "description": "an object is not an array",
202− "data": {},
203− "valid": false
204− },
205− {
206− "description": "an array is an array",
207− "data": [],
208− "valid": true
209− },
210− {
211− "description": "a boolean is not an array",
212− "data": true,
213− "valid": false
214− },
215− {
216− "description": "null is not an array",
217− "data": null,
218− "valid": false
219− }
220− ]
221− },
222− {
223− "description": "boolean type matches booleans",
224− "schema": {"type": "boolean"},
225− "tests": [
226− {
227− "description": "an integer is not a boolean",
228− "data": 1,
229− "valid": false
230− },
231− {
232− "description": "a float is not a boolean",
233− "data": 1.1,
234− "valid": false
235− },
236− {
237− "description": "a string is not a boolean",
238− "data": "foo",
239− "valid": false
240− },
241− {
242− "description": "an object is not a boolean",
243− "data": {},
244− "valid": false
245− },
246− {
247− "description": "an array is not a boolean",
248− "data": [],
249− "valid": false
250− },
251− {
252− "description": "a boolean is a boolean",
253− "data": true,
254− "valid": true
255− },
256− {
257− "description": "null is not a boolean",
258− "data": null,
259− "valid": false
260− }
261− ]
262− },
263− {
264− "description": "null type matches only the null object",
265− "schema": {"type": "null"},
266− "tests": [
267− {
268− "description": "an integer is not null",
269− "data": 1,
270− "valid": false
271− },
272− {
273− "description": "a float is not null",
274− "data": 1.1,
275− "valid": false
276− },
277− {
278− "description": "a string is not null",
279− "data": "foo",
280− "valid": false
281− },
282− {
283− "description": "an object is not null",
284− "data": {},
285− "valid": false
286− },
287− {
288− "description": "an array is not null",
289− "data": [],
290− "valid": false
291− },
292− {
293− "description": "a boolean is not null",
294− "data": true,
295− "valid": false
296− },
297− {
298− "description": "null is null",
299− "data": null,
300− "valid": true
301− }
302− ]
303− },
304− {
305− "description": "multiple types can be specified in an array",
306− "schema": {"type": ["integer", "string"]},
307− "tests": [
308− {
309− "description": "an integer is valid",
310− "data": 1,
311− "valid": true
312− },
313− {
314− "description": "a string is valid",
315− "data": "foo",
316− "valid": true
317− },
318− {
319− "description": "a float is invalid",
320− "data": 1.1,
321− "valid": false
322− },
323− {
324− "description": "an object is invalid",
325− "data": {},
326− "valid": false
327− },
328− {
329− "description": "an array is invalid",
330− "data": [],
331− "valid": false
332− },
333− {
334− "description": "a boolean is invalid",
335− "data": true,
336− "valid": false
337− },
338− {
339− "description": "null is invalid",
340− "data": null,
341− "valid": false
342− }
343− ]
344− }
345−]
JSON-Schema-Test-Suite/tests/draft6/uniqueItems.jsondeleted−79
@@ -1,79 +0,0 @@
1−[
2− {
3− "description": "uniqueItems validation",
4− "schema": {"uniqueItems": true},
5− "tests": [
6− {
7− "description": "unique array of integers is valid",
8− "data": [1, 2],
9− "valid": true
10− },
11− {
12− "description": "non-unique array of integers is invalid",
13− "data": [1, 1],
14− "valid": false
15− },
16− {
17− "description": "numbers are unique if mathematically unequal",
18− "data": [1.0, 1.00, 1],
19− "valid": false
20− },
21− {
22− "description": "unique array of objects is valid",
23− "data": [{"foo": "bar"}, {"foo": "baz"}],
24− "valid": true
25− },
26− {
27− "description": "non-unique array of objects is invalid",
28− "data": [{"foo": "bar"}, {"foo": "bar"}],
29− "valid": false
30− },
31− {
32− "description": "unique array of nested objects is valid",
33− "data": [
34− {"foo": {"bar" : {"baz" : true}}},
35− {"foo": {"bar" : {"baz" : false}}}
36− ],
37− "valid": true
38− },
39− {
40− "description": "non-unique array of nested objects is invalid",
41− "data": [
42− {"foo": {"bar" : {"baz" : true}}},
43− {"foo": {"bar" : {"baz" : true}}}
44− ],
45− "valid": false
46− },
47− {
48− "description": "unique array of arrays is valid",
49− "data": [["foo"], ["bar"]],
50− "valid": true
51− },
52− {
53− "description": "non-unique array of arrays is invalid",
54− "data": [["foo"], ["foo"]],
55− "valid": false
56− },
57− {
58− "description": "1 and true are unique",
59− "data": [1, true],
60− "valid": true
61− },
62− {
63− "description": "0 and false are unique",
64− "data": [0, false],
65− "valid": true
66− },
67− {
68− "description": "unique heterogeneous types are valid",
69− "data": [{}, [1], true, null, 1],
70− "valid": true
71− },
72− {
73− "description": "non-unique heterogeneous types are invalid",
74− "data": [{}, [1], true, null, {}, 1],
75− "valid": false
76− }
77− ]
78− }
79−]
README.md+50−10
@@ -1,25 +1,65 @@
1−# DEPRECATION NOTICE
1+![hjsonschema logo](./logo.jpg)
2
2
3−`hjsonschema` was an attempt to build a very modular JSON Schema library. Validators have [a concrete type](src/JSONSchema/Validator/Types.hs) and can be mixed and matched into new [Specs](src/JSONSchema/Types.hs).
3+A Haskell implementation of the most commonly used [JSON Schema](http://json-schema.org/) specification ([Draft 4](https://github.com/json-schema-org/json-schema-spec/wiki/Specification-Links#draft-4)).
4
4
5−However this flexibility came at the price of complicating the code. I don't think it was the right tradeoff, especially since situations where you'd want to change what validators make up a `Spec` at runtime seem rare.
5+[Hackage](https://hackage.haskell.org/package/hjsonschema) / [GitHub](https://github.com/seagreen/hjsonschema) / [Travis CI](https://travis-ci.org/seagreen/hjsonschema)
6
6
7−Also, there are many parts of JSON Schema that `hjsonschema` doesn't implement properly (as you can see from the issue tracker). I'm hoping that a new JSON Schema library will come along that handles these correctly. In the meantime I'm happy to merge working fixes into here.
7+# Notes
8
8
9−# Links
9++ As of 2017 [json-schema-org](https://github.com/json-schema-org/json-schema-spec) has begun releasing new drafts of the standard. Once this work stabilizes `hjsonschema` will add coverage for the latest draft.
10
10
11−[Hackage](https://hackage.haskell.org/package/hjsonschema) / [GitHub](https://github.com/seagreen/hjsonschema) / [Travis CI](https://travis-ci.org/seagreen/hjsonschema)
11++ Requires [pcre](http://www.pcre.org/) (`pkgs.pcre` in Nixpkgs).
12+
13++ Schemas with circular references can cause infinite loops. hjsonschema does loop detection but it may not be solid yet -- please open an issue if you find a situation where it fails.
12
14
13# Example
15# Example
14
16
15See [here](https://github.com/seagreen/hjsonschema/blob/master/examples/Simple.hs).
17See [here](https://github.com/seagreen/hjsonschema/blob/master/examples/Simple.hs).
16
18
17−# System dependencies
19+# Tests
18
20
19−+ Requires [pcre](http://www.pcre.org/) (`pkgs.pcre` in Nixpkgs).
21+Run all tests:
22+
23+`stack test`
24+
25+Run only local tests:
26+
27+`stack test hjsonschema:local`
28+
29+Run remote tests (makes GETs to json-schema.org, also temporarily starts an HTTP server on port 1234):
30+
31+`stack test hjsonschema:remote`
32+
33+# Details
34+
35+## Goals
36+
37++ Be a correct and fast implementation of the spec.
38+
39++ Be a useful reference for implementers in other languages. Haskell's high level nature, expressive type system and referential transparency suit this purpose well.
40+
41+## Good Parts
42+
43++ Passes all the required tests in the [language agnostic test suite](https://github.com/json-schema/JSON-Schema-Test-Suite).
44+
45++ Very modular, which should make it easy to support future versions of the specification.
46+
47+## Bad Parts
48+
49++ Uses the [pcre-heavy](https://hackage.haskell.org/package/pcre-heavy) regular expression library for the "pattern" validator. It should use a library based on the ECMA 262 regex dialect, which the [spec](http://json-schema.org/latest/json-schema-validation.html#anchor33) requires.
50+
51++ Currently doesn't support the optional `"format"` validators.
20
52
21## Vendoring
53## Vendoring
22
54
23−+ `JSON-Schema-Test-Suite` is vendored from commit # c1b12bf699f29a04b4286711c6e3bbfba66f21e5 [here](https://github.com/json-schema-org/JSON-Schema-Test-Suite).
55++ `JSON-Schema-Test-Suite` is vendored from commit # aabcb3427745ade7a0b4d49ff016ad7eda8b898b [here](https://github.com/json-schema-org/JSON-Schema-Test-Suite).
56+
57++ `src/draft4.json` is from commit # f3d5aeb5ffbe9d9a5a0ceb761dc47c7c4c2efa68 [here](https://github.com/json-schema/json-schema).
58+
59+## Credits
60+
61+[TJ Weigel](http://tjweigel.com/) created the logo.
62+
63+[Tim Baumann](https://github.com/timjb) wrote [aeson-schema](https://hackage.haskell.org/package/aeson-schema), on which hjsonschema's test code and its implementation of `SchemaGraph` were based.
24
64
25−+ `src/draft4.json` is from commit # c1b12bf699f29a04b4286711c6e3bbfba66f21e5 [here](https://github.com/json-schema/json-schema). The [root ref in remote ref](./JSON-Schema-Test-Suite/tests/draft4/refRemote.json) test has been modified to fix [#175](https://github.com/json-schema-org/JSON-Schema-Test-Suite/issues/175).
65+[Julian Berman](https://github.com/Julian) maintains the fantastic [language agnostic test suite](https://github.com/json-schema/JSON-Schema-Test-Suite).
changelog.md−54
@@ -1,57 +1,3 @@
1−# 1.8.0
2−
3−+ Add GHC 8.4 support (thanks @4e6 !).
4−+ Drop GHC 7.10 support.
5−+ Fix JSON Pointer resolution error.
6−
7−# 1.8.0
8−
9−+ Allow HTTPS references (thanks @creichert!).
10−+ Use `safe-exceptions` to eliminate the risk of catching asynchronous exceptions.
11−
12−# 1.7.2
13−
14−+ Remove upper bounds.
15−
16−# 1.7.1
17−
18−+ Bump http-types.
19−
20−# 1.7.0
21−
22−+ Test with GHC 8.2. Drop GHC 7.8.
23−+ Rework `allUniqueValues` related utility functions.
24−
25−# 1.6.3
26−
27−+ Bump hjsonpointer and QuickCheck.
28−
29−# 1.6.2
30−
31−+ Bump aeson.
32−
33−# 1.6.1
34−
35−+ Fix Haddocks.
36−
37−# 1.6.0
38−
39−+ Fix defect where validators alongside "$ref" weren't ignored.
40−
41−+ Fix defect where local references would fail if an "id" key had set resolution scope to start from a different document.
42−
43−+ Vendor latest tests.
44−
45−+ Remove `ReferencedSchemas`.
46−
47−+ Create `Scope` to hold information that changes during validation.
48−
49−+ Use a sum type for "type" values. Thanks to Philip Weaver (GitHub @pheaver).
50−
51−# 1.5.0.1
52−
53−+ Raise test dep upper bounds.
54−
55# 1.5.0.0
1# 1.5.0.0
56
2
57+ Report details of `"required"` validator failure.
3+ Report details of `"required"` validator failure.
examples/AlternateSchema.hs+57−86
@@ -5,24 +5,27 @@
5-- to copy this module instead of the 'JSONSchema.Draft4'. While it's
5-- to copy this module instead of the 'JSONSchema.Draft4'. While it's
6-- less convenient to write schemas in Haskell without a record type, you
6-- less convenient to write schemas in Haskell without a record type, you
7-- can get the implementation finished with far fewer lines of code.
7-- can get the implementation finished with far fewer lines of code.
8+
8module AlternateSchema where
9module AlternateSchema where
9
10
10import Protolude
11import Protolude
11
12
12−import Data.Aeson (FromJSON(..), Value(..), decodeStrict)
13+import Data.Aeson (FromJSON(..), Value(..),
14+ decodeStrict)
13−import qualified Data.Aeson as AE
15+import qualified Data.Aeson as AE
14−import qualified Data.HashMap.Strict as HM
16+import qualified Data.HashMap.Strict as HM
15−import Data.Maybe (fromMaybe)
17+import Data.Maybe (fromMaybe)
16−import Data.Profunctor (Profunctor(..))
18+import Data.Profunctor (Profunctor (..))
17−
19+
18−import JSONSchema.Draft4 (ValidatorFailure(..), metaSchemaBytes)
20+import JSONSchema.Draft4 (ValidatorFailure(..),
21+ metaSchemaBytes)
19−import JSONSchema.Fetch (SchemaWithURI(..), URISchemaMap(..))
22+import JSONSchema.Fetch (ReferencedSchemas(..),
23+ SchemaWithURI(..))
20−import qualified JSONSchema.Fetch as FE
24+import qualified JSONSchema.Fetch as FE
21−import JSONSchema.Types (Schema(..), Spec(..))
25+import JSONSchema.Types (Schema(..), Spec(..))
22−import qualified JSONSchema.Types as JT
26+import qualified JSONSchema.Types as JT
23−import qualified JSONSchema.Validator.Draft4 as D4
27+import qualified JSONSchema.Validator.Draft4 as D4
24−import JSONSchema.Validator.Reference (BaseURI(..), Scope(..),
28+import JSONSchema.Validator.Reference (updateResolutionScope)
25− updateResolutionScope)
26
29
27--------------------------------------------------
30--------------------------------------------------
28-- * Basic fetching tools
31-- * Basic fetching tools
@@ -42,38 +45,22 @@ draft4FetchInfo = FE.FetchInfo embedded (lookup "id") (lookup "$ref")
42 Just (String t) -> Just t
45 Just (String t) -> Just t
43 _ -> Nothing
46 _ -> Nothing
44
47
45−-- | An implementation of 'JT.embedded'.
46embedded :: Schema -> ([Schema], [Schema])
48embedded :: Schema -> ([Schema], [Schema])
47−embedded s =
48− JT.embedded (d4Spec mempty mempty (Scope s Nothing (BaseURI Nothing))) s
49+embedded s = JT.embedded (d4Spec (ReferencedSchemas s mempty) mempty Nothing) s
49
50
50--------------------------------------------------
51--------------------------------------------------
51-- * Main API
52-- * Main API
52--------------------------------------------------
53--------------------------------------------------
53
54
54validate
55validate
55− :: URISchemaMap Schema
56+ :: ReferencedSchemas Schema
57+ -> Maybe Text
56− -> SchemaWithURI Schema
58+ -> Schema
57 -> Value
59 -> Value
58 -> [ValidatorFailure]
60 -> [ValidatorFailure]
59−validate schemaMap sw =
60− JT.validate (d4Spec schemaMap visited scope) (_swSchema sw)
61− where
62− visited :: D4.VisitedSchemas
63− visited = D4.VisitedSchemas [(Nothing, Nothing)]
61+validate rs = continueValidating rs (D4.VisitedSchemas [(Nothing, Nothing)])
64
62
65− schemaId :: Maybe Text
66− schemaId = FE._fiId draft4FetchInfo (_swSchema sw)
67−
68− scope :: Scope Schema
69− scope = Scope
70− { _topLevelDocument = _swSchema sw
71− , _documentURI = _swURI sw
72− , _currentBaseURI = updateResolutionScope (BaseURI (_swURI sw))
73− schemaId
74− }
75−
76−-- | A schema for schemas themselves. Uses @src/draft4.json@ which is loaded
63+-- A schema for schemas themselves, using @src/draft4.json@ which is loaded
77-- at compile time.
64-- at compile time.
78metaSchema :: Schema
65metaSchema :: Schema
79metaSchema =
66metaSchema =
@@ -82,57 +69,47 @@ metaSchema =
82 $ metaSchemaBytes
69 $ metaSchemaBytes
83
70
84checkSchema :: Schema -> [ValidatorFailure]
71checkSchema :: Schema -> [ValidatorFailure]
85−checkSchema = validate schemaMap (SchemaWithURI metaSchema Nothing)
72+checkSchema = validate referenced Nothing metaSchema . Object . _unSchema
86− . Object
87− . _unSchema
88 where
73 where
89− schemaMap :: URISchemaMap Schema
74+ referenced :: ReferencedSchemas Schema
90− schemaMap =
75+ referenced = ReferencedSchemas
76+ metaSchema
91− URISchemaMap (HM.singleton "http://json-schema.org/draft-04/schema"
77+ (HM.singleton "http://json-schema.org/draft-04/schema"
92 metaSchema)
78 metaSchema)
93
79
94--------------------------------------------------
80--------------------------------------------------
95-- * Spec
81-- * Spec
96--------------------------------------------------
82--------------------------------------------------
97
83
98−validateSubschema
84+continueValidating
99− :: URISchemaMap Schema
85+ :: ReferencedSchemas Schema
100 -> D4.VisitedSchemas
86 -> D4.VisitedSchemas
101− -> Scope Schema
87+ -> Maybe Text
102 -> Schema
88 -> Schema
103 -> Value
89 -> Value
104 -> [ValidatorFailure]
90 -> [ValidatorFailure]
105−validateSubschema schemaMap visited scope schema =
91+continueValidating referenced visited mURI sc =
106− JT.validate (d4Spec schemaMap visited newScope) schema
92+ JT.validate (d4Spec referenced visited newScope) sc
107 where
93 where
108 schemaId :: Maybe Text
94 schemaId :: Maybe Text
109− schemaId = FE._fiId draft4FetchInfo schema
95+ schemaId = case HM.lookup "id" (_unSchema sc) of
96+ Just (String t) -> Just t
97+ _ -> Nothing
110
98
111− newScope :: Scope Schema
99+ newScope :: Maybe Text
112− newScope = scope
113− { _currentBaseURI = updateResolutionScope (_currentBaseURI scope)
100+ newScope = updateResolutionScope mURI schemaId
114− schemaId
115− }
116
101
117d4Spec
102d4Spec
118− :: URISchemaMap Schema
103+ :: ReferencedSchemas Schema
119 -> D4.VisitedSchemas
104 -> D4.VisitedSchemas
120− -> Scope Schema
105+ -> Maybe Text
121 -> Spec Schema ValidatorFailure
106 -> Spec Schema ValidatorFailure
122 -- ^ Here we reuses 'ValidatorFailure' from
107 -- ^ Here we reuses 'ValidatorFailure' from
123 -- 'JSONSchema.Draft4.Failure'. If your validators have different
108 -- 'JSONSchema.Draft4.Failure'. If your validators have different
124 -- failure possibilities you'll need to create your own validator
109 -- failure possibilities you'll need to create your own validator
125 -- failure type.
110 -- failure type.
126−d4Spec schemaMap visited scope =
111+d4Spec referenced visited scope =
127− Spec $
112+ Spec
128− [ dimap
129− f
130− FailureRef
131− (D4.refValidator (FE.getReference schemaMap) updateScope
132− valRef visited scope)
133− ]
134−
135− <> fmap (lmap disableIfRefPresent)
136 [ dimap f FailureMultipleOf D4.multipleOfValidator
113 [ dimap f FailureMultipleOf D4.multipleOfValidator
137 , dimap f FailureMaximum D4.maximumValidator
114 , dimap f FailureMaximum D4.maximumValidator
138 , dimap f FailureMinimum D4.minimumValidator
115 , dimap f FailureMinimum D4.minimumValidator
@@ -150,7 +127,6 @@ d4Spec schemaMap visited scope =
150 D4.IRInvalidItems e -> FailureItems e
127 D4.IRInvalidItems e -> FailureItems e
151 D4.IRInvalidAdditional e -> FailureAdditionalItems e)
128 D4.IRInvalidAdditional e -> FailureAdditionalItems e)
152 (D4.itemsRelatedValidator descend)
129 (D4.itemsRelatedValidator descend)
153− , lmap f D4.definitionsEmbedded
154
130
155 , dimap f FailureMaxProperties D4.maxPropertiesValidator
131 , dimap f FailureMaxProperties D4.maxPropertiesValidator
156 , dimap f FailureMinProperties D4.minPropertiesValidator
132 , dimap f FailureMinProperties D4.minPropertiesValidator
@@ -161,6 +137,10 @@ d4Spec schemaMap visited scope =
161 FailurePropertiesRelated
137 FailurePropertiesRelated
162 (D4.propertiesRelatedValidator descend)
138 (D4.propertiesRelatedValidator descend)
163
139
140+ , dimap
141+ f
142+ FailureRef
143+ (D4.refValidator visited scope (FE.getReference referenced) getRef)
164 , dimap f FailureEnum D4.enumValidator
144 , dimap f FailureEnum D4.enumValidator
165 , dimap f FailureType D4.typeValidator
145 , dimap f FailureType D4.typeValidator
166 , dimap f FailureAllOf (D4.allOfValidator lateral)
146 , dimap f FailureAllOf (D4.allOfValidator lateral)
@@ -170,31 +150,22 @@ d4Spec schemaMap visited scope =
170 ]
150 ]
171 where
151 where
172 f :: FromJSON a => Schema -> Maybe a
152 f :: FromJSON a => Schema -> Maybe a
173− f (Schema a) =
174− case AE.fromJSON (Object a) of
153+ f (Schema a) = case AE.fromJSON (Object a) of
175− AE.Error _ -> Nothing
154+ AE.Error _ -> Nothing
176− AE.Success b -> Just b
155+ AE.Success b -> Just b
177−
156+
178− disableIfRefPresent :: Schema -> Schema
157+ -- 'Maybe Text' is the URI the referenced schema is fetched from,
179− disableIfRefPresent schema =
158+ -- this probably needs a 'newtype' wrapper.
180− case FE._fiRef draft4FetchInfo schema of
159+ getRef
181− Nothing -> schema
182− Just _ -> Schema mempty
183−
184− updateScope :: BaseURI -> Schema -> BaseURI
185− updateScope uri schema =
186− updateResolutionScope uri (FE._fiId draft4FetchInfo schema)
187−
188− valRef
189 :: D4.VisitedSchemas
160 :: D4.VisitedSchemas
190− -> Scope Schema
161+ -> Maybe Text
191 -> Schema
162 -> Schema
192 -> Value
163 -> Value
193 -> [ValidatorFailure]
164 -> [ValidatorFailure]
194− valRef vis sc = JT.validate (d4Spec schemaMap vis sc)
165+ getRef = continueValidating referenced
195
166
196 descend :: Schema -> Value -> [ValidatorFailure]
167 descend :: Schema -> Value -> [ValidatorFailure]
197− descend = validateSubschema schemaMap mempty scope
168+ descend = continueValidating referenced mempty scope
198
169
199 lateral :: Schema -> Value -> [ValidatorFailure]
170 lateral :: Schema -> Value -> [ValidatorFailure]
200− lateral = validateSubschema schemaMap visited scope
171+ lateral = continueValidating referenced visited scope
examples/Simple.hs+5−4
@@ -1,13 +1,14 @@
1+
1module Simple where
2module Simple where
2
3
3import Protolude
4import Protolude
4
5
5−import Data.Aeson (Value(..), decodeStrict, toJSON)
6+import Data.Aeson (Value(..), decodeStrict, toJSON)
6−import qualified Data.ByteString as BS
7+import qualified Data.ByteString as BS
7import qualified Data.List.NonEmpty as NE
8import qualified Data.List.NonEmpty as NE
8−import Data.Maybe (fromMaybe)
9+import Data.Maybe (fromMaybe)
9
10
10−import qualified JSONSchema.Draft4 as D4
11+import qualified JSONSchema.Draft4 as D4
11
12
12badData :: Value
13badData :: Value
13badData = toJSON [True, True]
14badData = toJSON [True, True]
examples/TwoStep.hs+4−3
@@ -10,14 +10,15 @@
10-- 'fetchHTTPAndValidate' which fetched references over HTTP (though it
10-- 'fetchHTTPAndValidate' which fetched references over HTTP (though it
11-- didn't matter because the last schema didn't actually have any).
11-- didn't matter because the last schema didn't actually have any).
12-- This time we need to get them from the filesystem.
12-- This time we need to get them from the filesystem.
13+
13module TwoStep where
14module TwoStep where
14
15
15import Protolude
16import Protolude
16
17
17−import Data.Aeson (Value(..), toJSON)
18+import Data.Aeson (Value (..), toJSON)
18−import qualified Data.List.NonEmpty as NE
19+import qualified Data.List.NonEmpty as NE
19
20
20−import qualified JSONSchema.Draft4 as D4
21+import qualified JSONSchema.Draft4 as D4
21import qualified JSONSchema.Validator.Draft4 as VAL
22import qualified JSONSchema.Validator.Draft4 as VAL
22
23
23schema :: D4.Schema
24schema :: D4.Schema
hjsonschema.cabal+29−25
@@ -1,5 +1,5 @@
1name: hjsonschema
1name: hjsonschema
2−version: 1.9.0
2+version: 1.5.0.0
3synopsis: JSON Schema library
3synopsis: JSON Schema library
4homepage: https://github.com/seagreen/hjsonschema
4homepage: https://github.com/seagreen/hjsonschema
5license: MIT
5license: MIT
@@ -9,8 +9,6 @@ maintainer: ian@housejeffries.com
9category: Data
9category: Data
10build-type: Simple
10build-type: Simple
11cabal-version: >=1.10
11cabal-version: >=1.10
12−-- Rerun multi-ghc-travis (executable make-travis-yml-2) after changing:
13−Tested-With: GHC == 8.0.2, GHC == 8.2.2, GHC == 8.4.1
14extra-source-files:
12extra-source-files:
15 changelog.md
13 changelog.md
16 JSON-Schema-Test-Suite/remotes/*.json
14 JSON-Schema-Test-Suite/remotes/*.json
@@ -34,6 +32,7 @@ library
34 NoImplicitPrelude
32 NoImplicitPrelude
35 OverloadedStrings
33 OverloadedStrings
36 ScopedTypeVariables
34 ScopedTypeVariables
35+ TupleSections
37 if impl(ghc >= 8)
36 if impl(ghc >= 8)
38 default-extensions: StrictData
37 default-extensions: StrictData
39 ghc-options:
38 ghc-options:
@@ -58,28 +57,27 @@ library
58 JSONSchema.Validator.Draft4.Object.Properties
57 JSONSchema.Validator.Draft4.Object.Properties
59 , Import
58 , Import
60 build-depends:
59 build-depends:
61− base >= 4.7 && < 5
60+ base >= 4.7 && < 4.10
62 -- 0.11 is for `.:!`:
61 -- 0.11 is for `.:!`:
63− , aeson >= 0.11
62+ , aeson >= 0.11 && < 1.2
64− , bytestring >= 0.10
63+ , bytestring >= 0.10 && < 0.11
65− , containers >= 0.5
64+ , containers >= 0.5 && < 0.6
66− , file-embed >= 0.0.8
65+ , file-embed >= 0.0.8 && < 0.1
67− , filepath >= 1.3
66+ , filepath >= 1.3 && < 1.5
68− , hashable >= 1.2
67+ , hashable >= 1.2 && < 1.3
69− , hjsonpointer >= 1.1
68+ , hjsonpointer >= 1.1 && < 1.2
70 -- 0.4.30 is for parseUrlThrow:
69 -- 0.4.30 is for parseUrlThrow:
71− , http-client >= 0.4.30
70+ , http-client >= 0.4.30 && < 0.6
72− , http-client-tls >= 0.3
73− , http-types >= 0.8
71+ , http-types >= 0.8 && < 0.10
74− , pcre-heavy >= 1.0
72+ , pcre-heavy >= 1.0 && < 1.1
75− , profunctors >= 5.0
73+ , profunctors >= 5.0 && < 5.3
76− , protolude >= 0.1.10
74+ , protolude >= 0.1.10 && < 1.2
77− , QuickCheck >= 2.8
75+ , QuickCheck >= 2.8 && < 2.10
78− , safe-exceptions >= 0.1.6
79− , scientific >= 0.3
76+ , scientific >= 0.3 && < 0.4
77+ , semigroups >= 0.18 && < 0.19
80− , unordered-containers >= 0.2
78+ , unordered-containers >= 0.2 && < 0.3
81− , text >= 1.1
79+ , text >= 1.1 && < 1.3
82− , vector >= 0.10
80+ , vector >= 0.10 && < 1.0
83
81
84test-suite local
82test-suite local
85 hs-source-dirs:
83 hs-source-dirs:
@@ -114,14 +112,15 @@ test-suite local
114 , hjsonschema
112 , hjsonschema
115 , profunctors
113 , profunctors
116 , protolude
114 , protolude
115+ , semigroups
117 , text
116 , text
118 , QuickCheck
117 , QuickCheck
119 , unordered-containers
118 , unordered-containers
120 , vector
119 , vector
121
120
122 -- directory-1.2.5 required for `listDirectory`:
121 -- directory-1.2.5 required for `listDirectory`:
123− , directory >= 1.2.5
122+ , directory >= 1.2.5 && < 1.4
124− , hspec >= 2.2
123+ , hspec >= 2.2 && < 2.4
125
124
126test-suite remote
125test-suite remote
127 hs-source-dirs:
126 hs-source-dirs:
@@ -152,6 +151,7 @@ test-suite remote
152 , hjsonschema
151 , hjsonschema
153 , profunctors
152 , profunctors
154 , protolude
153 , protolude
154+ , semigroups
155 , text
155 , text
156 , unordered-containers
156 , unordered-containers
157 , vector
157 , vector
@@ -160,3 +160,7 @@ test-suite remote
160 , hspec
160 , hspec
161 , wai-app-static
161 , wai-app-static
162 , warp
162 , warp
163+
164+source-repository head
165+ type: git
166+ location: git://github.com/seagreen/hjsonschema.git
logo.jpgnew file

Binary file not shown.

shell.nix+3−5
@@ -1,15 +1,13 @@
1−{ghc}:
2with (import <nixpkgs> {});
1with (import <nixpkgs> {});
3
2
4haskell.lib.buildStackProject {
3haskell.lib.buildStackProject {
5 name = "none";
4 name = "none";
6 inherit ghc;
5 inherit ghc;
7 buildInputs = [
6 buildInputs = [
7+ pkgconfig
8 pcre
8 pcre
9
9
10− git # for `git:` references in stack.yml.
10+ # for `git:` references in stack.yml:
11− ncurses # for intero
11+ git
12− pkgconfig
13− zlib
14 ];
12 ];
15}
13}
src/Import.hs+8−15
@@ -1,19 +1,12 @@
1
1
2−module Import (module Export, fromJSONEither) where
2+module Import (module Export) where
3
3
4−import Protolude as Export
4+import Protolude as Export
5
5
6−import Data.Aeson as Export
6+import Data.Aeson as Export
7import Data.HashMap.Strict as Export (HashMap)
7import Data.HashMap.Strict as Export (HashMap)
8+import Data.List as Export (length, null) -- for older GHCs
8−import Data.List.NonEmpty as Export (NonEmpty)
9+import Data.List.NonEmpty as Export (NonEmpty)
9−import Data.Vector as Export (Vector)
10+import Data.Vector as Export (Vector)
10−import Test.QuickCheck as Export hiding (Failure, Result, Success,
11+import Test.QuickCheck as Export hiding ((.&.), Failure,
11− (.&.))
12+ Result, Success)
12−
13−import qualified Data.Text as T
14−
15−fromJSONEither :: FromJSON a => Value -> Either Text a
16−fromJSONEither a =
17− case fromJSON a of
18− Error e -> Left (T.pack e)
19− Success b -> Right b
src/JSONSchema/Draft4.hs+30−21
@@ -22,7 +22,8 @@ module JSONSchema.Draft4
22 , ValidatorFailure(..)
22 , ValidatorFailure(..)
23
23
24 -- * Fetching tools
24 -- * Fetching tools
25+ , ReferencedSchemas(..)
25− , URISchemaMap(..)
26+ , FE.URISchemaMap(..)
26 , referencesViaHTTP
27 , referencesViaHTTP
27 , referencesViaFilesystem
28 , referencesViaFilesystem
28
29
@@ -37,19 +38,23 @@ module JSONSchema.Draft4
37
38
38import Import
39import Import
39
40
41+import Control.Arrow (left)
40−import qualified Data.ByteString as BS
42+import qualified Data.ByteString as BS
41−import Data.FileEmbed (embedFile, makeRelativeToProject)
43+import Data.FileEmbed (embedFile,
44+ makeRelativeToProject)
42−import qualified Data.HashMap.Strict as HM
45+import qualified Data.HashMap.Strict as HM
43−import qualified Data.List.NonEmpty as NE
46+import qualified Data.List.NonEmpty as NE
44−import Data.Maybe (fromMaybe)
47+import Data.Maybe (fromMaybe)
45
48
46−import JSONSchema.Draft4.Failure (Invalid(..), SchemaInvalid(..),
49+import JSONSchema.Draft4.Failure (Invalid(..),
50+ SchemaInvalid(..),
47 ValidatorFailure(..))
51 ValidatorFailure(..))
48−import JSONSchema.Draft4.Schema (Schema)
52+import JSONSchema.Draft4.Schema (Schema)
49−import qualified JSONSchema.Draft4.Schema as SC
53+import qualified JSONSchema.Draft4.Schema as SC
50−import qualified JSONSchema.Draft4.Spec as Spec
54+import qualified JSONSchema.Draft4.Spec as Spec
51−import JSONSchema.Fetch (SchemaWithURI(..), URISchemaMap(..))
55+import JSONSchema.Fetch (ReferencedSchemas(..),
56+ SchemaWithURI(..))
52−import qualified JSONSchema.Fetch as FE
57+import qualified JSONSchema.Fetch as FE
53
58
54data HTTPValidationFailure
59data HTTPValidationFailure
55 = HVRequest FE.HTTPFailure
60 = HVRequest FE.HTTPFailure
@@ -65,11 +70,11 @@ fetchHTTPAndValidate
65 -> IO (Either HTTPValidationFailure ())
70 -> IO (Either HTTPValidationFailure ())
66fetchHTTPAndValidate sw v = do
71fetchHTTPAndValidate sw v = do
67 res <- referencesViaHTTP sw
72 res <- referencesViaHTTP sw
68− pure (g =<< f =<< first HVRequest res)
73+ pure (g =<< f =<< left HVRequest res)
69 where
74 where
70 f :: FE.URISchemaMap Schema
75 f :: FE.URISchemaMap Schema
71 -> Either HTTPValidationFailure (Value -> [ValidatorFailure])
76 -> Either HTTPValidationFailure (Value -> [ValidatorFailure])
72− f references = first HVSchema (checkSchema references sw)
77+ f references = left HVSchema (checkSchema references sw)
73
78
74 g :: (Value -> [ValidatorFailure]) -> Either HTTPValidationFailure ()
79 g :: (Value -> [ValidatorFailure]) -> Either HTTPValidationFailure ()
75 g val = case NE.nonEmpty (val v) of
80 g val = case NE.nonEmpty (val v) of
@@ -95,11 +100,11 @@ fetchFilesystemAndValidate
95 -> IO (Either FilesystemValidationFailure ())
100 -> IO (Either FilesystemValidationFailure ())
96fetchFilesystemAndValidate sw v = do
101fetchFilesystemAndValidate sw v = do
97 res <- referencesViaFilesystem sw
102 res <- referencesViaFilesystem sw
98− pure (g =<< f =<< first FVRead res)
103+ pure (g =<< f =<< left FVRead res)
99 where
104 where
100 f :: FE.URISchemaMap Schema
105 f :: FE.URISchemaMap Schema
101 -> Either FilesystemValidationFailure (Value -> [ValidatorFailure])
106 -> Either FilesystemValidationFailure (Value -> [ValidatorFailure])
102− f references = first FVSchema (checkSchema references sw)
107+ f references = left FVSchema (checkSchema references sw)
103
108
104 g :: (Value -> [ValidatorFailure]) -> Either FilesystemValidationFailure ()
109 g :: (Value -> [ValidatorFailure]) -> Either FilesystemValidationFailure ()
105 g val = case NE.nonEmpty (val v) of
110 g val = case NE.nonEmpty (val v) of
@@ -138,7 +143,10 @@ checkSchema
138checkSchema sm sw =
143checkSchema sm sw =
139 case NE.nonEmpty failures of
144 case NE.nonEmpty failures of
140 Just fs -> Left (SchemaInvalid fs)
145 Just fs -> Left (SchemaInvalid fs)
141− Nothing -> Right (Spec.specValidate sm sw)
146+ Nothing -> Right (Spec.specValidate
147+ (ReferencedSchemas (_swSchema sw)
148+ (FE._unURISchemaMap sm))
149+ sw)
142 where
150 where
143 failures :: [(Maybe Text, NonEmpty ValidatorFailure)]
151 failures :: [(Maybe Text, NonEmpty ValidatorFailure)]
144 failures =
152 failures =
@@ -161,11 +169,12 @@ metaSchemaBytes =
161-- (if so the returned list will be empty).
169-- (if so the returned list will be empty).
162schemaValidity :: Schema -> [ValidatorFailure]
170schemaValidity :: Schema -> [ValidatorFailure]
163schemaValidity =
171schemaValidity =
164− Spec.specValidate schemaMap (SchemaWithURI metaSchema Nothing) . toJSON
172+ Spec.specValidate referenced (SchemaWithURI metaSchema Nothing) . toJSON
165 where
173 where
166− schemaMap :: URISchemaMap Schema
174+ referenced :: ReferencedSchemas Schema
167− schemaMap =
175+ referenced = ReferencedSchemas
176+ metaSchema
168− URISchemaMap (HM.singleton "http://json-schema.org/draft-04/schema"
177+ (HM.singleton "http://json-schema.org/draft-04/schema"
169 metaSchema)
178 metaSchema)
170
179
171-- | Check that a set of referenced schemas are valid
180-- | Check that a set of referenced schemas are valid
src/JSONSchema/Draft4/Failure.hs+2−1
@@ -1,8 +1,9 @@
1+
1module JSONSchema.Draft4.Failure where
2module JSONSchema.Draft4.Failure where
2
3
3import Import
4import Import
4
5
5−import JSONSchema.Draft4.Schema (Schema)
6+import JSONSchema.Draft4.Schema (Schema)
6import qualified JSONSchema.Validator.Draft4 as VAL
7import qualified JSONSchema.Validator.Draft4 as VAL
7
8
8-- | Used to report an entire instance being invalidated, as opposed
9-- | Used to report an entire instance being invalidated, as opposed
src/JSONSchema/Draft4/Schema.hs+7−6
@@ -1,13 +1,14 @@
1+
1module JSONSchema.Draft4.Schema where
2module JSONSchema.Draft4.Schema where
2
3
3−import Import hiding (mapMaybe)
4+import Import hiding (mapMaybe)
4
5
5−import qualified Data.HashMap.Strict as HM
6+import qualified Data.HashMap.Strict as HM
6−import Data.List.NonEmpty (NonEmpty)
7+import Data.List.NonEmpty (NonEmpty)
7−import Data.Maybe (fromJust, isJust)
8+import Data.Maybe (fromJust, isJust)
8import Data.Scientific
9import Data.Scientific
9−import qualified Data.Set as Set
10+import qualified Data.Set as Set
10−import qualified Data.Text as T
11+import qualified Data.Text as T
11
12
12import qualified JSONSchema.Validator.Draft4 as D4
13import qualified JSONSchema.Validator.Draft4 as D4
13import JSONSchema.Validator.Utils
14import JSONSchema.Validator.Utils
src/JSONSchema/Draft4/Spec.hs+39−61
@@ -1,73 +1,53 @@
1+
1module JSONSchema.Draft4.Spec where
2module JSONSchema.Draft4.Spec where
2
3
3import Import
4import Import
4
5
5−import Data.Maybe (fromMaybe)
6+import Data.Maybe (fromMaybe)
6−import Data.Profunctor (Profunctor(..))
7+import Data.Profunctor (Profunctor(..))
7
8
8import JSONSchema.Draft4.Failure
9import JSONSchema.Draft4.Failure
9−import JSONSchema.Draft4.Schema (Schema(..), emptySchema)
10+import JSONSchema.Draft4.Schema (Schema(..))
10−import JSONSchema.Fetch (SchemaWithURI(..), URISchemaMap(..))
11+import JSONSchema.Fetch (ReferencedSchemas(..),
12+ SchemaWithURI(..))
11−import qualified JSONSchema.Fetch as FE
13+import qualified JSONSchema.Fetch as FE
12−import JSONSchema.Types (Spec(..))
14+import JSONSchema.Types (Spec(..))
13−import qualified JSONSchema.Types as JT
15+import qualified JSONSchema.Types as JT
14import JSONSchema.Validator.Draft4
16import JSONSchema.Validator.Draft4
15−import JSONSchema.Validator.Reference (BaseURI(..), Scope(..),
17+import JSONSchema.Validator.Reference (updateResolutionScope)
16− updateResolutionScope)
17
18
18−-- | An implementation of 'JT.embedded'.
19embedded :: Schema -> ([Schema], [Schema])
19embedded :: Schema -> ([Schema], [Schema])
20−embedded s =
21− JT.embedded (d4Spec mempty mempty (Scope s Nothing (BaseURI Nothing))) s
20+embedded s = JT.embedded (d4Spec (ReferencedSchemas s mempty) mempty Nothing) s
22
21
23specValidate
22specValidate
24− :: URISchemaMap Schema
23+ :: ReferencedSchemas Schema
25 -> SchemaWithURI Schema
24 -> SchemaWithURI Schema
26 -> Value
25 -> Value
27 -> [ValidatorFailure]
26 -> [ValidatorFailure]
28−specValidate schemaMap sw =
27+specValidate rs =
29− JT.validate (d4Spec schemaMap visited scope) (_swSchema sw)
30− where
31− visited :: VisitedSchemas
32− visited = VisitedSchemas [(Nothing, Nothing)]
28+ continueValidating rs (VisitedSchemas [(Nothing, Nothing)])
33−
34− scope :: Scope Schema
35− scope = Scope
36− { _topLevelDocument = _swSchema sw
37− , _documentURI = _swURI sw
38− , _currentBaseURI = updateResolutionScope (BaseURI (_swURI sw))
39− (_schemaId (_swSchema sw))
40− }
41
29
42−validateSubschema
30+continueValidating
43− :: URISchemaMap Schema
31+ :: ReferencedSchemas Schema
44 -> VisitedSchemas
32 -> VisitedSchemas
45− -> Scope Schema
46− -> Schema
33+ -> SchemaWithURI Schema
47 -> Value
34 -> Value
48 -> [ValidatorFailure]
35 -> [ValidatorFailure]
49−validateSubschema schemaMap visited scope schema =
36+continueValidating referenced visited sw =
50− JT.validate (d4Spec schemaMap visited newScope) schema
37+ JT.validate (d4Spec referenced visited currentScope)
38+ (_swSchema sw)
51 where
39 where
52− newScope :: Scope Schema
40+ currentScope :: Maybe Text
53− newScope = scope
54− { _currentBaseURI = updateResolutionScope (_currentBaseURI scope)
41+ currentScope = updateResolutionScope
42+ (_swURI sw)
55− (_schemaId schema)
43+ (_schemaId (_swSchema sw))
56− }
57
44
58d4Spec
45d4Spec
59− :: URISchemaMap Schema
46+ :: ReferencedSchemas Schema
60 -> VisitedSchemas
47 -> VisitedSchemas
61− -> Scope Schema
48+ -> Maybe Text
62 -> Spec Schema ValidatorFailure
49 -> Spec Schema ValidatorFailure
63−d4Spec schemaMap visited scope = Spec $
50+d4Spec referenced visited scope = Spec
64− [ dimap
65− (fmap Ref . _schemaRef)
66− FailureRef
67− (refValidator (FE.getReference schemaMap) updateScope valRef visited scope)
68− ]
69−
70− <> fmap (lmap disableIfRefPresent)
71 [ dimap (fmap MultipleOf . _schemaMultipleOf) FailureMultipleOf multipleOfValidator
51 [ dimap (fmap MultipleOf . _schemaMultipleOf) FailureMultipleOf multipleOfValidator
72 , dimap
52 , dimap
73 (\s -> Maximum (fromMaybe False (_schemaExclusiveMaximum s)) <$> _schemaMaximum s)
53 (\s -> Maximum (fromMaybe False (_schemaExclusiveMaximum s)) <$> _schemaMaximum s)
@@ -118,6 +98,10 @@ d4Spec schemaMap visited scope = Spec $
118 FailurePropertiesRelated
98 FailurePropertiesRelated
119 (propertiesRelatedValidator descend)
99 (propertiesRelatedValidator descend)
120
100
101+ , dimap
102+ (\s -> Ref <$> _schemaRef s)
103+ FailureRef
104+ (refValidator visited scope (FE.getReference referenced) getRef)
121 , dimap (fmap EnumValidator . _schemaEnum) FailureEnum enumValidator
105 , dimap (fmap EnumValidator . _schemaEnum) FailureEnum enumValidator
122 , dimap (fmap TypeContext . _schemaType) FailureType typeValidator
106 , dimap (fmap TypeContext . _schemaType) FailureType typeValidator
123 , dimap (fmap AllOf . _schemaAllOf) FailureAllOf (allOfValidator lateral)
107 , dimap (fmap AllOf . _schemaAllOf) FailureAllOf (allOfValidator lateral)
@@ -126,25 +110,19 @@ d4Spec schemaMap visited scope = Spec $
126 , dimap (fmap NotValidator . _schemaNot) FailureNot (notValidator lateral)
110 , dimap (fmap NotValidator . _schemaNot) FailureNot (notValidator lateral)
127 ]
111 ]
128 where
112 where
129− disableIfRefPresent :: Schema -> Schema
113+ getRef
130− disableIfRefPresent schema =
131− case _schemaRef schema of
132− Nothing -> schema
133− Just _ -> emptySchema
134−
135− updateScope :: BaseURI -> Schema -> BaseURI
136− updateScope uri schema = updateResolutionScope uri (_schemaId schema)
137−
138− valRef
139 :: VisitedSchemas
114 :: VisitedSchemas
140− -> Scope Schema
115+ -> Maybe Text
141 -> Schema
116 -> Schema
142 -> Value
117 -> Value
143 -> [ValidatorFailure]
118 -> [ValidatorFailure]
144− valRef vis sc = JT.validate (d4Spec schemaMap vis sc)
119+ getRef newVisited newScope schema =
120+ continueValidating referenced newVisited (SchemaWithURI schema newScope)
145
121
146 descend :: Schema -> Value -> [ValidatorFailure]
122 descend :: Schema -> Value -> [ValidatorFailure]
147− descend = validateSubschema schemaMap mempty scope
123+ descend schema =
124+ continueValidating referenced mempty (SchemaWithURI schema scope)
148
125
149 lateral :: Schema -> Value -> [ValidatorFailure]
126 lateral :: Schema -> Value -> [ValidatorFailure]
150− lateral = validateSubschema schemaMap visited scope
127+ lateral schema =
128+ continueValidating referenced visited (SchemaWithURI schema scope)
src/JSONSchema/Fetch.hs+65−46
@@ -1,18 +1,18 @@
1+
1module JSONSchema.Fetch where
2module JSONSchema.Fetch where
2
3
3import Import
4import Import
4
5
6+import Control.Arrow (left)
5−import qualified Control.Exception.Safe as Safe
7+import Control.Exception (IOException, catch)
6−import Control.Monad (foldM)
8+import Control.Monad (foldM)
7−import qualified Data.ByteString as BS
9+import qualified Data.ByteString as BS
8−import qualified Data.ByteString.Lazy as LBS
10+import qualified Data.ByteString.Lazy as LBS
9−import qualified Data.HashMap.Strict as HM
11+import qualified Data.HashMap.Strict as HM
10−import qualified Data.Semigroup as S
12+import qualified Data.Text as T
11−import qualified Data.Text as T
12−import qualified Network.HTTP.Client as NC
13+import qualified Network.HTTP.Client as NC
13−import qualified Network.HTTP.Client.TLS as NCTLS
14+
14−
15−import JSONSchema.Validator.Reference (BaseURI(..), resolveReference,
15+import JSONSchema.Validator.Reference (resolveReference,
16 updateResolutionScope)
16 updateResolutionScope)
17
17
18--------------------------------------------------
18--------------------------------------------------
@@ -27,22 +27,49 @@ data FetchInfo schema = FetchInfo
27 , _fiRef :: schema -> Maybe Text
27 , _fiRef :: schema -> Maybe Text
28 }
28 }
29
29
30+data ReferencedSchemas schema = ReferencedSchemas
31+ { _rsStarting :: !schema
32+ -- ^ Used to resolve relative references when we don't know what the scope
33+ -- of the current schema is. This only happens with starting schemas
34+ -- because if we're using a remote schema we had to know its URI in order
35+ -- to fetch it.
36+ --
37+ -- Tracking the starting schema (instead of just resolving the reference to
38+ -- the current schema being used for validation) is necessary for cases
39+ -- where schemas are embedded inside one another. For instance in this
40+ -- case not distinguishing the starting and "foo" schemas sends the code
41+ -- into an infinite loop:
42+ --
43+ -- {
44+ -- "additionalProperties": false,
45+ -- "properties": {
46+ -- "foo": {
47+ -- "$ref": "#"
48+ -- }
49+ -- }
50+ -- }
51+ , _rsSchemaMap :: !(HashMap Text schema)
52+ -- ^ Map of URIs to schemas.
53+ } deriving (Eq, Show)
54+
30-- | Keys are URIs (without URI fragments).
55-- | Keys are URIs (without URI fragments).
31newtype URISchemaMap schema
56newtype URISchemaMap schema
32 = URISchemaMap { _unURISchemaMap :: HashMap Text schema }
57 = URISchemaMap { _unURISchemaMap :: HashMap Text schema }
33− deriving (Eq, Show, S.Semigroup, Monoid)
58+ deriving (Eq, Show)
34
59
35−-- | A top-level schema along with its location.
36data SchemaWithURI schema = SchemaWithURI
60data SchemaWithURI schema = SchemaWithURI
37 { _swSchema :: !schema
61 { _swSchema :: !schema
38 , _swURI :: !(Maybe Text)
62 , _swURI :: !(Maybe Text)
39− -- ^ This is the URI from which the document was originally fetched.
63+ -- ^ This is the URI identifying the document containing the schema.
40 -- It's different than the schema's "id" field, which controls scope
64 -- It's different than the schema's "id" field, which controls scope
41 -- when resolving references contained in the schema.
65 -- when resolving references contained in the schema.
66+
67+ -- TODO: Make the no URI fragment requirement unnecessary.
42 } deriving (Eq, Show)
68 } deriving (Eq, Show)
43
69
44−getReference :: URISchemaMap schema -> Text -> Maybe schema
70+getReference :: ReferencedSchemas schema -> Maybe Text -> Maybe schema
45−getReference schemaMap t = HM.lookup t (_unURISchemaMap schemaMap)
71+getReference referenced Nothing = Just (_rsStarting referenced)
72+getReference referenced (Just t) = HM.lookup t (_rsSchemaMap referenced)
46
73
47--------------------------------------------------
74--------------------------------------------------
48-- * Fetch via HTTP
75-- * Fetch via HTTP
@@ -61,9 +88,9 @@ referencesViaHTTP'
61 -> SchemaWithURI schema
88 -> SchemaWithURI schema
62 -> IO (Either HTTPFailure (URISchemaMap schema))
89 -> IO (Either HTTPFailure (URISchemaMap schema))
63referencesViaHTTP' info sw = do
90referencesViaHTTP' info sw = do
64− manager <- NC.newManager NCTLS.tlsManagerSettings
91+ manager <- NC.newManager NC.defaultManagerSettings
65 let f = referencesMethodAgnostic (getURL manager) info sw
92 let f = referencesMethodAgnostic (getURL manager) info sw
66− Safe.catch (first HTTPParseFailure <$> f) handler
93+ catch (left HTTPParseFailure <$> f) handler
67 where
94 where
68 getURL :: NC.Manager -> Text -> IO BS.ByteString
95 getURL :: NC.Manager -> Text -> IO BS.ByteString
69 getURL man url = do
96 getURL man url = do
@@ -89,8 +116,7 @@ referencesViaFilesystem'
89 => FetchInfo schema
116 => FetchInfo schema
90 -> SchemaWithURI schema
117 -> SchemaWithURI schema
91 -> IO (Either FilesystemFailure (URISchemaMap schema))
118 -> IO (Either FilesystemFailure (URISchemaMap schema))
92−referencesViaFilesystem' info sw =
119+referencesViaFilesystem' info sw = catch (left FSParseFailure <$> f) handler
93− Safe.catch (first FSParseFailure <$> f) handler
94 where
120 where
95 f :: IO (Either Text (URISchemaMap schema))
121 f :: IO (Either Text (URISchemaMap schema))
96 f = referencesMethodAgnostic (BS.readFile . T.unpack) info sw
122 f = referencesMethodAgnostic (BS.readFile . T.unpack) info sw
@@ -129,33 +155,27 @@ getRecursiveReferences fetchRef info referenced sw =
129 f :: Either Text (URISchemaMap schema)
155 f :: Either Text (URISchemaMap schema)
130 -> SchemaWithURI schema
156 -> SchemaWithURI schema
131 -> IO (Either Text (URISchemaMap schema))
157 -> IO (Either Text (URISchemaMap schema))
132− f (Left e) _ = pure (Left e)
158+ f (Left e) _ = pure (Left e)
133− f (Right (URISchemaMap schemaMap)) (SchemaWithURI schema mURI) =
159+ f (Right (URISchemaMap usm)) (SchemaWithURI schema mUri) =
134 case newRef of
160 case newRef of
135− Nothing -> pure (Right (URISchemaMap schemaMap))
161+ Nothing -> pure (Right (URISchemaMap usm))
136 Just uri -> do
162 Just uri -> do
137 bts <- fetchRef uri
163 bts <- fetchRef uri
138 case eitherDecodeStrict bts of
164 case eitherDecodeStrict bts of
139− Left e -> pure . Left . T.pack $ e
165+ Left e -> pure . Left . T.pack $ e
140− Right s -> getRecursiveReferences
166+ Right schm -> getRecursiveReferences
141− fetchRef
167+ fetchRef
142− info
168+ info
143− (URISchemaMap (HM.insert uri s schemaMap))
169+ (URISchemaMap (HM.insert uri schm usm))
144− (SchemaWithURI s (Just uri))
170+ (SchemaWithURI schm (Just uri))
145 where
171 where
146 newRef :: Maybe Text
172 newRef :: Maybe Text
147− newRef = do
173+ newRef
148− ref <- _fiRef info schema
174+ | Just (Just uri,_) <- resolveReference mUri <$> _fiRef info schema
149−
150− -- Consider the reference before updating the scope.
151− -- If it's a only a fragment this isn't referencing
152− -- a new document.
153− void (fst (resolveReference (BaseURI Nothing) ref))
154−
155− uri <- fst (resolveReference (BaseURI mURI) ref)
156− case HM.lookup uri schemaMap of
175+ = case HM.lookup uri usm of
157− Nothing -> Just uri
176+ Nothing -> Just uri
158− Just _ -> Nothing
177+ Just _ -> Nothing
178+ | otherwise = Nothing
159
179
160-- | Return the schema passed in as an argument, as well as every
180-- | Return the schema passed in as an argument, as well as every
161-- subschema contained within it.
181-- subschema contained within it.
@@ -164,12 +184,11 @@ includeSubschemas
164 FetchInfo schema
184 FetchInfo schema
165 -> SchemaWithURI schema
185 -> SchemaWithURI schema
166 -> [SchemaWithURI schema]
186 -> [SchemaWithURI schema]
167−includeSubschemas info (SchemaWithURI schema mURI) =
187+includeSubschemas info (SchemaWithURI schema mUri) =
168− SchemaWithURI schema mURI
188+ SchemaWithURI schema mUri
169 : (includeSubschemas info =<< subSchemas)
189 : (includeSubschemas info =<< subSchemas)
170 where
190 where
171 subSchemas :: [SchemaWithURI schema]
191 subSchemas :: [SchemaWithURI schema]
172 subSchemas =
192 subSchemas =
173− let newScope = updateResolutionScope (BaseURI mURI) (_fiId info schema)
193+ (\a -> SchemaWithURI a (updateResolutionScope mUri (_fiId info schema)))
174− updateScope s = SchemaWithURI s (_unBaseURI newScope)
175− in updateScope <$> uncurry (<>) (_fiEmbedded info schema)
194+ <$> uncurry (<>) (_fiEmbedded info schema)
src/JSONSchema/Types.hs+1
@@ -1,3 +1,4 @@
1+
1module JSONSchema.Types where
2module JSONSchema.Types where
2
3
3import Import
4import Import
src/JSONSchema/Validator/Draft4.hs+19−19
@@ -1,7 +1,5 @@
1-- | Turn the validation functions into actual 'Validator's.
1-- | Turn the validation functions into actual 'Validator's.
2−--
2+
3−-- This is frankly a lot of busywork. It can perhaps be moved into the
4−-- validator modules themselves once we're sure this is the right design.
5module JSONSchema.Validator.Draft4
3module JSONSchema.Validator.Draft4
6 ( module JSONSchema.Validator.Draft4
4 ( module JSONSchema.Validator.Draft4
7 , module Export
5 , module Export
@@ -9,16 +7,18 @@ module JSONSchema.Validator.Draft4
9
7
10import Import
8import Import
11
9
12−import qualified Data.HashMap.Strict as HM
10+import qualified Data.HashMap.Strict as HM
13−import qualified Data.List.NonEmpty as NE
11+import qualified Data.List.NonEmpty as NE
12+import Data.Maybe (catMaybes, maybe, maybeToList)
13+import Data.Text (Text)
14
14
15−import JSONSchema.Validator.Draft4.Any as Export
15+import JSONSchema.Validator.Draft4.Any as Export
16−import JSONSchema.Validator.Draft4.Array as Export
16+import JSONSchema.Validator.Draft4.Array as Export
17import JSONSchema.Validator.Draft4.Number as Export
17import JSONSchema.Validator.Draft4.Number as Export
18import JSONSchema.Validator.Draft4.Object as Export
18import JSONSchema.Validator.Draft4.Object as Export
19import JSONSchema.Validator.Draft4.String as Export
19import JSONSchema.Validator.Draft4.String as Export
20−import JSONSchema.Validator.Reference (BaseURI(..), Scope(..))
20+import JSONSchema.Validator.Types (Validator(..))
21−import JSONSchema.Validator.Types (Validator(..))
21+import JSONSchema.Validator.Utils (fromJSONEither)
22
22
23-- | For internal use.
23-- | For internal use.
24--
24--
@@ -75,8 +75,6 @@ minItemsValidator = Validator noEmbedded (run minItemsVal)
75uniqueItemsValidator :: Validator a (Maybe UniqueItems) UniqueItemsInvalid
75uniqueItemsValidator :: Validator a (Maybe UniqueItems) UniqueItemsInvalid
76uniqueItemsValidator = Validator noEmbedded (run uniqueItemsVal)
76uniqueItemsValidator = Validator noEmbedded (run uniqueItemsVal)
77
77
78−-- TODO: Add tests to the language agnostic test suite to
79−-- make sure @"additionalItems"@ subschemas are embedded correctly.
80itemsRelatedValidator
78itemsRelatedValidator
81 :: (schema -> Value -> [err])
79 :: (schema -> Value -> [err])
82 -> Validator schema (ItemsRelated schema) (ItemsRelatedInvalid err)
80 -> Validator schema (ItemsRelated schema) (ItemsRelatedInvalid err)
@@ -147,7 +145,7 @@ propertiesRelatedValidator f =
147 <> HM.elems (fromMaybe mempty (_propPattern a))
145 <> HM.elems (fromMaybe mempty (_propPattern a))
148 <> case _propAdditional a of
146 <> case _propAdditional a of
149 Just (AdditionalPropertiesObject b) -> [b]
147 Just (AdditionalPropertiesObject b) -> [b]
150− _ -> mempty
148+ _ -> mempty
151 ))
149 ))
152 (\a b -> case fromJSONEither b of
150 (\a b -> case fromJSONEither b of
153 Left _ -> mempty
151 Left _ -> mempty
@@ -161,6 +159,9 @@ instance FromJSON schema => FromJSON (Definitions schema) where
161 parseJSON = withObject "Definitions" $ \o ->
159 parseJSON = withObject "Definitions" $ \o ->
162 Definitions <$> o .: "definitions"
160 Definitions <$> o .: "definitions"
163
161
162+-- TODO: Add tests to the language agnostic test suite to
163+-- make sure these schemas are embedded correctly
164+-- (and do so for @"additionalItems"@ as well).
164definitionsEmbedded
165definitionsEmbedded
165 :: Validator
166 :: Validator
166 schema
167 schema
@@ -179,16 +180,15 @@ definitionsEmbedded =
179
180
180refValidator
181refValidator
181 :: (FromJSON schema, ToJSON schema)
182 :: (FromJSON schema, ToJSON schema)
183+ => VisitedSchemas
182− => (Text -> Maybe schema)
184+ -> Maybe Text
183− -> (BaseURI -> schema -> BaseURI)
185+ -> (Maybe Text -> Maybe schema)
184− -> (VisitedSchemas -> Scope schema -> schema -> Value -> [err])
186+ -> (VisitedSchemas -> Maybe Text -> schema -> Value -> [err])
185− -> VisitedSchemas
186− -> Scope schema
187 -> Validator a (Maybe Ref) (RefInvalid err)
187 -> Validator a (Maybe Ref) (RefInvalid err)
188−refValidator getRef updateScope f visited scope =
188+refValidator visited scope getRef f =
189 Validator
189 Validator
190 noEmbedded
190 noEmbedded
191− (run (refVal getRef updateScope f visited scope))
191+ (run (refVal visited scope getRef f))
192
192
193enumValidator :: Validator a (Maybe EnumValidator) EnumInvalid
193enumValidator :: Validator a (Maybe EnumValidator) EnumInvalid
194enumValidator = Validator noEmbedded (run enumVal)
194enumValidator = Validator noEmbedded (run enumVal)
src/JSONSchema/Validator/Draft4/Any.hs+59−217
@@ -1,24 +1,20 @@
1+
1module JSONSchema.Validator.Draft4.Any where
2module JSONSchema.Validator.Draft4.Any where
2
3
3−import Import hiding ((<>))
4+import Import
4−
5+
5−import Data.Aeson.TH (constructorTagModifier)
6−import Data.Char (toLower)
7−import qualified Data.HashMap.Strict as HM
8−import Data.List.NonEmpty (NonEmpty((:|)))
6+import Data.List.NonEmpty (NonEmpty((:|)))
9−import qualified Data.List.NonEmpty as NE
7+import qualified Data.List.NonEmpty as NE
10−import qualified Data.Scientific as SCI
8+import qualified Data.Scientific as SCI
11−import Data.Semigroup
9+import Data.Semigroup (Semigroup) -- for older GHCs
12−import Data.Set (Set)
10+import Data.Set (Set)
13−import qualified Data.Set as Set
11+import qualified Data.Set as S
14−import Data.Text.Encoding.Error (UnicodeException)
15−import qualified JSONPointer as JP
12+import qualified JSONPointer as JP
16−import Network.HTTP.Types.URI (urlDecode)
13+
17−
14+import qualified JSONSchema.Validator.Utils as UT
18−import JSONSchema.Validator.Reference (BaseURI(..), Scope(..),
15+import JSONSchema.Validator.Reference (URIBaseAndFragment,
19− URIAndFragment,
16+ resolveFragment,
20 resolveReference)
17 resolveReference)
21−import qualified JSONSchema.Validator.Utils as UT
22
18
23--------------------------------------------------
19--------------------------------------------------
24-- * $ref
20-- * $ref
@@ -43,156 +39,42 @@ data RefInvalid err
43 -- Also note that ideally we would enforce in the type system that any
39 -- Also note that ideally we would enforce in the type system that any
44 -- failing references be dealt with before valididation. Then this could
40 -- failing references be dealt with before valididation. Then this could
45 -- be removed entirely.
41 -- be removed entirely.
46− | RefPointerResolution JSONPointerError
42+ | RefPointerResolution Text
47− | RefLoop Text VisitedSchemas URIAndFragment
43+ | RefLoop Text VisitedSchemas URIBaseAndFragment
48 | RefInvalid Text Value (NonEmpty err)
44 | RefInvalid Text Value (NonEmpty err)
49 -- ^ 'Text' is the URI and 'Value' is the linked schema.
45 -- ^ 'Text' is the URI and 'Value' is the linked schema.
50 deriving (Eq, Show)
46 deriving (Eq, Show)
51
47
52newtype VisitedSchemas
48newtype VisitedSchemas
53− = VisitedSchemas { _unVisited :: [URIAndFragment] }
49+ = VisitedSchemas { _unVisited :: [URIBaseAndFragment] }
54 deriving (Eq, Show, Semigroup, Monoid)
50 deriving (Eq, Show, Semigroup, Monoid)
55
51
56refVal
52refVal
57 :: forall err schema. (FromJSON schema, ToJSON schema)
53 :: forall err schema. (FromJSON schema, ToJSON schema)
54+ => VisitedSchemas
58− => (Text -> Maybe schema)
55+ -> Maybe Text
59− -- ^ Look up a schema.
56+ -> (Maybe Text -> Maybe schema)
60− -> (BaseURI -> schema -> BaseURI)
61− -- ^ Update scope (needed after moving deeper into nested schemas).
62− -> (VisitedSchemas -> Scope schema -> schema -> Value -> [err])
57+ -> (VisitedSchemas -> Maybe Text -> schema -> Value -> [err])
63− -- ^ Validate data.
64− -> VisitedSchemas
65− -> Scope schema
66 -> Ref
58 -> Ref
67 -> Value
59 -> Value
68 -> Maybe (RefInvalid err)
60 -> Maybe (RefInvalid err)
69−refVal getRef updateScope val visited scope (Ref reference) x
61+refVal visited scope getRef f (Ref reference) x
70 | (mURI, mFragment) `elem` _unVisited visited =
62 | (mURI, mFragment) `elem` _unVisited visited =
71 Just (RefLoop reference visited (mURI, mFragment))
63 Just (RefLoop reference visited (mURI, mFragment))
72− | otherwise = leftToMaybe $ do
64+ | otherwise =
73−
65+ case getRef mURI of
74− -- Get the referenced document
66+ Nothing -> Just (RefResolution reference)
75−
67+ Just schema ->
76− (newScope, doc) <- first RefResolution
77− $ getDocument getRef updateScope scope mURI reference
78−
79− -- Get the correct subschema within that document.
80−
81− res <- case mFragment of
68+ case resolveFragment mFragment schema of
82− Nothing -> Right (newScope, doc)
83− Just fragment -> first RefPointerResolution
69+ Nothing -> Just (RefPointerResolution reference)
84− $ resolveFragment updateScope newScope fragment
70+ Just s ->
85− let (finalScope, schema) = res
86−
87− -- Check if that schema is valid.
88−
89− let newVisited = VisitedSchemas [(_documentURI newScope, mFragment)]
71+ let newVisited = (VisitedSchemas [(mURI, mFragment)]
90− <> visited
72+ <> visited)
91− failures = val newVisited finalScope schema x
73+ errs = f newVisited mURI s x
92− first (RefInvalid reference (toJSON schema))
74+ in RefInvalid reference (toJSON schema)
93− . maybeToLeft ()
94− $ NE.nonEmpty failures
75+ <$> NE.nonEmpty errs
95 where
76 where
96− mURI :: Maybe Text
97− mFragment :: Maybe Text
98− (mURI, mFragment) = resolveReference (_currentBaseURI scope) reference
77+ (mURI, mFragment) = resolveReference scope reference
99−
100−getDocument
101− :: forall schema. (Text -> Maybe schema)
102− -> (BaseURI -> schema -> BaseURI)
103− -> Scope schema
104− -> Maybe Text
105− -> Text
106− -> Either Text (Scope schema, schema)
107− -- ^ 'Left' is the URI of the document we failed to resolve.
108−getDocument getRef updateScope scope mURI reference =
109− case mURI <* fst (resolveReference (BaseURI Nothing) reference) of
110− Nothing -> Right topOfThisDoc
111− Just uri ->
112− case getRef uri of
113− Nothing -> Left uri
114− Just s -> Right ( Scope s mURI (updateScope (BaseURI mURI) s)
115− , s
116− )
117− where
118− topOfThisDoc :: (Scope schema, schema)
119− topOfThisDoc =
120− ( scope { _currentBaseURI =
121− updateScope (BaseURI (_documentURI scope))
122− (_topLevelDocument scope)
123− }
124− , _topLevelDocument scope
125− )
126−
127−data JSONPointerError
128− = URLDecodingError UnicodeException
129− -- ^ Aspirationally internal.
130− | FormatError JP.FormatError
131− | ResolutionError JP.ResolutionError
132− | SubschemaDecodingError Text
133− -- ^ Aspirationally internal.
134− deriving (Eq, Show)
135−
136−resolveFragment
137− :: (FromJSON schema, ToJSON schema)
138− => (BaseURI -> schema -> BaseURI)
139− -> Scope schema
140− -> Text
141− -> Either JSONPointerError (Scope schema, schema)
142−resolveFragment updateScope scope fragment = do
143− urlDecoded <- first URLDecodingError
144− . decodeUtf8'
145− . urlDecode True
146− . encodeUtf8
147− $ fragment
148− JP.Pointer tokens <- first FormatError (JP.unescape urlDecoded)
149− let acc = (toJSON (_topLevelDocument scope), _currentBaseURI scope)
150− (schemaVal, base) <- foldM go acc tokens
151− schema <- first SubschemaDecodingError (fromJSONEither schemaVal)
152− pure (scope { _currentBaseURI = base }, schema)
153− where
154− -- We have to step through the document JSON Pointer token
155− -- by JSON Pointer token so that we can update the scope
156− -- based on each @"id"@ we encounter.
157− --
158− -- TODO: Do we need specialized code to skip @"id"@s such
159− -- as property keys that aren't meant to change scope?
160− -- Perhaps this should be added to the language agnostic
161− -- test suite as well.
162− --
163− -- In the meantime 'newBaseURIFromFragment' drops all keys
164− -- from JSON objects except "id", which at least prevents
165− -- SubschemaDecodingError in a situation where one of the
166− -- values we step through isn't a valid schema.
167− go :: (Value, BaseURI)
168− -> JP.Token
169− -> Either JSONPointerError (Value, BaseURI)
170− go (lastVal, baseURI) tok = do
171− v <- first ResolutionError (JP.resolveToken tok lastVal)
172− newBase <- newBaseURIFromFragment updateScope baseURI v
173− Right (v, newBase)
174−
175−-- | Update the 'BaseURI' (the store of the current "id" value)
176−-- after resolving one token of a JSON Pointer and stepping into
177−-- a new 'Value'.
178−newBaseURIFromFragment
179− :: FromJSON schema
180− => (BaseURI -> schema -> BaseURI)
181− -> BaseURI
182− -> Value
183− -> Either JSONPointerError BaseURI
184−newBaseURIFromFragment updateScope baseURI v =
185− case v of
186− Object hm -> do
187− let hmWithOnlyId = case HM.lookup idKey hm of
188− Nothing -> mempty
189− Just idVal -> HM.singleton idKey idVal
190− schema <- first SubschemaDecodingError (fromJSONEither (Object hmWithOnlyId))
191− Right (updateScope baseURI schema)
192− _ -> Right baseURI
193− where
194− idKey :: Text
195− idKey = "id"
196
78
197--------------------------------------------------
79--------------------------------------------------
198-- * enum
80-- * enum
@@ -227,10 +109,7 @@ instance Arbitrary EnumValidator where
227 Just ne -> pure (EnumValidator ne)
109 Just ne -> pure (EnumValidator ne)
228 where
110 where
229 toUnique :: [Value] -> [Value]
111 toUnique :: [Value] -> [Value]
230− toUnique = fmap UT._unOrdValue
112+ toUnique = fmap UT._unOrdValue . S.toList . S.fromList . fmap UT.OrdValue
231− . Set.toList
232− . Set.fromList
233− . fmap UT.OrdValue
234
113
235data EnumInvalid
114data EnumInvalid
236 = EnumInvalid EnumValidator Value
115 = EnumInvalid EnumValidator Value
@@ -238,9 +117,9 @@ data EnumInvalid
238
117
239enumVal :: EnumValidator -> Value -> Maybe EnumInvalid
118enumVal :: EnumValidator -> Value -> Maybe EnumInvalid
240enumVal a@(EnumValidator vs) x
119enumVal a@(EnumValidator vs) x
241− | not (UT.allUniqueValues vs) = Nothing
120+ | not (UT.allUniqueValues' vs) = Nothing
242− | x `elem` vs = Nothing
121+ | x `elem` vs = Nothing
243− | otherwise = Just $ EnumInvalid a x
122+ | otherwise = Just $ EnumInvalid a x
244
123
245--------------------------------------------------
124--------------------------------------------------
246-- * type
125-- * type
@@ -258,25 +137,10 @@ instance FromJSON TypeContext where
258 TypeContext <$> o .: "type"
137 TypeContext <$> o .: "type"
259
138
260data TypeValidator
139data TypeValidator
261− = TypeValidatorString SchemaType
140+ = TypeValidatorString Text
262− | TypeValidatorArray (Set SchemaType)
141+ | TypeValidatorArray (Set Text)
263 deriving (Eq, Show)
142 deriving (Eq, Show)
264
143
265−instance Semigroup TypeValidator where
266− (<>) x y
267− | isEmpty x = x
268− | isEmpty y = y
269− | x == y = x
270− | otherwise = TypeValidatorArray (setFromTypeValidator x
271− `Set.union`
272− setFromTypeValidator y)
273− where
274− isEmpty :: TypeValidator -> Bool
275− isEmpty (TypeValidatorString _) = False
276− isEmpty (TypeValidatorArray ts) = Set.null ts
277−
278− stimes = stimesIdempotent
279−
280instance FromJSON TypeValidator where
144instance FromJSON TypeValidator where
281 parseJSON v = fmap TypeValidatorString (parseJSON v)
145 parseJSON v = fmap TypeValidatorString (parseJSON v)
282 <|> fmap TypeValidatorArray (parseJSON v)
146 <|> fmap TypeValidatorArray (parseJSON v)
@@ -286,63 +150,40 @@ instance ToJSON TypeValidator where
286 toJSON (TypeValidatorArray ts) = toJSON ts
150 toJSON (TypeValidatorArray ts) = toJSON ts
287
151
288instance Arbitrary TypeValidator where
152instance Arbitrary TypeValidator where
289− arbitrary = oneof [ TypeValidatorString <$> arbitrary
153+ arbitrary = oneof [ TypeValidatorString <$> UT.arbitraryText
290− , TypeValidatorArray <$> arbitrary
154+ , TypeValidatorArray <$> UT.arbitrarySetOfText
291 ]
155 ]
292
156
293−data SchemaType
294− = SchemaObject
295− | SchemaArray
296− | SchemaString
297− | SchemaNumber
298− | SchemaInteger
299− | SchemaBoolean
300− | SchemaNull
301− deriving (Eq, Ord, Show, Bounded, Enum, Generic)
302−
303−instance FromJSON SchemaType where
304− parseJSON = genericParseJSON
305− defaultOptions
306− { constructorTagModifier = fmap toLower . drop 6 }
307−
308−instance ToJSON SchemaType where
309− toJSON = genericToJSON
310− defaultOptions
311− { constructorTagModifier = fmap toLower . drop 6 }
312−
313−instance Arbitrary SchemaType where
314− arbitrary = arbitraryBoundedEnum
315−
316data TypeValidatorInvalid
157data TypeValidatorInvalid
317 = TypeValidatorInvalid TypeValidator Value
158 = TypeValidatorInvalid TypeValidator Value
318 deriving (Eq, Show)
159 deriving (Eq, Show)
319
160
320typeVal :: TypeContext -> Value -> Maybe TypeValidatorInvalid
161typeVal :: TypeContext -> Value -> Maybe TypeValidatorInvalid
321typeVal (TypeContext tv) x
162typeVal (TypeContext tv) x
322− | Set.null matches = Just (TypeValidatorInvalid tv x)
163+ | S.null matches = Just (TypeValidatorInvalid tv x)
323− | otherwise = Nothing
164+ | otherwise = Nothing
324 where
165 where
325 -- There can be more than one match because a 'Value' can be both a
166 -- There can be more than one match because a 'Value' can be both a
326 -- @"number"@ and an @"integer"@.
167 -- @"number"@ and an @"integer"@.
327− matches :: Set SchemaType
168+ matches :: Set Text
328− matches = Set.intersection okTypes (setFromTypeValidator tv)
169+ matches = S.intersection okTypes (setFromTypeValidator tv)
329
170
330− okTypes :: Set SchemaType
171+ okTypes :: Set Text
331 okTypes =
172 okTypes =
332 case x of
173 case x of
333− Null -> Set.singleton SchemaNull
174+ Null -> S.singleton "null"
334− (Array _) -> Set.singleton SchemaArray
175+ (Array _) -> S.singleton "array"
335− (Bool _) -> Set.singleton SchemaBoolean
176+ (Bool _) -> S.singleton "boolean"
336− (Object _) -> Set.singleton SchemaObject
177+ (Object _) -> S.singleton "object"
337− (String _) -> Set.singleton SchemaString
178+ (String _) -> S.singleton "string"
338 (Number y) ->
179 (Number y) ->
339 if SCI.isInteger y
180 if SCI.isInteger y
340− then Set.fromList [SchemaNumber, SchemaInteger]
181+ then S.fromList ["number", "integer"]
341− else Set.singleton SchemaNumber
182+ else S.singleton "number"
342
183
343-- | Internal.
184-- | Internal.
344−setFromTypeValidator :: TypeValidator -> Set SchemaType
185+setFromTypeValidator :: TypeValidator -> Set Text
345−setFromTypeValidator (TypeValidatorString t) = Set.singleton t
186+setFromTypeValidator (TypeValidatorString t) = S.singleton t
346setFromTypeValidator (TypeValidatorArray ts) = ts
187setFromTypeValidator (TypeValidatorArray ts) = ts
347
188
348--------------------------------------------------
189--------------------------------------------------
@@ -399,7 +240,8 @@ anyOfVal
399 -> Value
240 -> Value
400 -> Maybe (AnyOfInvalid err)
241 -> Maybe (AnyOfInvalid err)
401anyOfVal f (AnyOf subSchemas) x
242anyOfVal f (AnyOf subSchemas) x
243+ -- Replace with @null@ once we drop GHC 7.8:
402− | any (null . snd) perhapsFailures = Nothing
244+ | any (((==) 0 . length) . snd) perhapsFailures = Nothing
403 | otherwise = AnyOfInvalid <$> NE.nonEmpty failures
245 | otherwise = AnyOfInvalid <$> NE.nonEmpty failures
404 where
246 where
405 perhapsFailures :: [(JP.Index, [err])]
247 perhapsFailures :: [(JP.Index, [err])]
src/JSONSchema/Validator/Draft4/Array.hs+7−8
@@ -1,10 +1,11 @@
1+
1module JSONSchema.Validator.Draft4.Array where
2module JSONSchema.Validator.Draft4.Array where
2
3
3import Import
4import Import
4
5
5−import qualified Data.List.NonEmpty as NE
6+import qualified Data.List.NonEmpty as NE
6−import qualified Data.Vector as V
7+import qualified Data.Vector as V
7−import qualified JSONPointer as JP
8+import qualified JSONPointer as JP
8
9
9import JSONSchema.Validator.Utils (allUniqueValues)
10import JSONSchema.Validator.Utils (allUniqueValues)
10
11
@@ -66,7 +67,7 @@ instance FromJSON UniqueItems where
66 parseJSON = withObject "UniqueItems" $ \o ->
67 parseJSON = withObject "UniqueItems" $ \o ->
67 UniqueItems <$> o .: "uniqueItems"
68 UniqueItems <$> o .: "uniqueItems"
68
69
69−newtype UniqueItemsInvalid
70+data UniqueItemsInvalid
70 = UniqueItemsInvalid (Vector Value)
71 = UniqueItemsInvalid (Vector Value)
71 deriving (Eq, Show)
72 deriving (Eq, Show)
72
73
@@ -173,8 +174,7 @@ itemsVal f a xs =
173 :: schema
174 :: schema
174 -> (JP.Index, Value)
175 -> (JP.Index, Value)
175 -> Maybe (JP.Index, NonEmpty err)
176 -> Maybe (JP.Index, NonEmpty err)
176− validateElem schema (index,x) =
177+ validateElem schema (index,x) = (index,) <$> NE.nonEmpty (f schema x)
177− (\v -> (index, v)) <$> NE.nonEmpty (f schema x)
178
178
179--------------------------------------------------
179--------------------------------------------------
180-- * additionalItems
180-- * additionalItems
@@ -219,7 +219,6 @@ additionalItemsVal _ (AdditionalBool False) xs =
219 AdditionalItemsBoolInvalid <$> NE.nonEmpty xs
219 AdditionalItemsBoolInvalid <$> NE.nonEmpty xs
220additionalItemsVal f (AdditionalObject subSchema) xs =
220additionalItemsVal f (AdditionalObject subSchema) xs =
221 let res = mapMaybe
221 let res = mapMaybe
222− (\(index,x) -> (\v -> (index, v))
223− <$> NE.nonEmpty (f subSchema x))
222+ (\(index,x) -> (index,) <$> NE.nonEmpty (f subSchema x))
224 xs
223 xs
225 in AdditionalItemsObjectInvalid <$> NE.nonEmpty res
224 in AdditionalItemsObjectInvalid <$> NE.nonEmpty res
src/JSONSchema/Validator/Draft4/Number.hs+2−1
@@ -1,8 +1,9 @@
1+
1module JSONSchema.Validator.Draft4.Number where
2module JSONSchema.Validator.Draft4.Number where
2
3
3import Import
4import Import
4
5
5−import Data.Fixed (mod')
6+import Data.Fixed (mod')
6import Data.Scientific (Scientific)
7import Data.Scientific (Scientific)
7
8
8--------------------------------------------------
9--------------------------------------------------
src/JSONSchema/Validator/Draft4/Object.hs+10−6
@@ -1,3 +1,4 @@
1+
1module JSONSchema.Validator.Draft4.Object
2module JSONSchema.Validator.Draft4.Object
2 ( module JSONSchema.Validator.Draft4.Object
3 ( module JSONSchema.Validator.Draft4.Object
3 , module JSONSchema.Validator.Draft4.Object.Properties
4 , module JSONSchema.Validator.Draft4.Object.Properties
@@ -5,11 +6,11 @@ module JSONSchema.Validator.Draft4.Object
5
6
6import Import
7import Import
7
8
8−import qualified Data.HashMap.Strict as HM
9+import qualified Data.HashMap.Strict as HM
9−import qualified Data.List.NonEmpty as NE
10+import qualified Data.List.NonEmpty as NE
10−import Data.Set (Set)
11+import Data.Set (Set)
11−import qualified Data.Set as Set
12+import qualified Data.Set as Set
12−import qualified Data.Text as T
13+import qualified Data.Text as T
13
14
14import JSONSchema.Validator.Draft4.Object.Properties
15import JSONSchema.Validator.Draft4.Object.Properties
15import JSONSchema.Validator.Utils
16import JSONSchema.Validator.Utils
@@ -95,6 +96,9 @@ data RequiredInvalid
95
96
96requiredVal :: Required -> HashMap Text Value -> Maybe RequiredInvalid
97requiredVal :: Required -> HashMap Text Value -> Maybe RequiredInvalid
97requiredVal r@(Required ts) x
98requiredVal r@(Required ts) x
99+ -- NOTE: When we no longer need to support GHCs before 7.10
100+ -- we can use null from Prelude throughout the library
101+ -- instead of specialized versions.
98 | Set.null ts = Nothing
102 | Set.null ts = Nothing
99 | Set.null leftovers = Nothing
103 | Set.null leftovers = Nothing
100 | otherwise = Just (RequiredInvalid r leftovers x)
104 | otherwise = Just (RequiredInvalid r leftovers x)
@@ -141,7 +145,7 @@ data DependencyMemberInvalid err
141 | PropertyDepInvalid (Set Text) (HashMap Text Value)
145 | PropertyDepInvalid (Set Text) (HashMap Text Value)
142 deriving (Eq, Show)
146 deriving (Eq, Show)
143
147
144−newtype DependenciesInvalid err
148+data DependenciesInvalid err
145 = DependenciesInvalid (HashMap Text (DependencyMemberInvalid err))
149 = DependenciesInvalid (HashMap Text (DependencyMemberInvalid err))
146 deriving (Eq, Show)
150 deriving (Eq, Show)
147
151
src/JSONSchema/Validator/Draft4/Object/Properties.hs+6−6
@@ -1,17 +1,17 @@
1+
1module JSONSchema.Validator.Draft4.Object.Properties where
2module JSONSchema.Validator.Draft4.Object.Properties where
2
3
3import Import
4import Import
4
5
5−import qualified Data.Hashable as HA
6+import qualified Data.Hashable as HA
6−import qualified Data.HashMap.Strict as HM
7+import qualified Data.HashMap.Strict as HM
7−import qualified Data.List.NonEmpty as NE
8+import qualified Data.List.NonEmpty as NE
8−import Data.Text.Encoding (encodeUtf8)
9+import Data.Text.Encoding (encodeUtf8)
9−import qualified JSONPointer as JP
10+import qualified JSONPointer as JP
10import qualified Text.Regex.PCRE.Heavy as RE
11import qualified Text.Regex.PCRE.Heavy as RE
11
12
12data PropertiesRelated schema = PropertiesRelated
13data PropertiesRelated schema = PropertiesRelated
13 { _propProperties :: Maybe (HashMap Text schema)
14 { _propProperties :: Maybe (HashMap Text schema)
14− -- ^ 'Maybe' is used to distinguish whether the key is present or not.
15 , _propPattern :: Maybe (HashMap Text schema)
15 , _propPattern :: Maybe (HashMap Text schema)
16 , _propAdditional :: Maybe (AdditionalProperties schema)
16 , _propAdditional :: Maybe (AdditionalProperties schema)
17 } deriving (Eq, Show)
17 } deriving (Eq, Show)
src/JSONSchema/Validator/Draft4/String.hs+3−2
@@ -1,9 +1,10 @@
1+
1module JSONSchema.Validator.Draft4.String where
2module JSONSchema.Validator.Draft4.String where
2
3
3import Import
4import Import
4
5
5−import qualified Data.Text as T
6+import qualified Data.Text as T
6−import Data.Text.Encoding (encodeUtf8)
7+import Data.Text.Encoding (encodeUtf8)
7import qualified Text.Regex.PCRE.Heavy as RE
8import qualified Text.Regex.PCRE.Heavy as RE
8
9
9--------------------------------------------------
10--------------------------------------------------
src/JSONSchema/Validator/Reference.hs+36−28
@@ -3,34 +3,42 @@
3--
3--
4-- And is extended for JSON Schema here:
4-- And is extended for JSON Schema here:
5-- <http://json-schema.org/latest/json-schema-core.html#anchor26>
5-- <http://json-schema.org/latest/json-schema-core.html#anchor26>
6+
6module JSONSchema.Validator.Reference where
7module JSONSchema.Validator.Reference where
7
8
8import Import
9import Import
9
10
10−import qualified Data.Text as T
11+import qualified Data.Text as T
12+import Data.Text.Encoding (decodeUtf8, encodeUtf8)
13+import qualified JSONPointer as JP
14+import Network.HTTP.Types.URI (urlDecode)
11−import System.FilePath (dropFileName, (</>))
15+import System.FilePath ((</>), dropFileName)
12−
13−data Scope schema = Scope
14− { _topLevelDocument :: schema
15− , _documentURI :: Maybe Text
16− , _currentBaseURI :: BaseURI
17− } deriving (Eq, Show)
18
16
19−newtype BaseURI
17+-- | TODO: Replace these with actual URI data types.
20− = BaseURI { _unBaseURI :: Maybe Text }
18+type URIBase = Maybe Text
21− deriving (Eq, Show)
19+type URIBaseAndFragment = (Maybe Text, Maybe Text)
22
20
23−-- | TODO: no `type`s.
21+updateResolutionScope :: URIBase -> Maybe Text -> URIBase
24−type URIAndFragment = (Maybe Text, Maybe Text)
22+updateResolutionScope mScope idKeyword
23+ | Just t <- idKeyword = fst . baseAndFragment $ resolveScopeAgainst mScope t
24+ | otherwise = mScope
25
25
26−updateResolutionScope :: BaseURI -> Maybe Text -> BaseURI
26+resolveReference :: URIBase -> Text -> URIBaseAndFragment
27−updateResolutionScope base idKeyword =
28− case idKeyword of
29− Just t -> BaseURI . fst . baseAndFragment $ resolveScopeAgainst base t
27+resolveReference mScope t = baseAndFragment $ resolveScopeAgainst mScope t
30− Nothing -> base
31
28
32−resolveReference :: BaseURI -> Text -> URIAndFragment
29+resolveFragment
33−resolveReference base t = baseAndFragment (resolveScopeAgainst base t)
30+ :: (FromJSON schema, ToJSON schema)
31+ => Maybe Text
32+ -> schema
33+ -> Maybe schema
34+resolveFragment Nothing schema = Just schema
35+resolveFragment (Just pointer) schema = do
36+ let urlDecoded = decodeUtf8 . urlDecode True . encodeUtf8 $ pointer
37+ p <- either (const Nothing) Just (JP.unescape urlDecoded)
38+ x <- either (const Nothing) Just (JP.resolve p (toJSON schema))
39+ case fromJSON x of
40+ Error _ -> Nothing
41+ Success schema' -> Just schema'
34
42
35--------------------------------------------------
43--------------------------------------------------
36-- * Helpers
44-- * Helpers
@@ -39,10 +47,10 @@ resolveReference base t = baseAndFragment (resolveScopeAgainst base t)
39isRemoteReference :: Text -> Bool
47isRemoteReference :: Text -> Bool
40isRemoteReference = T.isInfixOf "://"
48isRemoteReference = T.isInfixOf "://"
41
49
42−baseAndFragment :: Text -> URIAndFragment
50+baseAndFragment :: Text -> URIBaseAndFragment
43baseAndFragment = f . T.splitOn "#"
51baseAndFragment = f . T.splitOn "#"
44 where
52 where
45− f :: [Text] -> URIAndFragment
53+ f :: [Text] -> URIBaseAndFragment
46 f [x] = (g x, Nothing)
54 f [x] = (g x, Nothing)
47 f [x,y] = (g x, g y)
55 f [x,y] = (g x, g y)
48 f _ = (Nothing, Nothing)
56 f _ = (Nothing, Nothing)
@@ -50,9 +58,9 @@ baseAndFragment = f . T.splitOn "#"
50 g "" = Nothing
58 g "" = Nothing
51 g x = Just x
59 g x = Just x
52
60
53−resolveScopeAgainst :: BaseURI -> Text -> Text
61+resolveScopeAgainst :: Maybe Text -> Text -> Text
54−resolveScopeAgainst (BaseURI Nothing) t = t
62+resolveScopeAgainst Nothing t = t
55−resolveScopeAgainst (BaseURI (Just base)) t
63+resolveScopeAgainst (Just scope) t
56 | isRemoteReference t = t
64 | isRemoteReference t = t
57 | otherwise = smartAppend
65 | otherwise = smartAppend
58 where
66 where
@@ -61,11 +69,11 @@ resolveScopeAgainst (BaseURI (Just base)) t
61 -- to cut it off before appending.
69 -- to cut it off before appending.
62 smartAppend :: Text
70 smartAppend :: Text
63 smartAppend =
71 smartAppend =
64− case baseAndFragment base of
72+ case baseAndFragment scope of
65− (Just uri,_) ->
73+ (Just base,_) ->
66 case T.unpack t of
74 case T.unpack t of
67 -- We want "/foo" and "#/bar" to combine into
75 -- We want "/foo" and "#/bar" to combine into
68 -- "/foo#/bar" not "/foo/#/bar".
76 -- "/foo#/bar" not "/foo/#/bar".
69 '#':_ -> base <> t
77 '#':_ -> base <> t
70− _ -> T.pack (dropFileName (T.unpack uri) </> T.unpack t)
78+ _ -> T.pack (dropFileName (T.unpack base) </> T.unpack t)
71 _ -> t
79 _ -> t
src/JSONSchema/Validator/Types.hs+1
@@ -1,3 +1,4 @@
1+
1module JSONSchema.Validator.Types where
2module JSONSchema.Validator.Types where
2
3
3import Import
4import Import
src/JSONSchema/Validator/Utils.hs+27−11
@@ -1,15 +1,16 @@
1+
1module JSONSchema.Validator.Utils where
2module JSONSchema.Validator.Utils where
2
3
3import Import
4import Import
4
5
5−import Control.Monad (fail)
6+import Control.Monad (fail)
6import qualified Data.HashMap.Strict as HM
7import qualified Data.HashMap.Strict as HM
7−import qualified Data.List.NonEmpty as NE
8+import qualified Data.List.NonEmpty as NE
8−import Data.Scientific (Scientific, fromFloatDigits)
9+import Data.Scientific (Scientific, fromFloatDigits)
9−import Data.Set (Set)
10+import Data.Set (Set)
10−import qualified Data.Set as S
11+import qualified Data.Set as S
11−import qualified Data.Text as T
12+import qualified Data.Text as T
12−import qualified Data.Vector as V
13+import qualified Data.Vector as V
13
14
14--------------------------------------------------
15--------------------------------------------------
15-- * QuickCheck
16-- * QuickCheck
@@ -82,11 +83,16 @@ instance Arbitrary a => Arbitrary (NonEmpty' a) where
82-- * allUniqueValues
83-- * allUniqueValues
83--------------------------------------------------
84--------------------------------------------------
84
85
85−allUniqueValues :: (Foldable f, Functor f) => f Value -> Bool
86+allUniqueValues :: Vector Value -> Bool
87+allUniqueValues = allUnique . fmap OrdValue . V.toList
88+
89+-- NOTE: When we no longer support GHC 7.8 we can generalize
90+-- allUnique to work on any Foldable and remove this function.
91+allUniqueValues' :: NonEmpty Value -> Bool
86−allUniqueValues = allUnique . fmap OrdValue
92+allUniqueValues' = allUnique . fmap OrdValue . NE.toList
87
93
88−allUnique :: (Foldable f, Ord a) => f a -> Bool
94+allUnique :: (Ord a) => [a] -> Bool
89−allUnique xs = S.size (S.fromList (toList xs)) == length xs
95+allUnique xs = S.size (S.fromList xs) == length xs
90
96
91-- | OrdValue's Ord instance needs benchmarking, but it allows us to
97-- | OrdValue's Ord instance needs benchmarking, but it allows us to
92-- use our 'allUnique' function instead of O(n^2) nub, so it's probably
98-- use our 'allUnique' function instead of O(n^2) nub, so it's probably
@@ -117,3 +123,13 @@ instance Ord OrdValue where
117
123
118 (OrdValue (Object x)) `compare` (OrdValue (Object y)) =
124 (OrdValue (Object x)) `compare` (OrdValue (Object y)) =
119 HM.toList (OrdValue <$> x) `compare` HM.toList (OrdValue <$> y)
125 HM.toList (OrdValue <$> x) `compare` HM.toList (OrdValue <$> y)
126+
127+--------------------------------------------------
128+-- * other
129+--------------------------------------------------
130+
131+fromJSONEither :: FromJSON a => Value -> Either Text a
132+fromJSONEither a =
133+ case fromJSON a of
134+ Error e -> Left (T.pack e)
135+ Success b -> Right b
stack.yamldeleted−2
@@ -1,2 +0,0 @@
1−resolver: lts-10.8
2−pvp-bounds: upper-revision
test/Local.hs+14−10
@@ -1,18 +1,21 @@
1+
1module Main where
2module Main where
2
3
3import Protolude
4import Protolude
4
5
5import Data.Aeson
6import Data.Aeson
6import qualified Data.List.NonEmpty as NE
7import qualified Data.List.NonEmpty as NE
7−import qualified System.Timeout as TO
8+import qualified System.Timeout as TO
8import Test.Hspec
9import Test.Hspec
9−import Test.QuickCheck (property)
10+import Test.QuickCheck (property)
10
11
11−import qualified JSONSchema.Draft4 as D4
12+import qualified JSONSchema.Draft4 as D4
13+import JSONSchema.Fetch (ReferencedSchemas(..),
14+ URISchemaMap(..))
12−import qualified JSONSchema.Types as JT
15+import qualified JSONSchema.Types as JT
13import qualified Local.Failure
16import qualified Local.Failure
14−import qualified Local.Reference
15import qualified Local.Validation
17import qualified Local.Validation
18+import qualified Local.Reference
16import Shared
19import Shared
17
20
18-- Examples
21-- Examples
@@ -32,10 +35,12 @@ main = do
32 -- Language agnostic tests
35 -- Language agnostic tests
33 ts <- readSchemaTests
36 ts <- readSchemaTests
34 dir
37 dir
35− (\a -> not (isHTTPTest a || skipTest a))
38+ (\a -> not (isHTTPTest a || skipOptional a))
36
39
37 -- Custom supplements to the language agnostic tests
40 -- Custom supplements to the language agnostic tests
38− supplementTs <- readSchemaTests supplementDir (not . isHTTPTest)
41+ supplementTs <- readSchemaTests
42+ supplementDir
43+ (\a -> not (isHTTPTest a || skipOptional a))
39
44
40 hspec $ do
45 hspec $ do
41 describe "Examples" exampleTests
46 describe "Examples" exampleTests
@@ -79,9 +84,8 @@ main = do
79 Left e -> panic ("Local.validateExample error: " <> show e)
84 Left e -> panic ("Local.validateExample error: " <> show e)
80 Right schemaMap -> do
85 Right schemaMap -> do
81 let failures = AlternateSchema.validate
86 let failures = AlternateSchema.validate
82− schemaMap
87+ (ReferencedSchemas s (_unURISchemaMap schemaMap))
83− (D4.SchemaWithURI s Nothing)
84− (_scData sc)
88+ Nothing s (_scData sc)
85 assertResult sc failures
89 assertResult sc failures
86
90
87quickCheckTests :: Spec
91quickCheckTests :: Spec
test/Local/Failure.hs+7−6
@@ -1,14 +1,15 @@
1+
1module Local.Failure where
2module Local.Failure where
2
3
3import Protolude
4import Protolude
4
5
5import Data.Aeson
6import Data.Aeson
6−import qualified Data.Vector as V
7−import qualified JSONPointer as JP
8import Test.Hspec
7import Test.Hspec
8+import qualified Data.Vector as V
9+import qualified JSONPointer as JP
9
10
10import JSONSchema.Draft4
11import JSONSchema.Draft4
11−import qualified JSONSchema.Draft4.Spec as Spec
12+import qualified JSONSchema.Draft4.Spec as Spec
12import qualified JSONSchema.Validator.Draft4 as VAL
13import qualified JSONSchema.Validator.Draft4 as VAL
13
14
14spec :: Spec
15spec :: Spec
@@ -30,7 +31,7 @@ itemsArray =
30 ]
31 ]
31 where
32 where
32 failures :: [ValidatorFailure]
33 failures :: [ValidatorFailure]
33− failures = Spec.specValidate mempty sw badData
34+ failures = Spec.specValidate (ReferencedSchemas schema mempty) sw badData
34
35
35 schema :: Schema
36 schema :: Schema
36 schema = emptySchema
37 schema = emptySchema
@@ -60,7 +61,7 @@ itemsObject =
60 ]
61 ]
61 where
62 where
62 failures :: [ValidatorFailure]
63 failures :: [ValidatorFailure]
63− failures = Spec.specValidate mempty sw badData
64+ failures = Spec.specValidate (ReferencedSchemas schema mempty) sw badData
64
65
65 schema :: Schema
66 schema :: Schema
66 schema = emptySchema
67 schema = emptySchema
@@ -88,7 +89,7 @@ loopRef =
88 ]
89 ]
89 where
90 where
90 failures :: [ValidatorFailure]
91 failures :: [ValidatorFailure]
91− failures = Spec.specValidate mempty sw badData
92+ failures = Spec.specValidate (ReferencedSchemas schema mempty) sw badData
92
93
93 schema :: Schema
94 schema :: Schema
94 schema = emptySchema
95 schema = emptySchema
test/Local/Reference.hs+13−12
@@ -1,3 +1,4 @@
1+
1module Local.Reference where
2module Local.Reference where
2
3
3import Protolude
4import Protolude
@@ -9,28 +10,28 @@ import JSONSchema.Validator.Reference
9spec :: Spec
10spec :: Spec
10spec = do
11spec = do
11 it "updateResolutionScope gives correct results" $ do
12 it "updateResolutionScope gives correct results" $ do
12− updateResolutionScope (BaseURI Nothing) Nothing
13+ updateResolutionScope Nothing Nothing
13− `shouldBe` BaseURI Nothing
14+ `shouldBe` Nothing
14
15
15− updateResolutionScope (BaseURI Nothing) (Just "#")
16+ updateResolutionScope Nothing (Just "#")
16− `shouldBe` BaseURI Nothing
17+ `shouldBe` Nothing
17
18
18− updateResolutionScope (BaseURI Nothing) (Just "foo")
19+ updateResolutionScope Nothing (Just "foo")
19− `shouldBe` BaseURI (Just "foo")
20+ `shouldBe` Just "foo"
20
21
21 -- TODO: Normalize after updateResolutionScope:
22 -- TODO: Normalize after updateResolutionScope:
22− updateResolutionScope (BaseURI (Just "/foo")) (Just "./bar")
23+ updateResolutionScope (Just "/foo") (Just "./bar")
23− `shouldBe` BaseURI (Just "/./bar")
24+ `shouldBe` Just "/./bar"
24
25
25 it "resolveReference gives correct results" $ do
26 it "resolveReference gives correct results" $ do
26− resolveReference (BaseURI (Just "/foo")) "bar"
27+ resolveReference (Just "/foo") "bar"
27 `shouldBe` (Just "/bar", Nothing)
28 `shouldBe` (Just "/bar", Nothing)
28
29
29− resolveReference (BaseURI (Just "/foo/bar")) "/baz"
30+ resolveReference (Just "/foo/bar") "/baz"
30 `shouldBe` (Just "/baz", Nothing)
31 `shouldBe` (Just "/baz", Nothing)
31
32
32− resolveReference (BaseURI Nothing) "#/bar"
33+ resolveReference Nothing "#/bar"
33 `shouldBe` (Nothing, Just "/bar")
34 `shouldBe` (Nothing, Just "/bar")
34
35
35− resolveReference (BaseURI (Just "/foo")) "#/bar"
36+ resolveReference (Just "/foo") "#/bar"
36 `shouldBe` (Just "/foo", Just "/bar")
37 `shouldBe` (Just "/foo", Just "/bar")
test/Local/Validation.hs+6−5
@@ -1,16 +1,17 @@
1+
1module Local.Validation where
2module Local.Validation where
2
3
3−import Protolude
4+import Protolude hiding (msg)
4
5
5import Data.Aeson
6import Data.Aeson
6−import qualified Data.Aeson as AE
7+import qualified Data.Aeson as AE
7import qualified Data.HashMap.Strict as HM
8import qualified Data.HashMap.Strict as HM
8−import Data.String (String)
9+import Data.String (String)
9import Test.Hspec
10import Test.Hspec
10
11
11−import qualified AlternateSchema as AS
12import JSONSchema.Draft4
12import JSONSchema.Draft4
13−import qualified JSONSchema.Types as JT
13+import qualified JSONSchema.Types as JT
14+import qualified AlternateSchema as AS
14
15
15spec :: Spec
16spec :: Spec
16spec = do
17spec = do
test/Remote.hs+11−9
@@ -1,16 +1,19 @@
1+
1module Main where
2module Main where
2
3
3import Protolude
4import Protolude
4
5
5−import Control.Concurrent.Async (withAsync)
6+import Control.Concurrent.Async (withAsync)
6−import qualified Data.List.NonEmpty as NE
7+import qualified Data.List.NonEmpty as NE
7import Network.Wai.Application.Static (defaultFileServerSettings,
8import Network.Wai.Application.Static (defaultFileServerSettings,
8 staticApp)
9 staticApp)
9−import qualified Network.Wai.Handler.Warp as Warp
10+import Network.Wai.Handler.Warp (run)
10import Test.Hspec
11import Test.Hspec
11
12
12−import qualified JSONSchema.Draft4 as D4
13+import qualified JSONSchema.Draft4 as D4
14+import JSONSchema.Fetch (ReferencedSchemas(..),
15+ URISchemaMap(..))
13−import qualified JSONSchema.Types as JT
16+import qualified JSONSchema.Types as JT
14import Shared
17import Shared
15
18
16-- Examples
19-- Examples
@@ -45,13 +48,12 @@ main = withAsync serve $ \_ -> do
45 Left e -> panic ("Remote.validateExample error: " <> show e)
48 Left e -> panic ("Remote.validateExample error: " <> show e)
46 Right schemaMap -> do
49 Right schemaMap -> do
47 let failures = AlternateSchema.validate
50 let failures = AlternateSchema.validate
48− schemaMap
51+ (ReferencedSchemas s (_unURISchemaMap schemaMap))
49− (D4.SchemaWithURI s Nothing)
50− (_scData sc)
52+ Nothing s (_scData sc)
51 assertResult sc failures
53 assertResult sc failures
52
54
53serve :: IO ()
55serve :: IO ()
54−serve = Warp.run 1234
56+serve = run 1234
55 . staticApp
57 . staticApp
56 . defaultFileServerSettings
58 . defaultFileServerSettings
57 $ "JSON-Schema-Test-Suite/remotes"
59 $ "JSON-Schema-Test-Suite/remotes"
test/Shared.hs+19−18
@@ -1,29 +1,19 @@
1+
1module Shared where
2module Shared where
2
3
3import Protolude
4import Protolude
4
5
5−import Control.Monad (fail)
6+import Control.Monad (fail)
6import Data.Aeson
7import Data.Aeson
7−import Data.Aeson.TH (fieldLabelModifier)
8+import Data.Aeson.TH (fieldLabelModifier)
8−import qualified Data.ByteString as BS
9+import qualified Data.ByteString as BS
9−import Data.Char (toLower)
10+import Data.Char (toLower)
10−import Data.List (stripPrefix, unlines)
11+import Data.List (stripPrefix, unlines)
11−import qualified Data.Text as T
12+import qualified Data.Text as T
12import qualified System.Directory as SD
13import qualified System.Directory as SD
13−import System.FilePath ((</>))
14+import System.FilePath ((</>))
14import Test.Hspec
15import Test.Hspec
15
16
16−skipTest :: FilePath -> Bool
17−skipTest file = (file == "optional/format.json") -- Optional
18− || (file == "optional/zeroTerminatedFloats.json")
19− || (file == "optional/ecmascript-regex.json")
20−
21−
22−isHTTPTest :: FilePath -> Bool
23−isHTTPTest file = (file == "definitions.json")
24− || (file == "ref.json")
25− || (file == "refRemote.json")
26−
27-- Recursively return the contents of a directory
17-- Recursively return the contents of a directory
28-- (or return itself if given a file as an argument).
18-- (or return itself if given a file as an argument).
29--
19--
@@ -47,6 +37,17 @@ listFilesFullPath path = do
47 fs <- fmap (path </>) <$> SD.listDirectory path
37 fs <- fmap (path </>) <$> SD.listDirectory path
48 concat <$> traverse listFilesFullPath fs
38 concat <$> traverse listFilesFullPath fs
49
39
40+isHTTPTest :: FilePath -> Bool
41+isHTTPTest file = (file == "definitions.json")
42+ || (file == "ref.json")
43+ || (file == "refRemote.json")
44+
45+-- | We may never support the @"format"@ keywords, and
46+-- are currently failing the zeroTerminatedFloats test.
47+skipOptional :: FilePath -> Bool
48+skipOptional file = (file == "optional/format.json")
49+ || (file == "optional/zeroTerminatedFloats.json")
50+
50data SchemaTest = SchemaTest
51data SchemaTest = SchemaTest
51 { _stDescription :: Text
52 { _stDescription :: Text
52 , _stSchema :: Value
53 , _stSchema :: Value