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.
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
+ }