attributor 5.0.2 → 5.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +30 -0
- data/.travis.yml +6 -4
- data/CHANGELOG.md +6 -1
- data/Gemfile +1 -1
- data/Guardfile +14 -8
- data/Rakefile +4 -5
- data/attributor.gemspec +34 -29
- data/lib/attributor.rb +23 -29
- data/lib/attributor/attribute.rb +108 -127
- data/lib/attributor/attribute_resolver.rb +12 -26
- data/lib/attributor/dsl_compiler.rb +17 -21
- data/lib/attributor/dumpable.rb +1 -2
- data/lib/attributor/example_mixin.rb +5 -8
- data/lib/attributor/exceptions.rb +5 -6
- data/lib/attributor/extensions/randexp.rb +3 -5
- data/lib/attributor/extras/field_selector.rb +4 -4
- data/lib/attributor/extras/field_selector/transformer.rb +6 -7
- data/lib/attributor/families/numeric.rb +0 -2
- data/lib/attributor/families/temporal.rb +1 -4
- data/lib/attributor/hash_dsl_compiler.rb +22 -25
- data/lib/attributor/type.rb +24 -32
- data/lib/attributor/types/bigdecimal.rb +7 -14
- data/lib/attributor/types/boolean.rb +5 -8
- data/lib/attributor/types/class.rb +9 -10
- data/lib/attributor/types/collection.rb +34 -44
- data/lib/attributor/types/container.rb +9 -15
- data/lib/attributor/types/csv.rb +7 -10
- data/lib/attributor/types/date.rb +20 -25
- data/lib/attributor/types/date_time.rb +7 -14
- data/lib/attributor/types/float.rb +4 -6
- data/lib/attributor/types/hash.rb +171 -196
- data/lib/attributor/types/ids.rb +2 -6
- data/lib/attributor/types/integer.rb +12 -17
- data/lib/attributor/types/model.rb +39 -48
- data/lib/attributor/types/object.rb +2 -4
- data/lib/attributor/types/polymorphic.rb +118 -0
- data/lib/attributor/types/regexp.rb +4 -5
- data/lib/attributor/types/string.rb +6 -7
- data/lib/attributor/types/struct.rb +8 -15
- data/lib/attributor/types/symbol.rb +3 -6
- data/lib/attributor/types/tempfile.rb +5 -6
- data/lib/attributor/types/time.rb +11 -11
- data/lib/attributor/types/uri.rb +9 -10
- data/lib/attributor/version.rb +1 -1
- data/spec/attribute_resolver_spec.rb +57 -78
- data/spec/attribute_spec.rb +174 -216
- data/spec/attributor_spec.rb +11 -15
- data/spec/dsl_compiler_spec.rb +19 -33
- data/spec/dumpable_spec.rb +6 -7
- data/spec/extras/field_selector/field_selector_spec.rb +1 -1
- data/spec/families_spec.rb +1 -3
- data/spec/hash_dsl_compiler_spec.rb +65 -74
- data/spec/spec_helper.rb +9 -3
- data/spec/support/hashes.rb +2 -3
- data/spec/support/models.rb +30 -36
- data/spec/support/polymorphics.rb +10 -0
- data/spec/type_spec.rb +38 -61
- data/spec/types/bigdecimal_spec.rb +11 -15
- data/spec/types/boolean_spec.rb +12 -39
- data/spec/types/class_spec.rb +10 -11
- data/spec/types/collection_spec.rb +72 -81
- data/spec/types/container_spec.rb +22 -26
- data/spec/types/csv_spec.rb +15 -16
- data/spec/types/date_spec.rb +16 -33
- data/spec/types/date_time_spec.rb +16 -33
- data/spec/types/file_upload_spec.rb +1 -2
- data/spec/types/float_spec.rb +7 -14
- data/spec/types/hash_spec.rb +285 -289
- data/spec/types/ids_spec.rb +5 -7
- data/spec/types/integer_spec.rb +37 -46
- data/spec/types/model_spec.rb +111 -128
- data/spec/types/polymorphic_spec.rb +134 -0
- data/spec/types/regexp_spec.rb +4 -7
- data/spec/types/string_spec.rb +17 -21
- data/spec/types/struct_spec.rb +40 -47
- data/spec/types/tempfile_spec.rb +1 -2
- data/spec/types/temporal_spec.rb +9 -0
- data/spec/types/time_spec.rb +16 -32
- data/spec/types/type_spec.rb +15 -0
- data/spec/types/uri_spec.rb +6 -7
- metadata +77 -25
data/spec/types/boolean_spec.rb
CHANGED
@@ -1,93 +1,66 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
|
2
2
|
|
3
3
|
describe Attributor::Boolean do
|
4
|
-
|
5
4
|
subject(:type) { Attributor::Boolean }
|
6
5
|
|
7
6
|
it 'it is not Dumpable' do
|
8
|
-
type.new.is_a?(Attributor::Dumpable).
|
7
|
+
expect(type.new.is_a?(Attributor::Dumpable)).not_to be(true)
|
9
8
|
end
|
10
9
|
|
11
10
|
context '.valid_type?' do
|
12
|
-
|
13
11
|
context 'for incoming Boolean values' do
|
14
|
-
|
15
12
|
[false, true].each do |value|
|
16
|
-
|
17
13
|
it "returns true for #{value.inspect}" do
|
18
|
-
type.valid_type?(value).
|
14
|
+
expect(type.valid_type?(value)).to be_truthy
|
19
15
|
end
|
20
|
-
|
21
16
|
end
|
22
|
-
|
23
17
|
end
|
24
18
|
|
25
19
|
context 'for incoming non-Boolean values' do
|
26
|
-
|
27
20
|
['false', 2, 1.0, Class, Object.new].each do |value|
|
28
|
-
|
29
21
|
it "returns false for #{value.inspect}" do
|
30
|
-
type.valid_type?(value).
|
22
|
+
expect(type.valid_type?(value)).to be_falsey
|
31
23
|
end
|
32
|
-
|
33
24
|
end
|
34
|
-
|
35
25
|
end
|
36
|
-
|
37
26
|
end
|
38
27
|
|
39
28
|
context '.example' do
|
40
|
-
it
|
41
|
-
[true, false].
|
29
|
+
it 'should return a valid Boolean' do
|
30
|
+
expect([true, false]).to include type.example
|
42
31
|
end
|
43
32
|
end
|
44
33
|
|
45
34
|
context '.load' do
|
46
|
-
|
47
35
|
context 'for incoming Boolean false values' do
|
48
|
-
|
49
36
|
[false, 'false', 'FALSE', '0', 0, 'f', 'F'].each do |value|
|
50
|
-
|
51
37
|
it "returns false for #{value.inspect}" do
|
52
|
-
type.load(value).
|
38
|
+
expect(type.load(value)).to be(false)
|
53
39
|
end
|
54
|
-
|
55
40
|
end
|
56
|
-
|
57
41
|
end
|
58
42
|
|
59
43
|
context 'for incoming Boolean false values' do
|
60
|
-
|
61
44
|
[true, 'true', 'TRUE', '1', 1, 't', 'T'].each do |value|
|
62
|
-
|
63
45
|
it "returns true for #{value.inspect}" do
|
64
|
-
type.load(value).
|
46
|
+
expect(type.load(value)).to be(true)
|
65
47
|
end
|
66
|
-
|
67
48
|
end
|
68
|
-
|
69
49
|
end
|
70
50
|
|
71
51
|
it 'returns nil for nil' do
|
72
|
-
type.load(nil).
|
52
|
+
expect(type.load(nil)).to be(nil)
|
73
53
|
end
|
74
54
|
|
75
55
|
context 'that are not valid Booleans' do
|
76
|
-
let(:context){
|
56
|
+
let(:context) { %w(root subattr) }
|
77
57
|
['string', 2, 1.0, Class, Object.new].each do |value|
|
78
|
-
|
79
58
|
it "raises Attributor::CoercionError for #{value.inspect}" do
|
80
|
-
expect
|
81
|
-
type.load(value,context)
|
82
|
-
|
59
|
+
expect do
|
60
|
+
type.load(value, context)
|
61
|
+
end.to raise_error(Attributor::CoercionError, /Error coercing from .+ to Attributor::Boolean.* #{context.join('.')}/)
|
83
62
|
end
|
84
|
-
|
85
63
|
end
|
86
|
-
|
87
64
|
end
|
88
|
-
|
89
65
|
end
|
90
|
-
|
91
66
|
end
|
92
|
-
|
93
|
-
|
data/spec/types/class_spec.rb
CHANGED
@@ -2,15 +2,14 @@ require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
|
|
2
2
|
require 'backports'
|
3
3
|
|
4
4
|
describe Attributor::Class do
|
5
|
-
|
6
5
|
subject(:type) { Attributor::Class }
|
7
6
|
|
8
7
|
it 'it is not Dumpable' do
|
9
|
-
type.new.is_a?(Attributor::Dumpable).
|
8
|
+
expect(type.new.is_a?(Attributor::Dumpable)).not_to be(true)
|
10
9
|
end
|
11
10
|
|
12
11
|
its(:native_type) { should be(::Class) }
|
13
|
-
its(:family) { should
|
12
|
+
its(:family) { should eq 'string' }
|
14
13
|
|
15
14
|
context '.example' do
|
16
15
|
its(:example) { should be_a(::String) }
|
@@ -28,8 +27,8 @@ describe Attributor::Class do
|
|
28
27
|
|
29
28
|
context 'for incoming String values' do
|
30
29
|
['Object', '::Object', '::Hash', 'Attributor::Struct'].each do |value|
|
31
|
-
it "loads
|
32
|
-
type.load(value).
|
30
|
+
it "loads #{value.inspect}" do
|
31
|
+
expect(type.load(value)).to eq(value.constantize)
|
33
32
|
end
|
34
33
|
end
|
35
34
|
end
|
@@ -37,7 +36,7 @@ describe Attributor::Class do
|
|
37
36
|
context 'for incoming Class values' do
|
38
37
|
[Object, ::Object, ::Hash, Attributor::Struct].each do |value|
|
39
38
|
it "loads '#{value}' as #{value}" do
|
40
|
-
type.load(value).
|
39
|
+
expect(type.load(value)).to eq(value)
|
41
40
|
end
|
42
41
|
end
|
43
42
|
end
|
@@ -47,11 +46,11 @@ describe Attributor::Class do
|
|
47
46
|
subject(:type) { Attributor::Class.of(klass) }
|
48
47
|
|
49
48
|
it "loads 'Integer' as Integer" do
|
50
|
-
type.load('Integer').
|
49
|
+
expect(type.load('Integer')).to eq(Integer)
|
51
50
|
end
|
52
51
|
|
53
|
-
it
|
54
|
-
type.load(nil).
|
52
|
+
it 'returns specified class for nil' do
|
53
|
+
expect(type.load(nil)).to be(klass)
|
55
54
|
end
|
56
55
|
|
57
56
|
it "raises when given a class that doesn't match specified class" do
|
@@ -60,11 +59,11 @@ describe Attributor::Class do
|
|
60
59
|
end
|
61
60
|
|
62
61
|
it 'returns nil for nil' do
|
63
|
-
type.load(nil).
|
62
|
+
expect(type.load(nil)).to be(nil)
|
64
63
|
end
|
65
64
|
|
66
65
|
it 'raises when given a non-String' do
|
67
|
-
expect {type.load(1)}.to raise_exception(Attributor::IncompatibleTypeError)
|
66
|
+
expect { type.load(1) }.to raise_exception(Attributor::IncompatibleTypeError)
|
68
67
|
end
|
69
68
|
end
|
70
69
|
end
|
@@ -1,16 +1,14 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
|
2
2
|
|
3
3
|
describe Attributor::Collection do
|
4
|
-
|
5
4
|
subject(:type) { Attributor::Collection }
|
6
5
|
|
7
6
|
context '.of' do
|
8
|
-
|
9
7
|
[Attributor::Integer, Attributor::Struct].each do |member_type|
|
10
8
|
it "returns an anonymous class with correct member_attribute of type #{member_type}" do
|
11
9
|
klass = type.of(member_type)
|
12
|
-
klass.
|
13
|
-
klass.member_type.
|
10
|
+
expect(klass).to be_a(::Class)
|
11
|
+
expect(klass.member_type).to eq member_type
|
14
12
|
end
|
15
13
|
end
|
16
14
|
|
@@ -21,13 +19,12 @@ describe Attributor::Collection do
|
|
21
19
|
#::Object
|
22
20
|
].each do |member_type|
|
23
21
|
it "raises when given invalid element type #{member_type}" do
|
24
|
-
expect {
|
22
|
+
expect { type.of(member_type) }.to raise_error(Attributor::AttributorException)
|
25
23
|
end
|
26
24
|
end
|
27
25
|
end
|
28
26
|
|
29
27
|
context '.construct' do
|
30
|
-
|
31
28
|
# context 'with a Model (or Struct) member_type' do
|
32
29
|
# let(:member_type) { Attributor::Struct }
|
33
30
|
|
@@ -52,14 +49,13 @@ describe Attributor::Collection do
|
|
52
49
|
# end
|
53
50
|
|
54
51
|
context 'with :member_options option' do
|
55
|
-
let(:element_options) { {:
|
52
|
+
let(:element_options) { { identity: 'name' } }
|
56
53
|
end
|
57
|
-
|
58
54
|
end
|
59
55
|
|
60
56
|
context '.native_type' do
|
61
|
-
it
|
62
|
-
type.native_type.
|
57
|
+
it 'returns Array' do
|
58
|
+
expect(type.native_type).to be(type)
|
63
59
|
end
|
64
60
|
end
|
65
61
|
|
@@ -72,7 +68,7 @@ describe Attributor::Collection do
|
|
72
68
|
'["alpha", 2, 3.0]'
|
73
69
|
].each do |value|
|
74
70
|
it "parses JSON string as array when incoming value is #{value.inspect}" do
|
75
|
-
type.decode_json(value).
|
71
|
+
expect(type.decode_json(value)).to eq JSON.parse(value)
|
76
72
|
end
|
77
73
|
end
|
78
74
|
end
|
@@ -86,50 +82,47 @@ describe Attributor::Collection do
|
|
86
82
|
nil
|
87
83
|
].each do |value|
|
88
84
|
it "parses JSON string as array when incoming value is #{value.inspect}" do
|
89
|
-
expect
|
85
|
+
expect do
|
90
86
|
type.decode_json(value)
|
91
|
-
|
87
|
+
end.to raise_error(Attributor::AttributorException)
|
92
88
|
end
|
93
89
|
end
|
94
90
|
end
|
95
|
-
|
96
91
|
end
|
97
92
|
|
98
93
|
context '.load' do
|
99
94
|
context 'from a Set' do
|
100
|
-
let(:values) { [1,2,3]}
|
95
|
+
let(:values) { [1, 2, 3] }
|
101
96
|
let(:value) { Set.new(values) }
|
102
97
|
it 'loads properly' do
|
103
|
-
type.load(value).
|
98
|
+
expect(type.load(value)).to match_array values
|
104
99
|
end
|
105
|
-
|
106
100
|
end
|
107
101
|
|
108
102
|
context 'with unspecified element type' do
|
109
103
|
context 'for nil values' do
|
110
104
|
it 'returns nil' do
|
111
|
-
type.load(nil).
|
105
|
+
expect(type.load(nil)).to be nil
|
112
106
|
end
|
113
107
|
end
|
114
108
|
|
115
109
|
context 'for valid values' do
|
116
110
|
[
|
117
111
|
[],
|
118
|
-
[1,2,3],
|
119
|
-
[Object.new, [1,2], nil, true]
|
112
|
+
[1, 2, 3],
|
113
|
+
[Object.new, [1, 2], nil, true]
|
120
114
|
].each do |value|
|
121
115
|
it "returns value when incoming value is #{value.inspect}" do
|
122
|
-
|
123
|
-
type.load(value).should =~ value
|
116
|
+
expect(type.load(value)).to match_array value
|
124
117
|
end
|
125
118
|
end
|
126
119
|
end
|
127
120
|
|
128
121
|
context 'for invalid values' do
|
129
|
-
let(:context){
|
122
|
+
let(:context) { %w(root subattr) }
|
130
123
|
[1, Object.new, false, true, 3.0].each do |value|
|
131
124
|
it "raises error when incoming value is #{value.inspect} (propagating the context)" do
|
132
|
-
expect { type.load(value,context).
|
125
|
+
expect { expect(type.load(value, context)).to eq value }.to raise_error(Attributor::IncompatibleTypeError, /#{context.join('.')}/)
|
133
126
|
end
|
134
127
|
end
|
135
128
|
end
|
@@ -138,15 +131,15 @@ describe Attributor::Collection do
|
|
138
131
|
context 'with Attributor::Type element type' do
|
139
132
|
context 'for valid values' do
|
140
133
|
{
|
141
|
-
Attributor::String =>
|
142
|
-
Attributor::Integer => [1,
|
143
|
-
Attributor::Float => [1.0,
|
144
|
-
Attributor::DateTime => [
|
134
|
+
Attributor::String => %w(foo bar),
|
135
|
+
Attributor::Integer => [1, '2', 3],
|
136
|
+
Attributor::Float => [1.0, '2.0', Math::PI, Math::E],
|
137
|
+
Attributor::DateTime => ['2001-02-03T04:05:06+07:00', 'Sat, 3 Feb 2001 04:05:06 +0700'],
|
145
138
|
::Chicken => [::Chicken.new, ::Chicken.new]
|
146
139
|
}.each do |member_type, value|
|
147
140
|
it "returns loaded value when member_type is #{member_type} and value is #{value.inspect}" do
|
148
|
-
expected_result = value.map {|v| member_type.load(v)}
|
149
|
-
type.of(member_type).load(value).
|
141
|
+
expected_result = value.map { |v| member_type.load(v) }
|
142
|
+
expect(type.of(member_type).load(value)).to match_array expected_result
|
150
143
|
end
|
151
144
|
end
|
152
145
|
end
|
@@ -154,17 +147,15 @@ describe Attributor::Collection do
|
|
154
147
|
context 'for invalid values' do
|
155
148
|
let(:member_type) { ::Chicken }
|
156
149
|
let(:value) { [::Turducken.example] }
|
157
|
-
it
|
158
|
-
expect
|
159
|
-
|
160
|
-
|
150
|
+
it 'raises error when incoming value is not of member_type' do
|
151
|
+
expect do
|
152
|
+
type.of(member_type).load(value)
|
153
|
+
end.to raise_error(Attributor::AttributorException, /Unknown key received/)
|
161
154
|
end
|
162
|
-
|
163
155
|
end
|
164
156
|
end
|
165
157
|
|
166
158
|
context 'with Attributor::Struct element type' do
|
167
|
-
|
168
159
|
# FIXME: Raise in all cases of empty Structs
|
169
160
|
# context 'for empty structs' do
|
170
161
|
# let(:attribute_definition) do
|
@@ -188,7 +179,7 @@ describe Attributor::Collection do
|
|
188
179
|
# it "returns value when incoming value is #{value.inspect}" do
|
189
180
|
# #pending
|
190
181
|
# expected_value = value.map {|v| empty_struct.load(v)}
|
191
|
-
# type.of(Struct).load(value).should
|
182
|
+
# type.of(Struct).load(value).should eq expected_value
|
192
183
|
# end
|
193
184
|
# end
|
194
185
|
# end
|
@@ -206,13 +197,11 @@ describe Attributor::Collection do
|
|
206
197
|
# end
|
207
198
|
# end
|
208
199
|
|
209
|
-
|
210
200
|
# end
|
211
201
|
|
212
|
-
|
213
202
|
context 'for simple structs' do
|
214
203
|
let(:attribute_definition) do
|
215
|
-
|
204
|
+
proc do
|
216
205
|
attribute :name, Attributor::String
|
217
206
|
end
|
218
207
|
end
|
@@ -221,26 +210,26 @@ describe Attributor::Collection do
|
|
221
210
|
|
222
211
|
context 'for valid struct values' do
|
223
212
|
[
|
224
|
-
[{
|
213
|
+
[{ 'name' => 'value' }, { 'name' => 'another_value' }], # Ruby hash
|
225
214
|
['{"name":"value"}'], # JSON hash
|
226
215
|
].each do |value|
|
227
216
|
it "returns value when incoming value is #{value.inspect}" do
|
228
|
-
expected_value = value.map {|v| simple_struct.load(v.clone)}
|
229
|
-
type.of(simple_struct).load(value).
|
217
|
+
expected_value = value.map { |v| simple_struct.load(v.clone) }
|
218
|
+
expect(type.of(simple_struct).load(value)).to match_array expected_value
|
230
219
|
end
|
231
220
|
end
|
232
221
|
end
|
233
222
|
|
234
223
|
context 'for invalid struct values' do
|
235
224
|
[
|
236
|
-
[{
|
225
|
+
[{ 'name' => 'value' }, { 'foo' => 'another_value' }], # Ruby hash
|
237
226
|
['{"bar":"value"}'], # JSON hash
|
238
|
-
[1,2]
|
227
|
+
[1, 2]
|
239
228
|
].each do |value|
|
240
229
|
it "raises when incoming value is #{value.inspect}" do
|
241
|
-
expect
|
230
|
+
expect do
|
242
231
|
type.of(simple_struct).load(value)
|
243
|
-
|
232
|
+
end.to raise_error(Attributor::AttributorException)
|
244
233
|
end
|
245
234
|
end
|
246
235
|
end
|
@@ -251,37 +240,36 @@ describe Attributor::Collection do
|
|
251
240
|
context '.validate' do
|
252
241
|
context 'compatible type values' do
|
253
242
|
let(:collection_members) { [1, 2, 'three'] }
|
254
|
-
let(:expected_errors) { [
|
243
|
+
let(:expected_errors) { ['error 1', 'error 2', 'error 3'] }
|
255
244
|
|
256
245
|
let(:value) { type.load(collection_members) }
|
257
246
|
|
258
247
|
before do
|
259
248
|
collection_members.zip(expected_errors).each do |member, expected_error|
|
260
|
-
type.member_attribute.
|
261
|
-
with(member,an_instance_of(Array))
|
262
|
-
and_return([expected_error])
|
249
|
+
expect(type.member_attribute).to receive(:validate)
|
250
|
+
.with(member, an_instance_of(Array)) # we don't care about the exact context here
|
251
|
+
.and_return([expected_error])
|
263
252
|
end
|
264
253
|
end
|
265
254
|
|
266
255
|
it 'validates members' do
|
267
|
-
type.validate(value).
|
256
|
+
expect(type.validate(value)).to match_array expected_errors
|
268
257
|
end
|
269
258
|
end
|
270
259
|
context 'invalid incoming types' do
|
271
260
|
subject(:type) { Attributor::Collection.of(Integer) }
|
272
261
|
it 'raise an exception' do
|
273
|
-
expect
|
262
|
+
expect do
|
274
263
|
type.validate('invalid_value')
|
275
|
-
|
264
|
+
end.to raise_error(ArgumentError, /can not validate object of type String/)
|
276
265
|
end
|
277
266
|
end
|
278
267
|
end
|
279
268
|
|
280
|
-
|
281
269
|
context '.example' do
|
282
|
-
it
|
270
|
+
it 'returns an instance of the type' do
|
283
271
|
value = type.example
|
284
|
-
value.
|
272
|
+
expect(value).to be_a(type)
|
285
273
|
end
|
286
274
|
|
287
275
|
[
|
@@ -294,46 +282,50 @@ describe Attributor::Collection do
|
|
294
282
|
].each do |member_type|
|
295
283
|
it "returns an Array of native types of #{member_type}" do
|
296
284
|
value = Attributor::Collection.of(member_type).example
|
297
|
-
value.
|
298
|
-
value.all? { |element| member_type.valid_type?(element) }.
|
285
|
+
expect(value).not_to be_empty
|
286
|
+
expect(value.all? { |element| member_type.valid_type?(element) }).to be_truthy
|
299
287
|
end
|
300
288
|
end
|
301
289
|
|
302
|
-
it
|
303
|
-
type.example(options: {size: 5}).size.
|
290
|
+
it 'returns an Array with size specified' do
|
291
|
+
expect(type.example(options: { size: 5 }).size).to eq(5)
|
304
292
|
end
|
305
293
|
|
306
|
-
it
|
294
|
+
it 'returns an Array with size within a range' do
|
307
295
|
5.times do
|
308
|
-
type.example(options: {size: (2..4)}).size.
|
296
|
+
expect(type.example(options: { size: (2..4) }).size).to be_within(1).of(3)
|
309
297
|
end
|
310
298
|
end
|
311
299
|
|
312
|
-
context
|
300
|
+
context 'passing a non array context' do
|
313
301
|
it 'still is handled correctly ' do
|
314
|
-
expect
|
315
|
-
type.example(
|
316
|
-
|
302
|
+
expect do
|
303
|
+
type.example('SimpleString')
|
304
|
+
end.to_not raise_error
|
317
305
|
end
|
318
306
|
end
|
319
|
-
|
320
307
|
end
|
321
308
|
|
322
309
|
context '.describe' do
|
323
|
-
let(:type){ Attributor::Collection.of(Attributor::String)}
|
324
|
-
let(:example){ nil }
|
325
|
-
subject(:described){ type.describe(example: example)}
|
310
|
+
let(:type) { Attributor::Collection.of(Attributor::String) }
|
311
|
+
let(:example) { nil }
|
312
|
+
subject(:described) { type.describe(example: example) }
|
326
313
|
it 'includes the member_attribute' do
|
327
|
-
described.
|
328
|
-
described
|
314
|
+
expect(described).to have_key(:member_attribute)
|
315
|
+
expect(described).not_to have_key(:example)
|
316
|
+
expect(described[:member_attribute]).not_to have_key(:example)
|
329
317
|
end
|
330
318
|
|
331
319
|
context 'with an example' do
|
332
|
-
let(:example){ type.example }
|
320
|
+
let(:example) { type.example }
|
333
321
|
it 'includes the member_attribute with an example from the first member' do
|
334
|
-
described.
|
335
|
-
described[:member_attribute].
|
336
|
-
described[:member_attribute].
|
322
|
+
expect(described).to have_key(:member_attribute)
|
323
|
+
expect(described[:member_attribute]).to have_key(:example)
|
324
|
+
expect(described[:member_attribute]).to eq(type.member_attribute.describe(example: example.first))
|
325
|
+
end
|
326
|
+
it 'includes the incoming example for the whole collection as well' do
|
327
|
+
expect(described).to have_key(:example)
|
328
|
+
expect(described[:example]).to eq(example)
|
337
329
|
end
|
338
330
|
end
|
339
331
|
end
|
@@ -342,15 +334,14 @@ describe Attributor::Collection do
|
|
342
334
|
let(:type) { Attributor::Collection.of(Cormorant) }
|
343
335
|
|
344
336
|
it 'it is Dumpable' do
|
345
|
-
type.new.is_a?(Attributor::Dumpable).
|
337
|
+
expect(type.new.is_a?(Attributor::Dumpable)).to be(true)
|
346
338
|
end
|
347
339
|
|
348
340
|
subject(:example) { type.example }
|
349
341
|
it 'dumps' do
|
350
|
-
expect
|
342
|
+
expect do
|
351
343
|
example.dump
|
352
|
-
|
344
|
+
end.to_not raise_error
|
353
345
|
end
|
354
346
|
end
|
355
|
-
|
356
347
|
end
|