dao 5.5.0 → 8.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +6 -14
  2. data/README.md +258 -0
  3. data/Rakefile +4 -5
  4. data/coerce-0.0.8/README +28 -0
  5. data/coerce-0.0.8/Rakefile +392 -0
  6. data/coerce-0.0.8/coerce.gemspec +31 -0
  7. data/coerce-0.0.8/lib/coerce.rb +210 -0
  8. data/dao.gemspec +38 -25
  9. data/lib/dao.rb +18 -81
  10. data/lib/dao/_lib.rb +42 -0
  11. data/lib/dao/active_record.rb +8 -8
  12. data/lib/dao/api/call.rb +19 -4
  13. data/lib/dao/api/dsl.rb +1 -1
  14. data/lib/dao/coerce.rb +211 -0
  15. data/lib/dao/conducer.rb +10 -14
  16. data/lib/dao/conducer/controller_support.rb +5 -0
  17. data/lib/dao/conducer/view_support.rb +0 -2
  18. data/lib/dao/db.rb +0 -1
  19. data/lib/dao/errors.rb +17 -11
  20. data/lib/dao/errors2html.rb +128 -0
  21. data/lib/dao/form.rb +13 -16
  22. data/lib/dao/messages.rb +0 -4
  23. data/lib/dao/path.rb +1 -1
  24. data/lib/dao/route.rb +2 -2
  25. data/lib/dao/status.rb +3 -4
  26. data/lib/dao/support.rb +26 -19
  27. data/lib/dao/upload.rb +0 -1
  28. data/lib/dao/validations/common.rb +6 -6
  29. data/lib/dao/validations/validator.rb +3 -3
  30. data/lib/dao/wrap.rb +259 -0
  31. data/tasks/default.rake +207 -0
  32. data/tasks/this.rb +207 -0
  33. data/test/active_model_conducer_lint_test.rb +3 -11
  34. data/test/api_test.rb +24 -35
  35. data/test/conducer_test.rb +37 -47
  36. data/test/errors_test.rb +29 -13
  37. data/test/form_test.rb +24 -34
  38. data/test/rake_rerun_reporter.rb +74 -0
  39. data/test/support_test.rb +9 -14
  40. data/test/test_helper.rb +220 -0
  41. data/test/{helper.rb → util.rb} +0 -0
  42. data/test/validations_test.rb +14 -28
  43. data/wrap-1.5.2/README +57 -0
  44. data/wrap-1.5.2/Rakefile +394 -0
  45. data/wrap-1.5.2/lib/wrap.rb +295 -0
  46. data/{test → wrap-1.5.2/test}/testing.rb +0 -1
  47. data/wrap-1.5.2/test/wrap_test.rb +397 -0
  48. data/wrap-1.5.2/wrap.gemspec +38 -0
  49. metadata +47 -103
  50. data/Gemfile +0 -16
  51. data/Gemfile.lock +0 -118
  52. 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
@@ -1,4 +1,3 @@
1
- # -*- encoding : utf-8 -*-
2
1
  require 'test/unit'
3
2
 
4
3
  testdir = File.expand_path(File.dirname(__FILE__))
@@ -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
+ }