dao 7.0.0 → 8.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,195 @@
1
+ require 'test/unit'
2
+
3
+ testdir = File.expand_path(File.dirname(__FILE__))
4
+ rootdir = File.dirname(testdir)
5
+ libdir = File.join(rootdir, 'lib')
6
+
7
+ STDOUT.sync = true
8
+
9
+ $:.unshift(testdir) unless $:.include?(testdir)
10
+ $:.unshift(libdir) unless $:.include?(libdir)
11
+ $:.unshift(rootdir) unless $:.include?(rootdir)
12
+
13
+ class Testing
14
+ class Slug < ::String
15
+ def Slug.for(*args)
16
+ string = args.flatten.compact.join('-')
17
+ words = string.to_s.scan(%r/\w+/)
18
+ words.map!{|word| word.gsub %r/[^0-9a-zA-Z_-]/, ''}
19
+ words.delete_if{|word| word.nil? or word.strip.empty?}
20
+ new(words.join('-').downcase)
21
+ end
22
+ end
23
+
24
+ class Context
25
+ attr_accessor :name
26
+
27
+ def initialize(name, *args)
28
+ @name = name
29
+ end
30
+
31
+ def to_s
32
+ Slug.for(name)
33
+ end
34
+ end
35
+ end
36
+
37
+ def Testing(*args, &block)
38
+ Class.new(::Test::Unit::TestCase) do
39
+
40
+ ## class methods
41
+ #
42
+ class << self
43
+ def contexts
44
+ @contexts ||= []
45
+ end
46
+
47
+ def context(*args, &block)
48
+ return contexts.last if(args.empty? and block.nil?)
49
+
50
+ context = Testing::Context.new(*args)
51
+ contexts.push(context)
52
+
53
+ begin
54
+ block.call(context)
55
+ ensure
56
+ contexts.pop
57
+ end
58
+ end
59
+
60
+ def slug_for(*args)
61
+ string = [context, args].flatten.compact.join('-')
62
+ words = string.to_s.scan(%r/\w+/)
63
+ words.map!{|word| word.gsub %r/[^0-9a-zA-Z_-]/, ''}
64
+ words.delete_if{|word| word.nil? or word.strip.empty?}
65
+ words.join('-').downcase.sub(/_$/, '')
66
+ end
67
+
68
+ def name() const_get(:Name) end
69
+
70
+ def testno()
71
+ '%05d' % (@testno ||= 0)
72
+ ensure
73
+ @testno += 1
74
+ end
75
+
76
+ def testing(*args, &block)
77
+ method = ["test", testno, slug_for(*args)].delete_if{|part| part.empty?}.join('_')
78
+ define_method(method, &block)
79
+ end
80
+
81
+ def test(*args, &block)
82
+ testing(*args, &block)
83
+ end
84
+
85
+ def setup(&block)
86
+ define_method(:setup, &block) if block
87
+ end
88
+
89
+ def teardown(&block)
90
+ define_method(:teardown, &block) if block
91
+ end
92
+
93
+ def prepare(&block)
94
+ @prepare ||= []
95
+ @prepare.push(block) if block
96
+ @prepare
97
+ end
98
+
99
+ def cleanup(&block)
100
+ @cleanup ||= []
101
+ @cleanup.push(block) if block
102
+ @cleanup
103
+ end
104
+ end
105
+
106
+ ## configure the subclass!
107
+ #
108
+ const_set(:Testno, '0')
109
+ slug = slug_for(*args).gsub(%r/-/,'_')
110
+ name = ['TESTING', '%03d' % const_get(:Testno), slug].delete_if{|part| part.empty?}.join('_')
111
+ name = name.upcase!
112
+ const_set(:Name, name)
113
+ const_set(:Missing, Object.new.freeze)
114
+
115
+ ## instance methods
116
+ #
117
+ alias_method('__assert__', 'assert')
118
+
119
+ def assert(*args, &block)
120
+ if args.size == 1 and args.first.is_a?(Hash)
121
+ options = args.first
122
+ expected = getopt(:expected, options){ missing }
123
+ actual = getopt(:actual, options){ missing }
124
+ if expected == missing and actual == missing
125
+ actual, expected, *ignored = options.to_a.flatten
126
+ end
127
+ expected = expected.call() if expected.respond_to?(:call)
128
+ actual = actual.call() if actual.respond_to?(:call)
129
+ assert_equal(expected, actual)
130
+ end
131
+
132
+ if block
133
+ label = "assert(#{ args.join(' ') })"
134
+ result = nil
135
+ assert_nothing_raised{ result = block.call }
136
+ __assert__(result, label)
137
+ result
138
+ else
139
+ result = args.shift
140
+ label = "assert(#{ args.join(' ') })"
141
+ __assert__(result, label)
142
+ result
143
+ end
144
+ end
145
+
146
+ def missing
147
+ self.class.const_get(:Missing)
148
+ end
149
+
150
+ def getopt(opt, hash, options = nil, &block)
151
+ [opt.to_s, opt.to_s.to_sym].each do |key|
152
+ return hash[key] if hash.has_key?(key)
153
+ end
154
+ default =
155
+ if block
156
+ block.call
157
+ else
158
+ options.is_a?(Hash) ? options[:default] : nil
159
+ end
160
+ return default
161
+ end
162
+
163
+ def subclass_of exception
164
+ class << exception
165
+ def ==(other) super or self > other end
166
+ end
167
+ exception
168
+ end
169
+
170
+ ##
171
+ #
172
+ module_eval(&block)
173
+
174
+ self.setup()
175
+ self.prepare.each{|b| b.call()}
176
+
177
+ at_exit{
178
+ self.teardown()
179
+ self.cleanup.each{|b| b.call()}
180
+ }
181
+
182
+ self
183
+ end
184
+ end
185
+
186
+
187
+ if $0 == __FILE__
188
+
189
+ Testing 'Testing' do
190
+ testing('foo'){ assert true }
191
+ test{ assert true }
192
+ p instance_methods.grep(/test/)
193
+ end
194
+
195
+ end
@@ -0,0 +1,397 @@
1
+
2
+ Testing Wrap do
3
+
4
+ ##
5
+ #
6
+ testing 'that wrap can be included in a class' do
7
+ assert do
8
+ Class.new do
9
+ include Wrap
10
+ end
11
+ end
12
+ end
13
+
14
+ ##
15
+ #
16
+ testing 'that a method can be wrapped ***after*** it is defined' do
17
+ assert do
18
+ wrapped_class do
19
+ def foo() 42 end
20
+
21
+ assert{ new.foo() == 42 }
22
+
23
+ wrap :foo
24
+
25
+ assert{ new.foo() == 42 }
26
+ end
27
+ end
28
+ end
29
+
30
+ ##
31
+ #
32
+ testing 'that a method can be wrapped ***before*** it is defined' do
33
+ assert do
34
+ wrapped_class do
35
+ assert_raises(NoMethodError){ new.foo() }
36
+
37
+ wrap :foo
38
+
39
+ assert_raises(NoMethodError){ new.foo() }
40
+
41
+ define_method(:foo){ accum.push(42) }
42
+
43
+ assert_nothing_raised{ new.foo() }
44
+ end
45
+ end
46
+ end
47
+
48
+ ##
49
+ #
50
+ testing 'that wrapping gives :before and :after goodness' do
51
+ assert do
52
+ wrapped_class do
53
+ wrap :foo
54
+
55
+ define_method(:foo){ accum.push(42) }
56
+ before(:foo){ accum.push(:before) }
57
+ after(:foo){ accum.push(:after) }
58
+
59
+ assert {
60
+ c = new
61
+ c.foo()
62
+ c.accum == [:before, 42, :after]
63
+ }
64
+ end
65
+ end
66
+ end
67
+
68
+ ##
69
+ #
70
+ testing 'that :before and :after will auto-wrap methods iff needed' do
71
+ assert do
72
+ wrapped_class do
73
+ before(:foo){ accum.push(:before) }
74
+ after(:foo){ accum.push(:after) }
75
+
76
+ define_method(:foo){ accum.push(42) }
77
+
78
+ assert {
79
+ c = new
80
+ c.foo()
81
+ c.accum == [:before, 42, :after]
82
+ }
83
+ end
84
+ end
85
+ end
86
+
87
+ ##
88
+ #
89
+ testing 'that callbacks are halted with "false" iff they return "false"' do
90
+ assert do
91
+ wrapped_class do
92
+ wrap :foo
93
+
94
+ define_method(:foo){ accum.push(42) }
95
+
96
+ before(:foo){ accum.push(:foo) }
97
+ before(:foo){ accum.push(:bar); return false}
98
+ before(:foo){ accum.push(:foobar) }
99
+
100
+ assert {
101
+ c = new
102
+ c.foo()
103
+ c.accum == [:foo, :bar]
104
+ }
105
+ end
106
+ end
107
+ end
108
+
109
+ ##
110
+ #
111
+ testing 'that callbacks can be halted with "halt!"' do
112
+ assert do
113
+ wrapped_class do
114
+ wrap :foo
115
+
116
+ define_method(:foo){ accum.push(42) }
117
+
118
+ before(:foo){ accum.push(:foo) }
119
+ before(:foo){ accum.push(:bar); halt!}
120
+ before(:foo){ accum.push(:foobar) }
121
+
122
+ assert {
123
+ c = new
124
+ c.foo()
125
+ c.accum == [:foo, :bar]
126
+ }
127
+ end
128
+ end
129
+
130
+ assert do
131
+ wrapped_class do
132
+ wrap :foo
133
+
134
+ define_method(:foo){ accum.push(42) }
135
+
136
+ after(:foo){ accum.push(:foo) }
137
+ after(:foo){ accum.push(:bar); halt!}
138
+ after(:foo){ accum.push(:foobar) }
139
+
140
+ assert {
141
+ c = new
142
+ c.foo()
143
+ c.accum == [42, :foo, :bar]
144
+ }
145
+ end
146
+ end
147
+ end
148
+
149
+ ##
150
+ #
151
+ testing 'that :before callbacks are passed the number of args they can eat, and no more' do
152
+ c =
153
+ assert do
154
+ wrapped_class do
155
+ wrap :foo
156
+
157
+ define_method(:foo){|*a|}
158
+
159
+ before(:foo){|x| accum.push([x]) }
160
+ before(:foo){|x,y| accum.push([x,y]) }
161
+ before(:foo){|x,y,z| accum.push([x,y,z]) }
162
+ end
163
+ end
164
+
165
+ assert do
166
+ o = c.new
167
+ o.foo(1,2,3)
168
+ assert o.accum === [[1], [1,2], [1,2,3]]
169
+ true
170
+ end
171
+ end
172
+
173
+ ##
174
+ #
175
+ testing 'that :after callbacks are passed result of the method they follow, iff possible' do
176
+ c =
177
+ assert do
178
+ wrapped_class do
179
+ wrap :foo
180
+
181
+ define_method(:foo){ result = [1,2,3] }
182
+
183
+ after(:foo){ accum.push(:nada) }
184
+ after(:foo){|result| accum.push(result) }
185
+ end
186
+ end
187
+
188
+ assert do
189
+ o = c.new
190
+ o.foo()
191
+ assert o.accum === [:nada, [1,2,3]]
192
+ true
193
+ end
194
+ end
195
+
196
+ ##
197
+ #
198
+ testing 'that callbacks are inherited cleverly' do
199
+ c =
200
+ assert do
201
+ wrapped_class do
202
+ wrap :foo
203
+
204
+ define_method(:foo){}
205
+
206
+ before(:foo){ accum.push(:before_superclass) }
207
+ after(:foo){ accum.push(:after_superclass) }
208
+ end
209
+ end
210
+
211
+ assert do
212
+ o = c.new
213
+ o.foo()
214
+ assert o.accum === [:before_superclass, :after_superclass]
215
+ end
216
+
217
+ b =
218
+ assert do
219
+ Class.new(c) do
220
+ before(:foo){ accum.push(:before_subclass) }
221
+ after(:foo){ accum.push(:after_subclass) }
222
+ end
223
+ end
224
+
225
+ assert do
226
+ o = b.new
227
+ o.foo()
228
+ assert o.accum === [:before_superclass, :before_subclass, :after_subclass, :after_superclass]
229
+ end
230
+ end
231
+
232
+ ##
233
+ #
234
+ testing 'that methods added via module inclusion preserve wrapping too' do
235
+ c =
236
+ assert do
237
+ wrapped_class do
238
+ define_method(:foo){ accum.push(:original) }
239
+
240
+ wrap :foo
241
+
242
+ before(:foo){ accum.push(:before) }
243
+ after(:foo){ accum.push(:after) }
244
+ end
245
+ end
246
+
247
+ assert do
248
+ o = c.new
249
+ o.foo()
250
+ #assert o.accum === [:before, :original, :after]
251
+ end
252
+
253
+ m =
254
+ Module.new do
255
+ define_method(:foo){ accum.push(:mixin); accum }
256
+ end
257
+
258
+ c.send(:include, m)
259
+
260
+ assert do
261
+ o = c.new
262
+ o.foo()
263
+ assert o.accum === [:before, :mixin, :after]
264
+ end
265
+ end
266
+
267
+ ##
268
+ #
269
+ testing 'that initialize can be wrapped' do
270
+ c =
271
+ assert do
272
+ wrapped_class do
273
+ define_method(:initialize){ accum.push(42) }
274
+
275
+ wrap :initialize
276
+
277
+ before(:initialize){ accum.push(:before) }
278
+ after(:initialize){ accum.push(:after) }
279
+ end
280
+ end
281
+
282
+ assert do
283
+ o = c.new
284
+ assert o.accum === [:before, 42, :after]
285
+ end
286
+ end
287
+
288
+
289
+ ##
290
+ #
291
+ testing 'that wrap aliases can be defined as syntax sugar' do
292
+ c =
293
+ assert do
294
+ wrapped_class do
295
+ define_method(:run_validations){ accum.push(:during); accum }
296
+
297
+ wrap :run_validations
298
+ end
299
+ end
300
+
301
+ assert do
302
+ o = c.new
303
+ o.run_validations()
304
+ o.accum
305
+ assert o.accum === [:during]
306
+ end
307
+
308
+ c.class_eval do
309
+ wrap_alias :validation, :run_validations
310
+
311
+ before(:validation){ accum.push(:before) }
312
+ after(:validation){ accum.push(:after) }
313
+ end
314
+
315
+ assert do
316
+ o = c.new
317
+ o.run_validations()
318
+ o.accum
319
+ assert o.accum === [:before, :during, :after]
320
+ end
321
+
322
+ assert do
323
+ o = Class.new(c).new
324
+ o.run_validations()
325
+ o.accum
326
+ assert o.accum === [:before, :during, :after]
327
+ end
328
+ end
329
+
330
+ ##
331
+ #
332
+ testing 'that wrapping preserves method arity like a boss' do
333
+ assert do
334
+ wrapped_class do
335
+ def foo(x, y) [x, y] end
336
+
337
+ assert{ instance_method(:foo).arity == 2 }
338
+ assert{ new.foo(4, 2) == [4, 2] }
339
+
340
+ wrap :foo
341
+
342
+ assert{ instance_method(:foo).arity == 2 }
343
+ assert{ new.foo(4, 2) == [4, 2] }
344
+
345
+ def foo() end
346
+ assert{ instance_method(:foo).arity == 0 }
347
+
348
+ def foo(x) end
349
+ assert{ instance_method(:foo).arity == 1 }
350
+
351
+ def foo(*x) end
352
+ assert{ instance_method(:foo).arity == -1 }
353
+
354
+ def foo(x, *y) end
355
+ assert{ instance_method(:foo).arity == -2 }
356
+ end
357
+ end
358
+ end
359
+
360
+ private
361
+ def wrapped_class(&block)
362
+ tc = self
363
+
364
+ c =
365
+ Class.new do
366
+ include Wrap
367
+
368
+ const_set(:TC, tc)
369
+
370
+ def self.method_missing(method, *args, &block)
371
+ case method.to_s
372
+ when /^\Aassert/
373
+ const_get(:TC).send(method, *args, &block)
374
+ else
375
+ super
376
+ end
377
+ end
378
+
379
+ def accum
380
+ @accum ||= []
381
+ end
382
+
383
+ module_eval(&block)
384
+ end
385
+
386
+ c
387
+ end
388
+ end
389
+
390
+
391
+ BEGIN {
392
+ testdir = File.dirname(File.expand_path(__FILE__))
393
+ rootdir = File.dirname(testdir)
394
+ libdir = File.join(rootdir, 'lib')
395
+ require File.join(libdir, 'wrap')
396
+ require File.join(testdir, 'testing')
397
+ }