attributor 5.0.2 → 5.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +30 -0
  3. data/.travis.yml +6 -4
  4. data/CHANGELOG.md +6 -1
  5. data/Gemfile +1 -1
  6. data/Guardfile +14 -8
  7. data/Rakefile +4 -5
  8. data/attributor.gemspec +34 -29
  9. data/lib/attributor.rb +23 -29
  10. data/lib/attributor/attribute.rb +108 -127
  11. data/lib/attributor/attribute_resolver.rb +12 -26
  12. data/lib/attributor/dsl_compiler.rb +17 -21
  13. data/lib/attributor/dumpable.rb +1 -2
  14. data/lib/attributor/example_mixin.rb +5 -8
  15. data/lib/attributor/exceptions.rb +5 -6
  16. data/lib/attributor/extensions/randexp.rb +3 -5
  17. data/lib/attributor/extras/field_selector.rb +4 -4
  18. data/lib/attributor/extras/field_selector/transformer.rb +6 -7
  19. data/lib/attributor/families/numeric.rb +0 -2
  20. data/lib/attributor/families/temporal.rb +1 -4
  21. data/lib/attributor/hash_dsl_compiler.rb +22 -25
  22. data/lib/attributor/type.rb +24 -32
  23. data/lib/attributor/types/bigdecimal.rb +7 -14
  24. data/lib/attributor/types/boolean.rb +5 -8
  25. data/lib/attributor/types/class.rb +9 -10
  26. data/lib/attributor/types/collection.rb +34 -44
  27. data/lib/attributor/types/container.rb +9 -15
  28. data/lib/attributor/types/csv.rb +7 -10
  29. data/lib/attributor/types/date.rb +20 -25
  30. data/lib/attributor/types/date_time.rb +7 -14
  31. data/lib/attributor/types/float.rb +4 -6
  32. data/lib/attributor/types/hash.rb +171 -196
  33. data/lib/attributor/types/ids.rb +2 -6
  34. data/lib/attributor/types/integer.rb +12 -17
  35. data/lib/attributor/types/model.rb +39 -48
  36. data/lib/attributor/types/object.rb +2 -4
  37. data/lib/attributor/types/polymorphic.rb +118 -0
  38. data/lib/attributor/types/regexp.rb +4 -5
  39. data/lib/attributor/types/string.rb +6 -7
  40. data/lib/attributor/types/struct.rb +8 -15
  41. data/lib/attributor/types/symbol.rb +3 -6
  42. data/lib/attributor/types/tempfile.rb +5 -6
  43. data/lib/attributor/types/time.rb +11 -11
  44. data/lib/attributor/types/uri.rb +9 -10
  45. data/lib/attributor/version.rb +1 -1
  46. data/spec/attribute_resolver_spec.rb +57 -78
  47. data/spec/attribute_spec.rb +174 -216
  48. data/spec/attributor_spec.rb +11 -15
  49. data/spec/dsl_compiler_spec.rb +19 -33
  50. data/spec/dumpable_spec.rb +6 -7
  51. data/spec/extras/field_selector/field_selector_spec.rb +1 -1
  52. data/spec/families_spec.rb +1 -3
  53. data/spec/hash_dsl_compiler_spec.rb +65 -74
  54. data/spec/spec_helper.rb +9 -3
  55. data/spec/support/hashes.rb +2 -3
  56. data/spec/support/models.rb +30 -36
  57. data/spec/support/polymorphics.rb +10 -0
  58. data/spec/type_spec.rb +38 -61
  59. data/spec/types/bigdecimal_spec.rb +11 -15
  60. data/spec/types/boolean_spec.rb +12 -39
  61. data/spec/types/class_spec.rb +10 -11
  62. data/spec/types/collection_spec.rb +72 -81
  63. data/spec/types/container_spec.rb +22 -26
  64. data/spec/types/csv_spec.rb +15 -16
  65. data/spec/types/date_spec.rb +16 -33
  66. data/spec/types/date_time_spec.rb +16 -33
  67. data/spec/types/file_upload_spec.rb +1 -2
  68. data/spec/types/float_spec.rb +7 -14
  69. data/spec/types/hash_spec.rb +285 -289
  70. data/spec/types/ids_spec.rb +5 -7
  71. data/spec/types/integer_spec.rb +37 -46
  72. data/spec/types/model_spec.rb +111 -128
  73. data/spec/types/polymorphic_spec.rb +134 -0
  74. data/spec/types/regexp_spec.rb +4 -7
  75. data/spec/types/string_spec.rb +17 -21
  76. data/spec/types/struct_spec.rb +40 -47
  77. data/spec/types/tempfile_spec.rb +1 -2
  78. data/spec/types/temporal_spec.rb +9 -0
  79. data/spec/types/time_spec.rb +16 -32
  80. data/spec/types/type_spec.rb +15 -0
  81. data/spec/types/uri_spec.rb +6 -7
  82. metadata +77 -25
@@ -1,8 +1,6 @@
1
1
  require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
2
2
 
3
-
4
3
  describe Attributor::Hash do
5
-
6
4
  subject(:type) { Attributor::Hash }
7
5
 
8
6
  its(:native_type) { should be(type) }
@@ -16,45 +14,63 @@ describe Attributor::Hash do
16
14
  Class.new(Attributor::Model) do
17
15
  attributes do
18
16
  raise 'sorry :('
19
- attribute :name, String
20
17
  end
21
18
  end
22
19
  end
23
20
 
24
21
  it 'throws original exception upon first run' do
25
- lambda {
22
+ expect do
26
23
  broken_model.attributes
27
- }.should raise_error(RuntimeError, 'sorry :(')
24
+ end.to raise_error(RuntimeError, 'sorry :(')
28
25
  end
26
+ context 'subsequent use' do
27
+ before do
28
+ expect do
29
+ broken_model.attributes
30
+ end.to raise_error(RuntimeError, 'sorry :(')
31
+ end
29
32
 
30
- it 'throws InvalidDefinition for subsequent access' do
31
- broken_model.attributes rescue nil
32
-
33
- lambda {
34
- broken_model.attributes
35
- }.should raise_error(Attributor::InvalidDefinition)
36
- end
33
+ it 'throws InvalidDefinition for subsequent access' do
34
+ expect do
35
+ broken_model.attributes
36
+ end.to raise_error(Attributor::InvalidDefinition)
37
+ end
37
38
 
38
- it 'throws for any attempts at using of an instance of it' do
39
- broken_model.attributes rescue nil
39
+ it 'throws for any attempts at using of an instance of it' do
40
+ instance = broken_model.new
41
+ expect do
42
+ instance.name
43
+ end.to raise_error(Attributor::InvalidDefinition)
44
+ end
40
45
 
41
- instance = broken_model.new
42
- lambda {
43
- instance.name
44
- }.should raise_error(Attributor::InvalidDefinition)
46
+ context 'for a type with a name' do
47
+ subject(:broken_model) do
48
+ Class.new(Attributor::Model) do
49
+ def self.name
50
+ 'BrokenModel'
51
+ end
52
+ attributes do
53
+ raise 'sorry :('
54
+ end
55
+ end
56
+ end
57
+ it 'includes the correct type.name if applicable' do
58
+ expect do
59
+ broken_model.attributes
60
+ end.to raise_error(Attributor::InvalidDefinition, /BrokenModel/)
61
+ end
62
+ end
45
63
  end
