hashie 2.0.5 → 2.1.0
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.
- 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)
|