dao 7.0.0 → 8.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
data/lib/dao/conducer.rb
CHANGED
@@ -86,14 +86,10 @@ module Dao
|
|
86
86
|
# instance methods
|
87
87
|
#
|
88
88
|
%w[
|
89
|
-
attributes
|
90
|
-
form
|
91
89
|
params
|
92
|
-
errors
|
93
90
|
messages
|
94
91
|
models
|
95
92
|
model
|
96
|
-
conduces
|
97
93
|
].each{|attr| fattr(attr)}
|
98
94
|
|
99
95
|
# ctors
|
@@ -323,6 +319,10 @@ module Dao
|
|
323
319
|
update_attributes(attributes)
|
324
320
|
end
|
325
321
|
|
322
|
+
def attributes
|
323
|
+
@attributes
|
324
|
+
end
|
325
|
+
|
326
326
|
def set(*args, &block)
|
327
327
|
update_attributes(*args, &block)
|
328
328
|
end
|
@@ -399,10 +399,10 @@ module Dao
|
|
399
399
|
end
|
400
400
|
|
401
401
|
def id_for(object)
|
402
|
-
|
402
|
+
modelish?(object) ? object.id : object
|
403
403
|
end
|
404
404
|
|
405
|
-
def
|
405
|
+
def modelish?(object)
|
406
406
|
object.respond_to?(:persisted?)
|
407
407
|
end
|
408
408
|
|
@@ -478,10 +478,6 @@ module Dao
|
|
478
478
|
Dao.key_for(key)
|
479
479
|
end
|
480
480
|
|
481
|
-
def errors
|
482
|
-
validator.errors
|
483
|
-
end
|
484
|
-
|
485
481
|
def model_name
|
486
482
|
self.class.model_name
|
487
483
|
end
|
data/lib/dao/errors2html.rb
CHANGED
data/lib/dao/support.rb
CHANGED
@@ -183,11 +183,12 @@ module Dao
|
|
183
183
|
def json_for(object, options = {})
|
184
184
|
object = object.as_json if object.respond_to?(:as_json)
|
185
185
|
|
186
|
-
|
187
|
-
|
186
|
+
pretty = (options.delete(:pretty) || json_pretty?)
|
187
|
+
|
188
|
+
generate = pretty ? :pretty_generate : :generate
|
188
189
|
|
189
190
|
begin
|
190
|
-
|
191
|
+
JSON.send(generate, object, options)
|
191
192
|
rescue Object => _
|
192
193
|
YAML.load( object.to_yaml ).to_json
|
193
194
|
end
|
@@ -231,21 +232,9 @@ module Dao
|
|
231
232
|
end
|
232
233
|
end
|
233
234
|
|
234
|
-
|
235
|
-
|
236
|
-
'ffi-uuid' => proc{|*args| FFI::UUID.generate_time.to_s},
|
237
|
-
'uuidtools' => proc{|*args| UUIDTools::UUID.timestamp_create.to_s},
|
238
|
-
'uuid' => proc{|*args| UUID.generate.to_s},
|
239
|
-
}.each do |lib, implementation|
|
240
|
-
begin
|
241
|
-
require(lib)
|
242
|
-
define_method(:uuid, &implementation)
|
243
|
-
break
|
244
|
-
rescue LoadError
|
245
|
-
nil
|
246
|
-
end
|
235
|
+
def uuid
|
236
|
+
SecureRandom.uuid
|
247
237
|
end
|
248
|
-
abort 'no suitable uuid generation library detected' unless method_defined?(:uuid)
|
249
238
|
|
250
239
|
def ensure_interface!(object, *interface)
|
251
240
|
interface.flatten.compact.each do |method|
|
data/lib/dao/wrap.rb
ADDED
@@ -0,0 +1,259 @@
|
|
1
|
+
module Dao
|
2
|
+
module Wrap
|
3
|
+
def Wrap.included(other)
|
4
|
+
super
|
5
|
+
ensure
|
6
|
+
other.send(:instance_eval, &ClassMethods)
|
7
|
+
other.send(:class_eval, &InstanceMethods)
|
8
|
+
end
|
9
|
+
|
10
|
+
def Wrap.code_for(method)
|
11
|
+
name = method.name.to_s
|
12
|
+
arity = method.arity
|
13
|
+
|
14
|
+
case
|
15
|
+
when arity == 0
|
16
|
+
signature = <<-__.strip
|
17
|
+
def #{ name }(&block)
|
18
|
+
args = []
|
19
|
+
__
|
20
|
+
|
21
|
+
when arity < 0
|
22
|
+
argv = Array.new(arity.abs - 1){|i| "arg#{ i }"}
|
23
|
+
argv.push('*args')
|
24
|
+
argv = argv.join(', ')
|
25
|
+
|
26
|
+
signature = <<-__.strip
|
27
|
+
def #{ name }(#{ argv }, &block)
|
28
|
+
args = [#{ argv }]
|
29
|
+
__
|
30
|
+
|
31
|
+
when arity > 0
|
32
|
+
argv = Array.new(arity){|i| "arg#{ i }"}
|
33
|
+
argv = argv.join(', ')
|
34
|
+
|
35
|
+
signature = <<-__.strip
|
36
|
+
def #{ name }(#{ argv }, &block)
|
37
|
+
args = [#{ argv }]
|
38
|
+
__
|
39
|
+
end
|
40
|
+
|
41
|
+
code =
|
42
|
+
<<-__
|
43
|
+
#{ signature.strip }
|
44
|
+
|
45
|
+
if running_callbacks?(#{ name.inspect })
|
46
|
+
return wrapped_#{ name }(*args, &block)
|
47
|
+
end
|
48
|
+
|
49
|
+
running_callbacks(#{ name.inspect }) do
|
50
|
+
catch(:halt) do
|
51
|
+
return false if run_callbacks(:before, #{ name.inspect }, args)==false
|
52
|
+
|
53
|
+
begin
|
54
|
+
result = wrapped_#{ name }(*args, &block)
|
55
|
+
ensure
|
56
|
+
run_callbacks(:after, #{ name.inspect }, [result]) unless $!
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
__
|
62
|
+
|
63
|
+
return code
|
64
|
+
end
|
65
|
+
|
66
|
+
ClassMethods = proc do
|
67
|
+
def method_added(name)
|
68
|
+
return super if wrapping?
|
69
|
+
begin
|
70
|
+
super
|
71
|
+
ensure
|
72
|
+
wrap!(name) if wrapped?(name)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def include(other)
|
77
|
+
super
|
78
|
+
ensure
|
79
|
+
other.instance_methods.each do |name|
|
80
|
+
if wrapped?(name)
|
81
|
+
begin
|
82
|
+
remove_method(name)
|
83
|
+
rescue NameError
|
84
|
+
nil
|
85
|
+
end
|
86
|
+
wrap!(name)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def wrap(name, *args, &block)
|
92
|
+
wrapped!(name)
|
93
|
+
|
94
|
+
wrap!(name) if
|
95
|
+
begin
|
96
|
+
instance_method(name)
|
97
|
+
true
|
98
|
+
rescue NameError
|
99
|
+
false
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def wrapped!(name)
|
104
|
+
name = name.to_s
|
105
|
+
wrapped.push(name) unless wrapped.include?(name)
|
106
|
+
name
|
107
|
+
end
|
108
|
+
|
109
|
+
def wrapped
|
110
|
+
@wrapped ||= []
|
111
|
+
end
|
112
|
+
|
113
|
+
def wrapped?(name)
|
114
|
+
ancestors.any?{|ancestor| ancestor.respond_to?(:wrapped) and ancestor.wrapped.include?(name.to_s)}
|
115
|
+
end
|
116
|
+
|
117
|
+
def wrap!(name)
|
118
|
+
name = name.to_s
|
119
|
+
method = instance_method(name)
|
120
|
+
|
121
|
+
wrapping! name do
|
122
|
+
name = name.to_s
|
123
|
+
wrapped_name = "wrapped_#{ name }"
|
124
|
+
|
125
|
+
begin
|
126
|
+
remove_method(wrapped_name)
|
127
|
+
rescue NameError
|
128
|
+
nil
|
129
|
+
end
|
130
|
+
|
131
|
+
alias_method(wrapped_name, name)
|
132
|
+
|
133
|
+
module_eval(Wrap.code_for(method))
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def wrapping!(name, &block)
|
138
|
+
name = name.to_s
|
139
|
+
@wrapping ||= []
|
140
|
+
|
141
|
+
return if @wrapping.last == name
|
142
|
+
|
143
|
+
@wrapping.push(name)
|
144
|
+
|
145
|
+
begin
|
146
|
+
block.call
|
147
|
+
ensure
|
148
|
+
@wrapping.pop
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def wrapping?(*name)
|
153
|
+
@wrapping ||= []
|
154
|
+
|
155
|
+
if name.empty?
|
156
|
+
!@wrapping.empty?
|
157
|
+
else
|
158
|
+
@wrapping.last == name.last.to_s
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def callbacks
|
163
|
+
@callbacks ||= Map.new
|
164
|
+
end
|
165
|
+
|
166
|
+
def initialize_callbacks!(name)
|
167
|
+
callbacks[name] ||= Map[ :before, [], :after, [] ]
|
168
|
+
callbacks[name]
|
169
|
+
end
|
170
|
+
|
171
|
+
def before(name, *args, &block)
|
172
|
+
wrap(name) unless wrapped?(name)
|
173
|
+
name = wrap_expand_aliases(name)
|
174
|
+
cb = initialize_callbacks!(name)
|
175
|
+
cb.before.push(args.shift || block)
|
176
|
+
end
|
177
|
+
|
178
|
+
def after(name, *args, &block)
|
179
|
+
wrap(name) unless wrapped?(name)
|
180
|
+
name = wrap_expand_aliases(name)
|
181
|
+
cb = initialize_callbacks!(name)
|
182
|
+
cb.after.push(args.shift || block)
|
183
|
+
end
|
184
|
+
|
185
|
+
def wrap_aliases
|
186
|
+
@@wrap_aliases ||= Hash.new
|
187
|
+
end
|
188
|
+
|
189
|
+
def wrap_alias(dst, src)
|
190
|
+
wrap_aliases[dst.to_s] = src.to_s
|
191
|
+
end
|
192
|
+
|
193
|
+
def wrap_expand_aliases(name)
|
194
|
+
name = name.to_s
|
195
|
+
loop do
|
196
|
+
break unless wrap_aliases.has_key?(name)
|
197
|
+
name = wrap_aliases[name]
|
198
|
+
end
|
199
|
+
name
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
InstanceMethods = proc do
|
204
|
+
def running_callbacks(name, &block)
|
205
|
+
name = name.to_s
|
206
|
+
@running_callbacks ||= []
|
207
|
+
return block.call() if @running_callbacks.last == name
|
208
|
+
|
209
|
+
@running_callbacks.push(name)
|
210
|
+
|
211
|
+
begin
|
212
|
+
block.call()
|
213
|
+
ensure
|
214
|
+
@running_callbacks.pop
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
def running_callbacks?(*name)
|
219
|
+
@running_callbacks ||= []
|
220
|
+
|
221
|
+
if name.empty?
|
222
|
+
@running_callbacks.last
|
223
|
+
else
|
224
|
+
@running_callbacks.last == name.last.to_s
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
def run_callbacks(which, name, argv)
|
229
|
+
which = which.to_s.to_sym
|
230
|
+
name = name.to_s
|
231
|
+
list = []
|
232
|
+
|
233
|
+
self.class.ancestors.each do |ancestor|
|
234
|
+
next unless ancestor.respond_to?(:callbacks)
|
235
|
+
|
236
|
+
if ancestor.callbacks.is_a?(Map) and ancestor.callbacks[name].is_a?(Map)
|
237
|
+
callbacks = ancestor.callbacks[name][which]
|
238
|
+
accumulate = (which == :before ? :unshift : :push)
|
239
|
+
list.send(accumulate, *callbacks) if callbacks.is_a?(Array)
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
list.each do |callback|
|
244
|
+
block = callback.respond_to?(:call) ? callback : proc{ send(callback.to_s.to_sym) }
|
245
|
+
args = argv.slice(0 .. (block.arity > 0 ? block.arity : -1))
|
246
|
+
result = instance_exec(*args, &block)
|
247
|
+
return false if result == false
|
248
|
+
end
|
249
|
+
|
250
|
+
true
|
251
|
+
end
|
252
|
+
|
253
|
+
def halt!(*args)
|
254
|
+
value = args.size == 0 ? false : args.shift
|
255
|
+
throw(:halt, value)
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
data/test/conducer_test.rb
CHANGED
@@ -498,7 +498,7 @@ $pry=true
|
|
498
498
|
|
499
499
|
path = File.join(File.dirname(__FILE__), 'data/han-solo.jpg')
|
500
500
|
assert{ test(?s, path) }
|
501
|
-
|
501
|
+
_up = Upload.new(path)
|
502
502
|
comment = Comment.new
|
503
503
|
|
504
504
|
c = conducer_class.new( comment, :up => {:file => Upload.new(path)} )
|
@@ -512,8 +512,8 @@ $pry=true
|
|
512
512
|
|
513
513
|
assert{ c.save }
|
514
514
|
|
515
|
-
|
516
|
-
|
515
|
+
_value_was_relayed = assert{ comment.attributes[:up] == upload._value }
|
516
|
+
_value_was_cleared = assert{ !test(?f, upload.path) }
|
517
517
|
|
518
518
|
assert{ test(?s, path) }
|
519
519
|
ensure
|
@@ -705,7 +705,7 @@ protected
|
|
705
705
|
|
706
706
|
def method_missing(method, *args, &block)
|
707
707
|
re = /^([^=!?]+)([=!?])?$/imox
|
708
|
-
|
708
|
+
_matched, key, suffix = re.match(method.to_s).to_a
|
709
709
|
|
710
710
|
case suffix
|
711
711
|
when '=' then attributes.set(key, args.first)
|
data/test/form_test.rb
CHANGED
data/test/validations_test.rb
CHANGED
@@ -111,8 +111,9 @@ class DaoValidationsTest < ::Dao::TestCase
|
|
111
111
|
end
|
112
112
|
|
113
113
|
test 'simple validates_confirmation_of' do
|
114
|
+
=begin
|
114
115
|
return :pending
|
115
|
-
|
116
|
+
=end
|
116
117
|
api_class =
|
117
118
|
Dao.api do
|
118
119
|
endpoint('/foobar'){
|
@@ -136,7 +137,6 @@ class DaoValidationsTest < ::Dao::TestCase
|
|
136
137
|
#
|
137
138
|
test 'that validations clear only that which they know about' do
|
138
139
|
params = Dao::Params.new
|
139
|
-
errors = params.errors
|
140
140
|
|
141
141
|
assert{ params.validates(:email){|email| email.to_s.split(/@/).size == 2} }
|
142
142
|
assert{ params.validates(:password){|password| password == 'pa$$w0rd'} }
|
data/wrap-1.5.2/README
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
NAME
|
2
|
+
wrap
|
3
|
+
|
4
|
+
SYNOPSIS
|
5
|
+
non-sucking :before and :after filters for any ruby class
|
6
|
+
|
7
|
+
DESCRIPTION
|
8
|
+
yes yes, active_support does this. but crapily. with active_support you'll
|
9
|
+
need to do this
|
10
|
+
|
11
|
+
|
12
|
+
class Record
|
13
|
+
include ActiveSupport::Callbacks
|
14
|
+
define_callbacks :save
|
15
|
+
|
16
|
+
def save
|
17
|
+
run_callbacks :save do
|
18
|
+
puts "- save"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
but hey, if a subclass forgets to call 'super' or doesn't manually run
|
24
|
+
'run_callbacks' the codez are *screwed*. that sux. why not this?
|
25
|
+
|
26
|
+
|
27
|
+
class Record
|
28
|
+
include Wrap
|
29
|
+
|
30
|
+
wrap :save
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
yes, it's that simple. you can now do
|
35
|
+
|
36
|
+
class SubRecord < Record
|
37
|
+
before :save do
|
38
|
+
special_sauce
|
39
|
+
end
|
40
|
+
|
41
|
+
def save
|
42
|
+
no_special_sauce
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
did you get that? the :before and :after hooks will be called no matter
|
47
|
+
what the subclass does. the method will be wrapped, period. no special
|
48
|
+
work required. of course, if the sublcass messes with 'method_added' their
|
49
|
+
will be hell to pay. that's the price for simplicity.
|
50
|
+
|
51
|
+
the callbacks are very close, but not identical to active_supports. you can
|
52
|
+
return 'false' to halt the chain, but you can also simply call 'halt!'.
|
53
|
+
another neat trick is that :before callbacks will be called with the
|
54
|
+
arguments to the wrapped method itself iff possible and :after callbacks
|
55
|
+
will be called with the result of the wrapped method, iff possible.
|
56
|
+
|
57
|
+
the test suite reads pretty damn clean. have a go.
|