1
2
3
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
require 'spec_helper'
describe Hashie::Extensions::Coercion do
class Initializable
attr_reader :coerced, :value
def initialize(obj, coerced = false)
@coerced = coerced
@value = obj.class.to_s
end
def coerced?
!!@coerced
end
end
class Coercable < Initializable
def self.coerce(obj)
new(obj, true)
end
end
before(:each) do
class ExampleCoercableHash < Hash
include Hashie::Extensions::Coercion
include Hashie::Extensions::MergeInitializer
end
end
subject { ExampleCoercableHash }
let(:instance) { subject.new }
describe '#coerce_key' do
it { subject.should be_respond_to(:coerce_key) }
it 'runs through coerce on a specified key' do
subject.coerce_key :foo, Coercable
instance[:foo] = 'bar'
instance[:foo].should be_coerced
end
it 'supports an array of keys' do
subject.coerce_keys :foo, :bar, Coercable
instance[:foo] = 'bar'
instance[:bar] = 'bax'
instance[:foo].should be_coerced
instance[:bar].should be_coerced
end
it 'calls #new if no coerce method is available' do
subject.coerce_key :foo, Initializable
instance[:foo] = 'bar'
instance[:foo].value.should eq 'String'
instance[:foo].should_not be_coerced
end
it 'coerces when the merge initializer is used' do
subject.coerce_key :foo, Coercable
instance = subject.new(foo: 'bar')
instance[:foo].should be_coerced
end
context 'when #replace is used' do
before { subject.coerce_key :foo, :bar, Coercable }
let(:instance) do
subject.new(foo: 'bar').replace(foo: 'foz', bar: 'baz', hi: 'bye')
end
it 'coerces relevant keys' do
instance[:foo].should be_coerced
instance[:bar].should be_coerced
instance[:hi].should_not respond_to(:coerced?)
end
it 'sets correct values' do
instance[:hi].should eq 'bye'
end
end
context 'when used with a Mash' do
class UserMash < Hashie::Mash
end
class TweetMash < Hashie::Mash
include Hashie::Extensions::Coercion
coerce_key :user, UserMash
end
it 'coerces with instance initialization' do
tweet = TweetMash.new(user: { email: 'foo@bar.com' })
tweet[:user].should be_a(UserMash)
end
it 'coerces when setting with attribute style' do
tweet = TweetMash.new
tweet.user = { email: 'foo@bar.com' }
tweet[:user].should be_a(UserMash)
end
it 'coerces when setting with string index' do
tweet = TweetMash.new
tweet['user'] = { email: 'foo@bar.com' }
tweet[:user].should be_a(UserMash)
end
it 'coerces when setting with symbol index' do
tweet = TweetMash.new
tweet[:user] = { email: 'foo@bar.com' }
tweet[:user].should be_a(UserMash)
end
end
end
describe '#coerce_value' do
context 'with strict: true' do
it 'coerces any value of the exact right class' do
subject.coerce_value String, Coercable
instance[:foo] = 'bar'
instance[:bar] = 'bax'
instance[:hi] = :bye
instance[:foo].should be_coerced
instance[:bar].should be_coerced
instance[:hi].should_not respond_to(:coerced?)
end
it 'coerces values from a #replace call' do
subject.coerce_value String, Coercable
instance[:foo] = :bar
instance.replace(foo: 'bar', bar: 'bax')
instance[:foo].should be_coerced
instance[:bar].should be_coerced
end
it 'does not coerce superclasses' do
klass = Class.new(String)
subject.coerce_value klass, Coercable
instance[:foo] = 'bar'
instance[:foo].should_not be_kind_of(Coercable)
instance[:foo] = klass.new
instance[:foo].should be_kind_of(Coercable)
end
end
end
after(:each) do
Object.send(:remove_const, :ExampleCoercableHash)
end
end
|