46
-
47
64
  end
48
65
  end
49
66
 
50
67
  context 'default options' do
51
68
  subject(:options) { type.options }
52
69
  it 'has allow_extra false' do
53
- options[:allow_extra].should be(false)
70
+ expect(options[:allow_extra]).to be(false)
54
71
  end
55
72
  end
56
73
 
57
-
58
74
  context '.example' do
59
75
  context 'for a simple hash' do
60
76
  subject(:example) { Attributor::Hash.example }
@@ -65,12 +81,12 @@ describe Attributor::Hash do
65
81
  end
66
82
 
67
83
  context 'for a typed hash' do
68
- subject(:example){ Attributor::Hash.of(value: Integer).example}
84
+ subject(:example) { Attributor::Hash.of(value: Integer).example }
69
85
 
70
86
  it 'returns a hash with keys and/or values of the right type' do
71
- example.should be_kind_of(Attributor::Hash)
72
- example.keys.size.should > 0
73
- example.values.all? {|v| v.kind_of? Integer}.should be(true)
87
+ expect(example).to be_kind_of(Attributor::Hash)
88
+ expect(example.keys.size).to be > 0
89
+ expect(example.values.all? { |v| v.is_a? Integer }).to be(true)
74
90
  end
75
91
  end
76
92
 
@@ -81,128 +97,129 @@ describe Attributor::Hash do
81
97
  subject(:example) { HashWithStrings.example(name: name, something: something) }
82
98
 
83
99
  context 'resolves a lazy attributes on demand' do
84
- before { example.lazy_attributes.keys.should eq [:name, :something] }
85
- after { example.lazy_attributes.keys.should eq [:something] }
100
+ before { expect(example.lazy_attributes.keys).to eq [:name, :something] }
101
+ after { expect(example.lazy_attributes.keys).to eq [:something] }
86
102
 
87
103
  it 'using get' do
88
- example.get(:name).should be name
104
+ expect(example.get(:name)).to be name
89
105
  end
90
106
  it 'using []' do
91
- example[:name].should be name
107
+ expect(example[:name]).to be name
92
108
  end
93
109
 
94
110
  it 'using set' do
95
111
  example.set :name, 'not bob'
96
- example.get(:name).should == 'not bob'
112
+ expect(example.get(:name)).to eq 'not bob'
97
113
  end
98
114
  it 'using []=' do
99
115
  example[:name] = 'not bob'
100
- example[:name].should == 'not bob'
116
+ expect(example[:name]).to eq 'not bob'
101
117
  end
102
118
  end
103
119
 
104
120
  its(:size) { should eq 2 }
105
- its(:values) { should =~ [name, something] }
106
- its(:keys) { should =~ [:name, :something] }
121
+ its(:values) { should match_array [name, something] }
122
+ its(:keys) { should match_array [:name, :something] }
107
123
  it do
108
124
  should_not be_empty
109
125
  end
110
126
 
111
127
  it 'responds to key? correctly' do
112
- example.key?(:name).should be(true)
113
- example.key?(:something).should be(true)
128
+ expect(example.key?(:name)).to be(true)
129
+ expect(example.key?(:something)).to be(true)
114
130
  end
115
131
 
116
132
  it 'enumerates the contents' do
117
- example.collect {|k,v| k }.should eq [:name, :something ]
133
+ expect(example.collect { |k, _v| k }).to eq [:name, :something]
118
134
  end
119
135
 
120
136
  it 'enumerates the contents using each_pair' do
121
137
  pairs = []
122
- example.each_pair {|pair| pairs << pair }
123
- pairs.should =~ [ [:name, name], [:something, something] ]
138
+ example.each_pair { |pair| pairs << pair }
139
+ expect(pairs).to match_array [[:name, name], [:something, something]]
124
140
  end
125
141
 
126
- its(:contents){ should eq ({name: name, something: something}) }
142
+ its(:contents) { should eq(name: name, something: something) }
127
143
  it 'does not create methods for the keys' do
128
- example.should_not respond_to(:name)
129
- example.should_not respond_to(:something)
144
+ expect(example).not_to respond_to(:name)
145
+ expect(example).not_to respond_to(:something)
130
146
  end
131
-
132
147
  end
133
148
 
134
149
  context 'using a non array context' do
135
150
  it 'should work for hashes with key/value types' do
136
- expect{ Attributor::Hash.of(key:String,value:String).example("Not an Array") }.to_not raise_error
151
+ expect do
152
+ Attributor::Hash.of(key: String, value: String)
153
+ .example('Not an Array')
154
+ end.to_not raise_error
137
155
  end
138
156
  it 'should work for hashes with keys defined' do
139
157
  block = proc { key 'a string', String }
140
- hash = Attributor::Hash.of(key:String).construct(block)
158
+ hash = Attributor::Hash.of(key: String).construct(block)
141
159
 
142
- expect{ hash.example("Not an Array") }.to_not raise_error
160
+ expect { hash.example('Not an Array') }.to_not raise_error
143
161
  end
144
162
  end
145
163
  end
146
164
 
147
165
  context '.load' do
148
- let(:value) { {one: 'two', three: 4} }
166
+ let(:value) { { one: 'two', three: 4 } }
149
167
  subject(:hash) { type.load(value) }
150
168
 
151
169
  context 'for nil with recurse: true' do
152
170
  let(:value) { nil }
153
- subject(:hash) { HashWithModel.load(value, recurse:true) }
171
+ subject(:hash) { HashWithModel.load(value, recurse: true) }
154
172
 
155
173
  it 'works' do
156
- hash[:name].should eq('Turkey McDucken')
157
- hash[:chicken].age.should eq(1)
174
+ expect(hash[:name]).to eq('Turkey McDucken')
175
+ expect(hash[:chicken].age).to eq(1)
158
176
  end
159
177
  end
160
178
 
161
179
  context 'for a simple hash' do
162
180
  it { should eq(value) }
163
181
  it 'equals the hash' do
164
- hash.should eq value
165
- hash[:one].should eq('two')
166
- hash[:three].should eq(4)
182
+ expect(hash).to eq value
183
+ expect(hash[:one]).to eq('two')
184
+ expect(hash[:three]).to eq(4)
167
185
  end
168
186
  end
169
187
 
170
188
  context 'for a JSON encoded hash' do
171
- let(:value_as_hash) { {'one' => 'two', 'three' => 4} }
172
- let(:value) { JSON.dump( value_as_hash ) }
189
+ let(:value_as_hash) { { 'one' => 'two', 'three' => 4 } }
190
+ let(:value) { JSON.dump(value_as_hash) }
173
191
  it 'deserializes and converts it to a real hash' do
174
- hash.should eq(value_as_hash)
175
- hash['one'].should eq 'two'
192
+ expect(hash).to eq(value_as_hash)
193
+ expect(hash['one']).to eq 'two'
176
194
  end
177
195
  end
