must_be 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,225 @@
1
+ require 'spec_helper'
2
+
3
+ describe MustBe do
4
+ include MustBeExampleHelper
5
+
6
+ describe 'Module#attr_typed' do
7
+ context "when updating" do
8
+ module ModuleWhoUsesAttrTyped
9
+ attr_typed :int, Bignum, Fixnum
10
+ attr_typed :positive_int, Bignum, Fixnum do |n|
11
+ n > 0
12
+ end
13
+ attr_typed :non_nil
14
+ end
15
+
16
+ class UsesAttrTyped
17
+ include ModuleWhoUsesAttrTyped
18
+
19
+ attr_typed :float, Float
20
+ attr_typed :empty, &:empty?
21
+ attr_typed :collection, Array, Hash, Range
22
+ end
23
+
24
+ subject { UsesAttrTyped.new }
25
+
26
+ context "against one type constraint" do
27
+ it "should not notify if new value has the type" do
28
+ subject.float = 23.3
29
+ subject.float.should == 23.3
30
+ should_not notify
31
+ end
32
+
33
+ it "should notify if new value does not have the type" do
34
+ subject.float = 23
35
+ should notify("attribute `float' must be a Float,"\
36
+ " but value 23 is a Fixnum")
37
+ end
38
+ end
39
+
40
+ context "against two type constraints" do
41
+ it "should not notify if new value matches one of the constraints" do
42
+ subject.int = 56
43
+ should_not notify
44
+ end
45
+
46
+ it "should notify if new value does not match either constraint " do
47
+ subject.int = 56.6
48
+ should notify("attribute `int' must be a Bignum or Fixnum,"\
49
+ " but value 56.6 is a Float")
50
+ end
51
+ end
52
+
53
+ context "against multiple type constraints" do
54
+ it "should not notify if new value matches last constraint" do
55
+ subject.collection = 1..3
56
+ should_not notify
57
+ end
58
+
59
+ it "should notify if new value matches none of the constraints" do
60
+ subject.collection = :scalar
61
+ should notify("attribute `collection' must be a one of"\
62
+ " [Array, Hash, Range], but value :scalar is a Symbol")
63
+ end
64
+ end
65
+
66
+ context "against a block constraint" do
67
+ it "should not notify if block[value] is true" do
68
+ subject.empty = []
69
+ should_not notify
70
+ end
71
+
72
+ it "should notify if block[value] is not true" do
73
+ subject.empty = [:not, :empty]
74
+ should notify("attribute `empty' cannot be [:not, :empty]")
75
+ end
76
+ end
77
+
78
+ context "against two types and a block constraint" do
79
+ it "should not notify if new value matches one of the types"\
80
+ " and block[value] is true" do
81
+ subject.positive_int = 45
82
+ should_not notify
83
+ end
84
+
85
+ it "should notify if new value does not match one of the types" do
86
+ subject.positive_int = 87.6
87
+ should notify("attribute `positive_int' must be a Bignum"\
88
+ " or Fixnum, but value 87.6 is a Float")
89
+ end
90
+
91
+ it "should notify if block[value] is not true" do
92
+ subject.positive_int = -11
93
+ should notify("attribute `positive_int' cannot be -11")
94
+ end
95
+ end
96
+
97
+ context "against no listed contraint" do
98
+ it "should not notify if new value is non-nil" do
99
+ subject.non_nil = false
100
+ should_not notify
101
+ end
102
+
103
+ it "should notify if new value is nil" do
104
+ subject.non_nil = nil
105
+ should notify("attribute `non_nil' cannot be nil")
106
+ end
107
+ end
108
+ end
109
+
110
+ context "when called twice with the same symbol" do
111
+ class AttrTypedCalledTwiceForSameSymbol
112
+ attr_typed :twice, Symbol
113
+ attr_typed :twice, String
114
+ end
115
+
116
+ subject { AttrTypedCalledTwiceForSameSymbol.new }
117
+
118
+ it "second call should override first" do
119
+ subject.twice = :symbol
120
+ should notify("attribute `twice' must be a String,"\
121
+ " but value :symbol is a Symbol")
122
+ end
123
+ end
124
+
125
+ context "when called with bad arguments" do
126
+ subject { Class.new }
127
+
128
+ context "when symbol is bad" do
129
+ it "should raise if symbol cannot be converted #to_sym" do
130
+ expect do
131
+ subject.attr_typed [], Object
132
+ end.should raise_error(TypeError, "[] is not a symbol")
133
+ end
134
+
135
+ it "should raise if symbol is a Fixnum" do
136
+ expect do
137
+ subject.attr_typed 111, Object
138
+ end.should raise_error(TypeError, "111 is not a symbol")
139
+ end
140
+
141
+ it "should be fine if symbol is a String" do
142
+ expect do
143
+ subject.attr_typed "string", Object
144
+ end.should_not raise_error
145
+ end
146
+ end
147
+
148
+ context "when types is bad" do
149
+ it "should raise if any type is an array" do
150
+ expect do
151
+ subject.attr_typed :prop, [Array, Object]
152
+ end.should raise_error(TypeError, "class or module required")
153
+ end
154
+
155
+ it "should raise if any type is a String" do
156
+ expect do
157
+ subject.attr_typed :prop, "string"
158
+ end.should raise_error(TypeError, "class or module required")
159
+ end
160
+ end
161
+ end
162
+
163
+ context "after disabling" do
164
+ before do
165
+ @enabled_class = Class.new
166
+ @enabled_class.attr_typed :prop, Symbol
167
+ @enabled_instance = @enabled_class.new
168
+ end
169
+
170
+ before_disable_after_enable
171
+
172
+ context "when .attr_typed was called while still enabled" do
173
+ it "should not notify" do
174
+ @enabled_instance.prop = 91
175
+ @enabled_instance.prop.should == 91
176
+ should_not notify
177
+ end
178
+
179
+ context "after being re-enabled" do
180
+ before do
181
+ MustBe.enable
182
+ end
183
+
184
+ it "should notify again" do
185
+ @enabled_instance.prop = 91
186
+ should notify("attribute `prop' must be a Symbol,"\
187
+ " but value 91 is a Fixnum")
188
+ end
189
+ end
190
+ end
191
+
192
+ context "when .attr_typed is called" do
193
+ before do
194
+ @disabled_class = Class.new
195
+ @disabled_class.attr_typed :prop, Symbol
196
+ @disabled_instance = @disabled_class.new
197
+ end
198
+
199
+ it "should not notify" do
200
+ @disabled_instance.prop = 91
201
+ @disabled_instance.prop.should == 91
202
+ should_not notify
203
+ end
204
+
205
+ context "after being re-enabled" do
206
+ before do
207
+ MustBe.enable
208
+ end
209
+
210
+ it "should still not notify" do
211
+ @disabled_instance.prop = 91
212
+ should_not notify
213
+ end
214
+
215
+ it ".attr_typed should be re-enabled" do
216
+ @disabled_class.attr_typed :prop, Symbol
217
+ @disabled_instance.prop = 91
218
+ should notify("attribute `prop' must be a Symbol,"\
219
+ " but value 91 is a Fixnum")
220
+ end
221
+ end
222
+ end
223
+ end
224
+ end
225
+ end