dao 4.4.4 → 4.6.4

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.
data/lib/dao/rails.rb CHANGED
@@ -27,6 +27,10 @@ if defined?(Rails)
27
27
  #initializer "dao.middleware" do |app|
28
28
  #app.middleware.use Dao::Middleware::ParamsParser
29
29
  #end
30
+
31
+ config.after_initialize do
32
+ Dao::Conducer.install_routes!
33
+ end
30
34
 
31
35
  # yes yes, this should probably be somewhere else...
32
36
  #
@@ -1,28 +1,18 @@
1
- /* dao errors */
1
+ /* dao form errors */
2
2
 
3
- .dao.errors {
4
- font-weight: normal;
3
+ .errors-summary {
4
+ box-sizing: border-box;
5
5
  width: 100%;
6
- border-bottom: 1px solid #ccc;
7
- background-color: #ffe;
8
- padding: 0.5em;
6
+ height: auto;
7
+ color: #666;
8
+ background-color: #fffff6;
9
+ padding: 1em;
9
10
  }
10
-
11
- .dao.errors .caption {
11
+ .errors-caption {
12
12
  font-weight: bold;
13
- color: #333;
14
- font-style: italic;
15
- text-align: left;
16
- margin-bottom: 0.5em;
17
13
  }
18
-
19
- .dao.errors .title {
20
- padding-left: 1em;
21
- color: #666;
14
+ .errors-title {
22
15
  }
23
-
24
- .dao.errors .message {
25
- font-style: italic;
26
- font-weight: bold;
27
- width: 100%;
16
+ .errors-message {
28
17
  }
18
+
@@ -1,52 +1,27 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  module DaoHelper
3
3
  def dao_form_for(*args, &block)
4
- options = args.extract_options!.to_options!
5
-
6
- model = args.flatten.detect{|arg| arg.respond_to?(:persisted?)}
7
-
8
- if model
9
- first = args.shift
10
- url = args.shift || options.delete(:url)
4
+ model = args.flatten.select{|arg| arg.respond_to?(:persisted?)}.last
11
5
 
12
- method = options.delete(:method)
13
- html = dao_form_attrs(options)
14
-
15
- options.clear
6
+ options = args.extract_options!.to_options!
16
7
 
17
- if model.persisted?
18
- method ||= :put
19
- else
20
- method ||= :post
21
- end
8
+ options[:builder] = Dao::Form::Builder
22
9
 
23
- url =
24
- case method
25
- when :put
26
- url_for(:action => :update)
27
- when :post
28
- url_for(:action => :create)
29
- else
30
- './'
31
- end
10
+ if options[:post] or model.blank?
11
+ options[:url] ||= (options.delete(:post) || request.fullpath)
12
+ options[:method] ||= :post
13
+ end
32
14
 
33
- options[:url] = url
34
- options[:html] = html.dup.merge(:method => method)
35
- #options[:builder] = Dao::Form::Builder
15
+ args.push(options)
36
16
 
37
- args.push(model)
38
- args.push(options)
39
-
40
- form_for(*args) do
41
- block.call(model.form)
42
- end
43
- else
44
- args.push(request.fullpath) if args.empty?
45
- args.push(dao_form_attrs(options))
46
- form_tag(*args, &block)
17
+ if model.blank?
18
+ name = 'form'
19
+ model = Class.new(Dao::Conducer){ model_name(name) }.new(params[name])
20
+ args.unshift(model)
47
21
  end
48
- end
49
22
 
23
+ form_for(*args, &block)
24
+ end
50
25
  alias_method(:dao_form, :dao_form_for)
51
26
 
52
27
  def dao_form_attrs(*args)
@@ -92,11 +67,10 @@ module DaoHelper
92
67
 
93
68
  @dao = api.send(mode, path, params)
94
69
  @dao.route = request.fullpath
95
- #@dao.mode = mode
96
70
 
97
- #unless options[:error!] == false
98
- @dao.error! unless @dao.status.ok?
99
- #end
71
+ unless options[:error!] == false
72
+ @dao.error! unless(@dao.status =~ or @dao.status == 420)
73
+ end
100
74
 
101
75
  block ? block.call(@dao) : @dao
102
76
  end
data/lib/dao/route.rb CHANGED
@@ -20,7 +20,7 @@ module Dao
20
20
  def pattern_for(route)
21
21
  route = Path.absolute_path_for(route.to_s)
22
22
  re = route.gsub(%r{/:[^/]+}, '/([^/]+)')
23
- /#{ re }/ioux
23
+ /#{ re }/iux
24
24
  end
25
25
 
26
26
  def path_for(route, params = {})
@@ -59,7 +59,8 @@ module Dao
59
59
 
60
60
  def params_for(path)
61
61
  match = pattern.match(path).to_a
62
- if match
62
+
63
+ unless match.empty?
63
64
  map = Map.new
64
65
  ignored = match.shift
65
66
  @keys.each_with_index do |key, index|
@@ -79,7 +80,7 @@ module Dao
79
80
  def match(name)
80
81
  each do |route|
81
82
  match = route.match(name)
82
- return route if match
83
+ return route unless match.empty?
83
84
  end
84
85
  return nil
85
86
  end
data/lib/dao/upload.rb CHANGED
@@ -152,6 +152,13 @@ class Upload < ::Map
152
152
  end
153
153
  end
154
154
 
155
+ def path_for(arg)
156
+ [:original_path, :original_filename, :path, :filename, :pathname].
157
+ map{|msg| arg.send(msg).to_s if arg.respond_to?(msg)}.
158
+ compact.
159
+ first or raise("could not find path_for(#{ arg.inspect })")
160
+ end
161
+
155
162
  alias_method('mount', 'new')
156
163
  end
157
164
 
@@ -161,7 +168,7 @@ class Upload < ::Map
161
168
  attr_accessor :hidden_key
162
169
  attr_accessor :name
163
170
  attr_accessor :value
164
- attr_accessor :path
171
+ attr_reader :path
165
172
  attr_accessor :dirname
166
173
  attr_accessor :basename
167
174
  attr_accessor :io
@@ -192,6 +199,8 @@ class Upload < ::Map
192
199
  end
193
200
 
194
201
  def _set(value)
202
+ return unless value
203
+
195
204
  value =
196
205
  case
197
206
  when value.is_a?(Hash)
@@ -216,6 +225,8 @@ class Upload < ::Map
216
225
  url = @value ? File.join(Upload.url, @value) : @placeholder.url
217
226
 
218
227
  update(:file => @io, :cache => @value, :url => url)
228
+
229
+ set_path(Upload.path_for(@io)) rescue nil
219
230
  end
220
231
 
221
232
  def _key
@@ -280,7 +291,7 @@ class Upload < ::Map
280
291
  copied = false
281
292
 
282
293
  Upload.rewind(io) do
283
- src = io.path
294
+ src = Upload.path_for(io)
284
295
  dst = path
285
296
 
286
297
  strategies = [
@@ -305,15 +316,26 @@ class Upload < ::Map
305
316
  end
306
317
 
307
318
  def gcopen(path)
308
- @path = path
309
- @dirname, @basename = File.split(@path)
310
- @value = File.join(File.basename(@dirname), @basename).strip
319
+ set_path(path)
311
320
  @io = open(@path, 'rb')
312
321
  IOs[object_id] = @io.fileno
313
322
  ObjectSpace.define_finalizer(self, Upload.method(:finalizer).to_proc)
314
323
  @io
315
324
  end
316
325
 
326
+ def set_path(path)
327
+ if path
328
+ @path = path.to_s.strip
329
+ @dirname, @basename = File.split(@path)
330
+ @value = File.join(File.basename(@dirname), @basename).strip
331
+ @path
332
+ else
333
+ @path, @dirname, @basename, @value = nil
334
+ end
335
+ end
336
+
337
+ alias_method('path=', 'set_path')
338
+
317
339
  def inspect
318
340
  {
319
341
  Upload.name =>
@@ -63,7 +63,6 @@ module Dao
63
63
  valid?
64
64
  forcing_validity?
65
65
  errors
66
- status
67
66
  ).each do |method|
68
67
  module_eval <<-__, __FILE__, __LINE__
69
68
  def #{ method }(*args, &block)
@@ -17,7 +17,9 @@ module Dao
17
17
 
18
18
  class << Validator
19
19
  def mixin(*args, &block)
20
- new(*args, &block).tap{|validator| validator.mixin = true}
20
+ new(*args, &block).tap do |validator|
21
+ validator.mixin = true
22
+ end
21
23
  end
22
24
  end
23
25
 
@@ -58,6 +60,8 @@ module Dao
58
60
  @object.validator = self
59
61
  end
60
62
 
63
+ @errors.object = @object
64
+
61
65
  #@object.extend(InstanceExec) unless @object.respond_to?(:instance_exec)
62
66
  end
63
67
 
@@ -30,10 +30,39 @@ Testing Dao::Conducer do
30
30
  assert{ c.models == [comment, post, user] }
31
31
  assert{ c.model == comment }
32
32
  assert{ c.model == c.conduces }
33
+ end
34
+
35
+ #
36
+ testing 'that the conduced model can be declared at the class level' do
37
+ user = User.new
38
+ post = Post.new
39
+ comment = Comment.new
40
+ params = {}
41
+
42
+ args = [comment, post, user, params]
43
+
44
+ c = new_conducer(*args){ conduces User }
33
45
 
34
- assert{ c.conduces(post) }
35
- assert{ c.models == [post, comment, user] }
36
- assert{ c.model == post }
46
+ assert{ c.models == [comment, post, user] }
47
+ assert{ c.model == user }
48
+ assert{ c.model == c.conduces }
49
+ end
50
+
51
+ #
52
+ testing 'that the conduced model can be declared at the instance level' do
53
+ user = User.new
54
+ post = Post.new
55
+ comment = Comment.new
56
+ params = {}
57
+
58
+ args = [comment, post, user, params]
59
+
60
+ c = new_conducer(*args)
61
+
62
+ c.conduces(user)
63
+
64
+ assert{ c.models == [user, comment, post] }
65
+ assert{ c.model == user }
37
66
  assert{ c.model == c.conduces }
38
67
  end
39
68
  end
@@ -80,10 +109,10 @@ Testing Dao::Conducer do
80
109
  assert{ c.instance_variable_get('@post') == post }
81
110
 
82
111
  expected = Map.new
83
- expected.update :user => user.attributes
84
- expected.update :post => post.attributes
85
- expected.update comment.attributes
86
- expected.update params
112
+ expected.add :user => user.attributes
113
+ expected.add :post => post.attributes
114
+ expected.add comment.attributes
115
+ expected.add params
87
116
 
88
117
  assert{ c.attributes =~ expected }
89
118
  assert{ c.instance_variable_get('@comment') == comment }
@@ -151,6 +180,15 @@ Testing Dao::Conducer do
151
180
  end
152
181
  end
153
182
 
183
+ #
184
+ testing 'that conducers *fold* in attributes' do
185
+ c = new_conducer
186
+
187
+ assert{ c.update_attributes :key => {:a => :b} }
188
+ assert{ c.update_attributes :key => {:nested => {:a => :b}} }
189
+ assert{ c.attributes =~ {:key => {:a => :b, :nested => {:a => :b}}} }
190
+ end
191
+
154
192
  ##
155
193
  #
156
194
  context :teh_default_save do
@@ -451,6 +489,8 @@ Testing Dao::Conducer do
451
489
 
452
490
  #
453
491
  testing 'that the default save uses the mounted _value and _clears it' do
492
+ begin
493
+ $pry=true
454
494
  conducer_class =
455
495
  new_conducer_class do
456
496
  mount Dao::Upload, :up, :placeholder => '/images/foo.jpg'
@@ -461,7 +501,7 @@ Testing Dao::Conducer do
461
501
  up = Upload.new(path)
462
502
  comment = Comment.new
463
503
 
464
- c = conducer_class.new( comment, :up => {:file => up} )
504
+ c = conducer_class.new( comment, :up => {:file => Upload.new(path)} )
465
505
 
466
506
  upload = assert{ c.get(:up) }
467
507
  assert{ upload.is_a?(Dao::Upload) }
@@ -476,6 +516,9 @@ Testing Dao::Conducer do
476
516
  value_was_cleared = assert{ !test(?f, upload.path) }
477
517
 
478
518
  assert{ test(?s, path) }
519
+ ensure
520
+ $pry=false
521
+ end
479
522
  end
480
523
  end
481
524
 
@@ -607,6 +650,10 @@ protected
607
650
  def initialize(path)
608
651
  super(IO.read(@path = path))
609
652
  end
653
+
654
+ def dup
655
+ self.class.new(path)
656
+ end
610
657
  end
611
658
 
612
659
  class Model
@@ -670,7 +717,7 @@ protected
670
717
  end
671
718
 
672
719
  def inspect(*args, &block)
673
- "#{ self.class.name }( #{ attributes.inspect } )"
720
+ "#{ self.class.name }(#{ attributes.inspect.strip })"
674
721
  end
675
722
 
676
723
  def errors
@@ -0,0 +1,81 @@
1
+ # -*- encoding : utf-8 -*-
2
+ Testing Dao::Errors do
3
+
4
+ testing 'that conducer-less error objects scopes keys in a generic fashion' do
5
+ e = Dao::Errors.new
6
+
7
+ e.add 'is fucked'
8
+ e.add 'foo is fucked'
9
+
10
+ actual = e.to_text
11
+
12
+ expected = <<-__
13
+ ---
14
+ global:
15
+ - is fucked
16
+ - foo is fucked
17
+ __
18
+
19
+ assert compress(actual) == compress(expected)
20
+ end
21
+
22
+ testing 'that conducer-based error objects scope keys in a model_name based fashion' do
23
+ c = new_foo_conducer
24
+
25
+ e = c.errors
26
+
27
+ e.add 'is fucked'
28
+ e.add 'foo is fucked'
29
+ e.add :first_name, 'is fucked'
30
+ e.add :last_name, 'is fucked'
31
+
32
+ actual = e.to_text
33
+
34
+ expected = <<-__
35
+ ---
36
+ foo:
37
+ - is fucked
38
+ - foo is fucked
39
+ foo.first_name:
40
+ - is fucked
41
+ foo.last_name:
42
+ - is fucked
43
+ __
44
+
45
+ assert compress(actual) == compress(expected)
46
+ end
47
+
48
+
49
+
50
+ protected
51
+ def compress(string)
52
+ string.to_s.gsub(/\s/, '')
53
+ end
54
+ def new_foo_conducer_class(&block)
55
+ const = :FooConducer
56
+ Object.send(:remove_const, const) if Object.send(:const_defined?, const)
57
+ name = const.to_s
58
+ c = assert{ Class.new(Dao::Conducer){ self.name = name } }
59
+ Object.send(:const_set, const, c)
60
+ assert{ c.name == 'FooConducer' }
61
+ assert{ c.model_name == 'Foo' }
62
+ assert{ c.table_name == 'foos' && c.collection_name == 'foos' }
63
+ assert{ c.class_eval(&block); true } if block
64
+ c
65
+ end
66
+ alias_method :new_conducer_class, :new_foo_conducer_class
67
+
68
+ def new_foo_conducer(*args, &block)
69
+ assert{ new_foo_conducer_class(&block).new(*args) }
70
+ end
71
+ alias_method :new_conducer, :new_foo_conducer
72
+ end
73
+
74
+ BEGIN {
75
+ testdir = File.dirname(File.expand_path(__FILE__))
76
+ rootdir = File.dirname(testdir)
77
+ libdir = File.join(rootdir, 'lib')
78
+ require File.join(libdir, 'dao')
79
+ require File.join(testdir, 'testing')
80
+ require 'stringio'
81
+ }