jschematic 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +1 -0
- data/.rvmrc +1 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +40 -0
- data/LICENSE +20 -0
- data/README.md +48 -0
- data/Rakefile +10 -0
- data/cucumber.yml +1 -0
- data/features/default.feature +72 -0
- data/features/dependencies.feature +73 -0
- data/features/enum.feature +26 -0
- data/features/format.feature +40 -0
- data/features/id.feature +75 -0
- data/features/items.feature +90 -0
- data/features/min_length_max_length.feature +20 -0
- data/features/minimum_maximum.feature +29 -0
- data/features/pattern.feature +6 -0
- data/features/pattern_properties.feature +18 -0
- data/features/properties.feature +124 -0
- data/features/required.feature +42 -0
- data/features/step_definitions/jschematic_steps.rb +62 -0
- data/features/support/env.rb +6 -0
- data/features/type.feature +76 -0
- data/jschematic.gemspec +22 -0
- data/lib/jschematic/attributes/additional_items.rb +35 -0
- data/lib/jschematic/attributes/additional_properties.rb +28 -0
- data/lib/jschematic/attributes/dependencies.rb +26 -0
- data/lib/jschematic/attributes/enum.rb +18 -0
- data/lib/jschematic/attributes/exclusive_maximum.rb +21 -0
- data/lib/jschematic/attributes/exclusive_minimum.rb +21 -0
- data/lib/jschematic/attributes/format.rb +56 -0
- data/lib/jschematic/attributes/items.rb +24 -0
- data/lib/jschematic/attributes/max_items.rb +18 -0
- data/lib/jschematic/attributes/max_length.rb +18 -0
- data/lib/jschematic/attributes/maximum.rb +22 -0
- data/lib/jschematic/attributes/min_items.rb +18 -0
- data/lib/jschematic/attributes/min_length.rb +18 -0
- data/lib/jschematic/attributes/minimum.rb +22 -0
- data/lib/jschematic/attributes/pattern.rb +18 -0
- data/lib/jschematic/attributes/pattern_properties.rb +23 -0
- data/lib/jschematic/attributes/properties.rb +38 -0
- data/lib/jschematic/attributes/required.rb +28 -0
- data/lib/jschematic/attributes/type.rb +61 -0
- data/lib/jschematic/attributes/unique_items.rb +18 -0
- data/lib/jschematic/attributes.rb +28 -0
- data/lib/jschematic/element.rb +25 -0
- data/lib/jschematic/errors.rb +34 -0
- data/lib/jschematic/schema.rb +77 -0
- data/lib/jschematic/validation_error.rb +13 -0
- data/lib/jschematic.rb +13 -0
- data/spec/jschematic/attributes/enum_spec.rb +14 -0
- data/spec/jschematic/attributes/max_items_spec.rb +15 -0
- data/spec/jschematic/attributes/min_items_spec.rb +15 -0
- data/spec/jschematic/attributes/minimum_maximum_spec.rb +33 -0
- data/spec/jschematic/attributes/required_spec.rb +29 -0
- data/spec/jschematic/attributes/type_spec.rb +63 -0
- data/spec/jschematic/attributes_spec.rb +12 -0
- data/spec/jschematic/errors_spec.rb +43 -0
- data/spec/jschematic/schema_spec.rb +58 -0
- data/spec/spec_helper.rb +16 -0
- metadata +199 -0
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'jschematic/element'
|
2
|
+
|
3
|
+
module Jschematic
|
4
|
+
module Attributes
|
5
|
+
class Minimum
|
6
|
+
include Jschematic::Element
|
7
|
+
|
8
|
+
attr_reader :minimum
|
9
|
+
|
10
|
+
def initialize(minimum)
|
11
|
+
@minimum = minimum
|
12
|
+
end
|
13
|
+
|
14
|
+
def accepts?(number)
|
15
|
+
return true unless minimum
|
16
|
+
return true unless (number.kind_of?(Integer) || number.kind_of?(Float))
|
17
|
+
|
18
|
+
(number >= minimum) || fail_validation!(">= #{@minimum}", number)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'jschematic/element'
|
2
|
+
|
3
|
+
module Jschematic
|
4
|
+
module Attributes
|
5
|
+
class Pattern
|
6
|
+
include Jschematic::Element
|
7
|
+
|
8
|
+
def initialize(pattern)
|
9
|
+
@pattern = Regexp.new(pattern)
|
10
|
+
end
|
11
|
+
|
12
|
+
def accepts?(instance)
|
13
|
+
return true unless String === instance
|
14
|
+
instance.match(@pattern) || fail_validation!("string matching #{@pattern}", instance)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'jschematic/element'
|
2
|
+
|
3
|
+
module Jschematic
|
4
|
+
module Attributes
|
5
|
+
class PatternProperties
|
6
|
+
include Jschematic::Element
|
7
|
+
|
8
|
+
def initialize(schema)
|
9
|
+
@schema = schema
|
10
|
+
end
|
11
|
+
|
12
|
+
def accepts?(instance)
|
13
|
+
instance.all? do |property, value|
|
14
|
+
if match = @schema.find{ |re, schema| property =~ Regexp.new(re) }
|
15
|
+
Schema.new(match[1]).accepts?(value)
|
16
|
+
else
|
17
|
+
false
|
18
|
+
end
|
19
|
+
end || fail_validation!(@schema, instance)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'jschematic/element'
|
2
|
+
|
3
|
+
module Jschematic
|
4
|
+
module Attributes
|
5
|
+
class Properties
|
6
|
+
include Jschematic::Element
|
7
|
+
|
8
|
+
def initialize(properties)
|
9
|
+
@schemas = properties.inject({}) do |schemas, (name, schema)|
|
10
|
+
schemas[name] = Schema.new(schema)
|
11
|
+
schemas[name].parent = self
|
12
|
+
schemas
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def accepts?(instance)
|
17
|
+
@schemas.all? do |name, schema|
|
18
|
+
value = instance.fetch(name) do |missing|
|
19
|
+
return true unless schema.required?
|
20
|
+
fail_validation!(missing, nil) unless schema.default
|
21
|
+
schema.default
|
22
|
+
end
|
23
|
+
schema.accepts?(value) || fail_validation!(name, value)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def each(&block)
|
28
|
+
@schemas.values.each do |schema|
|
29
|
+
block.call(schema)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def id
|
34
|
+
@parent.id
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'jschematic/element'
|
2
|
+
|
3
|
+
module Jschematic
|
4
|
+
module Attributes
|
5
|
+
class Required
|
6
|
+
include Jschematic::Element
|
7
|
+
|
8
|
+
def initialize(required=false)
|
9
|
+
case required
|
10
|
+
when TrueClass, FalseClass
|
11
|
+
@required = required
|
12
|
+
else
|
13
|
+
raise "Require must be strictly true or false. Truthy and false values are not allowed."
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def required?
|
18
|
+
@required
|
19
|
+
end
|
20
|
+
|
21
|
+
def accepts?(instance)
|
22
|
+
if @required
|
23
|
+
instance || fail_validation!(@required, instance)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'jschematic/element'
|
2
|
+
|
3
|
+
module Jschematic
|
4
|
+
module Attributes
|
5
|
+
class Type
|
6
|
+
include Jschematic::Element
|
7
|
+
|
8
|
+
attr_reader :type
|
9
|
+
|
10
|
+
def initialize(type)
|
11
|
+
@type = type
|
12
|
+
end
|
13
|
+
|
14
|
+
def accepts?(instance)
|
15
|
+
return true unless type
|
16
|
+
|
17
|
+
case type
|
18
|
+
when /^object$/
|
19
|
+
assert_kind_of([Hash], instance)
|
20
|
+
when /^number$/
|
21
|
+
assert_kind_of([Float, Integer], instance)
|
22
|
+
when /^integer$/
|
23
|
+
assert_kind_of([Integer], instance)
|
24
|
+
when /^boolean$/
|
25
|
+
assert_kind_of([TrueClass, FalseClass], instance)
|
26
|
+
when /^null$/
|
27
|
+
assert_kind_of([NilClass], instance)
|
28
|
+
when /^any$/
|
29
|
+
true
|
30
|
+
when Array # union
|
31
|
+
# TODO: this is gross. A specific Union type is likely called for.
|
32
|
+
type.any? do |union_type|
|
33
|
+
begin
|
34
|
+
if String===union_type
|
35
|
+
Type.new(union_type).accepts?(instance)
|
36
|
+
elsif Hash===union_type
|
37
|
+
Schema.new(union_type).accepts?(instance)
|
38
|
+
end
|
39
|
+
rescue ValidationError
|
40
|
+
false
|
41
|
+
end
|
42
|
+
end
|
43
|
+
else
|
44
|
+
# TODO: probably worth just putting in explicit mapping for all
|
45
|
+
# JSON schema types--there are only a few left
|
46
|
+
assert_kind_of([constantize(type)], instance)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def assert_kind_of(klassen, instance)
|
53
|
+
klassen.any?{ |klass| instance.kind_of?(klass) } || fail_validation!(klassen, instance)
|
54
|
+
end
|
55
|
+
|
56
|
+
def constantize(string)
|
57
|
+
Kernel.const_get(string.capitalize)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'jschematic/element'
|
2
|
+
|
3
|
+
module Jschematic
|
4
|
+
module Attributes
|
5
|
+
class UniqueItems
|
6
|
+
include Jschematic::Element
|
7
|
+
|
8
|
+
def initialize(value=false)
|
9
|
+
@value = value
|
10
|
+
end
|
11
|
+
|
12
|
+
def accepts?(instance)
|
13
|
+
require true unless Array === instance
|
14
|
+
(instance == instance.uniq) || fail_validation!("all items to be unique", instance)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'jschematic/attributes/type'
|
2
|
+
require 'jschematic/attributes/properties'
|
3
|
+
require 'jschematic/attributes/pattern_properties'
|
4
|
+
require 'jschematic/attributes/additional_properties'
|
5
|
+
require 'jschematic/attributes/items'
|
6
|
+
require 'jschematic/attributes/additional_items'
|
7
|
+
require 'jschematic/attributes/required'
|
8
|
+
require 'jschematic/attributes/dependencies'
|
9
|
+
require 'jschematic/attributes/minimum'
|
10
|
+
require 'jschematic/attributes/maximum'
|
11
|
+
require 'jschematic/attributes/exclusive_minimum'
|
12
|
+
require 'jschematic/attributes/exclusive_maximum'
|
13
|
+
require 'jschematic/attributes/min_items'
|
14
|
+
require 'jschematic/attributes/max_items'
|
15
|
+
require 'jschematic/attributes/unique_items'
|
16
|
+
require 'jschematic/attributes/pattern'
|
17
|
+
require 'jschematic/attributes/min_length'
|
18
|
+
require 'jschematic/attributes/max_length'
|
19
|
+
require 'jschematic/attributes/enum'
|
20
|
+
require 'jschematic/attributes/format'
|
21
|
+
|
22
|
+
module Jschematic
|
23
|
+
module Attributes
|
24
|
+
def self.[](name)
|
25
|
+
const_get(name[0].chr.capitalize + name[1..-1])
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'jschematic/validation_error'
|
2
|
+
|
3
|
+
module Jschematic
|
4
|
+
module Element
|
5
|
+
attr_accessor :parent
|
6
|
+
|
7
|
+
def required?
|
8
|
+
false
|
9
|
+
end
|
10
|
+
|
11
|
+
def title
|
12
|
+
nil
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_s
|
16
|
+
self.class.to_s
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def fail_validation!(expected, actual)
|
22
|
+
raise Jschematic::ValidationError.new(self, expected, actual)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Jschematic
|
2
|
+
class Errors
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
def initialize(raise_on_error = false)
|
6
|
+
@raise_on_error = raise_on_error
|
7
|
+
@errors = []
|
8
|
+
end
|
9
|
+
|
10
|
+
def add(id, desc)
|
11
|
+
if @raise_on_error
|
12
|
+
raise "Error: #{desc}"
|
13
|
+
else
|
14
|
+
@errors << [id, desc]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def all
|
19
|
+
@errors
|
20
|
+
end
|
21
|
+
|
22
|
+
def empty?
|
23
|
+
@errors.empty?
|
24
|
+
end
|
25
|
+
|
26
|
+
def reset!
|
27
|
+
@errors = []
|
28
|
+
end
|
29
|
+
|
30
|
+
def each(&block)
|
31
|
+
@errors.each(&block)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'addressable/uri'
|
2
|
+
|
3
|
+
require 'jschematic/errors'
|
4
|
+
require 'jschematic/element'
|
5
|
+
require 'jschematic/attributes'
|
6
|
+
|
7
|
+
module Jschematic
|
8
|
+
class Schema
|
9
|
+
include Enumerable
|
10
|
+
include Jschematic::Element
|
11
|
+
|
12
|
+
attr_reader :default, :title, :description, :id
|
13
|
+
attr_writer :parent
|
14
|
+
|
15
|
+
def initialize(raw_schema)
|
16
|
+
@raw_schema = raw_schema.dup || {}
|
17
|
+
|
18
|
+
@default = @raw_schema.delete("default")
|
19
|
+
@title = @raw_schema.delete("title") || ""
|
20
|
+
@description = @raw_schema.delete("description") || ""
|
21
|
+
@id = Addressable::URI.parse(@raw_schema.delete("id") || "")
|
22
|
+
|
23
|
+
@attributes = []
|
24
|
+
|
25
|
+
@raw_schema.each_pair do |attribute, value|
|
26
|
+
begin
|
27
|
+
attribute = Attributes[attribute].new(value){ |dep| @raw_schema[dep] }
|
28
|
+
attribute.parent = self
|
29
|
+
@attributes << attribute
|
30
|
+
rescue NameError => e
|
31
|
+
# Not finding an attribute is not necessarily an error, but this is
|
32
|
+
# obviously not the right way to handle it. Need to find a better way to
|
33
|
+
# report information.
|
34
|
+
# should we create accessors for property on the schema?
|
35
|
+
# we could have Attributes.[] raise a special exception rather than NameError
|
36
|
+
puts "NameError #{e} encountered... continuing"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def accepts?(instance)
|
42
|
+
@attributes.all?{ |child| child.accepts?(add_default(instance)) }
|
43
|
+
end
|
44
|
+
|
45
|
+
def required?
|
46
|
+
@attributes.any?{ |child| child.required? }
|
47
|
+
end
|
48
|
+
|
49
|
+
def each(&block)
|
50
|
+
block.call(self)
|
51
|
+
@attributes.each{ |child| child.each(&block) }
|
52
|
+
end
|
53
|
+
|
54
|
+
def id
|
55
|
+
if @parent
|
56
|
+
@parent.id + @id
|
57
|
+
else
|
58
|
+
@id
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def add_default(instance)
|
65
|
+
return instance unless default
|
66
|
+
|
67
|
+
case instance
|
68
|
+
when Hash
|
69
|
+
@default.keys.each do |key|
|
70
|
+
instance[key] = @default[key] unless instance.has_key?(key)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
instance
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Jschematic
|
2
|
+
class ValidationError < StandardError
|
3
|
+
attr_reader :what, :expected, :actual
|
4
|
+
|
5
|
+
def initialize(what, expected, actual)
|
6
|
+
@what, @expected, @actual = what, expected, actual
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_s
|
10
|
+
"#{what} expected #{expected} but found #{actual}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/jschematic.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Jschematic
|
4
|
+
module Attributes
|
5
|
+
describe Enum do
|
6
|
+
subject { Enum }
|
7
|
+
|
8
|
+
it "raises unless its schema value is an Array" do
|
9
|
+
expect { subject.new("this is allowed, right?") }.to raise_error
|
10
|
+
expect { subject.new(["not", "really"]) }.to_not raise_error
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Jschematic
|
4
|
+
module Attributes
|
5
|
+
describe MaxItems, "with a maximum of two items" do
|
6
|
+
subject { MaxItems.new(2) }
|
7
|
+
|
8
|
+
describe "#accepts?" do
|
9
|
+
it { should accept([1,2]) }
|
10
|
+
it { should_not accept([1,2,3]) }
|
11
|
+
it { should accept("instance that is not an array") }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Jschematic
|
4
|
+
module Attributes
|
5
|
+
describe MinItems, "with a minimum of two items" do
|
6
|
+
subject { MinItems.new(2) }
|
7
|
+
|
8
|
+
describe "#accepts?" do
|
9
|
+
it { should accept([1,2]) }
|
10
|
+
it { should_not accept([1]) }
|
11
|
+
it { should accept("instance that is not an array") }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Jschematic
|
4
|
+
module Attributes
|
5
|
+
describe Minimum do
|
6
|
+
subject { Minimum.new(2112) }
|
7
|
+
|
8
|
+
it { should accept("portokalli") }
|
9
|
+
end
|
10
|
+
|
11
|
+
describe Maximum do
|
12
|
+
subject { Maximum.new(2112) }
|
13
|
+
|
14
|
+
it { should accept("portokalli") }
|
15
|
+
end
|
16
|
+
|
17
|
+
describe ExclusiveMinimum do
|
18
|
+
subject { ExclusiveMinimum }
|
19
|
+
|
20
|
+
it "raises if minimum is not defined" do
|
21
|
+
expect { subject.new(true){|needed| nil} }.to raise_error(/'exclusiveMinimum' depends on 'minimum'/)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe ExclusiveMaximum do
|
26
|
+
subject { ExclusiveMaximum }
|
27
|
+
|
28
|
+
it "raises if maximum is not defined" do
|
29
|
+
expect { subject.new(true){|needed| nil} }.to raise_error(/'exclusiveMaximum' depends on 'maximum'/)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Jschematic
|
4
|
+
module Attributes
|
5
|
+
describe Required do
|
6
|
+
describe "#required?" do
|
7
|
+
subject { Required }
|
8
|
+
|
9
|
+
context "by default" do
|
10
|
+
it "answers false" do
|
11
|
+
subject.new.should_not be_required
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context "when true" do
|
16
|
+
it "answers true" do
|
17
|
+
subject.new(true).should be_required
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "when truthy or falsy" do
|
22
|
+
it "raises an error" do
|
23
|
+
expect { subject.new("true") }.to raise_error
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Jschematic
|
4
|
+
module Attributes
|
5
|
+
describe Type do
|
6
|
+
context "string" do
|
7
|
+
subject { Type.new("string") }
|
8
|
+
it { should_not accept(nil) }
|
9
|
+
end
|
10
|
+
|
11
|
+
context "number" do
|
12
|
+
subject { Type.new("number") }
|
13
|
+
it { should_not accept(nil) }
|
14
|
+
it { should accept(2112) }
|
15
|
+
end
|
16
|
+
|
17
|
+
context "integer" do
|
18
|
+
subject { Type.new("integer") }
|
19
|
+
it { should_not accept(nil) }
|
20
|
+
end
|
21
|
+
|
22
|
+
context "boolean" do
|
23
|
+
subject { Type.new("boolean") }
|
24
|
+
it { should_not accept(nil) }
|
25
|
+
it { should_not accept("true") }
|
26
|
+
it { should_not accept([1,2,3]) }
|
27
|
+
end
|
28
|
+
|
29
|
+
context "object" do
|
30
|
+
subject { Type.new("object") }
|
31
|
+
it { should_not accept(nil) }
|
32
|
+
it { should_not accept([1,2,3]) }
|
33
|
+
it { should_not accept("string") }
|
34
|
+
end
|
35
|
+
|
36
|
+
context "array" do
|
37
|
+
subject { Type.new("array") }
|
38
|
+
it { should_not accept(nil) }
|
39
|
+
it { should_not accept({:foo => "bar"}) }
|
40
|
+
it { should_not accept(1234) }
|
41
|
+
end
|
42
|
+
|
43
|
+
context "null" do
|
44
|
+
subject { Type.new("null") }
|
45
|
+
it { should accept(nil) }
|
46
|
+
it { should_not accept(true) }
|
47
|
+
it { should_not accept("string") }
|
48
|
+
it { should_not accept([1,2,3]) }
|
49
|
+
end
|
50
|
+
|
51
|
+
context "any" do
|
52
|
+
subject { Type.new("any") }
|
53
|
+
it { should accept(nil) }
|
54
|
+
end
|
55
|
+
|
56
|
+
context "union" do
|
57
|
+
subject { Type.new(["string", "integer"]) }
|
58
|
+
it { should_not accept(nil) }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Jschematic
|
4
|
+
describe Attributes do
|
5
|
+
describe ".[]" do
|
6
|
+
it "maps from javascript style names to classes" do
|
7
|
+
Attributes::ExclusiveMaximum.should_receive(:new).with(1, 2)
|
8
|
+
subject["exclusiveMaximum"].new(1, 2)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Jschematic
|
4
|
+
describe Errors do
|
5
|
+
let(:errors) { Errors.new }
|
6
|
+
|
7
|
+
it "is enumerable" do
|
8
|
+
errors.class.should include(Enumerable)
|
9
|
+
|
10
|
+
errors.add(:ident1, "desc1")
|
11
|
+
errors.add(:ident2, "desc2")
|
12
|
+
|
13
|
+
col = []
|
14
|
+
errors.each{ |error| col << error }
|
15
|
+
|
16
|
+
col.should == [[:ident1, "desc1"], [:ident2, "desc2"]]
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#add" do
|
20
|
+
it "records an error" do
|
21
|
+
errors.add(:ident, "description")
|
22
|
+
errors.all.should == [[:ident, "description"]]
|
23
|
+
end
|
24
|
+
|
25
|
+
context "when raise on error is true" do
|
26
|
+
let(:errors) { Errors.new(true) }
|
27
|
+
|
28
|
+
it "raises when an error is added" do
|
29
|
+
expect { errors.add(:ident, "description") }.to raise_error(/Error: description/)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#reset!" do
|
35
|
+
it "clears the collected errors" do
|
36
|
+
errors.add(:ident, "desc")
|
37
|
+
errors.should_not be_empty
|
38
|
+
errors.reset!
|
39
|
+
errors.should be_empty
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|