jschematic 0.0.2 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile.lock +1 -1
- data/History.txt +6 -0
- data/README.md +12 -8
- data/features/format.feature +34 -0
- data/features/id.feature +6 -11
- data/features/ref.feature +138 -0
- data/features/step_definitions/jschematic_steps.rb +26 -13
- data/jschematic.gemspec +1 -1
- data/lib/jschematic/attributes/format.rb +43 -19
- data/lib/jschematic/attributes/ref.rb +20 -0
- data/lib/jschematic/attributes.rb +3 -1
- data/lib/jschematic/context.rb +13 -0
- data/lib/jschematic/element.rb +10 -1
- data/lib/jschematic/{validation_error.rb → exceptions.rb} +12 -0
- data/lib/jschematic/schema.rb +22 -9
- data/lib/jschematic.rb +5 -5
- data/spec/jschematic/attributes/enum_spec.rb +30 -0
- data/spec/jschematic/attributes/format_spec.rb +13 -0
- data/spec/jschematic/attributes/ref_spec.rb +15 -0
- data/spec/jschematic/attributes_spec.rb +5 -0
- data/spec/jschematic/schema_spec.rb +7 -20
- data/spec/spec_helper.rb +17 -0
- metadata +13 -5
data/Gemfile.lock
CHANGED
data/History.txt
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
== 0.0.5
|
2
|
+
* Initial support for validation contexts (Mike Sassak)
|
3
|
+
* $ref support (Mike Sassak)
|
4
|
+
* Basic DateTime, Date support (Mike Sassak)
|
5
|
+
* Separate IPv4 and IPv6 classes (Mike Sassak)
|
6
|
+
|
1
7
|
== 0.0.2
|
2
8
|
* Refactored Properties and PatternProperties so the latter inherits from the former (Mike Sassak)
|
3
9
|
* Simple IPv4 CIDR format support (Mike Sassak)
|
data/README.md
CHANGED
@@ -2,24 +2,23 @@
|
|
2
2
|
|
3
3
|
Jschematic is a JSON Schema v3 Validator for Ruby.
|
4
4
|
|
5
|
-
It is currently
|
5
|
+
It is currently pre-release software. The basics work fairly well, but
|
6
|
+
it is a work in progress.
|
6
7
|
|
7
|
-
|
8
|
-
with these exceptions:
|
8
|
+
Most of the core schema definition is supported with these exceptions:
|
9
9
|
|
10
|
-
* $ref
|
11
10
|
* $schema
|
12
11
|
* extends
|
13
12
|
* divisibleBy
|
14
13
|
* disallow
|
15
14
|
|
16
|
-
In addition to this, only IPv4, IPv6 and URI formats are currently
|
15
|
+
In addition to this, only DateTime, Date, IPv4, IPv6 and URI formats are currently
|
17
16
|
implemented.
|
18
17
|
|
19
|
-
Please report any bugs you find
|
20
|
-
|
18
|
+
Please report any bugs you find in the issue tracker here:
|
19
|
+
https://github.com/msassak/jschematic/issues.
|
21
20
|
|
22
|
-
## Usage
|
21
|
+
## Basic Usage
|
23
22
|
|
24
23
|
require 'jschematic'
|
25
24
|
Jschematic.validate(json, schema) # => true or false
|
@@ -30,6 +29,10 @@ tracker here: https://github.com/msassak/jschematic/issues.
|
|
30
29
|
Jschematic doesn't care how you turn JSON into Ruby (though we use the
|
31
30
|
fine yajl-ruby gem for testing).
|
32
31
|
|
32
|
+
## Advanced Usage
|
33
|
+
|
34
|
+
Hasn't been documented yet.
|
35
|
+
|
33
36
|
## Testing
|
34
37
|
|
35
38
|
$ cucumber
|
@@ -42,6 +45,7 @@ Or `rake` if you want to run both.
|
|
42
45
|
* http://tools.ietf.org/html/draft-zyp-json-schema-03
|
43
46
|
* https://github.com/kriszyp/json-schema
|
44
47
|
* http://tools.ietf.org/html/rfc3986
|
48
|
+
* https://groups.google.com/d/topic/json-schema/lftABvH5KkA/discussion
|
45
49
|
|
46
50
|
## Copyright
|
47
51
|
|
data/features/format.feature
CHANGED
@@ -53,3 +53,37 @@ Feature: Core schema: format
|
|
53
53
|
But these are not valid JSON:
|
54
54
|
| "" |
|
55
55
|
| "127.0.0.1" |
|
56
|
+
|
57
|
+
Scenario: Date-Time
|
58
|
+
When the schema is:
|
59
|
+
"""
|
60
|
+
{
|
61
|
+
"type": "string",
|
62
|
+
"format": "date-time"
|
63
|
+
}
|
64
|
+
"""
|
65
|
+
Then these are valid JSON:
|
66
|
+
| "1999-12-31T23:59:59Z" |
|
67
|
+
| "2011-02-27T10:12:13Z" |
|
68
|
+
| "1980-02-29T08:51:32Z" |
|
69
|
+
But these are not valid JSON:
|
70
|
+
| "1999-12-31" |
|
71
|
+
| "1981-02-29T01:01:01Z" |
|
72
|
+
| "August 1st, 1986" |
|
73
|
+
|
74
|
+
Scenario: Date
|
75
|
+
When the schema is:
|
76
|
+
"""
|
77
|
+
{
|
78
|
+
"type": "string",
|
79
|
+
"format": "date"
|
80
|
+
}
|
81
|
+
"""
|
82
|
+
Then these are valid JSON:
|
83
|
+
| "1999-12-31" |
|
84
|
+
| "2011-02-27" |
|
85
|
+
| "1980-02-29" |
|
86
|
+
But these are not valid JSON:
|
87
|
+
| "1981-02-29" |
|
88
|
+
| "August 1st, 1986" |
|
89
|
+
|
data/features/id.feature
CHANGED
@@ -1,4 +1,10 @@
|
|
1
1
|
Feature: Core schema: id
|
2
|
+
|
3
|
+
See: https://groups.google.com/d/msg/json-schema/lftABvH5KkA/KW93ZX-JdpsJ
|
4
|
+
for an explanation. The relevant part is "URIs, not URLs", i.e. id attributes
|
5
|
+
are for *identifying* schemas, not for *locating* them. No retrieval is
|
6
|
+
necessary.
|
7
|
+
|
2
8
|
Scenario: absolute URI, single schema
|
3
9
|
When the schema is:
|
4
10
|
"""
|
@@ -10,17 +16,6 @@ Feature: Core schema: id
|
|
10
16
|
Then the id of "Test Schema" is "http://www.example.com/schemas/json"
|
11
17
|
|
12
18
|
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
19
|
When the schema is:
|
25
20
|
"""
|
26
21
|
{
|
@@ -0,0 +1,138 @@
|
|
1
|
+
Feature: Core schema: $ref
|
2
|
+
Scenario: Ref resolves to the same schema
|
3
|
+
When the schema is:
|
4
|
+
"""
|
5
|
+
{
|
6
|
+
"id": "http://www.example.com/schemas/person",
|
7
|
+
"title": "The Best Person Schema Ever",
|
8
|
+
"properties": {
|
9
|
+
"name": { "type": "string" },
|
10
|
+
"age": { "type": "integer" },
|
11
|
+
"favorite_person": { "$ref": "http://www.example.com/schemas/person" }
|
12
|
+
}
|
13
|
+
}
|
14
|
+
"""
|
15
|
+
Then this is valid JSON:
|
16
|
+
"""
|
17
|
+
{
|
18
|
+
"name": "Felizberto Albi",
|
19
|
+
"age": 24,
|
20
|
+
"favorite_person": {
|
21
|
+
"name": "Lil Wayne Pangles",
|
22
|
+
"age": 52,
|
23
|
+
"favorite_person": {
|
24
|
+
"name": "Birdman Pangles",
|
25
|
+
"age": 71,
|
26
|
+
"favorite_person": {
|
27
|
+
"name": "Best here to be silent",
|
28
|
+
"age": 105
|
29
|
+
}
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}
|
33
|
+
"""
|
34
|
+
But this is not valid JSON:
|
35
|
+
"""
|
36
|
+
{
|
37
|
+
"name": "Felizberto Albi",
|
38
|
+
"age": 24,
|
39
|
+
"favorite_person": {
|
40
|
+
"name": "Lil Wayne Pangles",
|
41
|
+
"age": "At least a billion. At least."
|
42
|
+
}
|
43
|
+
}
|
44
|
+
"""
|
45
|
+
|
46
|
+
Scenario: Ref with relative path resolves to the same schema
|
47
|
+
TODO: This scenario shares too much information with the one above it.
|
48
|
+
|
49
|
+
When the schema is:
|
50
|
+
"""
|
51
|
+
{
|
52
|
+
"id": "http://www.example.com/schemas/person",
|
53
|
+
"title": "The Best Person Schema Ever",
|
54
|
+
"properties": {
|
55
|
+
"name": { "type": "string" },
|
56
|
+
"age": { "type": "integer" },
|
57
|
+
"favorite_person": { "$ref": "/schemas/person" }
|
58
|
+
}
|
59
|
+
}
|
60
|
+
"""
|
61
|
+
Then this is valid JSON:
|
62
|
+
"""
|
63
|
+
{
|
64
|
+
"name": "Felizberto Albi",
|
65
|
+
"age": 24,
|
66
|
+
"favorite_person": {
|
67
|
+
"name": "Lil Wayne Pangles",
|
68
|
+
"age": 52,
|
69
|
+
"favorite_person": {
|
70
|
+
"name": "Birdman Pangles",
|
71
|
+
"age": 71,
|
72
|
+
"favorite_person": {
|
73
|
+
"name": "Best here to be silent",
|
74
|
+
"age": 105
|
75
|
+
}
|
76
|
+
}
|
77
|
+
}
|
78
|
+
}
|
79
|
+
"""
|
80
|
+
But this is not valid JSON:
|
81
|
+
"""
|
82
|
+
{
|
83
|
+
"name": "Felizberto Albi",
|
84
|
+
"age": 24,
|
85
|
+
"favorite_person": {
|
86
|
+
"name": "Lil Wayne Pangles",
|
87
|
+
"age": "At least a billion. At least."
|
88
|
+
}
|
89
|
+
}
|
90
|
+
"""
|
91
|
+
|
92
|
+
Scenario: Ref resolves to different schema
|
93
|
+
Given this schema:
|
94
|
+
"""
|
95
|
+
{
|
96
|
+
"id": "http://www.example.com/schemas/person",
|
97
|
+
"title": "The Best Person Schema Ever",
|
98
|
+
"properties": {
|
99
|
+
"name": { "type": "string" },
|
100
|
+
"age": { "type": "integer" }
|
101
|
+
}
|
102
|
+
}
|
103
|
+
"""
|
104
|
+
And this schema:
|
105
|
+
"""
|
106
|
+
{
|
107
|
+
"title": "A Happy Family Much Like All Other Happy Families",
|
108
|
+
"type": "array",
|
109
|
+
"items": {
|
110
|
+
"$ref": "http://www.example.com/schemas/person"
|
111
|
+
}
|
112
|
+
}
|
113
|
+
"""
|
114
|
+
Then this is valid JSON:
|
115
|
+
"""
|
116
|
+
[
|
117
|
+
{
|
118
|
+
"name": "Anna Arkadyevna Karenina",
|
119
|
+
"age": 18
|
120
|
+
},
|
121
|
+
|
122
|
+
{
|
123
|
+
"name": "Count Alexei Kirillovich Vronsky",
|
124
|
+
"age": 25
|
125
|
+
}
|
126
|
+
]
|
127
|
+
"""
|
128
|
+
But this is not valid JSON:
|
129
|
+
"""
|
130
|
+
[
|
131
|
+
{
|
132
|
+
"name": "The Underground Man",
|
133
|
+
"age": "timeless"
|
134
|
+
}
|
135
|
+
]
|
136
|
+
"""
|
137
|
+
|
138
|
+
Scenario: Ref appears before the id it references
|
@@ -1,36 +1,40 @@
|
|
1
|
+
Given "this schema:" do |schema|
|
2
|
+
add_schema(parse(schema))
|
3
|
+
end
|
4
|
+
|
1
5
|
When /^the schema is '(.+)'$/ do |schema|
|
2
|
-
|
6
|
+
add_schema(parse(schema))
|
3
7
|
end
|
4
8
|
|
5
9
|
When "the schema is:" do |schema|
|
6
|
-
|
10
|
+
add_schema(parse(schema))
|
7
11
|
end
|
8
12
|
|
9
13
|
Then /^'(.+)' is valid JSON$/ do |json|
|
10
|
-
assert_valid(parse(json),
|
14
|
+
assert_valid(parse(json), all_schemas)
|
11
15
|
end
|
12
16
|
|
13
17
|
Then /^'(.+)' is not valid JSON$/ do |json|
|
14
|
-
assert_invalid(parse(json),
|
18
|
+
assert_invalid(parse(json), all_schemas)
|
15
19
|
end
|
16
20
|
|
17
21
|
Then "this is valid JSON:" do |json|
|
18
|
-
assert_valid(parse(json),
|
22
|
+
assert_valid(parse(json), all_schemas)
|
19
23
|
end
|
20
24
|
|
21
25
|
Then "this is not valid JSON:" do |json|
|
22
|
-
assert_invalid(parse(json),
|
26
|
+
assert_invalid(parse(json), all_schemas)
|
23
27
|
end
|
24
28
|
|
25
29
|
Then "these are valid JSON:" do |instances|
|
26
30
|
instances.raw.each do |row|
|
27
|
-
assert_valid(parse(row[0]),
|
31
|
+
assert_valid(parse(row[0]), all_schemas)
|
28
32
|
end
|
29
33
|
end
|
30
34
|
|
31
35
|
Then "these are not valid JSON:" do |instances|
|
32
36
|
instances.raw.each do |row|
|
33
|
-
assert_invalid(parse(row[0]),
|
37
|
+
assert_invalid(parse(row[0]), all_schemas)
|
34
38
|
end
|
35
39
|
end
|
36
40
|
|
@@ -46,16 +50,25 @@ module JschematicWorld
|
|
46
50
|
raise "Parsing '#{json}' failed with #{e.to_s}"
|
47
51
|
end
|
48
52
|
|
49
|
-
def assert_valid(json,
|
50
|
-
Jschematic.validate(json,
|
53
|
+
def assert_valid(json, raw_schemas)
|
54
|
+
Jschematic.validate(json, *raw_schemas).should be_true
|
51
55
|
end
|
52
56
|
|
53
|
-
def assert_invalid(json,
|
54
|
-
Jschematic.validate(json,
|
57
|
+
def assert_invalid(json, raw_schemas)
|
58
|
+
Jschematic.validate(json, *raw_schemas).should be_false
|
55
59
|
end
|
56
60
|
|
57
61
|
def build_schema
|
58
|
-
@_schema ||= Jschematic::Schema.new(
|
62
|
+
@_schema ||= Jschematic::Schema.new(all_schemas.first)
|
63
|
+
end
|
64
|
+
|
65
|
+
def add_schema(schema)
|
66
|
+
@_schemas ||= []
|
67
|
+
@_schemas << schema
|
68
|
+
end
|
69
|
+
|
70
|
+
def all_schemas
|
71
|
+
@_schemas ||= []
|
59
72
|
end
|
60
73
|
end
|
61
74
|
|
data/jschematic.gemspec
CHANGED
@@ -1,20 +1,18 @@
|
|
1
1
|
require 'ipaddr'
|
2
2
|
require 'addressable/uri'
|
3
|
+
require 'date'
|
3
4
|
|
4
5
|
module Jschematic
|
5
6
|
module Attributes
|
6
7
|
module Format
|
7
8
|
def self.new(format)
|
8
|
-
|
9
|
-
|
10
|
-
Uri.new
|
11
|
-
when "ip-address", "ipv6"
|
12
|
-
Ip.new(format)
|
13
|
-
when "cidr"
|
14
|
-
Cidr.new(format)
|
15
|
-
else
|
16
|
-
NullFormat.new
|
9
|
+
format_class = format.split(/[^\w\d]/).inject("") do |name, part|
|
10
|
+
name << part.capitalize
|
17
11
|
end
|
12
|
+
|
13
|
+
const_get(format_class).new
|
14
|
+
rescue NameError
|
15
|
+
NullFormat.new(format)
|
18
16
|
end
|
19
17
|
|
20
18
|
class Uri
|
@@ -27,20 +25,21 @@ module Jschematic
|
|
27
25
|
end
|
28
26
|
end
|
29
27
|
|
30
|
-
class
|
28
|
+
class IpAddress
|
31
29
|
include Jschematic::Element
|
32
30
|
|
33
|
-
def
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
when "ipv6"
|
38
|
-
:ipv6?
|
39
|
-
end
|
31
|
+
def accepts?(addr)
|
32
|
+
IPAddr.new(addr).ipv4?
|
33
|
+
rescue ArgumentError
|
34
|
+
false
|
40
35
|
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class Ipv6
|
39
|
+
include Jschematic::Element
|
41
40
|
|
42
41
|
def accepts?(addr)
|
43
|
-
IPAddr.new(addr).
|
42
|
+
IPAddr.new(addr).ipv6?
|
44
43
|
rescue ArgumentError
|
45
44
|
false
|
46
45
|
end
|
@@ -52,12 +51,37 @@ module Jschematic
|
|
52
51
|
def accepts?(addr_with_cidr)
|
53
52
|
addr, cidr = addr_with_cidr.split("/")
|
54
53
|
return false unless cidr && (1..32).include?(cidr.to_i)
|
55
|
-
|
54
|
+
IpAddress.new.accepts?(addr)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class DateTime
|
59
|
+
include Jschematic::Element
|
60
|
+
|
61
|
+
def accepts?(date_time)
|
62
|
+
::DateTime.strptime(date_time)
|
63
|
+
rescue ArgumentError
|
64
|
+
false
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class Date
|
69
|
+
include Jschematic::Element
|
70
|
+
|
71
|
+
def accepts?(date)
|
72
|
+
::Date.strptime(date)
|
73
|
+
rescue ArgumentError
|
74
|
+
false
|
56
75
|
end
|
57
76
|
end
|
58
77
|
|
59
78
|
class NullFormat
|
60
79
|
include Jschematic::Element
|
80
|
+
attr_reader :format
|
81
|
+
|
82
|
+
def initialize(format)
|
83
|
+
@format = format
|
84
|
+
end
|
61
85
|
|
62
86
|
def accepts?(instance)
|
63
87
|
true
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'addressable/uri'
|
2
|
+
|
3
|
+
require 'jschematic/element'
|
4
|
+
|
5
|
+
module Jschematic
|
6
|
+
module Attributes
|
7
|
+
class Ref
|
8
|
+
include Jschematic::Element
|
9
|
+
|
10
|
+
def initialize(uri)
|
11
|
+
@uri = Addressable::URI.parse(uri)
|
12
|
+
end
|
13
|
+
|
14
|
+
def accepts?(instance)
|
15
|
+
schema = Schema.schema_for(@uri) || raise(SchemaNotFoundError.new(@uri))
|
16
|
+
schema.accepts?(instance)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -18,11 +18,13 @@ require 'jschematic/attributes/min_length'
|
|
18
18
|
require 'jschematic/attributes/max_length'
|
19
19
|
require 'jschematic/attributes/enum'
|
20
20
|
require 'jschematic/attributes/format'
|
21
|
+
require 'jschematic/attributes/ref'
|
21
22
|
|
22
23
|
module Jschematic
|
23
24
|
module Attributes
|
24
25
|
def self.[](name)
|
25
|
-
|
26
|
+
name_without_meta = name.gsub(/^\$/, '')
|
27
|
+
const_get(name_without_meta[0].chr.capitalize + name_without_meta[1..-1])
|
26
28
|
end
|
27
29
|
end
|
28
30
|
end
|
data/lib/jschematic/element.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
-
require 'jschematic/
|
1
|
+
require 'jschematic/exceptions'
|
2
2
|
|
3
3
|
module Jschematic
|
4
4
|
module Element
|
5
5
|
attr_accessor :parent
|
6
|
+
attr_writer :id
|
6
7
|
|
7
8
|
def required?
|
8
9
|
false
|
@@ -12,6 +13,14 @@ module Jschematic
|
|
12
13
|
nil
|
13
14
|
end
|
14
15
|
|
16
|
+
def id
|
17
|
+
if @parent
|
18
|
+
@parent.id + @id
|
19
|
+
else
|
20
|
+
@id
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
15
24
|
def to_s
|
16
25
|
self.class.to_s
|
17
26
|
end
|
@@ -10,4 +10,16 @@ module Jschematic
|
|
10
10
|
"#{what} expected #{expected} but found #{actual}"
|
11
11
|
end
|
12
12
|
end
|
13
|
+
|
14
|
+
class SchemaNotFoundError < StandardError
|
15
|
+
attr_reader :uri
|
16
|
+
|
17
|
+
def initialize(uri)
|
18
|
+
@uri = uri
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
"Cannot find schema for reference '#{uri}'"
|
23
|
+
end
|
24
|
+
end
|
13
25
|
end
|
data/lib/jschematic/schema.rb
CHANGED
@@ -15,7 +15,26 @@ module Jschematic
|
|
15
15
|
schema
|
16
16
|
end
|
17
17
|
|
18
|
-
|
18
|
+
def self.schema_for(ref)
|
19
|
+
if ref.relative?
|
20
|
+
rel = ref.omit(:scheme, :host, :port)
|
21
|
+
if match = schemas.find{ |ref, _| rel == ref.omit(:scheme, :host, :port) }
|
22
|
+
match[-1]
|
23
|
+
end
|
24
|
+
else
|
25
|
+
schemas[ref]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.add_schema(id, schema)
|
30
|
+
schemas[id] = schema
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.schemas
|
34
|
+
@schemas ||= {}
|
35
|
+
end
|
36
|
+
|
37
|
+
attr_reader :default, :title, :description
|
19
38
|
|
20
39
|
attr_accessor :name
|
21
40
|
attr_writer :parent
|
@@ -28,6 +47,8 @@ module Jschematic
|
|
28
47
|
@description = @raw_schema.delete("description") || ""
|
29
48
|
@id = Addressable::URI.parse(@raw_schema.delete("id") || "")
|
30
49
|
|
50
|
+
self.class.add_schema(@id, self) unless @id.to_s.empty?
|
51
|
+
|
31
52
|
@raw_schema.each_pair do |attribute, value|
|
32
53
|
begin
|
33
54
|
attribute = Attributes[attribute].new(value){ |dep| @raw_schema[dep] }
|
@@ -51,14 +72,6 @@ module Jschematic
|
|
51
72
|
children.any?{ |child| child.required? }
|
52
73
|
end
|
53
74
|
|
54
|
-
def id
|
55
|
-
if @parent
|
56
|
-
@parent.id + @id
|
57
|
-
else
|
58
|
-
@id
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
75
|
private
|
63
76
|
|
64
77
|
def add_default(instance)
|
data/lib/jschematic.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
|
-
require 'jschematic/
|
1
|
+
require 'jschematic/context'
|
2
2
|
|
3
3
|
module Jschematic
|
4
|
-
def self.validate(instance,
|
5
|
-
validate!(instance,
|
4
|
+
def self.validate(instance, *schemas)
|
5
|
+
validate!(instance, *schemas)
|
6
6
|
rescue ValidationError
|
7
7
|
false
|
8
8
|
end
|
9
9
|
|
10
|
-
def self.validate!(instance,
|
11
|
-
|
10
|
+
def self.validate!(instance, *schemas)
|
11
|
+
Context.new(*schemas).validate!(instance)
|
12
12
|
end
|
13
13
|
end
|
@@ -1,5 +1,31 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
+
shared_examples_for "an element" do |args|
|
4
|
+
let(:parent) { double("a parent element") }
|
5
|
+
let(:good) { args[:good] }
|
6
|
+
let(:bad) { args[:bad] }
|
7
|
+
|
8
|
+
it "has a parent" do
|
9
|
+
element.parent = parent
|
10
|
+
element.parent.should === parent
|
11
|
+
end
|
12
|
+
|
13
|
+
it "accepts good instance values" do
|
14
|
+
element.should accept(good)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "does not accept bad instance values" do
|
18
|
+
element.should_not accept(bad)
|
19
|
+
end
|
20
|
+
|
21
|
+
xit "adds errors to its parent" do
|
22
|
+
parent = Parent.new
|
23
|
+
element.parent = parent
|
24
|
+
element.validate(:garbage)
|
25
|
+
parent.errors.should include(some_stuff)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
3
29
|
module Jschematic
|
4
30
|
module Attributes
|
5
31
|
describe Enum do
|
@@ -9,6 +35,10 @@ module Jschematic
|
|
9
35
|
expect { subject.new("this is allowed, right?") }.to raise_error
|
10
36
|
expect { subject.new(["not", "really"]) }.to_not raise_error
|
11
37
|
end
|
38
|
+
|
39
|
+
it_should_behave_like "an element", good: 1, bad: 2 do
|
40
|
+
let(:element) { subject.new([1]) }
|
41
|
+
end
|
12
42
|
end
|
13
43
|
end
|
14
44
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Jschematic
|
4
|
+
module Attributes
|
5
|
+
describe Format do
|
6
|
+
it "returns a NullFormat when the format is not found" do
|
7
|
+
format = Format.new("i-don't-exist")
|
8
|
+
format.should be_an_instance_of(Format::NullFormat)
|
9
|
+
format.format.should == "i-don't-exist"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Jschematic
|
4
|
+
module Attributes
|
5
|
+
describe Ref do
|
6
|
+
describe "#accepts?" do
|
7
|
+
it "fails when the references schema does not exist" do
|
8
|
+
Schema.schemas.should be_empty
|
9
|
+
ref = Ref.new("does_not_exist")
|
10
|
+
expect { ref.accepts?({}) }.to raise_error(Jschematic::SchemaNotFoundError)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -7,6 +7,11 @@ module Jschematic
|
|
7
7
|
Attributes::ExclusiveMaximum.should_receive(:new).with(1, 2)
|
8
8
|
subject["exclusiveMaximum"].new(1, 2)
|
9
9
|
end
|
10
|
+
|
11
|
+
it "strips leading '$'" do
|
12
|
+
Attributes::Ref.should_receive(:new).with("foo")
|
13
|
+
subject["$ref"].new("foo")
|
14
|
+
end
|
10
15
|
end
|
11
16
|
end
|
12
17
|
end
|
@@ -32,27 +32,14 @@ module Jschematic
|
|
32
32
|
description.should == ""
|
33
33
|
end
|
34
34
|
end
|
35
|
-
end
|
36
|
-
|
37
|
-
class Parent
|
38
|
-
attr_reader :id
|
39
|
-
def initialize(opts)
|
40
|
-
@id = opts["id"]
|
41
|
-
@children = []
|
42
|
-
end
|
43
35
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
it "builds its id from its parent" do
|
52
|
-
parent = Parent.new("id" => "http://www.example.com/parent/")
|
53
|
-
schema = Schema.new("id" => "child")
|
54
|
-
parent.add_child(schema)
|
55
|
-
schema.id.should == "http://www.example.com/parent/child"
|
36
|
+
describe "#id" do
|
37
|
+
it "is built from the parent's id" do
|
38
|
+
parent = Parent.new("id" => "http://www.example.com/parent/")
|
39
|
+
schema = Schema.new("id" => "child")
|
40
|
+
parent.add_child(schema)
|
41
|
+
schema.id.should == "http://www.example.com/parent/child"
|
42
|
+
end
|
56
43
|
end
|
57
44
|
end
|
58
45
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -14,3 +14,20 @@ RSpec::Matchers.define :accept do |instance_value|
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
+
module Jschematic
|
18
|
+
class Parent
|
19
|
+
include Jschematic::Composite
|
20
|
+
|
21
|
+
def initialize(opts)
|
22
|
+
self.id = opts["id"]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class Child
|
27
|
+
include Jschematic::Element
|
28
|
+
|
29
|
+
def accepts?(instance)
|
30
|
+
!!instance
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 5
|
9
|
+
version: 0.0.5
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Mike Sassak
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-
|
17
|
+
date: 2011-03-15 00:00:00 -05:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -99,6 +99,7 @@ files:
|
|
99
99
|
- features/pattern.feature
|
100
100
|
- features/pattern_properties.feature
|
101
101
|
- features/properties.feature
|
102
|
+
- features/ref.feature
|
102
103
|
- features/required.feature
|
103
104
|
- features/step_definitions/jschematic_steps.rb
|
104
105
|
- features/support/env.rb
|
@@ -123,18 +124,22 @@ files:
|
|
123
124
|
- lib/jschematic/attributes/pattern.rb
|
124
125
|
- lib/jschematic/attributes/pattern_properties.rb
|
125
126
|
- lib/jschematic/attributes/properties.rb
|
127
|
+
- lib/jschematic/attributes/ref.rb
|
126
128
|
- lib/jschematic/attributes/required.rb
|
127
129
|
- lib/jschematic/attributes/type.rb
|
128
130
|
- lib/jschematic/attributes/unique_items.rb
|
129
131
|
- lib/jschematic/composite.rb
|
132
|
+
- lib/jschematic/context.rb
|
130
133
|
- lib/jschematic/element.rb
|
131
134
|
- lib/jschematic/errors.rb
|
135
|
+
- lib/jschematic/exceptions.rb
|
132
136
|
- lib/jschematic/schema.rb
|
133
|
-
- lib/jschematic/validation_error.rb
|
134
137
|
- spec/jschematic/attributes/enum_spec.rb
|
138
|
+
- spec/jschematic/attributes/format_spec.rb
|
135
139
|
- spec/jschematic/attributes/max_items_spec.rb
|
136
140
|
- spec/jschematic/attributes/min_items_spec.rb
|
137
141
|
- spec/jschematic/attributes/minimum_maximum_spec.rb
|
142
|
+
- spec/jschematic/attributes/ref_spec.rb
|
138
143
|
- spec/jschematic/attributes/required_spec.rb
|
139
144
|
- spec/jschematic/attributes/type_spec.rb
|
140
145
|
- spec/jschematic/attributes_spec.rb
|
@@ -172,7 +177,7 @@ rubyforge_project:
|
|
172
177
|
rubygems_version: 1.3.7
|
173
178
|
signing_key:
|
174
179
|
specification_version: 3
|
175
|
-
summary: jschematic 0.0.
|
180
|
+
summary: jschematic 0.0.5
|
176
181
|
test_files:
|
177
182
|
- features/default.feature
|
178
183
|
- features/dependencies.feature
|
@@ -185,14 +190,17 @@ test_files:
|
|
185
190
|
- features/pattern.feature
|
186
191
|
- features/pattern_properties.feature
|
187
192
|
- features/properties.feature
|
193
|
+
- features/ref.feature
|
188
194
|
- features/required.feature
|
189
195
|
- features/step_definitions/jschematic_steps.rb
|
190
196
|
- features/support/env.rb
|
191
197
|
- features/type.feature
|
192
198
|
- spec/jschematic/attributes/enum_spec.rb
|
199
|
+
- spec/jschematic/attributes/format_spec.rb
|
193
200
|
- spec/jschematic/attributes/max_items_spec.rb
|
194
201
|
- spec/jschematic/attributes/min_items_spec.rb
|
195
202
|
- spec/jschematic/attributes/minimum_maximum_spec.rb
|
203
|
+
- spec/jschematic/attributes/ref_spec.rb
|
196
204
|
- spec/jschematic/attributes/required_spec.rb
|
197
205
|
- spec/jschematic/attributes/type_spec.rb
|
198
206
|
- spec/jschematic/attributes_spec.rb
|