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.
@@ -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
- model?(object) ? object.id : object
402
+ modelish?(object) ? object.id : object
403
403
  end
404
404
 
405
- def model?(object)
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
@@ -71,7 +71,7 @@ module Dao
71
71
  when Map
72
72
  hash = Hash.new
73
73
  hashlike.depth_first_each do |key, value|
74
- index = key.pop if key.last.is_a?(Integer)
74
+ _ = key.pop if key.last.is_a?(Integer)
75
75
  (hash[key] ||= []).push(value)
76
76
  end
77
77
  hash
@@ -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
- options = options.empty? ? Map.for(options) : options
187
- options[:pretty] = json_pretty? unless options.has_key?(:pretty)
186
+ pretty = (options.delete(:pretty) || json_pretty?)
187
+
188
+ generate = pretty ? :pretty_generate : :generate
188
189
 
189
190
  begin
190
- MultiJson.dump(object, options)
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|
@@ -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
@@ -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
- up = Upload.new(path)
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
- value_was_relayed = assert{ comment.attributes[:up] == upload._value }
516
- value_was_cleared = assert{ !test(?f, upload.path) }
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
- matched, key, suffix = re.match(method.to_s).to_a
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)
@@ -2,8 +2,8 @@
2
2
  require_relative 'test_helper'
3
3
  class DaoFormTest < ::Dao::TestCase
4
4
  test '.new' do
5
- form = new_form()
6
- form = new_named_form()
5
+ _ = new_form()
6
+ _ = new_named_form()
7
7
  end
8
8
 
9
9
  test 'name_for' do
@@ -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'} }
@@ -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.