chattr 0.9.0 → 0.9.1
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.
- 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
|