178
196
 
179
197
  context 'for a typed hash' do
180
- subject(:type){ Attributor::Hash.of(key: String, value: Integer)}
198
+ subject(:type) { Attributor::Hash.of(key: String, value: Integer) }
181
199
  context 'with good values' do
182
- let(:value) { {one: '1', 'three' => 3} }
200
+ let(:value) { { one: '1', 'three' => 3 } }
183
201
  it 'coerces good values into the correct types' do
184
- hash.should eq({'one' => 1, 'three' => 3})
185
- hash['one'].should eq(1)
202
+ expect(hash).to eq('one' => 1, 'three' => 3)
203
+ expect(hash['one']).to eq(1)
186
204
  end
187
205
  end
188
206
 
189
207
  context 'with incompatible values' do
190
- let(:value) { {one: 'two', three: 4} }
208
+ let(:value) { { one: 'two', three: 4 } }
191
209
  it 'fails' do
192
- expect{
210
+ expect do
193
211
  type.load(value)
194
- }.to raise_error(/invalid value for Integer/)
212
+ end.to raise_error(/invalid value for Integer/)
195
213
  end
196
214
  end
197
-
198
215
  end
199
216
 
200
217
  context 'for a partially typed hash' do
201
- subject(:type){ Attributor::Hash.of(value: Integer) }
218
+ subject(:type) { Attributor::Hash.of(value: Integer) }
202
219
  context 'with good values' do
203
- let(:value) { {one: '1', [1,2,3] => 3} }
220
+ let(:value) { { one: '1', [1, 2, 3] => 3 } }
204
221
  it 'coerces only values into the correct types (and leave keys alone)' do
205
- hash.should eq({:one => 1, [1,2,3] => 3})
222
+ expect(hash).to eq(:one => 1, [1, 2, 3] => 3)
206
223
  end
207
224
  end
208
225
  end
@@ -222,20 +239,20 @@ describe Attributor::Hash do
222
239
  Class.new(Attributor::Hash) do
223
240
  keys do
224
241
  key 'id', Integer
225
- key 'name', String, default: "unnamed"
242
+ key 'name', String, default: 'unnamed'
226
243
  key 'chicken', Chicken
227
244
  end
228
245
  end
229
246
  end
230
247
 
231
- let(:value) { {'chicken' => Chicken.example} }
248
+ let(:value) { { 'chicken' => Chicken.example } }
232
249
 
233
250
  subject(:hash) { type.load(value) }
234
251
 
235
252
  it { should_not have_key('id') }
236
253
  it 'has the defaulted key' do
237
- hash.should have_key('name')
238
- hash['name'].should eq('unnamed')
254
+ expect(hash).to have_key('name')
255
+ expect(hash['name']).to eq('unnamed')
239
256
  end
240
257
  end
241
258
 
@@ -273,44 +290,39 @@ describe Attributor::Hash do
273
290
  end
274
291
 
275
292
  it 'complains about an unknown key' do
276
- expect {
293
+ expect do
277
294
  loader_hash.load(value)
278
- }.to raise_error(Attributor::AttributorException,/Unknown key received: :weird_key/)
295
+ end.to raise_error(Attributor::AttributorException,
296
+ /Unknown key received: :weird_key/)
279
297
  end
280
298
  end
281
299
  end
282
300
  end
283
-
284
-
285
301
  end
286
302
 
287
-
288
303
  context '.of' do
289
304
  context 'specific key and value types' do
290
- let(:key_type){ String }
291
- let(:value_type){ Integer }
305
+ let(:key_type) { String }
306
+ let(:value_type) { Integer }
292
307
 
293
308
  subject(:type) { Attributor::Hash.of(key: key_type, value: value_type) }
294
309
 
295
310
  it { should be_a(::Class) }
296
311
  its(:ancestors) { should include(Attributor::Hash) }
297
- its(:key_type) { should == Attributor::String }
298
- its(:value_type) { should == Attributor::Integer }
312
+ its(:key_type) { should eq Attributor::String }
313
+ its(:value_type) { should eq Attributor::Integer }
299
314
 
300
315
  context '.load' do
301
- let(:value) { {one: '2', 3 => 4} }
316
+ let(:value) { { one: '2', 3 => 4 } }
302
317
 
303
318
  subject(:hash) { type.load(value) }
304
319
 
305
320
  it 'coerces the types properly' do
306
- hash['one'].should eq(2)
307
- hash['3'].should eq(4)
321
+ expect(hash['one']).to eq(2)
322
+ expect(hash['3']).to eq(4)
308
323
  end
309
-
310
324
  end
311
-
312
325
  end
313
-
314
326
  end
315
327
 
316
328
  context '.construct' do
@@ -323,36 +335,35 @@ describe Attributor::Hash do
323
335
  end
324
336
  end
325
337
 
326
-
327
338
  subject(:type) { Attributor::Hash.construct(block) }
328
339
 
329
- it { should_not be(Attributor::Hash)
330
- }
340
+ it do
341
+ should_not be(Attributor::Hash)
342
+ end
331
343
 
332
344
  context 'loading' do
333
- let(:date) { DateTime.parse("2014-07-15") }
345
+ let(:date) { DateTime.parse('2014-07-15') }
334
346
  let(:value) do
335
- {'a string' => 12, '1' => '2', :some_date => date.to_s}
347
+ { 'a string' => 12, '1' => '2', :some_date => date.to_s }
336
348
  end
337
349
 
338
- subject(:hash) { type.load(value)}
350
+ subject(:hash) { type.load(value) }
339
351
 
340
352
  it 'loads' do
341
- hash['a string'].should eq('12')
342
- hash['1'].should eq(2)
343
- hash[:some_date].should eq(date)
344
- hash['defaulted'].should eq('default value')
353
+ expect(hash['a string']).to eq('12')
354
+ expect(hash['1']).to eq(2)
355
+ expect(hash[:some_date]).to eq(date)
356
+ expect(hash['defaulted']).to eq('default value')
345
357
  end
346
358
 
347
359
  context 'with unknown keys in input' do
348
360
  it 'raises an error' do
349
- expect {
350
- type.load({'other_key' => :value})
351
- }.to raise_error(Attributor::AttributorException)
361
+ expect do
362
+ type.load('other_key' => :value)
363
+ end.to raise_error(Attributor::AttributorException)
352
364
  end
353
365
  end
354
366
 
355
-
356
367
  context 'with a key_type' do
357
368
  let(:block) do
358
369
  proc do
@@ -365,16 +376,15 @@ describe Attributor::Hash do
365
376
 
366
377
  subject(:type) { Attributor::Hash.of(key: String).construct(block) }
367
378
  let(:value) do
368
- {'a string' => 12, 1 => '2', :some_date => date.to_s}
379
+ { 'a string' => 12, 1 => '2', :some_date => date.to_s }
369
380
  end
370
381
 
371
382
  it 'loads' do
372
- hash['a string'].should eq('12')
373
- hash['1'].should eq(2)
374
- hash['some_date'].should eq(date)
375
- hash['defaulted'].should eq('default value')
383
+ expect(hash['a string']).to eq('12')
384
+ expect(hash['1']).to eq(2)
385
+ expect(hash['some_date']).to eq(date)
386
+ expect(hash['defaulted']).to eq('default value')
376
387
  end
