hashie 2.0.5 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rubocop.yml +36 -0
- data/.travis.yml +13 -6
- data/CHANGELOG.md +40 -21
- data/CONTRIBUTING.md +110 -19
- data/Gemfile +9 -0
- data/LICENSE +1 -1
- data/README.md +347 -0
- data/Rakefile +4 -2
- data/hashie.gemspec +4 -7
- data/lib/hashie.rb +3 -0
- data/lib/hashie/clash.rb +19 -19
- data/lib/hashie/dash.rb +47 -39
- data/lib/hashie/extensions/coercion.rb +10 -6
- data/lib/hashie/extensions/deep_fetch.rb +29 -0
- data/lib/hashie/extensions/deep_merge.rb +15 -6
- data/lib/hashie/extensions/ignore_undeclared.rb +41 -0
- data/lib/hashie/extensions/indifferent_access.rb +37 -10
- data/lib/hashie/extensions/key_conversion.rb +3 -3
- data/lib/hashie/extensions/method_access.rb +9 -9
- data/lib/hashie/hash.rb +7 -7
- data/lib/hashie/hash_extensions.rb +5 -7
- data/lib/hashie/mash.rb +38 -31
- data/lib/hashie/rash.rb +119 -0
- data/lib/hashie/trash.rb +31 -22
- data/lib/hashie/version.rb +1 -1
- data/spec/hashie/clash_spec.rb +43 -45
- data/spec/hashie/dash_spec.rb +115 -53
- data/spec/hashie/extensions/coercion_spec.rb +42 -37
- data/spec/hashie/extensions/deep_fetch_spec.rb +70 -0
- data/spec/hashie/extensions/deep_merge_spec.rb +11 -9
- data/spec/hashie/extensions/ignore_undeclared_spec.rb +23 -0
- data/spec/hashie/extensions/indifferent_access_spec.rb +117 -64
- data/spec/hashie/extensions/key_conversion_spec.rb +28 -27
- data/spec/hashie/extensions/merge_initializer_spec.rb +13 -10
- data/spec/hashie/extensions/method_access_spec.rb +49 -40
- data/spec/hashie/hash_spec.rb +25 -13
- data/spec/hashie/mash_spec.rb +243 -187
- data/spec/hashie/rash_spec.rb +44 -0
- data/spec/hashie/trash_spec.rb +81 -43
- data/spec/hashie/version_spec.rb +7 -0
- data/spec/spec_helper.rb +0 -4
- metadata +27 -78
- data/.document +0 -5
- data/README.markdown +0 -236
- data/lib/hashie/extensions/structure.rb +0 -47
data/lib/hashie/version.rb
CHANGED
data/spec/hashie/clash_spec.rb
CHANGED
@@ -1,50 +1,48 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Hashie::Clash do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
@c[:foo].should be_nil
|
48
|
-
@c[:hello].should be_nil
|
4
|
+
subject { Hashie::Clash.new }
|
5
|
+
|
6
|
+
it 'is able to set an attribute via method_missing' do
|
7
|
+
subject.foo('bar')
|
8
|
+
subject[:foo].should eq 'bar'
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'is able to set multiple attributes' do
|
12
|
+
subject.foo('bar').baz('wok')
|
13
|
+
subject.should eq(foo: 'bar', baz: 'wok')
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'converts multiple arguments into an array' do
|
17
|
+
subject.foo(1, 2, 3)
|
18
|
+
subject[:foo].should eq [1, 2, 3]
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'is able to use bang notation to create a new Clash on a key' do
|
22
|
+
subject.foo!
|
23
|
+
subject[:foo].should be_kind_of(Hashie::Clash)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'is able to chain onto the new Clash when using bang notation' do
|
27
|
+
subject.foo!.bar('abc').baz(123)
|
28
|
+
subject.should eq(foo: { bar: 'abc', baz: 123 })
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'is able to jump back up to the parent in the chain with #_end!' do
|
32
|
+
subject.foo!.bar('abc')._end!.baz(123)
|
33
|
+
subject.should eq(foo: { bar: 'abc' }, baz: 123)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'merges rather than replaces existing keys' do
|
37
|
+
subject.where(abc: 'def').where(hgi: 123)
|
38
|
+
subject.should eq(where: { abc: 'def', hgi: 123 })
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'is able to replace all of its own keys with #replace' do
|
42
|
+
subject.foo(:bar).hello(:world)
|
43
|
+
subject.replace(baz: 123, hgi: 123).should eq(baz: 123, hgi: 123)
|
44
|
+
subject.should eq(baz: 123, hgi: 123)
|
45
|
+
subject[:foo].should be_nil
|
46
|
+
subject[:hello].should be_nil
|
49
47
|
end
|
50
48
|
end
|
data/spec/hashie/dash_spec.rb
CHANGED
@@ -7,41 +7,45 @@ Hashie::Hash.class_eval do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
class DashTest < Hashie::Dash
|
10
|
-
property :first_name, :
|
10
|
+
property :first_name, required: true
|
11
11
|
property :email
|
12
|
-
property :count, :
|
12
|
+
property :count, default: 0
|
13
13
|
end
|
14
14
|
|
15
15
|
class DashNoRequiredTest < Hashie::Dash
|
16
16
|
property :first_name
|
17
17
|
property :email
|
18
|
-
property :count, :
|
18
|
+
property :count, default: 0
|
19
|
+
end
|
20
|
+
|
21
|
+
class PropertyBangTest < Hashie::Dash
|
22
|
+
property :important!
|
19
23
|
end
|
20
24
|
|
21
25
|
class Subclassed < DashTest
|
22
|
-
property :last_name, :
|
26
|
+
property :last_name, required: true
|
23
27
|
end
|
24
28
|
|
25
29
|
class DashDefaultTest < Hashie::Dash
|
26
|
-
property :aliases, :
|
30
|
+
property :aliases, default: ['Snake']
|
27
31
|
end
|
28
32
|
|
29
33
|
class DeferredTest < Hashie::Dash
|
30
|
-
property :created_at, :
|
34
|
+
property :created_at, default: proc { Time.now }
|
31
35
|
end
|
32
36
|
|
33
37
|
describe DashTest do
|
34
38
|
|
35
|
-
subject { DashTest.new(:
|
39
|
+
subject { DashTest.new(first_name: 'Bob', email: 'bob@example.com') }
|
36
40
|
|
37
41
|
it('subclasses Hashie::Hash') { should respond_to(:to_mash) }
|
38
42
|
|
39
|
-
its(:to_s) { should
|
43
|
+
its(:to_s) { should eq '#<DashTest count=0 email="bob@example.com" first_name="Bob">' }
|
40
44
|
|
41
45
|
it 'lists all set properties in inspect' do
|
42
46
|
subject.first_name = 'Bob'
|
43
47
|
subject.email = 'bob@example.com'
|
44
|
-
subject.inspect.should
|
48
|
+
subject.inspect.should eq '#<DashTest count=0 email="bob@example.com" first_name="Bob">'
|
45
49
|
end
|
46
50
|
|
47
51
|
its(:count) { should be_zero }
|
@@ -59,7 +63,6 @@ describe DashTest do
|
|
59
63
|
end
|
60
64
|
|
61
65
|
context 'writing to properties' do
|
62
|
-
|
63
66
|
it 'fails writing a required property to nil' do
|
64
67
|
lambda { subject.first_name = nil }.should raise_error(ArgumentError)
|
65
68
|
end
|
@@ -74,13 +77,13 @@ describe DashTest do
|
|
74
77
|
|
75
78
|
it 'works for an existing property using []=' do
|
76
79
|
subject['first_name'] = 'Bob'
|
77
|
-
subject['first_name'].should
|
78
|
-
subject[:first_name].should
|
80
|
+
subject['first_name'].should eq 'Bob'
|
81
|
+
subject[:first_name].should eq 'Bob'
|
79
82
|
end
|
80
83
|
|
81
84
|
it 'works for an existing property using a method call' do
|
82
85
|
subject.first_name = 'Franklin'
|
83
|
-
subject.first_name.should
|
86
|
+
subject.first_name.should eq 'Franklin'
|
84
87
|
end
|
85
88
|
end
|
86
89
|
|
@@ -89,40 +92,40 @@ describe DashTest do
|
|
89
92
|
lambda { subject['nonexistent'] }.should raise_error(NoMethodError)
|
90
93
|
end
|
91
94
|
|
92
|
-
it
|
93
|
-
subject[
|
95
|
+
it 'is able to retrieve properties through blocks' do
|
96
|
+
subject['first_name'] = 'Aiden'
|
94
97
|
value = nil
|
95
|
-
subject.[](
|
96
|
-
value.should
|
98
|
+
subject.[]('first_name') { |v| value = v }
|
99
|
+
value.should eq 'Aiden'
|
97
100
|
end
|
98
101
|
|
99
|
-
it
|
100
|
-
subject[
|
102
|
+
it 'is able to retrieve properties through blocks with method calls' do
|
103
|
+
subject['first_name'] = 'Frodo'
|
101
104
|
value = nil
|
102
105
|
subject.first_name { |v| value = v }
|
103
|
-
value.should
|
106
|
+
value.should eq 'Frodo'
|
104
107
|
end
|
105
108
|
end
|
106
109
|
|
107
110
|
context 'reading from deferred properties' do
|
108
|
-
it '
|
111
|
+
it 'evaluates proc after initial read' do
|
109
112
|
DeferredTest.new['created_at'].should be_instance_of(Time)
|
110
113
|
end
|
111
114
|
|
112
|
-
it
|
115
|
+
it 'does not evalute proc after subsequent reads' do
|
113
116
|
deferred = DeferredTest.new
|
114
|
-
deferred['created_at'].object_id.should
|
117
|
+
deferred['created_at'].object_id.should eq deferred['created_at'].object_id
|
115
118
|
end
|
116
119
|
end
|
117
120
|
|
118
|
-
describe '
|
121
|
+
describe '#new' do
|
119
122
|
it 'fails with non-existent properties' do
|
120
|
-
lambda { described_class.new(:
|
123
|
+
lambda { described_class.new(bork: '') }.should raise_error(NoMethodError)
|
121
124
|
end
|
122
125
|
|
123
|
-
it '
|
124
|
-
obj = described_class.new :
|
125
|
-
obj.first_name.should
|
126
|
+
it 'sets properties that it is able to' do
|
127
|
+
obj = described_class.new first_name: 'Michael'
|
128
|
+
obj.first_name.should eq 'Michael'
|
126
129
|
end
|
127
130
|
|
128
131
|
it 'accepts nil' do
|
@@ -131,25 +134,83 @@ describe DashTest do
|
|
131
134
|
|
132
135
|
it 'accepts block to define a global default' do
|
133
136
|
obj = described_class.new { |hash, key| key.to_s.upcase }
|
134
|
-
obj.first_name.should
|
137
|
+
obj.first_name.should eq 'FIRST_NAME'
|
135
138
|
obj.count.should be_zero
|
136
139
|
end
|
137
140
|
|
138
|
-
it
|
141
|
+
it 'fails when required values are missing' do
|
139
142
|
expect { DashTest.new }.to raise_error(ArgumentError)
|
140
143
|
end
|
141
144
|
|
142
|
-
it
|
145
|
+
it 'does not overwrite default values' do
|
143
146
|
obj1 = DashDefaultTest.new
|
144
|
-
obj1.aliases <<
|
147
|
+
obj1.aliases << 'El Rey'
|
145
148
|
obj2 = DashDefaultTest.new
|
146
|
-
obj2.aliases.should_not include
|
149
|
+
obj2.aliases.should_not include 'El Rey'
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
describe '#merge' do
|
154
|
+
it 'creates a new instance of the Dash' do
|
155
|
+
new_dash = subject.merge(first_name: 'Robert')
|
156
|
+
subject.object_id.should_not eq new_dash.object_id
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'merges the given hash' do
|
160
|
+
new_dash = subject.merge(first_name: 'Robert', email: 'robert@example.com')
|
161
|
+
new_dash.first_name.should eq 'Robert'
|
162
|
+
new_dash.email.should eq 'robert@example.com'
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'fails with non-existent properties' do
|
166
|
+
expect { subject.merge(middle_name: 'James') }.to raise_error(NoMethodError)
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'errors out when attempting to set a required property to nil' do
|
170
|
+
expect { subject.merge(first_name: nil) }.to raise_error(ArgumentError)
|
171
|
+
end
|
172
|
+
|
173
|
+
context 'given a block' do
|
174
|
+
it "sets merged key's values to the block's return value" do
|
175
|
+
subject.merge(first_name: 'Jim') do |key, oldval, newval|
|
176
|
+
"#{key}: #{newval} #{oldval}"
|
177
|
+
end.first_name.should eq 'first_name: Jim Bob'
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
describe '#merge!' do
|
183
|
+
it 'modifies the existing instance of the Dash' do
|
184
|
+
original_dash = subject.merge!(first_name: 'Robert')
|
185
|
+
subject.object_id.should eq original_dash.object_id
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'merges the given hash' do
|
189
|
+
subject.merge!(first_name: 'Robert', email: 'robert@example.com')
|
190
|
+
subject.first_name.should eq 'Robert'
|
191
|
+
subject.email.should eq 'robert@example.com'
|
192
|
+
end
|
193
|
+
|
194
|
+
it 'fails with non-existent properties' do
|
195
|
+
expect { subject.merge!(middle_name: 'James') }.to raise_error(NoMethodError)
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'errors out when attempting to set a required property to nil' do
|
199
|
+
expect { subject.merge!(first_name: nil) }.to raise_error(ArgumentError)
|
200
|
+
end
|
201
|
+
|
202
|
+
context 'given a block' do
|
203
|
+
it "sets merged key's values to the block's return value" do
|
204
|
+
subject.merge!(first_name: 'Jim') do |key, oldval, newval|
|
205
|
+
"#{key}: #{newval} #{oldval}"
|
206
|
+
end.first_name.should eq 'first_name: Jim Bob'
|
207
|
+
end
|
147
208
|
end
|
148
209
|
end
|
149
210
|
|
150
211
|
describe 'properties' do
|
151
212
|
it 'lists defined properties' do
|
152
|
-
described_class.properties.should
|
213
|
+
described_class.properties.should eq Set.new([:first_name, :email, :count])
|
153
214
|
end
|
154
215
|
|
155
216
|
it 'checks if a property exists' do
|
@@ -167,33 +228,36 @@ describe DashTest do
|
|
167
228
|
end
|
168
229
|
|
169
230
|
it 'lists declared defaults' do
|
170
|
-
described_class.defaults.should
|
231
|
+
described_class.defaults.should eq(count: 0)
|
232
|
+
end
|
233
|
+
|
234
|
+
it 'allows properties that end in bang' do
|
235
|
+
PropertyBangTest.property?(:important!).should be_true
|
171
236
|
end
|
172
237
|
end
|
173
238
|
|
174
239
|
describe '#replace' do
|
175
|
-
before { subject.replace(:
|
240
|
+
before { subject.replace(first_name: 'Cain') }
|
176
241
|
|
177
242
|
it 'return self' do
|
178
|
-
subject.replace(:email =>
|
179
|
-
should == {"email" => "bar", "count" => 0}
|
243
|
+
subject.replace(email: 'bar').to_hash.should eq('email' => 'bar', 'count' => 0)
|
180
244
|
end
|
181
245
|
|
182
246
|
it 'sets all specified keys to their corresponding values' do
|
183
|
-
subject.first_name.should
|
247
|
+
subject.first_name.should eq 'Cain'
|
184
248
|
end
|
185
249
|
|
186
250
|
it 'leaves only specified keys and keys with default values' do
|
187
|
-
subject.keys.sort.should
|
251
|
+
subject.keys.sort.should eq %w(count first_name)
|
188
252
|
subject.email.should be_nil
|
189
|
-
subject.count.should
|
253
|
+
subject.count.should eq 0
|
190
254
|
end
|
191
255
|
|
192
256
|
context 'when replacing keys with default values' do
|
193
|
-
before { subject.replace(:
|
257
|
+
before { subject.replace(count: 3) }
|
194
258
|
|
195
259
|
it 'sets all specified keys to their corresponding values' do
|
196
|
-
subject.count.should
|
260
|
+
subject.count.should eq 3
|
197
261
|
end
|
198
262
|
end
|
199
263
|
end
|
@@ -225,29 +289,28 @@ describe Hashie::Dash, 'inheritance' do
|
|
225
289
|
|
226
290
|
it 'allows overriding a default on an existing property' do
|
227
291
|
@top.property :echo
|
228
|
-
@middle.property :echo, :
|
229
|
-
@bottom.properties.to_a.should
|
230
|
-
@bottom.new.echo.should
|
292
|
+
@middle.property :echo, default: 123
|
293
|
+
@bottom.properties.to_a.should eq [:echo]
|
294
|
+
@bottom.new.echo.should eq 123
|
231
295
|
end
|
232
296
|
|
233
297
|
it 'allows clearing an existing default' do
|
234
298
|
@top.property :echo
|
235
|
-
@middle.property :echo, :
|
299
|
+
@middle.property :echo, default: 123
|
236
300
|
@bottom.property :echo
|
237
|
-
@bottom.properties.to_a.should
|
301
|
+
@bottom.properties.to_a.should eq [:echo]
|
238
302
|
@bottom.new.echo.should be_nil
|
239
303
|
end
|
240
304
|
|
241
|
-
it '
|
242
|
-
@bottom.property :echo, :
|
305
|
+
it 'allows nil defaults' do
|
306
|
+
@bottom.property :echo, default: nil
|
243
307
|
@bottom.new.should have_key('echo')
|
244
308
|
end
|
245
309
|
|
246
310
|
end
|
247
311
|
|
248
312
|
describe Subclassed do
|
249
|
-
|
250
|
-
subject { Subclassed.new(:first_name => 'Bob', :last_name => 'McNob', :email => 'bob@example.com') }
|
313
|
+
subject { Subclassed.new(first_name: 'Bob', last_name: 'McNob', email: 'bob@example.com') }
|
251
314
|
|
252
315
|
its(:count) { should be_zero }
|
253
316
|
|
@@ -263,5 +326,4 @@ describe Subclassed do
|
|
263
326
|
it "didn't override superclass inheritance logic" do
|
264
327
|
described_class.instance_variable_get('@inheritance_test').should be_true
|
265
328
|
end
|
266
|
-
|
267
329
|
end
|
@@ -2,12 +2,16 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Hashie::Extensions::Coercion do
|
4
4
|
class Initializable
|
5
|
+
attr_reader :coerced, :value
|
6
|
+
|
5
7
|
def initialize(obj, coerced = false)
|
6
8
|
@coerced = coerced
|
7
9
|
@value = obj.class.to_s
|
8
10
|
end
|
9
|
-
|
10
|
-
|
11
|
+
|
12
|
+
def coerced?
|
13
|
+
!!@coerced
|
14
|
+
end
|
11
15
|
end
|
12
16
|
|
13
17
|
class Coercable < Initializable
|
@@ -22,39 +26,41 @@ describe Hashie::Extensions::Coercion do
|
|
22
26
|
include Hashie::Extensions::MergeInitializer
|
23
27
|
end
|
24
28
|
end
|
29
|
+
|
25
30
|
subject { ExampleCoercableHash }
|
26
|
-
let(:instance){ subject.new }
|
27
31
|
|
28
|
-
|
32
|
+
let(:instance) { subject.new }
|
33
|
+
|
34
|
+
describe '#coerce_key' do
|
29
35
|
it { subject.should be_respond_to(:coerce_key) }
|
30
36
|
|
31
|
-
it '
|
37
|
+
it 'runs through coerce on a specified key' do
|
32
38
|
subject.coerce_key :foo, Coercable
|
33
39
|
|
34
|
-
instance[:foo] =
|
40
|
+
instance[:foo] = 'bar'
|
35
41
|
instance[:foo].should be_coerced
|
36
42
|
end
|
37
43
|
|
38
|
-
it
|
44
|
+
it 'supports an array of keys' do
|
39
45
|
subject.coerce_keys :foo, :bar, Coercable
|
40
46
|
|
41
|
-
instance[:foo] =
|
42
|
-
instance[:bar] =
|
47
|
+
instance[:foo] = 'bar'
|
48
|
+
instance[:bar] = 'bax'
|
43
49
|
instance[:foo].should be_coerced
|
44
50
|
instance[:bar].should be_coerced
|
45
51
|
end
|
46
52
|
|
47
|
-
it '
|
53
|
+
it 'calls #new if no coerce method is available' do
|
48
54
|
subject.coerce_key :foo, Initializable
|
49
55
|
|
50
|
-
instance[:foo] =
|
51
|
-
instance[:foo].value.should
|
56
|
+
instance[:foo] = 'bar'
|
57
|
+
instance[:foo].value.should eq 'String'
|
52
58
|
instance[:foo].should_not be_coerced
|
53
59
|
end
|
54
60
|
|
55
|
-
it
|
61
|
+
it 'coerces when the merge initializer is used' do
|
56
62
|
subject.coerce_key :foo, Coercable
|
57
|
-
instance = subject.new(:
|
63
|
+
instance = subject.new(foo: 'bar')
|
58
64
|
|
59
65
|
instance[:foo].should be_coerced
|
60
66
|
end
|
@@ -63,22 +69,21 @@ describe Hashie::Extensions::Coercion do
|
|
63
69
|
before { subject.coerce_key :foo, :bar, Coercable }
|
64
70
|
|
65
71
|
let(:instance) do
|
66
|
-
subject.new(:foo
|
67
|
-
replace(:foo => "foz", :bar => "baz", :hi => "bye")
|
72
|
+
subject.new(foo: 'bar').replace(foo: 'foz', bar: 'baz', hi: 'bye')
|
68
73
|
end
|
69
74
|
|
70
|
-
it
|
75
|
+
it 'coerces relevant keys' do
|
71
76
|
instance[:foo].should be_coerced
|
72
77
|
instance[:bar].should be_coerced
|
73
78
|
instance[:hi].should_not respond_to(:coerced?)
|
74
79
|
end
|
75
80
|
|
76
|
-
it
|
77
|
-
instance[:hi].should
|
81
|
+
it 'sets correct values' do
|
82
|
+
instance[:hi].should eq 'bye'
|
78
83
|
end
|
79
84
|
end
|
80
85
|
|
81
|
-
context
|
86
|
+
context 'when used with a Mash' do
|
82
87
|
class UserMash < Hashie::Mash
|
83
88
|
end
|
84
89
|
class TweetMash < Hashie::Mash
|
@@ -86,58 +91,58 @@ describe Hashie::Extensions::Coercion do
|
|
86
91
|
coerce_key :user, UserMash
|
87
92
|
end
|
88
93
|
|
89
|
-
it
|
90
|
-
tweet = TweetMash.new(:
|
94
|
+
it 'coerces with instance initialization' do
|
95
|
+
tweet = TweetMash.new(user: { email: 'foo@bar.com' })
|
91
96
|
tweet[:user].should be_a(UserMash)
|
92
97
|
end
|
93
98
|
|
94
|
-
it
|
99
|
+
it 'coerces when setting with attribute style' do
|
95
100
|
tweet = TweetMash.new
|
96
|
-
tweet.user = {:
|
101
|
+
tweet.user = { email: 'foo@bar.com' }
|
97
102
|
tweet[:user].should be_a(UserMash)
|
98
103
|
end
|
99
104
|
|
100
|
-
it
|
105
|
+
it 'coerces when setting with string index' do
|
101
106
|
tweet = TweetMash.new
|
102
|
-
tweet['user'] = {:
|
107
|
+
tweet['user'] = { email: 'foo@bar.com' }
|
103
108
|
tweet[:user].should be_a(UserMash)
|
104
109
|
end
|
105
110
|
|
106
|
-
it
|
111
|
+
it 'coerces when setting with symbol index' do
|
107
112
|
tweet = TweetMash.new
|
108
|
-
tweet[:user] = {:
|
113
|
+
tweet[:user] = { email: 'foo@bar.com' }
|
109
114
|
tweet[:user].should be_a(UserMash)
|
110
115
|
end
|
111
116
|
end
|
112
117
|
end
|
113
118
|
|
114
|
-
describe '
|
115
|
-
context 'with :
|
116
|
-
it '
|
119
|
+
describe '#coerce_value' do
|
120
|
+
context 'with strict: true' do
|
121
|
+
it 'coerces any value of the exact right class' do
|
117
122
|
subject.coerce_value String, Coercable
|
118
123
|
|
119
|
-
instance[:foo] =
|
120
|
-
instance[:bar] =
|
124
|
+
instance[:foo] = 'bar'
|
125
|
+
instance[:bar] = 'bax'
|
121
126
|
instance[:hi] = :bye
|
122
127
|
instance[:foo].should be_coerced
|
123
128
|
instance[:bar].should be_coerced
|
124
129
|
instance[:hi].should_not respond_to(:coerced?)
|
125
130
|
end
|
126
131
|
|
127
|
-
it '
|
132
|
+
it 'coerces values from a #replace call' do
|
128
133
|
subject.coerce_value String, Coercable
|
129
134
|
|
130
135
|
instance[:foo] = :bar
|
131
|
-
instance.replace(:
|
136
|
+
instance.replace(foo: 'bar', bar: 'bax')
|
132
137
|
instance[:foo].should be_coerced
|
133
138
|
instance[:bar].should be_coerced
|
134
139
|
end
|
135
140
|
|
136
|
-
it '
|
141
|
+
it 'does not coerce superclasses' do
|
137
142
|
klass = Class.new(String)
|
138
143
|
subject.coerce_value klass, Coercable
|
139
144
|
|
140
|
-
instance[:foo] =
|
145
|
+
instance[:foo] = 'bar'
|
141
146
|
instance[:foo].should_not be_kind_of(Coercable)
|
142
147
|
instance[:foo] = klass.new
|
143
148
|
instance[:foo].should be_kind_of(Coercable)
|