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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
|
require 'spec_helper'
Hashie::Hash.class_eval do
def self.inherited(klass)
klass.instance_variable_set('@inheritance_test', true)
end
end
class LashTest < Hashie::Lash
property :first_name, :required => true
property :email, :required => true
property :count, :default => 0, :required => true
end
class SubclassedLash < LashTest
property :last_name, :required => true
end
describe LashTest, :wip => true do
context "without a required value" do
it "errors out when values are missing" do
expect { LashTest.new }.to raise_error(ArgumentError)
end
end
subject { LashTest.new(:first_name => 'Bob', :email => 'bob@example.com') }
it('subclasses Hashie::Hash') { should respond_to(:to_mash) }
it 'lists all set properties in inspect' do
subject.first_name = 'Bob'
subject.email = 'bob@example.com'
subject.inspect.should == '<#LashTest count=0 email="bob@example.com" first_name="Bob">'
end
its(:count) { should be_zero }
it { should respond_to(:first_name) }
it { should respond_to(:first_name=) }
it { should_not respond_to(:nonexistent) }
it 'errors out for a non-existent property' do
lambda { subject['nonexistent'] }.should raise_error(NoMethodError)
end
it 'errors out when attempting to set a required property to nil' do
lambda { subject.first_name = nil }.should raise_error(ArgumentError)
end
context 'writing to properties' do
it 'fails writing to a non-existent property using []=' do
lambda { subject['nonexistent'] = 123 }.should raise_error(NoMethodError)
end
it 'works for an existing property using []=' do
subject['first_name'] = 'Bob'
subject['first_name'].should == 'Bob'
subject[:first_name].should == 'Bob'
end
it 'works for an existing property using a method call' do
subject.first_name = 'Franklin'
subject.first_name.should == 'Franklin'
end
end
context 'reading from properties' do
it 'fails reading from a non-existent property using []' do
lambda { subject['nonexistent'] }.should raise_error(NoMethodError)
end
it "should be able to retrieve properties through blocks" do
subject["first_name"] = "Aiden"
value = nil
subject.[]("first_name") { |v| value = v }
value.should == "Aiden"
end
it "should be able to retrieve properties through blocks with method calls" do
subject["first_name"] = "Frodo"
value = nil
subject.first_name { |v| value = v }
value.should == "Frodo"
end
end
describe '.new' do
it 'fails with non-existent properties' do
lambda { described_class.new(:bork => '') }.should raise_error(NoMethodError)
end
it 'should set properties that it is able to' do
obj = described_class.new :first_name => 'Michael', :email => 'michael@example.com'
obj.first_name.should == 'Michael'
end
it 'does not accept nil' do
lambda { described_class.new(nil) }.should raise_error(ArgumentError)
end
it 'accepts block to define a global default' do
obj = described_class.new { |hash, key| key.to_s.upcase }
obj.first_name.should == 'FIRST_NAME'
obj.count.should be_zero
end
end
describe 'properties' do
it 'lists defined properties' do
described_class.properties.should == Set.new([:first_name, :email, :count])
end
it 'checks if a property exists' do
described_class.property?('first_name').should be_true
described_class.property?(:first_name).should be_true
end
it 'doesnt include property from subclass' do
described_class.property?(:last_name).should be_false
end
it 'lists declared defaults' do
described_class.defaults.should == { :count => 0 }
end
end
end
describe Hashie::Lash, 'inheritance' do
before do
@top = Class.new(Hashie::Lash)
@middle = Class.new(@top)
@bottom = Class.new(@middle)
end
it 'reports empty properties when nothing defined' do
@top.properties.should be_empty
@top.defaults.should be_empty
end
it 'inherits properties downwards' do
@top.property :echo
@middle.properties.should include(:echo)
@bottom.properties.should include(:echo)
end
it 'doesnt inherit properties upwards' do
@middle.property :echo
@top.properties.should_not include(:echo)
@bottom.properties.should include(:echo)
end
it 'allows overriding a default on an existing property' do
@top.property :echo
@middle.property :echo, :default => 123
@bottom.properties.to_a.should == [:echo]
@bottom.new.echo.should == 123
end
it 'allows clearing an existing default' do
@top.property :echo
@middle.property :echo, :default => 123
@bottom.property :echo
@bottom.properties.to_a.should == [:echo]
@bottom.new.echo.should be_nil
end
it 'should allow nil defaults' do
@bottom.property :echo, :default => nil
@bottom.new.should have_key('echo')
end
end
describe SubclassedLash do
subject { SubclassedLash.new(:first_name => 'Bob', :email => 'bob@example.com', :last_name => 'Example') }
its(:count) { should be_zero }
it { should respond_to(:first_name) }
it { should respond_to(:first_name=) }
it { should respond_to(:last_name) }
it { should respond_to(:last_name=) }
it 'has one additional property' do
described_class.property?(:last_name).should be_true
end
it "didn't override superclass inheritance logic" do
described_class.instance_variable_get('@inheritance_test').should be_true
end
end
|