dao 5.5.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 +6 -14
- data/README.md +258 -0
- 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 +38 -25
- data/lib/dao.rb +18 -81
- data/lib/dao/_lib.rb +42 -0
- data/lib/dao/active_record.rb +8 -8
- data/lib/dao/api/call.rb +19 -4
- data/lib/dao/api/dsl.rb +1 -1
- data/lib/dao/coerce.rb +211 -0
- data/lib/dao/conducer.rb +10 -14
- data/lib/dao/conducer/controller_support.rb +5 -0
- data/lib/dao/conducer/view_support.rb +0 -2
- data/lib/dao/db.rb +0 -1
- data/lib/dao/errors.rb +17 -11
- data/lib/dao/errors2html.rb +128 -0
- data/lib/dao/form.rb +13 -16
- data/lib/dao/messages.rb +0 -4
- data/lib/dao/path.rb +1 -1
- data/lib/dao/route.rb +2 -2
- data/lib/dao/status.rb +3 -4
- data/lib/dao/support.rb +26 -19
- data/lib/dao/upload.rb +0 -1
- data/lib/dao/validations/common.rb +6 -6
- data/lib/dao/validations/validator.rb +3 -3
- data/lib/dao/wrap.rb +259 -0
- data/tasks/default.rake +207 -0
- data/tasks/this.rb +207 -0
- data/test/active_model_conducer_lint_test.rb +3 -11
- data/test/api_test.rb +24 -35
- data/test/conducer_test.rb +37 -47
- data/test/errors_test.rb +29 -13
- data/test/form_test.rb +24 -34
- data/test/rake_rerun_reporter.rb +74 -0
- data/test/support_test.rb +9 -14
- data/test/test_helper.rb +220 -0
- data/test/{helper.rb → util.rb} +0 -0
- data/test/validations_test.rb +14 -28
- 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/{test → wrap-1.5.2/test}/testing.rb +0 -1
- data/wrap-1.5.2/test/wrap_test.rb +397 -0
- data/wrap-1.5.2/wrap.gemspec +38 -0
- metadata +47 -103
- data/Gemfile +0 -16
- data/Gemfile.lock +0 -118
- data/README +0 -256
@@ -0,0 +1,295 @@
|
|
1
|
+
##
|
2
|
+
#
|
3
|
+
module Wrap; end
|
4
|
+
|
5
|
+
##
|
6
|
+
#
|
7
|
+
class << Wrap
|
8
|
+
Wrap::Version = '1.5.2' unless defined?(Wrap::Version)
|
9
|
+
|
10
|
+
def version
|
11
|
+
Wrap::Version
|
12
|
+
end
|
13
|
+
|
14
|
+
def dependencies
|
15
|
+
{
|
16
|
+
'map' => [ 'map' , ' >= 4.7.1' ]
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
def description
|
21
|
+
'non-sucking :before and :after filters for any ruby class'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
#
|
27
|
+
begin
|
28
|
+
require 'rubygems'
|
29
|
+
Wrap.dependencies.each{|name, dependency| gem(*dependency)}
|
30
|
+
rescue LoadError
|
31
|
+
nil
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
#
|
36
|
+
require 'map'
|
37
|
+
|
38
|
+
##
|
39
|
+
#
|
40
|
+
module Wrap
|
41
|
+
def Wrap.included(other)
|
42
|
+
super
|
43
|
+
ensure
|
44
|
+
other.send(:instance_eval, &ClassMethods)
|
45
|
+
other.send(:class_eval, &InstanceMethods)
|
46
|
+
end
|
47
|
+
|
48
|
+
def Wrap.code_for(method)
|
49
|
+
name = method.name.to_s
|
50
|
+
arity = method.arity
|
51
|
+
|
52
|
+
case
|
53
|
+
when arity == 0
|
54
|
+
signature = <<-__.strip
|
55
|
+
def #{ name }(&block)
|
56
|
+
args = []
|
57
|
+
__
|
58
|
+
|
59
|
+
when arity < 0
|
60
|
+
argv = Array.new(arity.abs - 1){|i| "arg#{ i }"}
|
61
|
+
argv.push('*args')
|
62
|
+
argv = argv.join(', ')
|
63
|
+
|
64
|
+
signature = <<-__.strip
|
65
|
+
def #{ name }(#{ argv }, &block)
|
66
|
+
args = [#{ argv }]
|
67
|
+
__
|
68
|
+
|
69
|
+
when arity > 0
|
70
|
+
argv = Array.new(arity){|i| "arg#{ i }"}
|
71
|
+
argv = argv.join(', ')
|
72
|
+
|
73
|
+
signature = <<-__.strip
|
74
|
+
def #{ name }(#{ argv }, &block)
|
75
|
+
args = [#{ argv }]
|
76
|
+
__
|
77
|
+
end
|
78
|
+
|
79
|
+
code =
|
80
|
+
<<-__
|
81
|
+
#{ signature.strip }
|
82
|
+
|
83
|
+
if running_callbacks?(#{ name.inspect })
|
84
|
+
return wrapped_#{ name }(*args, &block)
|
85
|
+
end
|
86
|
+
|
87
|
+
running_callbacks(#{ name.inspect }) do
|
88
|
+
catch(:halt) do
|
89
|
+
return false if run_callbacks(:before, #{ name.inspect }, args)==false
|
90
|
+
|
91
|
+
begin
|
92
|
+
result = wrapped_#{ name }(*args, &block)
|
93
|
+
ensure
|
94
|
+
run_callbacks(:after, #{ name.inspect }, [result]) unless $!
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
__
|
100
|
+
end
|
101
|
+
|
102
|
+
ClassMethods = proc do
|
103
|
+
def method_added(name)
|
104
|
+
return super if wrapping?
|
105
|
+
begin
|
106
|
+
super
|
107
|
+
ensure
|
108
|
+
wrap!(name) if wrapped?(name)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def include(other)
|
113
|
+
super
|
114
|
+
ensure
|
115
|
+
other.instance_methods.each do |name|
|
116
|
+
if wrapped?(name)
|
117
|
+
begin
|
118
|
+
remove_method(name)
|
119
|
+
rescue NameError
|
120
|
+
nil
|
121
|
+
end
|
122
|
+
wrap!(name)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def wrap(name, *args, &block)
|
128
|
+
wrapped!(name)
|
129
|
+
|
130
|
+
wrap!(name) if
|
131
|
+
begin
|
132
|
+
instance_method(name)
|
133
|
+
true
|
134
|
+
rescue NameError
|
135
|
+
false
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def wrapped!(name)
|
140
|
+
name = name.to_s
|
141
|
+
wrapped.push(name) unless wrapped.include?(name)
|
142
|
+
name
|
143
|
+
end
|
144
|
+
|
145
|
+
def wrapped
|
146
|
+
@wrapped ||= []
|
147
|
+
end
|
148
|
+
|
149
|
+
def wrapped?(name)
|
150
|
+
ancestors.any?{|ancestor| ancestor.respond_to?(:wrapped) and ancestor.wrapped.include?(name.to_s)}
|
151
|
+
end
|
152
|
+
|
153
|
+
def wrap!(name)
|
154
|
+
name = name.to_s
|
155
|
+
method = instance_method(name)
|
156
|
+
arity = method.arity
|
157
|
+
|
158
|
+
wrapping! name do
|
159
|
+
name = name.to_s
|
160
|
+
wrapped_name = "wrapped_#{ name }"
|
161
|
+
|
162
|
+
begin
|
163
|
+
remove_method(wrapped_name)
|
164
|
+
rescue NameError
|
165
|
+
nil
|
166
|
+
end
|
167
|
+
|
168
|
+
alias_method(wrapped_name, name)
|
169
|
+
|
170
|
+
module_eval(Wrap.code_for(method))
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def wrapping!(name, &block)
|
175
|
+
name = name.to_s
|
176
|
+
@wrapping ||= []
|
177
|
+
|
178
|
+
return if @wrapping.last == name
|
179
|
+
|
180
|
+
@wrapping.push(name)
|
181
|
+
|
182
|
+
begin
|
183
|
+
block.call
|
184
|
+
ensure
|
185
|
+
@wrapping.pop
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
def wrapping?(*name)
|
190
|
+
@wrapping ||= []
|
191
|
+
|
192
|
+
if name.empty?
|
193
|
+
!@wrapping.empty?
|
194
|
+
else
|
195
|
+
@wrapping.last == name.last.to_s
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
def callbacks
|
200
|
+
@callbacks ||= Map.new
|
201
|
+
end
|
202
|
+
|
203
|
+
def initialize_callbacks!(name)
|
204
|
+
callbacks[name] ||= Map[ :before, [], :after, [] ]
|
205
|
+
callbacks[name]
|
206
|
+
end
|
207
|
+
|
208
|
+
def before(name, *args, &block)
|
209
|
+
wrap(name) unless wrapped?(name)
|
210
|
+
name = wrap_expand_aliases(name)
|
211
|
+
cb = initialize_callbacks!(name)
|
212
|
+
cb.before.push(args.shift || block)
|
213
|
+
end
|
214
|
+
|
215
|
+
def after(name, *args, &block)
|
216
|
+
wrap(name) unless wrapped?(name)
|
217
|
+
name = wrap_expand_aliases(name)
|
218
|
+
cb = initialize_callbacks!(name)
|
219
|
+
cb.after.push(args.shift || block)
|
220
|
+
end
|
221
|
+
|
222
|
+
def wrap_aliases
|
223
|
+
@@wrap_aliases ||= Hash.new
|
224
|
+
end
|
225
|
+
|
226
|
+
def wrap_alias(dst, src)
|
227
|
+
wrap_aliases[dst.to_s] = src.to_s
|
228
|
+
end
|
229
|
+
|
230
|
+
def wrap_expand_aliases(name)
|
231
|
+
name = name.to_s
|
232
|
+
loop do
|
233
|
+
break unless wrap_aliases.has_key?(name)
|
234
|
+
name = wrap_aliases[name]
|
235
|
+
end
|
236
|
+
name
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
InstanceMethods = proc do
|
241
|
+
def running_callbacks(name, &block)
|
242
|
+
name = name.to_s
|
243
|
+
@running_callbacks ||= []
|
244
|
+
return block.call() if @running_callbacks.last == name
|
245
|
+
|
246
|
+
@running_callbacks.push(name)
|
247
|
+
|
248
|
+
begin
|
249
|
+
block.call()
|
250
|
+
ensure
|
251
|
+
@running_callbacks.pop
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
def running_callbacks?(*name)
|
256
|
+
@running_callbacks ||= []
|
257
|
+
|
258
|
+
if name.empty?
|
259
|
+
@running_callbacks.last
|
260
|
+
else
|
261
|
+
@running_callbacks.last == name.last.to_s
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
def run_callbacks(which, name, argv)
|
266
|
+
which = which.to_s.to_sym
|
267
|
+
name = name.to_s
|
268
|
+
list = []
|
269
|
+
|
270
|
+
self.class.ancestors.each do |ancestor|
|
271
|
+
next unless ancestor.respond_to?(:callbacks)
|
272
|
+
|
273
|
+
if ancestor.callbacks.is_a?(Map) and ancestor.callbacks[name].is_a?(Map)
|
274
|
+
callbacks = ancestor.callbacks[name][which]
|
275
|
+
accumulate = (which == :before ? :unshift : :push)
|
276
|
+
list.send(accumulate, *callbacks) if callbacks.is_a?(Array)
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
list.each do |callback|
|
281
|
+
block = callback.respond_to?(:call) ? callback : proc{ send(callback.to_s.to_sym) }
|
282
|
+
args = argv.slice(0 .. (block.arity > 0 ? block.arity : -1))
|
283
|
+
result = instance_exec(*args, &block)
|
284
|
+
return false if result == false
|
285
|
+
end
|
286
|
+
|
287
|
+
true
|
288
|
+
end
|
289
|
+
|
290
|
+
def halt!(*args)
|
291
|
+
value = args.size == 0 ? false : args.shift
|
292
|
+
throw(:halt, value)
|
293
|
+
end
|
294
|
+
end
|
295
|
+
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
|
+
}
|