jschematic 0.0.1
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/.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
|