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.
- checksums.yaml +5 -5
- data/Rakefile +4 -5
- data/coerce-0.0.8/README +28 -0
- data/coerce-0.0.8/Rakefile +392 -0
- data/coerce-0.0.8/coerce.gemspec +31 -0
- data/coerce-0.0.8/lib/coerce.rb +210 -0
- data/dao.gemspec +25 -19
- data/lib/dao.rb +8 -15
- data/lib/dao/_lib.rb +6 -10
- data/lib/dao/active_record.rb +2 -2
- data/lib/dao/api/call.rb +6 -2
- data/lib/dao/coerce.rb +211 -0
- data/lib/dao/conducer.rb +6 -10
- data/lib/dao/errors2html.rb +1 -1
- data/lib/dao/support.rb +6 -17
- data/lib/dao/wrap.rb +259 -0
- data/test/conducer_test.rb +4 -4
- data/test/form_test.rb +2 -2
- data/test/validations_test.rb +2 -2
- data/wrap-1.5.2/README +57 -0
- data/wrap-1.5.2/Rakefile +394 -0
- data/wrap-1.5.2/lib/wrap.rb +295 -0
- data/wrap-1.5.2/test/testing.rb +195 -0
- data/wrap-1.5.2/test/wrap_test.rb +397 -0
- data/wrap-1.5.2/wrap.gemspec +38 -0
- metadata +26 -72
- data/notes/ara.txt +0 -15
@@ -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
|
+
}
|