oval 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.
@@ -0,0 +1,19 @@
1
+ lib = File.expand_path(File.join(File.dirname(__FILE__),'lib'))
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.name = 'oval'
6
+ gem.version = '0.0.1'
7
+ gem.authors = ["Pawel Tomulik"]
8
+ gem.email = ["ptomulik@meil.pw.edu.pl"]
9
+ gem.description = %q{Validate options when passed to methods}
10
+ gem.summary = %q{Using hashes to pass options to methods is a very common ruby practice. With **Oval** method authors may restrict callers to pass only declared options that meet requirements described in a hash declaration.}
11
+ gem.homepage = "https://github.com/ptomulik/rubygems-oval"
12
+ gem.license = "Apache 2.0"
13
+ gem.files = `git ls-files`.split($/)
14
+ gem.executables = []
15
+ gem.test_files = gem.files.grep(/^(test|spec|features)/)
16
+ gem.require_paths = ["lib"]
17
+
18
+ gem.add_development_dependency "rake"
19
+ end
@@ -0,0 +1,13 @@
1
+ if RUBY_VERSION >= "1.9"
2
+ require 'coveralls'
3
+ Coveralls.wear! do
4
+ add_filter 'spec/'
5
+ end
6
+ end
7
+
8
+ RSpec.configure do |config|
9
+ config.mock_framework = :mocha
10
+ end
11
+
12
+ #
13
+ #require 'puppetlabs_spec_helper/module_spec_helper'
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+ require 'oval/anything'
3
+ describe Oval::Anything do
4
+ let(:subject) { described_class.instance }
5
+ context 'the class' do
6
+ it { described_class.should respond_to :instance }
7
+ it { described_class.should respond_to :[] }
8
+ it { described_class.should_not respond_to :new }
9
+ end
10
+ context 'an instance' do
11
+ it { should respond_to :validate }
12
+ end
13
+ describe "instance (i.e. class method called instance)" do
14
+ it "should return singleton" do
15
+ previous = described_class.instance
16
+ described_class.instance.should be previous
17
+ end
18
+ end
19
+ describe "[]" do
20
+ it "should == #{described_class}.instance" do
21
+ described_class.stubs(:instance).once.with().returns :ok
22
+ described_class[].should be :ok
23
+ end
24
+ end
25
+ describe "#validate" do
26
+ # It should accept anything, which is quite hard to test, so I put here
27
+ # some random stuff ...
28
+ [
29
+ :symbol, nil, 1, 2.1, '', Array, NilClass, Object, Module,
30
+ Class.new, /regex/
31
+ ].each do |x|
32
+ context "validate(#{x.inspect})" do
33
+ let(:x) { x }
34
+ it { expect { subject.validate(x) }.to_not raise_error }
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,60 @@
1
+ require 'spec_helper.rb'
2
+ require 'oval/array_item.rb'
3
+
4
+ describe Oval::ArrayItem do
5
+ context 'the class' do
6
+ it { described_class.should respond_to :[] }
7
+ end
8
+ context 'an instance' do
9
+ let(:subject) { described_class[:item_decl0] }
10
+ it { should respond_to :validate }
11
+ it { should respond_to :item_decl }
12
+ end
13
+
14
+ describe "[]" do
15
+ context "#{described_class.name}[:item_decl0]" do
16
+ it "should == new(:item_decl0)" do
17
+ described_class.stubs(:new).once.with(:item_decl0).returns :ok
18
+ described_class[:item_decl0].should be :ok
19
+ end
20
+ end
21
+ end
22
+
23
+ describe "item_decl" do
24
+ let(:subject) { described_class[:item_decl0] }
25
+ context "#{described_class.name}[:item_decl0].item_decl" do
26
+ it { subject.item_decl.should be :item_decl0 }
27
+ end
28
+ context "when @item_decl = :item_decl1" do
29
+ before { subject.instance_variable_set(:@item_decl, :item_decl1) }
30
+ it { subject.item_decl.should be :item_decl1 }
31
+ end
32
+ end
33
+
34
+ describe "item_decl=" do
35
+ let(:subject) { described_class[:item_decl0] }
36
+ context "item_decl = :item_decl1" do
37
+ it "should assign @item_decl = :item_decl1" do
38
+ subject.send(:item_decl=, :item_decl1)
39
+ subject.instance_variable_get(:@item_decl).should be :item_decl1
40
+ end
41
+ end
42
+ end
43
+
44
+ describe "#validate" do
45
+ let(:subject) { described_class[:item_decl0] }
46
+ context "validate(:item1,0)" do
47
+ it 'should invoke self.class.ensure_match(:item1,:item_decl0,nil) once' do
48
+ described_class.expects(:ensure_match).once.with(:item1,:item_decl0,nil)
49
+ subject.validate(:item1,0)
50
+ end
51
+ end
52
+ context "validate(:item1,0,'foo')" do
53
+ it 'should invoke self.class.ensure_match(:item1,:item_decl0,"foo[0]") once' do
54
+ described_class.expects(:ensure_match).once.with(:item1,:item_decl0,"foo[0]")
55
+ subject.validate(:item1,0,'foo')
56
+ end
57
+ end
58
+ end
59
+ end
60
+
@@ -0,0 +1,184 @@
1
+ require 'spec_helper'
2
+ require 'oval/base'
3
+
4
+ describe Oval::Base do
5
+ context "the class" do
6
+ [
7
+ :ensure_equal,
8
+ :ensure_match,
9
+ :[],
10
+ :for_subject,
11
+ :enumerate,
12
+ ].each do |method|
13
+ it { described_class.should respond_to method }
14
+ end
15
+ end
16
+
17
+ context "an instance" do
18
+ let(:subject) { described_class[:shape0] }
19
+ [
20
+ :validate,
21
+ :for_subject,
22
+ :enumerate,
23
+ ].each do |method|
24
+ it { should respond_to method }
25
+ end
26
+ end
27
+
28
+ describe "ensure_match" do
29
+ context "ensure_match(:foo,:bar)" do
30
+ it "should invoke ensure_equal(:foo,:bar,nil) once" do
31
+ described_class.expects(:ensure_equal).once.with(:foo,:bar,nil)
32
+ expect { described_class.ensure_match(:foo,:bar) }.to_not raise_error
33
+ end
34
+ end
35
+ context "ensure_match(:foo,:bar,'subj1')" do
36
+ it "should invoke ensure_equal(:foo,:bar,'subj1') once" do
37
+ described_class.expects(:ensure_equal).once.with(:foo,:bar,'subj1')
38
+ expect { described_class.ensure_match(:foo,:bar,'subj1') }.to_not raise_error
39
+ end
40
+ end
41
+ context "ensure_match(:foo,shape)" do
42
+ let(:shape) { described_class[:shape0] }
43
+ it "should invoke shape.validate(:foo,nil) once" do
44
+ shape.expects(:validate).once.with(:foo,nil)
45
+ expect { described_class.ensure_match(:foo,shape) }.to_not raise_error
46
+ end
47
+ end
48
+ context "ensure_match(:foo,shape,'subj1')" do
49
+ let(:shape) { described_class[:shape0] }
50
+ it "should invoke shape.validate(:foo,'subj1') once" do
51
+ shape.expects(:validate).once.with(:foo,'subj1')
52
+ expect { described_class.ensure_match(:foo,shape,'subj1') }.to_not raise_error
53
+ end
54
+ end
55
+ end
56
+
57
+ describe "[]" do
58
+ [ [], [:arg1], [:arg1,:arg2] ].each do |args|
59
+ context "[#{args.map{|x| x.inspect}.join(', ')}]" do
60
+ let(:args) { args }
61
+ it "should == new(#{args.map{|x| x.inspect}.join(', ')})" do
62
+ described_class.expects(:new).once.with(*args).returns :ok
63
+ described_class[*args].should be :ok
64
+ end
65
+ end
66
+ end
67
+ end
68
+
69
+ describe "#validate" do
70
+ let(:subject) { described_class[:shape0] }
71
+ let(:msg) { "This method should be overwritten by a subclass" }
72
+ [ [], [:arg1,:arg2,:arg3] ].each do |args|
73
+ context "validate(#{args.map{|x| x.inspect}.join(', ')})" do
74
+ let(:args) { args }
75
+ before { described_class.expects(:validate).never }
76
+ it { expect { subject.validate(*args) }.to raise_error ArgumentError }
77
+ end
78
+ end
79
+ context "validate(:value)" do
80
+ it { expect { subject.validate(:value) }.to raise_error NotImplementedError, msg}
81
+ end
82
+ context "validate(:value,:subj1)" do
83
+ it { expect { subject.validate(:value,:subj1) }.to raise_error NotImplementedError, msg}
84
+ end
85
+ end
86
+
87
+ ## describe "#validate_shape" do
88
+ ## let(:subject) { described_class[:shape0] }
89
+ ## let(:msg) { "This method should be overwritten by a subclass" }
90
+ ## [ [:arg1,:arg2] ].each do |args|
91
+ ## context "validate_shape(#{args.map{|x| x.inspect}.join(', ')})" do
92
+ ## let(:args) { args }
93
+ ## it { expect { subject.validate_shape(*args) }.to raise_error ArgumentError }
94
+ ## end
95
+ ## end
96
+ ## context "validate_shape()" do
97
+ ## it { expect { subject.validate_shape() }.to raise_error NotImplementedError, msg}
98
+ ## end
99
+ ## context "validate_shape(:subj1)" do
100
+ ## it { expect { subject.validate_shape(:subj1) }.to raise_error NotImplementedError, msg}
101
+ ## end
102
+ ## end
103
+
104
+
105
+ ## describe "shape" do
106
+ #### before { described_class.stubs(:validate_shape) }
107
+ ## context "new(:shape0).shape" do
108
+ ## it { described_class.new(:shape0).shape.should be :shape0 }
109
+ ## end
110
+ ## context "when @shape == :shape1" do
111
+ ## let(:subject) { described_class.new(:shape0) }
112
+ ## before { subject.instance_variable_set(:@shape,:shape1) }
113
+ ## it { subject.shape.should be :shape1 }
114
+ ## end
115
+ ## end
116
+ ##
117
+ ## describe "#shape=" do
118
+ #### before { described_class.stubs(:validate_shape) }
119
+ ## let(:subject) { described_class.new(:shape0) }
120
+ ## context "#shape = :shape1" do
121
+ #### it "should call self.class.validate_shape(:shape1) once" do
122
+ #### subject # reference before re-stubbing validate_shape
123
+ #### described_class.stubs(:validate_shape).never
124
+ #### described_class.stubs(:validate_shape).once.with(:shape1,'Base')
125
+ #### expect { subject.send(:shape=,:shape1) }.to_not raise_error
126
+ #### end
127
+ ## it "should assign @shape = :shape1" do
128
+ ## subject.send(:shape=, :shape1)
129
+ ## subject.instance_variable_get(:@shape).should be :shape1
130
+ ## end
131
+ ## end
132
+ ## end
133
+
134
+ describe "for_subject" do
135
+ [
136
+ [nil,""],
137
+ ["Subj1", " for Subj1"],
138
+ [:subj, " for subj"],
139
+ ].each do |arg,res|
140
+ context "for_subject(#{arg.inspect})" do
141
+ let(:arg) { arg }
142
+ let(:res) { res }
143
+ it { described_class.send(:for_subject,arg).should == res }
144
+ end
145
+ end
146
+ end
147
+
148
+ describe "#for_subject" do
149
+ ## before { described_class.stubs(:validate_shape) }
150
+ let(:subject) { described_class.new(:shape0) }
151
+ context "for_subject(:subj1)" do
152
+ it "should == self.class.for_subject(subject)" do
153
+ described_class.expects(:for_subject).once.with(:subj1).returns :ok
154
+ subject.send(:for_subject,:subj1).should be :ok
155
+ end
156
+ end
157
+ end
158
+
159
+ describe "enumerate" do
160
+ [
161
+ [[[],'and'],'none'],
162
+ [[['one'],'and'],'"one"'],
163
+ [[['one','two'],'and'],'"one" and "two"'],
164
+ [[['one','two','three'],'and'],'"one", "two" and "three"'],
165
+ ].each do |args,res|
166
+ context "enumerate(#{args.map{|x| x.inspect}.join(', ')})" do
167
+ let(:args) { args }
168
+ let(:res) { res }
169
+ it { described_class.send(:enumerate,*args).should == res }
170
+ end
171
+ end
172
+ end
173
+
174
+ describe "#enumerate" do
175
+ ## before { described_class.stubs(:validate_shape) }
176
+ let(:subject) { described_class.new(:shape0) }
177
+ context "enumerate([],'and')" do
178
+ it "should == self.class.enumerate(subject)" do
179
+ described_class.expects(:enumerate).once.with([],'and').returns :ok
180
+ subject.send(:enumerate,[],'and').should be :ok
181
+ end
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+ require 'oval/class_decl_base'
3
+
4
+ describe Oval::ClassDeclBase do
5
+ context "the class" do
6
+ [
7
+ :[],
8
+ ].each do |method|
9
+ it { described_class.should respond_to method }
10
+ end
11
+ end
12
+
13
+ context "an instance" do
14
+ let(:subject) { described_class[:klass0] }
15
+ before { described_class.any_instance.stubs(:validate_class) }
16
+ it { should be_kind_of Oval::Base }
17
+ [
18
+ :validate_class,
19
+ :klass,
20
+ :klass=,
21
+ ].each do |method|
22
+ it { should respond_to method }
23
+ end
24
+ end
25
+
26
+ describe "#validate_class" do
27
+ let(:subject) { described_class.new(:klass0) }
28
+ before do
29
+ described_class.any_instance.stubs(:validate_class)
30
+ subject
31
+ described_class.any_instance.unstub(:validate_class)
32
+ end
33
+ context "validate_class(:symbol1)" do
34
+ let(:msg) { "Invalid class :symbol1 for ClassDeclBase" }
35
+ it { expect { subject.send(:validate_class,:symbol1) }.to raise_error Oval::DeclError, msg }
36
+ end
37
+ [ Array, String, NilClass ].each do |klass|
38
+ context "validate_class(#{klass.name})" do
39
+ let(:klass) { klass }
40
+ it { expect { subject.send(:validate_class,klass) }.to_not raise_error }
41
+ end
42
+ end
43
+ end
44
+
45
+ describe "klass" do
46
+ before { described_class.any_instance.stubs(:validate_class) }
47
+ context "new(:klass0).klass" do
48
+ it { described_class.new(:klass0).klass.should be :klass0 }
49
+ end
50
+ context "when @klass == :klass1" do
51
+ let(:subject) { described_class.new(:klass0) }
52
+ before { subject.instance_variable_set(:@klass,:klass1) }
53
+ it { subject.klass.should be :klass1 }
54
+ end
55
+ end
56
+
57
+ describe "#klass=" do
58
+ before { described_class.any_instance.stubs(:validate_class) }
59
+ let(:subject) { described_class.new(:klass0) }
60
+ context "#klass = :klass1" do
61
+ it "should call self.class.validate_class(:klass1) once" do
62
+ subject # reference before re-stubbing validate_class
63
+ subject.stubs(:validate_class).never
64
+ subject.stubs(:validate_class).once.with(:klass1)
65
+ expect { subject.send(:klass=,:klass1) }.to_not raise_error
66
+ end
67
+ it "should assign @klass = :klass1" do
68
+ subject.send(:klass=, :klass1)
69
+ subject.instance_variable_get(:@klass).should be :klass1
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,267 @@
1
+ require 'spec_helper'
2
+ require 'oval/collection'
3
+ require 'oval/one_of'
4
+ require 'oval/instance_of'
5
+ require 'oval/kind_of'
6
+
7
+ describe Oval::Collection do
8
+ ## Anything = Oval::Anything
9
+ ## SubclassOf = Oval::SubclassOf
10
+ ## InstanceOf = Oval::InstanceOf
11
+ ## KindOf = Oval::KindOf
12
+ ## OneOf = Oval::OneOf
13
+ ## DeclError = Oval::DeclError
14
+ ## ValueError = Oval::ValueError
15
+ describe 'the class' do
16
+ it { described_class.should respond_to :[] }
17
+ it { described_class.should respond_to :new }
18
+ it { described_class.should respond_to :validate_class_decl }
19
+ end
20
+ describe 'an instance' do
21
+ let(:subject) { described_class[Array,nil] }
22
+ it { should respond_to :validate }
23
+ it { should respond_to :class_decl }
24
+ it { should respond_to :class_decl= }
25
+ it { should respond_to :item_decl }
26
+ it { should respond_to :item_decl= }
27
+ it { should respond_to :select_item_validator }
28
+ end
29
+
30
+ describe "[]" do
31
+ context "[]" do
32
+ it { expect { described_class[] }.to raise_error ArgumentError, /wrong number of arguments / }
33
+ end
34
+ context "[:arg1,:arg2,:arg3]" do
35
+ it { expect { described_class[:arg1,:arg2,:arg3] }.to raise_error ArgumentError, /wrong number of arguments / }
36
+ end
37
+ context "[:arg1]" do
38
+ it "should == new(:arg1,Oval::Anything[])" do
39
+ described_class.expects(:new).once.with(:arg1,Oval::Anything[]).returns :ok
40
+ described_class[:arg1].should be :ok
41
+ end
42
+ end
43
+ context "[:arg1,:arg2]" do
44
+ it "should == new(:arg1,:arg2)" do
45
+ described_class.expects(:new).once.with(:arg1,:arg2).returns :ok
46
+ described_class[:arg1,:arg2].should be :ok
47
+ end
48
+ end
49
+ end
50
+
51
+ describe "new" do
52
+ context "new(:arg1,:arg2)" do
53
+ it "should assign self.class_decl=:arg1 and self.item_decl=:arg2 in seqence" do
54
+ seq = sequence('assignments')
55
+ described_class.any_instance.expects(:class_decl=).once.with(:arg1).in_sequence(seq)
56
+ described_class.any_instance.expects(:item_decl=).once.with(:arg2).in_sequence(seq)
57
+ expect { described_class.new(:arg1,:arg2) }.to_not raise_error
58
+ end
59
+ end
60
+ end
61
+
62
+ describe "validate_class_decl" do
63
+ [
64
+ [Array, "Array"],
65
+ [Hash, "Hash" ],
66
+ [Class.new(Array), "Class.new(Array)" ],
67
+ [Class.new(Hash), "Class.new(Hash)" ],
68
+ [Oval::SubclassOf[Array], "Oval::SubclassOf[Array]" ],
69
+ [Oval::SubclassOf[Hash], "Oval::SubclassOf[Hash]" ],
70
+ [Oval::SubclassOf[Class.new(Array)], "Oval::SubclassOf[Class.new(Array)]" ],
71
+ [Oval::SubclassOf[Class.new(Hash)], "Oval::SubclassOf[Class.new(Hash)]" ],
72
+ ].each do |decl,desc|
73
+ context "validate_class_decl(#{desc})" do
74
+ let(:decl) { decl }
75
+ it { expect { described_class.validate_class_decl(decl) }.to_not raise_error }
76
+ end
77
+ end
78
+ [ 'a', nil, 0, {}, [] ].each do |decl|
79
+ context "validate_class_decl(#{decl.inspect})" do
80
+ let(:decl) { decl }
81
+ let(:msg) { "Invalid collection class declarator #{decl.inspect}. Should be a (subclass of) Hash or Array" }
82
+ it { expect { described_class.validate_class_decl(decl) }.to raise_error Oval::DeclError, msg }
83
+ end
84
+ end
85
+ end
86
+
87
+ ## describe "validate_item_decl" do
88
+ ## [
89
+ ## [Hash, "Hash"],
90
+ ## [Class.new(Hash), "Class.new(Hash)" ],
91
+ ## ].each do |class_decl,class_desc|
92
+ ## context "validate_item_decl(:decl1, #{class_desc})" do
93
+ ## let(:class_decl) { class_decl }
94
+ ## it "should invoke validate_hash_item_decl(:decl1) once" do
95
+ ## described_class.stubs(:validate_hash_item_decl).once.with(:decl1)
96
+ ## expect { described_class.validate_item_decl(:decl1,class_decl) }.to_not raise_error
97
+ ## end
98
+ ## end
99
+ ## end
100
+ ## [
101
+ ## [Array, "Array"],
102
+ ## [Class.new(Array), "Class.new(Array)" ],
103
+ ## ].each do |class_decl,class_desc|
104
+ ## context "validate_item_decl(:decl1, #{class_desc})" do
105
+ ## let(:class_decl) { class_decl }
106
+ ## it "should not invoke validate_hash_item_decl(:decl1)" do
107
+ ## described_class.stubs(:validate_hash_item_decl).never
108
+ ## expect { described_class.validate_item_decl(:decl1,class_decl) }.to_not raise_error
109
+ ## end
110
+ ## end
111
+ ## end
112
+ ## end
113
+
114
+ describe "#class_decl" do
115
+ before do
116
+ described_class.stubs(:validate_class_decl)
117
+ described_class.any_instance.stubs(:item_decl=)
118
+ end
119
+ context "new(:class_decl0,:item_decl0).class_decl" do
120
+ it { described_class.new(:class_decl0,:item_decl0).class_decl.should be :class_decl0 }
121
+ end
122
+ context "when @class_decl == :class_decl1" do
123
+ let(:subject) { described_class.new(:class_decl0) }
124
+ before { subject.instance_variable_set(:@class_decl,:class_decl1) }
125
+ it { subject.class_decl.should be :class_decl1 }
126
+ end
127
+ end
128
+
129
+ describe "#class_decl=" do
130
+ before do
131
+ described_class.stubs(:validate_class_decl)
132
+ described_class.any_instance.stubs(:item_decl=)
133
+ end
134
+ let(:subject) { described_class.new(:class_decl0,:item_decl0) }
135
+ context "#class_decl = :class_decl1" do
136
+ it "should call self.class.validate_class_decl(:class_decl1) once" do
137
+ subject # reference before re-stubbing validate_class_decl
138
+ described_class.stubs(:validate_class_decl).never
139
+ described_class.stubs(:validate_class_decl).once.with(:class_decl1)
140
+ expect { subject.send(:class_decl=,:class_decl1) }.to_not raise_error
141
+ end
142
+ it "should assign @class_decl = :class_decl1" do
143
+ subject.send(:class_decl=, :class_decl1)
144
+ subject.instance_variable_get(:@class_decl).should be :class_decl1
145
+ end
146
+ end
147
+ end
148
+
149
+ describe "#item_decl" do
150
+ before do
151
+ described_class.any_instance.stubs(:class_decl=)
152
+ described_class.any_instance.stubs(:bind_item_validator)
153
+ end
154
+ context "new(:class_decl0, :item_decl0).item_decl" do
155
+ it { described_class.new(:class_decl0,:item_decl0).item_decl.should be :item_decl0 }
156
+ end
157
+ context "when @item_decl == :item_decl1" do
158
+ let(:subject) { described_class.new(:item_decl0) }
159
+ before { subject.instance_variable_set(:@item_decl,:item_decl1) }
160
+ it { subject.item_decl.should be :item_decl1 }
161
+ end
162
+ end
163
+
164
+ describe "#item_decl=" do
165
+ let(:subject) { described_class.new(:class_decl0,:item_decl0) }
166
+ before do
167
+ described_class.any_instance.stubs(:class_decl=)
168
+ described_class.any_instance.stubs(:bind_item_validator)
169
+ end
170
+ context "#item_decl = :item_decl1" do
171
+ it "should call bind_item_validator(:item_decl1) once" do
172
+ subject.expects(:bind_item_validator).once.with(:item_decl1)
173
+ expect { subject.send(:item_decl=,:item_decl1) }.to_not raise_error
174
+ end
175
+ it "should assign @item_decl = :item_decl1" do
176
+ subject.send(:item_decl=, :item_decl1)
177
+ subject.instance_variable_get(:@item_decl).should be :item_decl1
178
+ end
179
+ end
180
+ end
181
+
182
+ describe "#select_item_validator" do
183
+ before do
184
+ described_class.any_instance.stubs(:class_decl=).once.with(:class_decl0)
185
+ described_class.any_instance.stubs(:item_decl=).once.with(:item_decl0)
186
+ end
187
+ let(:subject) { described_class.new(:class_decl0,:item_decl0) }
188
+ [
189
+ [Hash, 'Hash'],
190
+ [Class.new(Hash), 'Class.new(Hash)'],
191
+ ].each do |klass,desc|
192
+ context "when #klass == #{desc}" do
193
+ before { subject.stubs(:klass).with().returns(klass) }
194
+ it { subject.send(:select_item_validator).should be Oval::HashItem }
195
+ end
196
+ end
197
+ [
198
+ [Array, 'Array'],
199
+ [Class.new(Array), 'Class.new(Array)'],
200
+ ].each do |klass,desc|
201
+ context "when #klass == #{desc}" do
202
+ before { subject.stubs(:klass).with().returns(klass) }
203
+ it { subject.send(:select_item_validator).should be Oval::ArrayItem }
204
+ end
205
+ end
206
+ [ String, Fixnum, 1, nil, 0 ].each do |klass|
207
+ context "when #klass == #{klass.inspect}" do
208
+ before { subject.stubs(:klass).with().returns(klass) }
209
+ let(:msg) { "Invalid class #{klass.inspect} assigned to klass. It seems like we have a bug in #{described_class.name}" }
210
+ it { expect { subject.send(:select_item_validator) }.to raise_error RuntimeError, msg }
211
+ end
212
+ end
213
+ end
214
+
215
+ describe "#validate" do
216
+ class HashSubclass < Hash; end
217
+ class ArraySubclass < Array; end
218
+ # Valid collections
219
+ [
220
+ #
221
+ # Hash
222
+ #
223
+ ["Hash", Hash, Oval::Anything[], {:foo => :FOO}],
224
+ ["Hash", Hash, Oval::Anything, {:foo => :FOO}],
225
+ ["Hash", Hash, {Oval::Anything => Oval::Anything}, {:foo => :FOO}],
226
+ ["HashSubclass", HashSubclass, {Oval::Anything => Oval::Anything}, HashSubclass[{:foo => :FOO}]],
227
+ ["Oval::SubclassOf[Hash]", Oval::SubclassOf[Hash], {Oval::Anything => Oval::Anything}, HashSubclass[{:foo => :FOO}]],
228
+
229
+ ["Hash", Hash, {Oval::InstanceOf[Symbol] => Oval::InstanceOf[Symbol]}, {:foo => :FOO}],
230
+ ["Hash", Hash, {Oval::InstanceOf[String] => Oval::KindOf[Fixnum]}, {'one' => 1, 'two' => 2}],
231
+ #
232
+ # Array
233
+ #
234
+ ["Array", Array, Oval::Anything[], [:foo, :bar]],
235
+ ["Array", Array, Oval::Anything, [:foo,:bar]],
236
+ ["ArraySubclass", ArraySubclass, Oval::Anything, ArraySubclass[:foo,:bar]],
237
+ ["Oval::SubclassOf[Array]", Oval::SubclassOf[Array], Oval::Anything, ArraySubclass[:foo, :bar]],
238
+ ].each do |class_desc,class_decl,item_decl,collection|
239
+ context "#{described_class.name}[#{class_desc},#{item_decl.inspect}].validate(#{collection.inspect},'collection')" do
240
+ let(:subject) { described_class[class_decl, item_decl] }
241
+ let(:collection) { collection}
242
+ it { expect { subject.validate(collection,'collection') }.to_not raise_error }
243
+ end
244
+ end
245
+ # Invalid collections
246
+ [
247
+ ["Hash", Hash, {Oval::Anything => Oval::Anything}, :symbol, 'Invalid value Symbol for collection.class. Should be equal Hash'],
248
+ ["Hash", Hash, {Oval::Anything => Oval::Anything}, [], 'Invalid value Array for collection.class. Should be equal Hash'],
249
+ ["HashSubclass", HashSubclass, {Oval::Anything => Oval::Anything}, [], 'Invalid value Array for collection.class. Should be equal HashSubclass'],
250
+ ["HashSubclass", HashSubclass, {Oval::Anything => Oval::Anything}, {:foo => :FOO}, 'Invalid value Hash for collection.class. Should be equal HashSubclass'],
251
+ ["Array", Array, Oval::Anything, :symbol, 'Invalid value Symbol for collection.class. Should be equal Array'],
252
+ ["Array", Array, Oval::Anything, {}, 'Invalid value Hash for collection.class. Should be equal Array'],
253
+ ["ArraySubclass", ArraySubclass, Oval::Anything, {:foo => :FOO}, 'Invalid value Hash for collection.class. Should be equal ArraySubclass'],
254
+ ["ArraySubclass", ArraySubclass, Oval::Anything, [:foo, :bar], 'Invalid value Array for collection.class. Should be equal ArraySubclass'],
255
+ ["Hash", Hash, {Oval::InstanceOf[Symbol] => Oval::InstanceOf[Symbol]}, {:foo => :FOO, 'bar' => :BAR}, "Invalid object \"bar\" of type String for collection key. Should be an instance of Symbol"],
256
+ ["Hash", Hash, {Oval::InstanceOf[String] => Oval::KindOf[Fixnum]}, {'one' => 1, 'two' => :TWO}, "Invalid object :TWO of type Symbol for collection[\"two\"]. Should be a kind of Fixnum"],
257
+ ["Array", Array, Oval::InstanceOf[String], ['one', :two], "Invalid object :two of type Symbol for collection[1]. Should be an instance of String"],
258
+ ].each do |class_desc,class_decl,item_decl, collection, msg|
259
+ context "#{described_class.name}[#{class_desc},#{item_decl.inspect}].validate(#{collection.inspect},'collection')" do
260
+ let(:subject) { described_class[class_decl, item_decl] }
261
+ let(:collection) { collection }
262
+ let(:msg) { msg }
263
+ it { expect { subject.validate(collection,'collection') }.to raise_error Oval::ValueError, msg}
264
+ end
265
+ end
266
+ end
267
+ end