377
-
378
388
  end
379
389
  end
380
390
 
@@ -386,75 +396,73 @@ describe Attributor::Hash do
386
396
  end
387
397
 
388
398
  it 'raises an error' do
389
- expect {
390
- Attributor::Hash.of(key:String).construct(block).keys
391
- }.to raise_error(/Invalid key: :some_date, must be instance of String/)
399
+ expect do
400
+ Attributor::Hash.of(key: String).construct(block).keys
401
+ end.to raise_error(/Invalid key: :some_date, must be instance of String/)
392
402
  end
393
-
394
403
  end
395
404
  end
396
405
 
397
406
  context '.check_option!' do
398
407
  context ':case_insensitive_load' do
399
-
400
408
  it 'is valid when key_type is a string' do
401
- Attributor::Hash.of(key:String).check_option!(:case_insensitive_load, true).should == :ok
409
+ expect(Attributor::Hash.of(key: String).check_option!(:case_insensitive_load, true)).to eq :ok
402
410
  end
403
411
 
404
412
  it 'is invalid when key_type is non-string' do
405
- expect {
406
- Attributor::Hash.of(key:Integer).check_option!(:case_insensitive_load, true)
407
- }.to raise_error(Attributor::AttributorException, /:case_insensitive_load may not be used/)
413
+ expect do
414
+ Attributor::Hash.of(key: Integer).check_option!(:case_insensitive_load, true)
415
+ end.to raise_error(Attributor::AttributorException,
416
+ /:case_insensitive_load may not be used/)
408
417
  end
409
-
410
418
  end
411
- it 'rejects unknown options' do
412
- subject.check_option!(:bad_option, Object).should == :unknown
419
+ it 'rejects unknown options' do
420
+ expect(subject.check_option!(:bad_option, Object)).to eq :unknown
413
421
  end
414
-
415
422
  end
416
423
 
417
424
  context '.add_requirement' do
418
- let(:req_type){ :all }
419
- let(:req){ double("requirement", type: req_type, attr_names: req_attributes)}
425
+ let(:req_type) { :all }
426
+ let(:req) { double('requirement', type: req_type, attr_names: req_attributes) }
420
427
  context 'with valid attributes' do
421
- let(:req_attributes){ [:name] }
428
+ let(:req_attributes) { [:name] }
422
429
  it 'successfully saves it in the class' do
423
430
  HashWithStrings.add_requirement(req)
424
- HashWithStrings.requirements.should include(req)
431
+ expect(HashWithStrings.requirements).to include(req)
425
432
  end
426
433
  end
427
434
  context 'with attributes not defined in the class' do
428
- let(:req_attributes){ [:name, :invalid, :notgood] }
435
+ let(:req_attributes) { [:name, :invalid, :notgood] }
429
436
  it 'it complains loudly' do
430
- expect{
437
+ expect do
431
438
  HashWithStrings.add_requirement(req)
432
- }.to raise_error("Invalid attribute name(s) found (invalid, notgood) when defining a requirement of type all for HashWithStrings .The only existing attributes are [:name, :something]")
439
+ end.to raise_error(
440
+ 'Invalid attribute name(s) found (invalid, notgood) when defining a requirement of type all for HashWithStrings .The only existing attributes are [:name, :something]'
441
+ )
433
442
  end
434
443
  end
435
444
  end
436
445
 
437
446
  context '.dump' do
438
-
439
- let(:value) { {one: 1, two: 2} }
447
+ let(:value) { { one: 1, two: 2 } }
440
448
  let(:opts) { {} }
441
449
 
442
450
  it 'it is Dumpable' do
443
- type.new.is_a?(Attributor::Dumpable).should be(true)
451
+ expect(type.new.is_a?(Attributor::Dumpable)).to be(true)
444
452
  end
445
453
 
446
454
  context 'for a simple (untyped) hash' do
447
455
  it 'returns the untouched hash value' do
448
- type.dump(value, opts).should eq(value)
456
+ expect(type.dump(value, opts)).to eq(value)
449
457
  end
450
458
  end
451
459
 
452
460
  context 'for a typed hash' do
453
461
  before do
454
- subtype.should_receive(:dump).exactly(2).times.and_call_original
462
+ expect(subtype).to receive(:dump).exactly(2).times.and_call_original
455
463
  end
456
- let(:value1) { {first: "Joe", last: "Moe"} }
457
- let(:value2) { {first: "Mary", last: "Foe"} }
464
+ let(:value1) { { first: 'Joe', last: 'Moe' } }
465
+ let(:value2) { { first: 'Mary', last: 'Foe' } }
458
466
  let(:value) { { id1: subtype.new(value1), id2: subtype.new(value2) } }
459
467
  let(:subtype) do
460
468
  Class.new(Attributor::Model) do
@@ -468,11 +476,11 @@ describe Attributor::Hash do
468
476
 
469
477
  it 'returns a hash with the dumped values and keys' do
470
478
  dumped_value = type.dump(value, opts)
471
- dumped_value.should be_kind_of(::Hash)
472
- dumped_value.keys.should =~ ['id1','id2']
473
- dumped_value.values.should have(2).items
474
- dumped_value['id1'].should == value1
475
- dumped_value['id2'].should == value2
479
+ expect(dumped_value).to be_kind_of(::Hash)
480
+ expect(dumped_value.keys).to match_array %w(id1 id2)
481
+ expect(dumped_value.values).to have(2).items
482
+ expect(dumped_value['id1']).to eq value1
483
+ expect(dumped_value['id2']).to eq value2
476
484
  end
477
485
 
478
486
  context 'that has nil attribute values' do
@@ -480,31 +488,29 @@ describe Attributor::Hash do
480
488
 
481
489
  it 'correctly returns nil rather than trying to dump their contents' do
482
490
  dumped_value = type.dump(value, opts)
483
- dumped_value.should be_kind_of(::Hash)
484
- dumped_value.keys.should =~ ['id1','id2']
485
- dumped_value['id1'].should == nil
486
- dumped_value['id2'].should == value2
491
+ expect(dumped_value).to be_kind_of(::Hash)
492
+ expect(dumped_value.keys).to match_array %w(id1 id2)
493
+ expect(dumped_value['id1']).to be nil
494
+ expect(dumped_value['id2']).to eq value2
487
495
  end
488
496
  end
489
497
  end
490
-
491
498
  end
492
499
 
493
500
  context '#validate' do
494
501
  context 'for a key and value typed hash' do
495
- let(:key_type){ Integer }
496
- let(:value_type){ DateTime }
502
+ let(:key_type) { Integer }
503
+ let(:value_type) { DateTime }
497
504
 
498
505
  let(:type) { Attributor::Hash.of(key: key_type, value: value_type) }
499
506
  subject(:hash) { type.new('one' => :two) }
500
507
 
501
508
  it 'returns errors for key and value' do
502
509
  errors = hash.validate
