jschematic 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. data/.rspec +1 -0
  2. data/.rvmrc +1 -0
  3. data/Gemfile +2 -0
  4. data/Gemfile.lock +40 -0
  5. data/LICENSE +20 -0
  6. data/README.md +48 -0
  7. data/Rakefile +10 -0
  8. data/cucumber.yml +1 -0
  9. data/features/default.feature +72 -0
  10. data/features/dependencies.feature +73 -0
  11. data/features/enum.feature +26 -0
  12. data/features/format.feature +40 -0
  13. data/features/id.feature +75 -0
  14. data/features/items.feature +90 -0
  15. data/features/min_length_max_length.feature +20 -0
  16. data/features/minimum_maximum.feature +29 -0
  17. data/features/pattern.feature +6 -0
  18. data/features/pattern_properties.feature +18 -0
  19. data/features/properties.feature +124 -0
  20. data/features/required.feature +42 -0
  21. data/features/step_definitions/jschematic_steps.rb +62 -0
  22. data/features/support/env.rb +6 -0
  23. data/features/type.feature +76 -0
  24. data/jschematic.gemspec +22 -0
  25. data/lib/jschematic/attributes/additional_items.rb +35 -0
  26. data/lib/jschematic/attributes/additional_properties.rb +28 -0
  27. data/lib/jschematic/attributes/dependencies.rb +26 -0
  28. data/lib/jschematic/attributes/enum.rb +18 -0
  29. data/lib/jschematic/attributes/exclusive_maximum.rb +21 -0
  30. data/lib/jschematic/attributes/exclusive_minimum.rb +21 -0
  31. data/lib/jschematic/attributes/format.rb +56 -0
  32. data/lib/jschematic/attributes/items.rb +24 -0
  33. data/lib/jschematic/attributes/max_items.rb +18 -0
  34. data/lib/jschematic/attributes/max_length.rb +18 -0
  35. data/lib/jschematic/attributes/maximum.rb +22 -0
  36. data/lib/jschematic/attributes/min_items.rb +18 -0
  37. data/lib/jschematic/attributes/min_length.rb +18 -0
  38. data/lib/jschematic/attributes/minimum.rb +22 -0
  39. data/lib/jschematic/attributes/pattern.rb +18 -0
  40. data/lib/jschematic/attributes/pattern_properties.rb +23 -0
  41. data/lib/jschematic/attributes/properties.rb +38 -0
  42. data/lib/jschematic/attributes/required.rb +28 -0
  43. data/lib/jschematic/attributes/type.rb +61 -0
  44. data/lib/jschematic/attributes/unique_items.rb +18 -0
  45. data/lib/jschematic/attributes.rb +28 -0
  46. data/lib/jschematic/element.rb +25 -0
  47. data/lib/jschematic/errors.rb +34 -0
  48. data/lib/jschematic/schema.rb +77 -0
  49. data/lib/jschematic/validation_error.rb +13 -0
  50. data/lib/jschematic.rb +13 -0
  51. data/spec/jschematic/attributes/enum_spec.rb +14 -0
  52. data/spec/jschematic/attributes/max_items_spec.rb +15 -0
  53. data/spec/jschematic/attributes/min_items_spec.rb +15 -0
  54. data/spec/jschematic/attributes/minimum_maximum_spec.rb +33 -0
  55. data/spec/jschematic/attributes/required_spec.rb +29 -0
  56. data/spec/jschematic/attributes/type_spec.rb +63 -0
  57. data/spec/jschematic/attributes_spec.rb +12 -0
  58. data/spec/jschematic/errors_spec.rb +43 -0
  59. data/spec/jschematic/schema_spec.rb +58 -0
  60. data/spec/spec_helper.rb +16 -0
  61. metadata +199 -0
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm --create use 1.9.2@jschematic
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "http://rubygems.org"
2
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,40 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ jschematic (0.0.1)
5
+ addressable
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ addressable (2.2.4)
11
+ builder (3.0.0)
12
+ cucumber (0.10.0)
13
+ builder (>= 2.1.2)
14
+ diff-lcs (~> 1.1.2)
15
+ gherkin (~> 2.3.2)
16
+ json (~> 1.4.6)
17
+ term-ansicolor (~> 1.0.5)
18
+ diff-lcs (1.1.2)
19
+ gherkin (2.3.3)
20
+ json (~> 1.4.6)
21
+ json (1.4.6)
22
+ rspec (2.3.0)
23
+ rspec-core (~> 2.3.0)
24
+ rspec-expectations (~> 2.3.0)
25
+ rspec-mocks (~> 2.3.0)
26
+ rspec-core (2.3.1)
27
+ rspec-expectations (2.3.0)
28
+ diff-lcs (~> 1.1.2)
29
+ rspec-mocks (2.3.0)
30
+ term-ansicolor (1.0.5)
31
+ yajl-ruby (0.7.8)
32
+
33
+ PLATFORMS
34
+ ruby
35
+
36
+ DEPENDENCIES
37
+ cucumber
38
+ jschematic!
39
+ rspec
40
+ yajl-ruby
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Mike Sassak
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,48 @@
1
+ # Jschematic
2
+
3
+ Jschematic is a JSON Schema v3 Validator for Ruby.
4
+
5
+ It is currently incomplete, alpha quality software.
6
+
7
+ Having said that, most of the core schema definition is supported
8
+ with these exceptions:
9
+
10
+ * $ref
11
+ * $schema
12
+ * extends
13
+ * divisibleBy
14
+ * disallow
15
+
16
+ In addition to this, only IPv4, IPv6 and URI formats are currently
17
+ implemented.
18
+
19
+ Please report any bugs you find (and you will find bugs) at the issue
20
+ tracker here: https://github.com/msassak/jschematic/issues.
21
+
22
+ ## Usage
23
+
24
+ require 'jschematic'
25
+ Jschematic.validate(json, schema) # => true or false
26
+ Jschematic.validate!(json, schema) # => true or raise Jschematic::ValidationError
27
+
28
+ `json` and `schema` above must be Ruby data structures, not real JSON.
29
+
30
+ Jschematic doesn't care how you turn JSON into Ruby (though we use the
31
+ fine yajl-ruby gem for testing).
32
+
33
+ ## Testing
34
+
35
+ $ cucumber
36
+ $ rspec spec
37
+
38
+ Or `rake` if you want to run both.
39
+
40
+ ## Links
41
+
42
+ * http://tools.ietf.org/html/draft-zyp-json-schema-03
43
+ * https://github.com/kriszyp/json-schema
44
+ * http://tools.ietf.org/html/rfc3986
45
+
46
+ ## Copyright
47
+
48
+ Copyright (c) 2011 Mike Sassak. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ desc "Run Cukes and Specs"
2
+ task :default => ["cukes", "spec"]
3
+
4
+ task :cukes do
5
+ sh "cucumber"
6
+ end
7
+
8
+ task :spec do
9
+ sh "rspec spec"
10
+ end
data/cucumber.yml ADDED
@@ -0,0 +1 @@
1
+ default: -q --tags ~@ignore
@@ -0,0 +1,72 @@
1
+ Feature: Core schema: default
2
+
3
+ Scenario: validation succeeds because of default
4
+ When the schema is:
5
+ """
6
+ {
7
+ "properties": {
8
+ "name": {
9
+ "type": "string",
10
+ "required": true
11
+ }
12
+ },
13
+
14
+ "default": {
15
+ "name": "Gristle Thornbody"
16
+ }
17
+ }
18
+
19
+ """
20
+ Then '{ "age": 35 }' is valid JSON
21
+
22
+ Scenario: validation fails because of default
23
+ When the schema is:
24
+ """
25
+ {
26
+ "properties": {
27
+ "name": {
28
+ "type": "string"
29
+ }
30
+ },
31
+
32
+ "default": {
33
+ "name": 1999
34
+ }
35
+ }
36
+ """
37
+ Then '{ "age": 35 }' is not valid JSON
38
+
39
+ Scenario: validation of property succeeds because of default
40
+ When the schema is:
41
+ """
42
+ {
43
+ "properties": {
44
+ "pi": {
45
+ "type": "number",
46
+ "required": true,
47
+ "default": 3.1415
48
+ }
49
+ }
50
+ }
51
+ """
52
+ Then '{ "somethingElse": "foo" }' is valid JSON
53
+ But '{ "pi": "is delicious" }' is not valid JSON
54
+
55
+ Scenario: validation of property fails because of default
56
+ When the schema is:
57
+ """
58
+ {
59
+ "properties": {
60
+ "pi": {
61
+ "type": "number",
62
+ "required": true,
63
+ "default": "is delicious"
64
+ }
65
+ }
66
+ }
67
+ """
68
+ Then '{ "somethingElse": "foo" }' is not valid JSON
69
+ But '{ "pi": 3.1415 }' is valid JSON
70
+
71
+ Scenario: default for all types
72
+ TODO: spec
@@ -0,0 +1,73 @@
1
+ Feature: Core schema: dependencies
2
+ Scenario: depending on a single property name
3
+ When the schema is:
4
+ """
5
+ {
6
+ "dependencies": { "foo": "bar" }
7
+ }
8
+ """
9
+ Then this is valid JSON:
10
+ """
11
+ {
12
+ "foo": "baz",
13
+ "bar": "qux"
14
+ }
15
+ """
16
+ But this is not valid JSON:
17
+ """
18
+ {
19
+ "foo": "baz",
20
+ "wibble": "womble"
21
+ }
22
+ """
23
+
24
+ Scenario: depending on each item in list of property names
25
+ When the schema is:
26
+ """
27
+ {
28
+ "dependencies": { "foo": ["bar", "baz"] }
29
+ }
30
+ """
31
+ Then this is valid JSON:
32
+ """
33
+ {
34
+ "foo": "qux",
35
+ "bar": "quux",
36
+ "baz": "wibble"
37
+ }
38
+ """
39
+ But this is not valid JSON:
40
+ """
41
+ {
42
+ "foo": "qux",
43
+ "bar": "quux"
44
+ }
45
+ """
46
+
47
+ Scenario: depend on schema
48
+ When the schema is:
49
+ """
50
+ {
51
+ "dependencies": {
52
+ "foo": {
53
+ "properties": {
54
+ "favoriteNumber": { "type": "number" }
55
+ }
56
+ }
57
+ }
58
+ }
59
+ """
60
+ Then this is valid JSON:
61
+ """
62
+ {
63
+ "foo": "bar",
64
+ "favoriteNumber": 3.1415
65
+ }
66
+ """
67
+ But this is not valid JSON:
68
+ """
69
+ {
70
+ "foo": "bar",
71
+ "favoriteNumber": "eleventy million"
72
+ }
73
+ """
@@ -0,0 +1,26 @@
1
+ Feature: Core schema: enum
2
+ Scenario: enum
3
+ When the schema is:
4
+ """
5
+ {
6
+ "enum": [1, "two", [[], [], []], { "four": 4 }]
7
+ }
8
+ """
9
+ Then these are valid JSON:
10
+ | 1 |
11
+ | "two" |
12
+ | [[], [], []] |
13
+ | { "four": 4 } |
14
+ But these are not valid JSON:
15
+ | "one" |
16
+ | 2 |
17
+ | [true, false] |
18
+ | { "name": "Mariposa" } |
19
+
20
+ Scenario: empty enum
21
+ When the schema is '{ "enum": [] }'
22
+ Then these are not valid JSON:
23
+ | "" |
24
+ | [] |
25
+ | {} |
26
+ | null |
@@ -0,0 +1,40 @@
1
+ Feature: Core schema: format
2
+ Scenario: URI
3
+ When the schema is:
4
+ """
5
+ {
6
+ "type": "string",
7
+ "format": "uri"
8
+ }
9
+ """
10
+ Then '"http://www.google.com"' is valid JSON
11
+ But '"http://"' is not valid JSON
12
+
13
+ Scenario: IPv4
14
+ When the schema is:
15
+ """
16
+ {
17
+ "type": "string",
18
+ "format": "ip-address"
19
+ }
20
+ """
21
+ Then '"127.0.0.1"' is valid JSON
22
+ But these are not valid JSON:
23
+ | "" |
24
+ | "fe80::202:b3ff:fe1e:8329" |
25
+
26
+ Scenario: IPv6
27
+ When the schema is:
28
+ """
29
+ {
30
+ "type": "string",
31
+ "format": "ipv6"
32
+ }
33
+ """
34
+ Then these are valid JSON:
35
+ | "2001:0db8:85a3:0000:0000:8a2e:0370:7334" |
36
+ | "fe80:0:0:0:202:b3ff:fe1e:8329" |
37
+ | "fe80::202:b3ff:fe1e:8329" |
38
+ But these are not valid JSON:
39
+ | "" |
40
+ | "127.0.0.1" |
@@ -0,0 +1,75 @@
1
+ Feature: Core schema: id
2
+ Scenario: absolute URI, single schema
3
+ When the schema is:
4
+ """
5
+ {
6
+ "title": "Test Schema",
7
+ "id": "http://www.example.com/schemas/json"
8
+ }
9
+ """
10
+ Then the id of "Test Schema" is "http://www.example.com/schemas/json"
11
+
12
+ Scenario: relative URI, single schema
13
+ I-D says: "If this schema is not contained in any parent schema, the
14
+ current URI of the parent schema is held to be the URI under which
15
+ this schema was addressed."
16
+
17
+ I think this means that the id of the root schema is taken to be the
18
+ URI from which the schema was retrieved, i.e. schema validators are
19
+ supposed to include an HTTP client, which seems a bit bonkers to me,
20
+ or the client passes in the URI from where the schema was retrieved,
21
+ which is weird, but more palatable. The current implementation does
22
+ neither of these, but I don't think it's too important at this point.
23
+
24
+ When the schema is:
25
+ """
26
+ {
27
+ "title": "Test Schema",
28
+ "id": "/schemas/json"
29
+ }
30
+ """
31
+ Then the id of "Test Schema" is "/schemas/json"
32
+
33
+ Scenario: absolute URI at root, absolute in child
34
+ When the schema is:
35
+ """
36
+ {
37
+ "title": "Root Schema",
38
+ "id": "http://www.example.com/schemas/root",
39
+ "properties": {
40
+ "child": {
41
+ "title": "Child Schema",
42
+ "id": "http://www.example.org/schemas/child"
43
+ }
44
+ }
45
+ }
46
+ """
47
+ Then the id of "Root Schema" is "http://www.example.com/schemas/root"
48
+ And the id of "Child Schema" is "http://www.example.org/schemas/child"
49
+
50
+ Scenario: absolute URI at root, relative in child
51
+ When the schema is:
52
+ """
53
+ {
54
+ "title": "Root Schema",
55
+ "id": "http://www.example.com/schemas/root/",
56
+ "properties": {
57
+ "relchild": {
58
+ "title": "Relative Path Child Schema",
59
+ "id": "child"
60
+ },
61
+ "fragchild": {
62
+ "title": "Fragment Child Schema",
63
+ "id": "#child"
64
+ },
65
+ "abspathchild": {
66
+ "title": "Absolute Path Child Schema",
67
+ "id": "/child"
68
+ }
69
+ }
70
+ }
71
+ """
72
+ Then the id of "Root Schema" is "http://www.example.com/schemas/root/"
73
+ And the id of "Fragment Child Schema" is "http://www.example.com/schemas/root/#child"
74
+ And the id of "Absolute Path Child Schema" is "http://www.example.com/child"
75
+ And the id of "Relative Path Child Schema" is "http://www.example.com/schemas/root/child"
@@ -0,0 +1,90 @@
1
+ Feature: Core schema: items, additionalItems, minItems, maxItems & uniqueItems
2
+ Scenario: single schema
3
+ When the schema is:
4
+ """
5
+ {
6
+ "items": {
7
+ "type": "string"
8
+ }
9
+ }
10
+ """
11
+ Then '["Felizberto", "Lil Wayne", "Albi"]' is valid JSON
12
+ And '[]' is valid JSON
13
+ But '["Felizberto", 2112, "Albi"]' is not valid JSON
14
+
15
+ Scenario: tuple typing with an array of schemas
16
+ When the schema is:
17
+ """
18
+ {
19
+ "items": [
20
+ { "type": "string" },
21
+ { "type": "integer" }
22
+ ]
23
+ }
24
+ """
25
+ Then '["Felizberto", 2112]' is valid JSON
26
+ And '["Felizberto", 2112, "Albi"]' is valid JSON
27
+ But '[2112, "Felizberto"]' is not valid JSON
28
+ And '["Felizberto", "Lil Wayne"]' is not valid JSON
29
+
30
+ Scenario: tuple typing when additional items is false
31
+ When the schema is:
32
+ """
33
+ {
34
+ "items": [ { "type": "string" } ],
35
+ "additionalItems": false
36
+ }
37
+ """
38
+ Then '["Feliberto"]' is valid JSON
39
+ But '["Felizberto", "Albi"]' is not valid JSON
40
+
41
+ Scenario: tuple typing with additional items schema
42
+ When the schema is:
43
+ """
44
+ {
45
+ "items": [ { "type": "string" } ],
46
+ "additionalItems": { "type": "object" }
47
+ }
48
+ """
49
+ Then '["Albi", { "age": 24 }]' is valid JSON
50
+ But '["Albi", 24]' is not valid JSON
51
+
52
+ Scenario: instance JSON is not an array
53
+
54
+ Scenario: minItems
55
+ When the schema is '{ "minItems": 2 }'
56
+ Then '["apple", "orange", "pear"]' is valid JSON
57
+ And '["cucumber", "sativus"]' is valid JSON
58
+ But '["pomegranate"]' is not valid JSON
59
+
60
+ Scenario: maxItems
61
+ When the schema is '{ "maxItems": 2 }'
62
+ Then '["pomegranate"]' is valid JSON
63
+ And '["cucumber", "sativus"]' is valid JSON
64
+ But '["apple", "orange", "pear"]' is not valid JSON
65
+
66
+ Scenario: min and max together
67
+ When the schema is:
68
+ """
69
+ {
70
+ "minItems": 1,
71
+ "maxItems": 2
72
+ }
73
+ """
74
+ Then '["pomegranate"]' is valid JSON
75
+ And '["cucumber", "sativus"]' is valid JSON
76
+ But '["apple", "orange", "pear"]' is not valid JSON
77
+ And '[]' is not valid JSON
78
+
79
+ Scenario: uniqueItems
80
+ When the schema is '{ "uniqueItems": true }'
81
+ Then these are valid JSON:
82
+ | [1,2] |
83
+ | ["a", "b"] |
84
+ | [true, false] |
85
+ | [{"foo": 1}, {"foo": 2}] |
86
+ But these are not valid JSON:
87
+ | [1,1] |
88
+ | ["a", "a"] |
89
+ | [true, true] |
90
+ | [{"foo": 1}, {"foo": 1}] |
@@ -0,0 +1,20 @@
1
+ Feature: Core schema: minLength & maxLength
2
+
3
+ Scenario: minLength
4
+ When the schema is '{ "minLength": 3 }'
5
+ Then '"foo"' is valid JSON
6
+ And '"quux"' is valid JSON
7
+ But '"aa"' is not valid JSON
8
+
9
+ Scenario: maxLength
10
+ When the schema is '{ "maxLength": 3 }'
11
+ Then '"aa"' is valid JSON
12
+ And '"foo"' is valid JSON
13
+ But '"quux"' is not valid JSON
14
+
15
+ Scenario: together
16
+ When the schema is '{ "minLength": 1, "maxLength": 2 }'
17
+ Then '"a"' is valid JSON
18
+ And '"aa"' is valid JSON
19
+ But '"aaa"' is not valid JSON
20
+ And '""' is not valid JSON
@@ -0,0 +1,29 @@
1
+ Feature: Core Schema: minimum, exclusiveMinimum, maximum & exclusiveMaximum
2
+
3
+ Scenario: minimum
4
+ When the schema is '{ "minimum": 25 }'
5
+ Then '26.1' is valid JSON
6
+ And '25' is valid JSON
7
+ But '24' is not valid JSON
8
+
9
+ Scenario: exclusiveMinimum
10
+ When the schema is:
11
+ """
12
+ { "minimum": 25, "exclusiveMinimum": true }
13
+ """
14
+ Then '26' is valid JSON
15
+ But '25' is not valid JSON
16
+
17
+ Scenario: maximum
18
+ When the schema is '{ "maximum": 25 }'
19
+ Then '25' is valid JSON
20
+ And '24.9' is valid JSON
21
+ But '25.1' is not valid JSON
22
+
23
+ Scenario: exclusiveMaximum
24
+ When the schema is:
25
+ """
26
+ { "maximum": 25, "exclusiveMaximum": true }
27
+ """
28
+ Then '24.9' is valid JSON
29
+ But '25' is not valid JSON
@@ -0,0 +1,6 @@
1
+ Feature: Core schema: pattern
2
+ Scenario: pattern
3
+ When the schema is '{ "pattern": "^wibble$" }'
4
+ Then '"wibble"' is valid JSON
5
+ But '"rewibble"' is not valid JSON
6
+ And '"wibbler"' is not valid JSON
@@ -0,0 +1,18 @@
1
+ Feature: Core schema: patternProperties
2
+
3
+ Scenario: one pattern
4
+ When the schema is:
5
+ """
6
+ {
7
+ "patternProperties": {
8
+ "[Nn]ame$": { "type": "string" }
9
+ }
10
+ }
11
+ """
12
+ Then these are valid JSON:
13
+ | { "name": "Felizberto" } |
14
+ | { "firstName": "Fitzheraldo" } |
15
+ | { "fullName": "Inigo Montoya" } |
16
+ But these are not valid JSON:
17
+ | { "name": 2112 } |
18
+ | { "named": "Werner" } |