must_be 1.0.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.
@@ -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