503
- errors.should have(2).items
504
-
505
- errors.should include("Attribute $.key(\"one\") received value: \"one\" is of the wrong type (got: String, expected: Attributor::Integer)")
506
- errors.should include("Attribute $.value(:two) received value: :two is of the wrong type (got: Symbol, expected: Attributor::DateTime)")
510
+ expect(errors).to have(2).items
507
511
 
512
+ expect(errors).to include('Attribute $.key("one") received value: "one" is of the wrong type (got: String, expected: Attributor::Integer)')
513
+ expect(errors).to include('Attribute $.value(:two) received value: :two is of the wrong type (got: Symbol, expected: Attributor::DateTime)')
508
514
  end
509
515
  end
510
516
 
@@ -519,18 +525,16 @@ describe Attributor::Hash do
519
525
 
520
526
  let(:type) { Attributor::Hash.construct(block) }
521
527
 
522
- let(:values) { {'integer' => 'one', 'datetime' => 'now' } }
528
+ let(:values) { { 'integer' => 'one', 'datetime' => 'now' } }
523
529
  subject(:hash) { type.new(values) }
524
530
 
525
531
  it 'validates the keys' do
526
532
  errors = hash.validate
527
- errors.should have(3).items
528
- errors.should include("Attribute $.key(\"not-optional\") is required")
533
+ expect(errors).to have(3).items
534
+ expect(errors).to include('Attribute $.key("not-optional") is required')
529
535
  end
530
-
531
536
  end
532
537
 
533
-
534
538
  context 'with requirements defined' do
535
539
  let(:type) { Attributor::Hash.construct(block) }
536
540
 
@@ -548,9 +552,9 @@ describe Attributor::Hash do
548
552
 
549
553
  it 'complains not all the listed elements are set (false or true)' do
550
554
  errors = type.new('name' => 'CAP').validate
551
- errors.should have(2).items
552
- ['consistency','availability'].each do |name|
553
- errors.should include("Key #{name} is required for $.")
555
+ expect(errors).to have(2).items
556
+ %w(consistency availability).each do |name|
557
+ expect(errors).to include("Key #{name} is required for $.")
554
558
  end
555
559
  end
556
560
  end
@@ -568,9 +572,9 @@ describe Attributor::Hash do
568
572
 
569
573
  it 'complains if less than 2 in the group are set (false or true)' do
570
574
  errors = type.new('name' => 'CAP', 'consistency' => false).validate
