chattr 0.9.0 → 0.9.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/chattr.rb +24 -24
- data/spec/chattr_spec.rb +565 -0
- metadata +5 -3
data/lib/chattr.rb
CHANGED
@@ -24,13 +24,13 @@ When any value is entered into the Array, by any method,
|
|
24
24
|
that doesn't satisfy your checks, you'll get a nice exception.
|
25
25
|
Beware of catching this exception, as in some cases
|
26
26
|
(+flatten+ for instance) the operation has been completed
|
27
|
-
before the new array value is checked and the exception
|
27
|
+
before the new array value is checked and the exception raised.
|
28
28
|
|
29
29
|
Here's a simple example:
|
30
30
|
int_array = Array(Integer).new
|
31
31
|
int_array << 4
|
32
32
|
int_array.concat [ 6, 8, 10 ]
|
33
|
-
int_array << "Oops" # This will
|
33
|
+
int_array << "Oops" # This will raise an exception
|
34
34
|
|
35
35
|
Surprisingly, a call to <tt>Array()</tt> works even as a superclass in a new class definition:
|
36
36
|
class MyArray < Array(Integer)
|
@@ -39,12 +39,12 @@ Surprisingly, a call to <tt>Array()</tt> works even as a superclass in a new cla
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
-
and you can even use both together. An exception is
|
42
|
+
and you can even use both together. An exception is raised if the block returns false/nil:
|
43
43
|
class MyArray < Array(Integer) {|i|
|
44
44
|
(0..5).include?(i) # Value must be an integer from 0 to 5
|
45
45
|
}
|
46
46
|
end
|
47
|
-
MyArray.new << 6 # This will
|
47
|
+
MyArray.new << 6 # This will raise an exception
|
48
48
|
|
49
49
|
The parameter to Array is optional, which removes the class check.
|
50
50
|
You can use this to implement type checking that's all your own:
|
@@ -91,16 +91,16 @@ def Array(type = nil, &block)
|
|
91
91
|
if (a.size == 1 && a[0].class != Fixnum)
|
92
92
|
r.concat(a[0])
|
93
93
|
elsif (b)
|
94
|
-
|
94
|
+
raise "Wrong number of parameters for Array.new" if a.size != 1
|
95
95
|
(0...a[0]).each{|i|
|
96
96
|
v = b.call(i)
|
97
|
-
|
97
|
+
raise "Illegal array member from block initializer: \#{v.inspect}" unless @@_valid_type.call(v)
|
98
98
|
r[i] = v
|
99
99
|
}
|
100
100
|
else
|
101
101
|
v = a[1] || nil
|
102
102
|
if (a[1])
|
103
|
-
|
103
|
+
raise "Illegal array member initializer: \#{v.inspect}" unless @@_valid_type.call(v)
|
104
104
|
end
|
105
105
|
if (a.size > 0)
|
106
106
|
(0...a[0]).each_index{|i|
|
@@ -118,18 +118,18 @@ def Array(type = nil, &block)
|
|
118
118
|
|
119
119
|
def []=(*args)
|
120
120
|
element = args.last
|
121
|
-
|
121
|
+
raise "Illegal array member assignment: \#{element.inspect}" unless @@_valid_type.call(element)
|
122
122
|
super(*args)
|
123
123
|
end
|
124
124
|
|
125
125
|
def <<(element)
|
126
|
-
|
126
|
+
raise "Illegal array member append: \#{element.inspect}" unless @@_valid_type.call(element)
|
127
127
|
super(element)
|
128
128
|
end
|
129
129
|
|
130
130
|
def concat(other)
|
131
131
|
other.each{|e|
|
132
|
-
|
132
|
+
raise "Illegal array member in concat: \#{e.inspect}" unless @@_valid_type.call(e)
|
133
133
|
}
|
134
134
|
super(other)
|
135
135
|
end
|
@@ -137,7 +137,7 @@ def Array(type = nil, &block)
|
|
137
137
|
def fill(*a, &b)
|
138
138
|
unless b
|
139
139
|
v = a.shift
|
140
|
-
|
140
|
+
raise "Illegal array value fill: \#{v.inspect}" unless @@_valid_type.call(v)
|
141
141
|
b = lambda{|i| v}
|
142
142
|
end
|
143
143
|
|
@@ -152,7 +152,7 @@ def Array(type = nil, &block)
|
|
152
152
|
r = (a[0]..self.size-1) unless r.kind_of?(Range)
|
153
153
|
r.each{|i|
|
154
154
|
e = b.call(i)
|
155
|
-
|
155
|
+
raise "Illegal array block fill: \#{e.inspect}" unless @@_valid_type.call(e)
|
156
156
|
self[i] = e
|
157
157
|
}
|
158
158
|
when 2
|
@@ -164,7 +164,7 @@ def Array(type = nil, &block)
|
|
164
164
|
|
165
165
|
def check_valid(operation)
|
166
166
|
each{|e|
|
167
|
-
|
167
|
+
raise "Illegal array element: \#{e.inspect} after \#{operation}" unless @@_valid_type.call(e)
|
168
168
|
}
|
169
169
|
end
|
170
170
|
|
@@ -176,7 +176,7 @@ def Array(type = nil, &block)
|
|
176
176
|
rescue
|
177
177
|
clear
|
178
178
|
concat saved
|
179
|
-
|
179
|
+
raise
|
180
180
|
end
|
181
181
|
a
|
182
182
|
end
|
@@ -189,7 +189,7 @@ def Array(type = nil, &block)
|
|
189
189
|
rescue
|
190
190
|
clear # Restore the value
|
191
191
|
concat saved
|
192
|
-
|
192
|
+
raise
|
193
193
|
end
|
194
194
|
self
|
195
195
|
end
|
@@ -197,7 +197,7 @@ def Array(type = nil, &block)
|
|
197
197
|
def insert(*a)
|
198
198
|
start = a.shift
|
199
199
|
a.each{|e|
|
200
|
-
|
200
|
+
raise "Illegal array element insert: \#{e.inspect}" unless @@_valid_type.call(e)
|
201
201
|
}
|
202
202
|
super(start, *a)
|
203
203
|
end
|
@@ -205,7 +205,7 @@ def Array(type = nil, &block)
|
|
205
205
|
def collect!
|
206
206
|
each_with_index{|e, i|
|
207
207
|
v = yield(e)
|
208
|
-
|
208
|
+
raise "Illegal array element in collect!: \#{v.inspect}" unless @@_valid_type.call(v)
|
209
209
|
self[i] = v
|
210
210
|
}
|
211
211
|
self
|
@@ -243,7 +243,7 @@ call-seq:
|
|
243
243
|
|
244
244
|
typed_attr is like attr_accessor,
|
245
245
|
but with optional value checking using either _class_.kind_of? or by calling your block,
|
246
|
-
or both. Assignment of any value that fails the checks causes an assertion to be
|
246
|
+
or both. Assignment of any value that fails the checks causes an assertion to be raised.
|
247
247
|
|
248
248
|
The parameter list is processed in order, and may contain:
|
249
249
|
- a class. The following attributes will require values that are <tt>kind_of?</tt> this class
|
@@ -254,7 +254,7 @@ The parameter list is processed in order, and may contain:
|
|
254
254
|
|
255
255
|
In addition, typed_attr may be given a block.
|
256
256
|
Any value to be assigned will be passed to this block,
|
257
|
-
which must not return false/nil or an exception will be
|
257
|
+
which must not return false/nil or an exception will be raised.
|
258
258
|
You'll need to parenthesize the parameter list for a {|| } block,
|
259
259
|
or just use a do...end block.
|
260
260
|
|
@@ -301,11 +301,11 @@ constructor.
|
|
301
301
|
define_method("#{name}=") {|val|
|
302
302
|
if val == nil
|
303
303
|
unless nil_ok
|
304
|
-
|
304
|
+
raise "Can't assign nil to #{name} which is restricted to class #{klass}"
|
305
305
|
end
|
306
306
|
else
|
307
307
|
if !val.kind_of?(klass)
|
308
|
-
|
308
|
+
raise "Can't assign #{val.inspect} of class #{val.class} to attribute #{name} which is restricted to class #{klass}"
|
309
309
|
elsif (block && !block.call(val))
|
310
310
|
raise "Invalid value assigned to #{name}: #{val.inspect}"
|
311
311
|
end
|
@@ -333,7 +333,7 @@ The parameter list is processed in order, and may contain:
|
|
333
333
|
|
334
334
|
In addition, array_attr may be given a block.
|
335
335
|
Any value to be used as a member of the array will be passed to this block,
|
336
|
-
which must not return false/nil or an exception will be
|
336
|
+
which must not return false/nil or an exception will be raised.
|
337
337
|
You'll need to parenthesize the parameter list for a {|| } block,
|
338
338
|
or just use a do...end block.
|
339
339
|
|
@@ -375,11 +375,11 @@ Here's an example:
|
|
375
375
|
a.concat(val) # If conversion is legal, this will do it
|
376
376
|
rescue
|
377
377
|
instance_variable_set("@#{name}", saved)
|
378
|
-
|
378
|
+
raise
|
379
379
|
end
|
380
380
|
}
|
381
381
|
else
|
382
|
-
|
382
|
+
raise "Parameter to array_attr must be Class or Symbol"
|
383
383
|
end
|
384
384
|
}
|
385
385
|
end
|
data/spec/chattr_spec.rb
ADDED
@@ -0,0 +1,565 @@
|
|
1
|
+
require "chattr"
|
2
|
+
|
3
|
+
contexts = [
|
4
|
+
[ "Member element of Array of Integer type", lambda{ @array_class = Array(Integer) }, 2 ],
|
5
|
+
[ "Member element of Array of String type", lambda{ @array_class = Array(String) }, "foo" ]
|
6
|
+
]
|
7
|
+
|
8
|
+
contexts.each do |p| context_name, context_setup, context_value = *p
|
9
|
+
|
10
|
+
context context_name do
|
11
|
+
setup do
|
12
|
+
instance_eval &context_setup
|
13
|
+
@a = @array_class.new
|
14
|
+
@r = nil
|
15
|
+
@v = context_value
|
16
|
+
end
|
17
|
+
|
18
|
+
# Member assignment:
|
19
|
+
specify "should allow that type to be assigned" do
|
20
|
+
lambda{@r = (@a[0] = @v)}.should_not raise_error
|
21
|
+
@r.should == @v
|
22
|
+
end
|
23
|
+
|
24
|
+
specify "should error when other type is assigned to a member" do
|
25
|
+
@a << @v
|
26
|
+
lambda{@a[0] = []}.should raise_error(RuntimeError)
|
27
|
+
end
|
28
|
+
|
29
|
+
specify "should contain only the value assigned" do
|
30
|
+
@r = (@a[0] = @v)
|
31
|
+
@a[0].should == @v
|
32
|
+
@a.size.should == 1
|
33
|
+
@r.should == @v
|
34
|
+
end
|
35
|
+
|
36
|
+
specify "should allow that type to be appended" do
|
37
|
+
lambda{@r = (@a << @v)}.should_not raise_error
|
38
|
+
@r.should == [@v]
|
39
|
+
end
|
40
|
+
|
41
|
+
specify "should return nil on a positive out-of-bounds index" do
|
42
|
+
@r = (@a << @v)
|
43
|
+
@a[4].should == nil
|
44
|
+
@r.should == [@v]
|
45
|
+
end
|
46
|
+
|
47
|
+
specify "should return nil on a negative out-of-bounds index" do
|
48
|
+
@r = (@a << @v)
|
49
|
+
@a[-5].should == nil
|
50
|
+
@r.should == [@v]
|
51
|
+
end
|
52
|
+
|
53
|
+
specify "should replace() the value correctly" do
|
54
|
+
a = @v
|
55
|
+
b = @v+@v
|
56
|
+
c = b+@v
|
57
|
+
d = b+b
|
58
|
+
@a.concat [a, b]
|
59
|
+
@r = (@a.replace [c, d])
|
60
|
+
@a[0].should == c
|
61
|
+
@a[1].should == d
|
62
|
+
@a[2].should == nil
|
63
|
+
@a.size.should == 2
|
64
|
+
@r.should == [c, d]
|
65
|
+
end
|
66
|
+
|
67
|
+
specify "should throw error when replace breaks the constraints" do
|
68
|
+
a = @v
|
69
|
+
b = @v+@v
|
70
|
+
c = b+@v
|
71
|
+
d = b+b
|
72
|
+
@a.concat [a, b]
|
73
|
+
lambda{ @a.replace [c, {}, d] }.should raise_error
|
74
|
+
@a.should == [a, b]
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context "Appending and inserting to Array of a specified type" do
|
80
|
+
setup do
|
81
|
+
@array_class = Array(Integer)
|
82
|
+
@a = @array_class.new
|
83
|
+
end
|
84
|
+
|
85
|
+
specify "should contain only the value appended" do
|
86
|
+
@a << 5
|
87
|
+
@a[0].should == 5
|
88
|
+
@a.size.should == 1
|
89
|
+
end
|
90
|
+
|
91
|
+
specify "should return the value appended" do
|
92
|
+
@a << 6
|
93
|
+
@a << 7
|
94
|
+
@a[0].should == 6
|
95
|
+
@a[1].should == 7
|
96
|
+
@a[-1].should == 7
|
97
|
+
@a[-2].should == 6
|
98
|
+
end
|
99
|
+
|
100
|
+
specify "should error when other type is appended" do
|
101
|
+
lambda{@a << "foo"}.should raise_error
|
102
|
+
end
|
103
|
+
|
104
|
+
specify "should allow a normal array of that type to be concatenated" do
|
105
|
+
@a << 1
|
106
|
+
lambda{@a.concat([2, 3])}.should_not raise_error
|
107
|
+
@a[0].should == 1
|
108
|
+
@a[1].should == 2
|
109
|
+
@a[2].should == 3
|
110
|
+
@a.size.should == 3
|
111
|
+
end
|
112
|
+
|
113
|
+
specify "should allow a matching checked array to be concatenated" do
|
114
|
+
@a << 7
|
115
|
+
@addend = @array_class.new
|
116
|
+
@addend << 8
|
117
|
+
@addend << 9
|
118
|
+
lambda{@a.concat(@addend)}.should_not raise_error
|
119
|
+
@a[0].should == 7
|
120
|
+
@a[1].should == 8
|
121
|
+
@a[2].should == 9
|
122
|
+
@a.size.should == 3
|
123
|
+
end
|
124
|
+
|
125
|
+
specify "should return values from the concatenated array" do
|
126
|
+
@a << 1
|
127
|
+
@o = [2]
|
128
|
+
@a.concat @o
|
129
|
+
@a[0].should == 1
|
130
|
+
@a[1].should == 2
|
131
|
+
@a[2].should == nil
|
132
|
+
@a.size.should == 2
|
133
|
+
end
|
134
|
+
|
135
|
+
specify "should error when a normal array containing another type is concatenated" do
|
136
|
+
lambda{@a.concat([1, "foo"])}.should raise_error
|
137
|
+
end
|
138
|
+
|
139
|
+
specify "should include any values inserted" do
|
140
|
+
@a << 6
|
141
|
+
@a << 7
|
142
|
+
@a.insert(1, 2, 3)
|
143
|
+
@a[0].should == 6
|
144
|
+
@a[1].should == 2
|
145
|
+
@a[2].should == 3
|
146
|
+
@a[3].should == 7
|
147
|
+
@a[4].should == nil
|
148
|
+
@a.size.should == 4
|
149
|
+
end
|
150
|
+
|
151
|
+
specify "should error when other type is inserted" do
|
152
|
+
@a << 6
|
153
|
+
@a << 7
|
154
|
+
lambda{@a.insert(1, "foo")}.should raise_error
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
context "When using fill() with an Array of a specified type" do
|
159
|
+
setup do
|
160
|
+
@array_class = Array(Integer)
|
161
|
+
@a = @array_class.new
|
162
|
+
end
|
163
|
+
|
164
|
+
specify "should error when filled with an invalid value" do
|
165
|
+
@a.concat([1, 2, 3])
|
166
|
+
lambda { @a.fill("oops") }.should raise_error
|
167
|
+
end
|
168
|
+
|
169
|
+
specify "should error when filled with an invalid value from a block" do
|
170
|
+
@a.concat([1, 2, 3])
|
171
|
+
lambda { @a.fill() {|i| "oops"} }.should raise_error
|
172
|
+
end
|
173
|
+
|
174
|
+
specify "should be able to be filled with a valid value" do
|
175
|
+
@a.concat([1, 2, 3])
|
176
|
+
@a.fill(5)
|
177
|
+
@a[0].should == 5
|
178
|
+
@a[1].should == 5
|
179
|
+
@a[2].should == 5
|
180
|
+
@a[3].should == nil
|
181
|
+
end
|
182
|
+
|
183
|
+
specify "should be able to be filled from given offset with a valid value" do
|
184
|
+
@a.concat([1, 2, 3, 4])
|
185
|
+
@a.fill(5, 2)
|
186
|
+
@a[0].should == 1
|
187
|
+
@a[1].should == 2
|
188
|
+
@a[2].should == 5
|
189
|
+
@a[3].should == 5
|
190
|
+
@a[4].should == nil
|
191
|
+
end
|
192
|
+
|
193
|
+
specify "should be able to be range-filled with a valid value" do
|
194
|
+
@a.concat([1, 2, 3, 4, 5])
|
195
|
+
@a.fill(17, (2..3))
|
196
|
+
@a[0].should == 1
|
197
|
+
@a[1].should == 2
|
198
|
+
@a[2].should == 17
|
199
|
+
@a[3].should == 17
|
200
|
+
@a[4].should == 5
|
201
|
+
@a[5].should == nil
|
202
|
+
end
|
203
|
+
|
204
|
+
specify "should be able to be filled with a valid value using a block" do
|
205
|
+
@a.concat([1, 2, 3])
|
206
|
+
@a.fill() {|i| i+30 }
|
207
|
+
@a[0].should == 30
|
208
|
+
@a[1].should == 31
|
209
|
+
@a[2].should == 32
|
210
|
+
@a[3].should == nil
|
211
|
+
end
|
212
|
+
|
213
|
+
specify "should be able to be filled from given offset with a valid value using a block" do
|
214
|
+
@a.concat([1, 2, 3, 4])
|
215
|
+
@a.fill(2) {|i| i+30 }
|
216
|
+
@a[0].should == 1
|
217
|
+
@a[1].should == 2
|
218
|
+
@a[2].should == 32
|
219
|
+
@a[3].should == 33
|
220
|
+
@a[4].should == nil
|
221
|
+
end
|
222
|
+
|
223
|
+
specify "should be able to be range-filled with a valid value using a block" do
|
224
|
+
@a.concat([1, 2, 3, 4, 5])
|
225
|
+
@a.fill(2..3) {|i| i+30 }
|
226
|
+
@a[0].should == 1
|
227
|
+
@a[1].should == 2
|
228
|
+
@a[2].should == 32
|
229
|
+
@a[3].should == 33
|
230
|
+
@a[4].should == 5
|
231
|
+
@a[5].should == nil
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
context "When flatten()ing an Array of a specified type" do
|
236
|
+
setup do
|
237
|
+
@array_class = Array {|e|
|
238
|
+
# Any members must be arrays or be < 10
|
239
|
+
Array === e || e < 10
|
240
|
+
}
|
241
|
+
@a = @array_class.new
|
242
|
+
end
|
243
|
+
|
244
|
+
specify "should flatten like base Arrays" do
|
245
|
+
@a.concat [1, [2, 3], 4, [5, 6, 7] ]
|
246
|
+
@a.flatten!
|
247
|
+
(0...7).each{|i|
|
248
|
+
@a[i].should == i+1
|
249
|
+
}
|
250
|
+
end
|
251
|
+
|
252
|
+
specify "should throw error when flattening breaks the constraints" do
|
253
|
+
@a.concat [1, [2, 3], 4, [5, [10], 7] ]
|
254
|
+
lambda { @a.flatten!() }.should raise_error
|
255
|
+
@a.should == [1, [2, 3], 4, [5, [10], 7] ]
|
256
|
+
end
|
257
|
+
|
258
|
+
end
|
259
|
+
|
260
|
+
context "When using reflexive collect and map with Array" do
|
261
|
+
setup do
|
262
|
+
@array_class = Array(Integer)
|
263
|
+
@a = @array_class.new
|
264
|
+
end
|
265
|
+
|
266
|
+
specify "should work as long as constraints not broken" do
|
267
|
+
@a.concat([1, 2, 3])
|
268
|
+
@a.collect!{|i| i*3}
|
269
|
+
|
270
|
+
(0..2).each{|i|
|
271
|
+
@a[i].should == i*3+3
|
272
|
+
}
|
273
|
+
@a[3].should == nil
|
274
|
+
@a.size.should == 3
|
275
|
+
end
|
276
|
+
|
277
|
+
specify "should throw error when map! breaks the constraints" do
|
278
|
+
@a.concat([1, 2, 3, 4, 5])
|
279
|
+
lambda{ @a.map!{|i| i.to_s} }.should raise_error
|
280
|
+
end
|
281
|
+
|
282
|
+
end
|
283
|
+
|
284
|
+
context "Member element of Array having a check block" do
|
285
|
+
setup do
|
286
|
+
@array_class = Array {|e|
|
287
|
+
Integer === e && e < 10 || String === e && e.size < 4
|
288
|
+
}
|
289
|
+
@a = @array_class.new
|
290
|
+
end
|
291
|
+
|
292
|
+
specify "should allow valid values to be assigned" do
|
293
|
+
lambda{@a[0] = 1}.should_not raise_error
|
294
|
+
lambda{@a[1] = "foo"}.should_not raise_error
|
295
|
+
@a[0].should == 1
|
296
|
+
@a[1].should == "foo"
|
297
|
+
@a[2].should == nil
|
298
|
+
@a.size.should == 2
|
299
|
+
end
|
300
|
+
|
301
|
+
specify "should error when invalid values are assigned" do
|
302
|
+
lambda{@a[0] = 10}.should raise_error
|
303
|
+
lambda{@a[1] = "foobar"}.should raise_error
|
304
|
+
|
305
|
+
@a.size.should == 0
|
306
|
+
end
|
307
|
+
|
308
|
+
end
|
309
|
+
|
310
|
+
context "Member element of Array having a type and a check block" do
|
311
|
+
setup do
|
312
|
+
@array_class = Array String do |e|
|
313
|
+
e.size < 4
|
314
|
+
end
|
315
|
+
@a = @array_class.new
|
316
|
+
end
|
317
|
+
|
318
|
+
specify "should allow valid values to be assigned" do
|
319
|
+
lambda{@a[1] = "foo"}.should_not raise_error
|
320
|
+
@a[0].should == nil
|
321
|
+
@a[1].should == "foo"
|
322
|
+
@a[2].should == nil
|
323
|
+
@a.size.should == 2
|
324
|
+
end
|
325
|
+
|
326
|
+
specify "should error when invalid values are assigned" do
|
327
|
+
lambda{@a[0] = 1}.should raise_error
|
328
|
+
lambda{@a[1] = "foobar"}.should raise_error
|
329
|
+
|
330
|
+
@a.size.should == 0
|
331
|
+
end
|
332
|
+
|
333
|
+
end
|
334
|
+
|
335
|
+
context "Checked attribute" do
|
336
|
+
setup do
|
337
|
+
# Variables: Class, nil, default, block
|
338
|
+
my_class = Class.new do
|
339
|
+
typed_attr :not_nil
|
340
|
+
typed_attr nil, :unchecked
|
341
|
+
typed_attr Integer, :int
|
342
|
+
typed_attr Integer, nil, :int_nil
|
343
|
+
typed_attr(:block_checked) { |e|
|
344
|
+
String === e && e.size < 4
|
345
|
+
}
|
346
|
+
typed_attr Integer, :block_checked_int do |e|
|
347
|
+
e < 10
|
348
|
+
end
|
349
|
+
|
350
|
+
typed_attr 14, :not_nil_def
|
351
|
+
typed_attr 15, nil, :unchecked_def
|
352
|
+
typed_attr Integer, 16, :int_def
|
353
|
+
typed_attr Integer, 17, nil, :int_nil_def
|
354
|
+
typed_attr("bar", :block_checked_def) { |e|
|
355
|
+
String === e && e.size < 4
|
356
|
+
}
|
357
|
+
typed_attr Integer, 8, :block_checked_int_def do |e|
|
358
|
+
e < 10
|
359
|
+
end
|
360
|
+
end
|
361
|
+
@o = my_class.new
|
362
|
+
|
363
|
+
# Assign default to non-nil attributes:
|
364
|
+
@o.not_nil = "non-nil"
|
365
|
+
@o.int = -1
|
366
|
+
@o.block_checked = "asd"
|
367
|
+
@o.block_checked_int = 2
|
368
|
+
end
|
369
|
+
|
370
|
+
specify "should allow assignment to attributes of all forms" do
|
371
|
+
@o.not_nil = ""
|
372
|
+
@o.not_nil.should == ""
|
373
|
+
|
374
|
+
lambda{
|
375
|
+
@o.unchecked = 200
|
376
|
+
@o.unchecked = "A long string"
|
377
|
+
}.should_not raise_error
|
378
|
+
@o.unchecked.should == "A long string"
|
379
|
+
|
380
|
+
@o.int = 1
|
381
|
+
@o.int.should == 1
|
382
|
+
|
383
|
+
@o.int_nil = 2
|
384
|
+
@o.int_nil.should == 2
|
385
|
+
|
386
|
+
@o.int_nil = nil
|
387
|
+
@o.int_nil.should == nil
|
388
|
+
|
389
|
+
@o.block_checked = "foo"
|
390
|
+
@o.block_checked.should == "foo"
|
391
|
+
|
392
|
+
@o.block_checked_int = 7
|
393
|
+
@o.block_checked_int.should == 7
|
394
|
+
end
|
395
|
+
|
396
|
+
specify "should allow assignment to defaulted attributes of all forms" do
|
397
|
+
@o.not_nil_def.should == 14
|
398
|
+
@o.not_nil_def = 24
|
399
|
+
@o.not_nil_def.should == 24
|
400
|
+
|
401
|
+
@o.unchecked_def.should == 15
|
402
|
+
@o.unchecked_def = 25
|
403
|
+
@o.unchecked_def.should == 25
|
404
|
+
|
405
|
+
@o.int_def.should == 16
|
406
|
+
@o.int_def = 26
|
407
|
+
@o.int_def.should == 26
|
408
|
+
|
409
|
+
@o.int_nil_def.should == 17
|
410
|
+
@o.int_nil_def = 27
|
411
|
+
@o.int_nil_def.should == 27
|
412
|
+
|
413
|
+
@o.block_checked_def.should == "bar"
|
414
|
+
@o.block_checked_def = "foo"
|
415
|
+
@o.block_checked_def.should == "foo"
|
416
|
+
|
417
|
+
@o.block_checked_int_def.should == 8
|
418
|
+
@o.block_checked_int_def = 2
|
419
|
+
@o.block_checked_int_def.should == 2
|
420
|
+
end
|
421
|
+
|
422
|
+
specify "should error and leave value unchanged when assigned invalid values" do
|
423
|
+
|
424
|
+
lambda{@o.not_nil = nil}.should raise_error
|
425
|
+
@o.not_nil.should_not == nil
|
426
|
+
|
427
|
+
lambda{@o.int = "foo"}.should raise_error
|
428
|
+
@o.int.should_not == "foo"
|
429
|
+
|
430
|
+
lambda{@o.int_nil = "foo"}.should raise_error
|
431
|
+
@o.int_nil.should_not == "foo"
|
432
|
+
|
433
|
+
lambda{@o.int_nil = "foo"}.should raise_error
|
434
|
+
@o.int_nil.should_not == "foo"
|
435
|
+
|
436
|
+
lambda{@o.block_checked = "foobar"}.should raise_error
|
437
|
+
@o.block_checked.should_not == "foobar"
|
438
|
+
|
439
|
+
lambda{@o.block_checked = nil}.should raise_error
|
440
|
+
@o.block_checked.should_not == nil
|
441
|
+
|
442
|
+
lambda{@o.block_checked_int = 20}.should raise_error
|
443
|
+
@o.block_checked_int.should_not == 20
|
444
|
+
|
445
|
+
lambda{@o.block_checked_int = nil}.should raise_error
|
446
|
+
@o.block_checked_int.should_not == nil
|
447
|
+
|
448
|
+
lambda{@o.not_nil_def = nil}.should raise_error
|
449
|
+
@o.not_nil_def.should_not == nil
|
450
|
+
|
451
|
+
lambda{@o.int_def = "foo"}.should raise_error
|
452
|
+
@o.int_def.should_not == "foo"
|
453
|
+
|
454
|
+
lambda{@o.int_nil_def = "foo"}.should raise_error
|
455
|
+
@o.int_nil_def.should_not == "foo"
|
456
|
+
|
457
|
+
lambda{@o.int_nil_def = "foo"}.should raise_error
|
458
|
+
@o.int_nil_def.should_not == "foo"
|
459
|
+
|
460
|
+
lambda{@o.block_checked_def = "foobar"}.should raise_error
|
461
|
+
@o.block_checked_def.should_not == "foobar"
|
462
|
+
|
463
|
+
lambda{@o.block_checked_def = nil}.should raise_error
|
464
|
+
@o.block_checked_def.should_not == nil
|
465
|
+
|
466
|
+
lambda{@o.block_checked_int_def = 20}.should raise_error
|
467
|
+
@o.block_checked_int_def.should_not == 20
|
468
|
+
|
469
|
+
lambda{@o.block_checked_int_def = nil}.should raise_error
|
470
|
+
@o.block_checked_int_def.should_not == nil
|
471
|
+
|
472
|
+
end
|
473
|
+
end
|
474
|
+
|
475
|
+
context "Checked array attribute" do
|
476
|
+
setup do
|
477
|
+
# Variables: Class, nil, default, block
|
478
|
+
my_class = Class.new do
|
479
|
+
array_attr :unchecked
|
480
|
+
array_attr Integer, :int
|
481
|
+
array_attr(:block_checked) { |e|
|
482
|
+
String === e && e.size < 4
|
483
|
+
}
|
484
|
+
array_attr Integer, :block_checked_int do |e|
|
485
|
+
e < 10
|
486
|
+
end
|
487
|
+
|
488
|
+
end
|
489
|
+
@o = my_class.new
|
490
|
+
end
|
491
|
+
|
492
|
+
specify "should allow assignment to members (all forms of array)" do
|
493
|
+
lambda{
|
494
|
+
@o.unchecked[1] = "foo"
|
495
|
+
}.should_not raise_error
|
496
|
+
@o.unchecked[1].should == "foo"
|
497
|
+
|
498
|
+
@o.int[0] = 1
|
499
|
+
@o.int[0].should == 1
|
500
|
+
|
501
|
+
@o.block_checked[0] = "foo"
|
502
|
+
@o.block_checked[0].should == "foo"
|
503
|
+
|
504
|
+
@o.block_checked_int[0] = 7
|
505
|
+
@o.block_checked_int[0].should == 7
|
506
|
+
end
|
507
|
+
|
508
|
+
specify "should allow assignment of whole array (all forms of array)" do
|
509
|
+
lambda{
|
510
|
+
@o.unchecked[0] = 0
|
511
|
+
@o.unchecked = [ 1, 2, "foo" ]
|
512
|
+
}.should_not raise_error
|
513
|
+
@o.unchecked.should == [ 1, 2, "foo" ]
|
514
|
+
|
515
|
+
@o.int = [ 1, 2, 3 ]
|
516
|
+
@o.int.should == [ 1, 2, 3 ]
|
517
|
+
|
518
|
+
@o.block_checked = [ "foo", "bar", "baz" ]
|
519
|
+
@o.block_checked.should == [ "foo", "bar", "baz" ]
|
520
|
+
|
521
|
+
@o.block_checked_int = [ 5, 6, 7 ]
|
522
|
+
@o.block_checked_int.should == [ 5, 6, 7 ]
|
523
|
+
end
|
524
|
+
|
525
|
+
specify "should error and leave value unchanged when a member is assigned an invalid value" do
|
526
|
+
@o.int[0] = 1
|
527
|
+
lambda{
|
528
|
+
@o.int[0] = "foo"
|
529
|
+
}.should raise_error
|
530
|
+
@o.int.should == [1]
|
531
|
+
|
532
|
+
@o.block_checked[0] = "foo"
|
533
|
+
lambda{
|
534
|
+
@o.block_checked[0] = "foobar"
|
535
|
+
}.should raise_error
|
536
|
+
@o.block_checked[0].should == "foo"
|
537
|
+
|
538
|
+
@o.block_checked_int[0] = 7
|
539
|
+
lambda{
|
540
|
+
@o.block_checked_int[0] = 17
|
541
|
+
}.should raise_error
|
542
|
+
@o.block_checked_int[0].should == 7
|
543
|
+
end
|
544
|
+
|
545
|
+
specify "should error and leave value unchanged on assignment of whole array containing an invalid value (all forms of array)" do
|
546
|
+
@o.int = [ 1, 2, 3 ]
|
547
|
+
lambda{
|
548
|
+
@o.int = [ 1, "foo", 3 ]
|
549
|
+
}.should raise_error
|
550
|
+
@o.int.should == [ 1, 2, 3 ]
|
551
|
+
|
552
|
+
@o.block_checked = [ "foo", "bar", "baz" ]
|
553
|
+
lambda{
|
554
|
+
@o.block_checked = [ "foo", "foobar", "baz" ]
|
555
|
+
}.should raise_error
|
556
|
+
@o.block_checked.should == [ "foo", "bar", "baz" ]
|
557
|
+
|
558
|
+
@o.block_checked_int = [ 5, 6, 7 ]
|
559
|
+
lambda{
|
560
|
+
@o.block_checked_int = [ 5, 60, 7 ]
|
561
|
+
}.should raise_error
|
562
|
+
@o.block_checked_int.should == [ 5, 6, 7 ]
|
563
|
+
end
|
564
|
+
|
565
|
+
end
|
metadata
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.9.
|
2
|
+
rubygems_version: 0.9.2
|
3
3
|
specification_version: 1
|
4
4
|
name: chattr
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.9.
|
7
|
-
date: 2007-03-
|
6
|
+
version: 0.9.1
|
7
|
+
date: 2007-03-20 00:00:00 +11:00
|
8
8
|
summary: Methods for defining type-checked arrays and attributes
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -30,6 +30,8 @@ authors:
|
|
30
30
|
- Clifford Heath
|
31
31
|
files:
|
32
32
|
- lib/chattr.rb
|
33
|
+
- spec/chattr_spec.rb
|
34
|
+
- spec/runtest.rb
|
33
35
|
- LICENSE
|
34
36
|
test_files:
|
35
37
|
- spec/runtest.rb
|