571
- errors.should have(1).items
572
- errors.should include(
573
- "At least 2 keys out of [\"consistency\", \"availability\", \"partitioning\"] are required to be passed in for $. Found [\"consistency\"]"
575
+ expect(errors).to have(1).items
576
+ expect(errors).to include(
577
+ 'At least 2 keys out of ["consistency", "availability", "partitioning"] are required to be passed in for $. Found ["consistency"]'
574
578
  )
575
579
  end
576
580
  end
@@ -588,8 +592,8 @@ describe Attributor::Hash do
588
592
 
589
593
  it 'complains if more than 2 in the group are set (false or true)' do
590
594
  errors = type.new('name' => 'CAP', 'consistency' => false, 'availability' => true, 'partitioning' => false).validate
591
- errors.should have(1).items
592
- errors.should include("At most 2 keys out of [\"consistency\", \"availability\", \"partitioning\"] can be passed in for $. Found [\"consistency\", \"availability\", \"partitioning\"]")
595
+ expect(errors).to have(1).items
596
+ expect(errors).to include('At most 2 keys out of ["consistency", "availability", "partitioning"] can be passed in for $. Found ["consistency", "availability", "partitioning"]')
593
597
  end
594
598
  end
595
599
 
@@ -606,13 +610,13 @@ describe Attributor::Hash do
606
610
 
607
611
  it 'complains if less than 1 in the group are set (false or true)' do
608
612
  errors = type.new('name' => 'CAP').validate
609
- errors.should have(1).items
610
- errors.should include("Exactly 1 of the following keys [\"consistency\", \"availability\", \"partitioning\"] are required for $. Found 0 instead: []")
613
+ expect(errors).to have(1).items
614
+ expect(errors).to include('Exactly 1 of the following keys ["consistency", "availability", "partitioning"] are required for $. Found 0 instead: []')
611
615
  end
612
616
  it 'complains if more than 1 in the group are set (false or true)' do
613
617
  errors = type.new('name' => 'CAP', 'consistency' => false, 'availability' => true).validate
614
- errors.should have(1).items
615
- errors.should include("Exactly 1 of the following keys [\"consistency\", \"availability\", \"partitioning\"] are required for $. Found 2 instead: [\"consistency\", \"availability\"]")
618
+ expect(errors).to have(1).items
619
+ expect(errors).to include('Exactly 1 of the following keys ["consistency", "availability", "partitioning"] are required for $. Found 2 instead: ["consistency", "availability"]')
616
620
  end
617
621
  end
618
622
 
@@ -629,8 +633,8 @@ describe Attributor::Hash do
629
633
 
630
634
  it 'complains if two or more in the group are set (false or true)' do
631
635
  errors = type.new('name' => 'CAP', 'consistency' => false, 'availability' => true).validate
632
- errors.should have(1).items
633
- errors.should include("keys [\"consistency\", \"availability\"] are mutually exclusive for $.")
636
+ expect(errors).to have(1).items
637
+ expect(errors).to include('keys ["consistency", "availability"] are mutually exclusive for $.')
634
638
  end
635
639
  end
636
640
 
@@ -653,38 +657,36 @@ describe Attributor::Hash do
653
657
 
654
658
  it 'complains not all the listed elements are set (false or true)' do
655
659
  errors = type.new('name' => 'CAP').validate
656
- errors.should have(1).items
657
- errors.should include(
658
- "At least 1 keys out of [\"consistency\", \"availability\", \"partitioning\"] are required to be passed in for $. Found none"
660
+ expect(errors).to have(1).items
661
+ expect(errors).to include(
662
+ 'At least 1 keys out of ["consistency", "availability", "partitioning"] are required to be passed in for $. Found none'
659
663
  )
660
664
  end
661
665
  end
662
666
  end
663
-
664
667
  end
665
668
 
666
669
  context 'in an Attribute' do
667
670
  let(:options) { {} }
668
- subject(:attribute) { Attributor::Attribute.new(Attributor::Hash, options)}
671
+ subject(:attribute) { Attributor::Attribute.new(Attributor::Hash, options) }
669
672
 
670
673
  context 'with an example option that is a proc' do
671
- let(:example_hash) { {:key => "value"} }
674
+ let(:example_hash) { { key: 'value' } }
672
675
  let(:options) { { example: proc { example_hash } } }
673
676
  it 'uses the hash' do
674
- attribute.example.should eq(example_hash)
677
+ expect(attribute.example).to eq(example_hash)
675
678
  end
676
679
  end
677
-
678
680
  end
679
681
 
680
682
  context '.describe' do
681
- let(:example){ nil }
683
+ let(:example) { nil }
682
684
  subject(:description) { type.describe(example: example) }
683
685
  context 'for hashes with key and value types' do
684
686
  it 'describes the type correctly' do
685
- description[:name].should eq('Hash')
686
- description[:key].should eq(type:{name: 'Object', id: 'Attributor-Object', family: 'any'})
687
- description[:value].should eq(type:{name: 'Object', id: 'Attributor-Object', family: 'any'})
687
+ expect(description[:name]).to eq('Hash')
688
+ expect(description[:key]).to eq(type: { name: 'Object', id: 'Attributor-Object', family: 'any' })
689
+ expect(description[:value]).to eq(type: { name: 'Object', id: 'Attributor-Object', family: 'any' })
688
690
  end
689
691
  end
690
692
 
@@ -696,7 +698,7 @@ describe Attributor::Hash do
696
698
  key 'some_date', DateTime
697
699
  key 'defaulted', String, default: 'default value'
698
700
  requires do
699
- all.of '1','some_date'
701
+ all.of '1', 'some_date'
700
702
  exclusive 'some_date', 'defaulted'
701
703
  at_least(1).of 'a string', 'some_date'
702
704
  at_most(2).of 'a string', 'some_date'
@@ -708,30 +710,29 @@ describe Attributor::Hash do
708
710
  let(:type) { Attributor::Hash.of(key: String).construct(block) }
709
711
 
710
712
  it 'describes the type correctly' do
711
- description[:name].should eq('Hash')
712
- description[:key].should eq(type:{name: 'String', id: 'Attributor-String', family: 'string'})
713
- description.should_not have_key(:value)
713
+ expect(description[:name]).to eq('Hash')
714
+ expect(description[:key]).to eq(type: { name: 'String', id: 'Attributor-String', family: 'string' })
715
+ expect(description).not_to have_key(:value)
714
716
  end
715
717
 
716
718
  it 'describes the type attributes correctly' do
717
719
  attrs = description[:attributes]
718
720
 
719
- attrs['a string'].should eq(type: {name: 'String', id: 'Attributor-String', family: 'string'} )
720
- attrs['1'].should eq(type: {name: 'Integer', id: 'Attributor-Integer', family: 'numeric'}, options: {min: 1, max: 20} )
721
- attrs['some_date'].should eq(type: {name: 'DateTime', id: 'Attributor-DateTime', family: 'temporal'})
722
- attrs['defaulted'].should eq(type: {name: 'String', id: 'Attributor-String', family: 'string'}, default: 'default value')
721
+ expect(attrs['a string']).to eq(type: { name: 'String', id: 'Attributor-String', family: 'string' })
722
+ expect(attrs['1']).to eq(type: { name: 'Integer', id: 'Attributor-Integer', family: 'numeric' }, options: { min: 1, max: 20 })
723
+ expect(attrs['some_date']).to eq(type: { name: 'DateTime', id: 'Attributor-DateTime', family: 'temporal' })
724
+ expect(attrs['defaulted']).to eq(type: { name: 'String', id: 'Attributor-String', family: 'string' }, default: 'default value')
723
725
  end
724
726
 
725
727
  it 'describes the type requirements correctly' do
726
-
727
728
  reqs = description[:requirements]
728
- reqs.should be_kind_of(Array)
729
- reqs.size.should be(5)
730
- reqs.should include( type: :all, attributes: ['1','some_date'] )
731
- reqs.should include( type: :exclusive, attributes: ['some_date','defaulted'] )
732
- reqs.should include( type: :at_least, attributes: ['a string','some_date'], count: 1 )
733
- reqs.should include( type: :at_most, attributes: ['a string','some_date'], count: 2 )
734
- reqs.should include( type: :exactly, attributes: ['a string','some_date'], count: 1 )
729
+ expect(reqs).to be_kind_of(Array)
730
+ expect(reqs.size).to be(5)
731
+ expect(reqs).to include(type: :all, attributes: %w(1 some_date))
732
+ expect(reqs).to include(type: :exclusive, attributes: %w(some_date defaulted))
733
+ expect(reqs).to include(type: :at_least, attributes: ['a string', 'some_date'], count: 1)
734
+ expect(reqs).to include(type: :at_most, attributes: ['a string', 'some_date'], count: 2)
735
+ expect(reqs).to include(type: :exactly, attributes: ['a string', 'some_date'], count: 1)
735
736
  end
736
737
 
737
738
  context 'merging requires.all with attribute required: true' do
@@ -746,8 +747,8 @@ describe Attributor::Hash do
746
747
  end
747
748
  end
748
749
  it 'includes attributes with required: true into the :all requirements' do
749
- req_all = description[:requirements].select{|r| r[:type] == :all}.first
750
- req_all[:attributes].should include( 'required string','some_date' )
750
+ req_all = description[:requirements].select { |r| r[:type] == :all }.first
751
+ expect(req_all[:attributes]).to include('required string', 'some_date')
751
752
  end
752
753
  end
753
754
 
@@ -759,21 +760,21 @@ describe Attributor::Hash do
759
760
  end
760
761
  end
761
762
  it 'includes attributes with required: true into the :all requirements' do
762
- req_all = description[:requirements].select{|r| r[:type] == :all}.first
763
- req_all.should_not be(nil)
764
- req_all[:attributes].should include( 'required string','required integer' )
763
+ req_all = description[:requirements].select { |r| r[:type] == :all }.first
764
+ expect(req_all).not_to be(nil)
765
+ expect(req_all[:attributes]).to include('required string', 'required integer')
765
766
  end
766
767
  end
767
768
 
768
769
  context 'with an example' do
769
- let(:example){ type.example }
770
+ let(:example) { type.example }
770
771
 
771
772
  it 'should have the matching example for each leaf key' do
772
- description[:attributes].keys.should =~ type.keys.keys
773
- description[:attributes].each do |name,sub_description|
774
- sub_description.should have_key(:example)
773
+ expect(description[:attributes].keys).to match_array type.keys.keys
774
+ description[:attributes].each do |name, sub_description|
775
+ expect(sub_description).to have_key(:example)
775
776
  val = type.attributes[name].dump(example[name])
776
- sub_description[:example].should eq val
777
+ expect(sub_description[:example]).to eq val
777
778
  end
778
779
  end
779
780
  end
@@ -781,17 +782,17 @@ describe Attributor::Hash do
781
782
  end
782
783
 
783
784
  context '#dump' do
784
- let(:key_type){ String }
785
- let(:value_type){ Integer }
786
- let(:hash) { {one: '2', 3 => 4} }
785
+ let(:key_type) { String }
786
+ let(:value_type) { Integer }
787
+ let(:hash) { { one: '2', 3 => 4 } }
787
788
  let(:type) { Attributor::Hash.of(key: key_type, value: value_type) }
788
789
  let(:value) { type.load(hash) }
789
790
 
790
791
  subject(:output) { value.dump }
791
792
 
792
793
  it 'dumps the contents properly' do
793
- output.should be_kind_of(::Hash)
794
- output.should eq('one' => 2, '3' => 4)
794
+ expect(output).to be_kind_of(::Hash)
795
+ expect(output).to eq('one' => 2, '3' => 4)
795
796
  end
796
797
 
797
798
  context 'with a model as value type' do
@@ -803,17 +804,16 @@ describe Attributor::Hash do
803
804
  end
804
805
  end
805
806
  end
806
- let(:hash) { {one: value_type.example} }
807
-
807
+ let(:hash) { { one: value_type.example } }
808
808
  end
809
809
  context 'will always return a top level hash' do
810
- subject(:type_dump){ type.dump(value) }
811
- let(:key_type){ Attributor::Object }
812
- let(:value_type){ Attributor::Object }
810
+ subject(:type_dump) { type.dump(value) }
811
+ let(:key_type) { Attributor::Object }
812
+ let(:value_type) { Attributor::Object }
813
813
 
814
814
  it 'even when key/types are object' do
815
- subject.should be_kind_of(::Hash)
816
- subject.should eq( hash )
815
+ expect(subject).to be_kind_of(::Hash)
816
+ expect(subject).to eq(hash)
817
817
  end
818
818
  end
819
819
 
@@ -827,13 +827,13 @@ describe Attributor::Hash do
827
827
  end
828
828
  end
829
829
 
830
- let(:chicken) { {'name' => 'bob'} }
830
+ let(:chicken) { { 'name' => 'bob' } }
831
831
 
832
- let(:value) { {'id' => '1', 'chicken' => chicken } }
833
- let(:expected) { {'id' => 1, 'chicken' => Chicken.dump(chicken) } }
832
+ let(:value) { { 'id' => '1', 'chicken' => chicken } }
833
+ let(:expected) { { 'id' => 1, 'chicken' => Chicken.dump(chicken) } }
834
834
 
835
835
  it 'properly dumps the values' do
836
- type.dump(value).should eq(expected)
836
+ expect(type.dump(value)).to eq(expected)
837
837
  end
838
838
 
839
839
  context 'with allow_extra: true' do
@@ -846,10 +846,10 @@ describe Attributor::Hash do
846
846
  end
847
847
  end
848
848
 
849
- let(:value) { {'id' => '1', 'chicken' => chicken, 'rank' => 'bob rank'} }
850
- let(:expected) { {'id' => 1, 'chicken' => Chicken.dump(chicken), 'rank' => 'bob rank' } }
849
+ let(:value) { { 'id' => '1', 'chicken' => chicken, 'rank' => 'bob rank' } }
850
+ let(:expected) { { 'id' => 1, 'chicken' => Chicken.dump(chicken), 'rank' => 'bob rank' } }
851
851
  it 'preserves the extra keys at the top level' do
852
- type.dump(value).should eq(expected)
852
+ expect(type.dump(value)).to eq(expected)
853
853
  end
854
854
 
855
855
  context 'with extra option' do
@@ -863,9 +863,9 @@ describe Attributor::Hash do
863
863
  end
864
864
  end
865
865
 
866
- let(:expected) { {'id' => 1, 'chicken' => Chicken.dump(chicken), 'other' => {'rank' => 'bob rank' }} }
866
+ let(:expected) { { 'id' => 1, 'chicken' => Chicken.dump(chicken), 'other' => { 'rank' => 'bob rank' } } }
867
867
  it 'dumps the extra keys inside the subhash' do
868
- type.dump(value).should eq(expected)
868
+ expect(type.dump(value)).to eq(expected)
869
869
  end
870
870
  end
871
871
  end
@@ -873,7 +873,6 @@ describe Attributor::Hash do
873
873
  end
874
874
 
875
875
  context '.from_hash' do
876
-
877
876
  context 'without allowing extra keys' do
878
877
  let(:type) do
879
878
  Class.new(Attributor::Hash) do
@@ -885,29 +884,29 @@ describe Attributor::Hash do
885
884
  end
886
885
  end
887
886
  end
888
- subject(:input){ {} }
887
+ subject(:input) { {} }
889
888
  subject(:output) { type.load(input) }
890
889
 
891
- its(:class){ should be(type) }
890
+ its(:class) { should be(type) }
892
891
 
893
- let(:load_context) { "$.some_root" }
892
+ let(:load_context) { '$.some_root' }
894
893
  it 'complains about the extra, with the right context' do
895
- expect{
896
- type.load( {one: 'one', three: 3} , load_context )
897
- }.to raise_error(Attributor::AttributorException,/Unknown key received: :three while loading \$\.some_root.key\(:three\)/)
894
+ expect do
895
+ type.load({ one: 'one', three: 3 }, load_context)
896
+ end.to raise_error(Attributor::AttributorException, /Unknown key received: :three while loading \$\.some_root.key\(:three\)/)
898
897
  end
899
898
  context 'properly sets them (and loads them) in the created instance' do
900
- let(:input){ {one: 'one', two: 2 } }
899
+ let(:input) { { one: 'one', two: 2 } }
901
900
 
902
- its(:keys){ should eq([:one, :two])}
903
- its([:one]){ should eq('one') }
904
- its([:two]){ should eq('2') } #loaded as a string
901
+ its(:keys) { should eq([:one, :two]) }
902
+ its([:one]) { should eq('one') }
903
+ its([:two]) { should eq('2') } # loaded as a string
905
904
  end
906
905
  context 'properly sets the default values when not passed in' do
907
- let(:input){ {one: 'one'} }
906
+ let(:input) { { one: 'one' } }
908
907
 
909
- its([:one]){ should eq('one') }
910
- its([:two]){ should eq('two') }
908
+ its([:one]) { should eq('one') }
909
+ its([:two]) { should eq('two') }
911
910
  end
912
911
  end
913
912
 
@@ -920,10 +919,10 @@ describe Attributor::Hash do
920
919
  end
921
920
  end
922
921
  end
923
- let(:input){ {one: 'one', three: 'tres' } }
922
+ let(:input) { { one: 'one', three: 'tres' } }
924
923
  subject(:output) { type.load(input) }
925
924
 
926
- its(:keys){ should eq([:one,:three])}
925
+ its(:keys) { should eq([:one, :three]) }
927
926
  end
928
927
  context 'inside an :other subkey' do
929
928
  let(:type) do
@@ -934,12 +933,12 @@ describe Attributor::Hash do
934
933
  end
935
934
  end
936
935
  end
937
- let(:input){ {one: 'one', three: 'tres' } }
936
+ let(:input) { { one: 'one', three: 'tres' } }
938
937
  subject(:output) { type.load(input) }
939
938
 
940
- its(:keys){ should =~ [:one,:other] }
939
+ its(:keys) { should match_array [:one, :other] }
941
940
  it 'has the key inside the :other hash' do
942
- expect(output[:other]).to eq({three: 'tres'})
941
+ expect(output[:other]).to eq(three: 'tres')
943
942
  end
944
943
  end
945
944
  end
@@ -955,20 +954,19 @@ describe Attributor::Hash do
955
954
  key 'CamelCase', Integer
956
955
  end
957
956
  end
958
- let(:input) { {'DOWNCASE' => 1, 'upcase' => 2, 'CamelCase' => 3} }
957
+ let(:input) { { 'DOWNCASE' => 1, 'upcase' => 2, 'CamelCase' => 3 } }
959
958
  subject(:output) { type.load(input) }
960
959
 
961
960
  context 'when defined' do
962
-
963
961
  it 'maps the incoming keys to defined keys, regardless of case' do
964
- output['downcase'].should eq(1)
965
- output['UPCASE'].should eq(2)
966
- output['CamelCase'].should eq(3)
962
+ expect(output['downcase']).to eq(1)
963
+ expect(output['UPCASE']).to eq(2)
964
+ expect(output['CamelCase']).to eq(3)
967
965
  end
968
966
  it 'has loaded the (internal) insensitive_map upon building the definition' do
969
967
  type.definition
970
- type.insensitive_map.should be_kind_of(::Hash)
971
- type.insensitive_map.keys.should =~ ["downcase","upcase","camelcase"]
968
+ expect(type.insensitive_map).to be_kind_of(::Hash)
969
+ expect(type.insensitive_map.keys).to match_array %w(downcase upcase camelcase)
972
970
  end
973
971
  end
974
972
 
@@ -977,7 +975,7 @@ describe Attributor::Hash do
977
975
 
978
976
  it 'skips the loading of the (internal) insensitive_map' do
979
977
  type.definition
980
- type.insensitive_map.should be_nil
978
+ expect(type.insensitive_map).to be_nil
981
979
  end
982
980
  end
983
981
  end
@@ -994,19 +992,19 @@ describe Attributor::Hash do
994
992
  end
995
993
  end
996
994
 
997
- let(:input) { {one: 'one', three: 3} }
995
+ let(:input) { { one: 'one', three: 3 } }
998
996
  subject(:output) { type.load(input) }
999
997
 
1000
998
  context 'that should be saved at the top level' do
1001
- its(:keys) { should =~ [:one, :two, :three] }
999
+ its(:keys) { should match_array [:one, :two, :three] }
1002
1000
 
1003
1001
  it 'loads the extra keys' do
1004
- output[:one].should eq('one')
1005
- output[:two].should eq('two')
1006
- output[:three].should eq('3')
1002
+ expect(output[:one]).to eq('one')
1003
+ expect(output[:two]).to eq('two')
1004
+ expect(output[:three]).to eq('3')
1007
1005
  end
1008
1006
 
1009
- its( :validate ){ should be_empty }
1007
+ its(:validate) { should be_empty }
1010
1008
  end
1011
1009
 
1012
1010
  context 'that should be grouped into a sub-hash' do
@@ -1016,25 +1014,24 @@ describe Attributor::Hash do
1016
1014
  end
1017
1015
  end
1018
1016
 
1019
- its(:keys) { should =~ [:one, :two, :options] }
1017
+ its(:keys) { should match_array [:one, :two, :options] }
1020
1018
  it 'loads the extra keys into :options sub-hash' do
1021
- output[:one].should eq('one')
1022
- output[:two].should eq('two')
1023
- output[:options].should eq({three: 3})
1019
+ expect(output[:one]).to eq('one')
1020
+ expect(output[:two]).to eq('two')
1021
+ expect(output[:options]).to eq(three: 3)
1024
1022
  end
1025
- its( :validate ){ should be_empty }
1023
+ its(:validate) { should be_empty }
1026
1024
 
1027
1025
  context 'with an options value already provided' do
1028
- its(:keys) { should =~ [:one, :two, :options] }
1029
- let(:input) { {one: 'one', three: 3, options: {four: 4}} }
1026
+ its(:keys) { should match_array [:one, :two, :options] }
1027
+ let(:input) { { one: 'one', three: 3, options: { four: 4 } } }
1030
1028
 
1031
1029
  it 'loads the extra keys into :options sub-hash' do
1032
- output[:one].should eq('one')
1033
- output[:two].should eq('two')
1034
- output[:options].should eq({three: 3, four: 4})
1030
+ expect(output[:one]).to eq('one')
1031
+ expect(output[:two]).to eq('two')
1032
+ expect(output[:options]).to eq(three: 3, four: 4)
1035
1033
  end
1036
- its( :validate ){ should be_empty }
1037
-
1034
+ its(:validate) { should be_empty }
1038
1035
  end
1039
1036
  end
1040
1037
 
@@ -1049,53 +1046,50 @@ describe Attributor::Hash do
1049
1046
  end
1050
1047
  end
1051
1048
 
1052
- let(:chicken) { {name: 'bob'} }
1049
+ let(:chicken) { { name: 'bob' } }
1053
1050
  subject(:hash) { type.new }
1054
1051
 
1055
1052
  context '#set' do
1056
1053
  it 'sets values into "extra" keys if appplicable' do
1057
- hash.should_not have_key('others')
1054
+ expect(hash).not_to have_key('others')
1058
1055
  hash.set 'foo', 'bar'
1059
- hash['others'].should have_key('foo')
1060
- hash.should have_key('others')
1061
- hash['others']['foo'].should eq('bar')
1056
+ expect(hash['others']).to have_key('foo')
1057
+ expect(hash).to have_key('others')
1058
+ expect(hash['others']['foo']).to eq('bar')
1062
1059
  end
1063
1060
 
1064
1061
  it 'loads values before saving into the contents' do
1065
1062
  hash.set 'chicken', chicken
1066
- hash['chicken'].should be_a(Chicken)
1063
+ expect(hash['chicken']).to be_a(Chicken)
1067
1064
  end
1068
1065
  end
1069
1066
 
1070
1067
  context '#get' do
1071
1068
  before do
1072
1069
  hash['chicken'] = chicken
1073
- hash['chicken'].should eq(chicken)
1070
+ expect(hash['chicken']).to eq(chicken)
1074
1071
  end
1075
1072
 
1076
1073
  it 'loads and updates the saved value' do
1077
- hash.get('chicken').should be_a(Chicken)
1078
- hash['chicken'].should be_a(Chicken)
1074
+ expect(hash.get('chicken')).to be_a(Chicken)
1075
+ expect(hash['chicken']).to be_a(Chicken)
1079
1076
  end
1080
1077
 
1081
1078
  it 'retrieves values from an "extra" key' do
1082
1079
  bar = double('bar')
1083
1080
  hash.set 'foo', bar
1084
- hash.get('others').get('foo').should be(bar)
1081
+ expect(hash.get('others').get('foo')).to be(bar)
1085
1082
 
1086
- hash.get('foo').should be(bar)
1083
+ expect(hash.get('foo')).to be(bar)
1087
1084
  end
1088
1085
 
1089
1086
  it 'does not set a key that is unset' do
1090
- hash.should_not have_key('id')
1091
- hash.get('id').should be(nil)
1092
- hash.should_not have_key('id')
1087
+ expect(hash).not_to have_key('id')
1088
+ expect(hash.get('id')).to be(nil)
1089
+ expect(hash).not_to have_key('id')
1093
1090
  end
1094
-
1095
1091
  end
1096
-
1097
1092
  end
1098
-
1099
1093
  end
1100
1094
 
1101
1095
  context '#merge' do
@@ -1120,6 +1114,8 @@ describe Attributor::Hash do
1120
1114
  it 'merges' do
1121
1115
  expect(merger.merge(good_mergee)).to eq(result)
1122
1116
  end
1117
+ end
1123
1118
 
1119
+ context Attributor::InvalidDefinition do
1124
1120
  end
1125
1121
  end