dao 5.6.1 → 7.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.
- checksums.yaml +7 -0
- data/README.md +258 -0
- data/Rakefile +6 -6
- data/dao.gemspec +25 -18
- data/lib/dao.rb +18 -74
- data/lib/dao/_lib.rb +46 -0
- data/lib/dao/active_record.rb +6 -6
- data/lib/dao/api/call.rb +14 -3
- data/lib/dao/api/dsl.rb +1 -1
- data/lib/dao/conducer.rb +4 -4
- data/lib/dao/conducer/view_support.rb +0 -2
- data/lib/dao/db.rb +0 -1
- data/lib/dao/errors.rb +9 -11
- data/lib/dao/errors2html.rb +128 -0
- data/lib/dao/form.rb +12 -15
- data/lib/dao/messages.rb +0 -4
- data/lib/dao/path.rb +1 -1
- data/lib/dao/route.rb +2 -2
- data/lib/dao/status.rb +3 -4
- data/lib/dao/support.rb +2 -2
- data/lib/dao/upload.rb +0 -1
- data/lib/dao/validations/common.rb +6 -6
- data/lib/dao/validations/validator.rb +3 -3
- data/notes/ara.txt +15 -0
- data/tasks/default.rake +207 -0
- data/tasks/this.rb +207 -0
- data/test/active_model_conducer_lint_test.rb +3 -11
- data/test/api_test.rb +24 -35
- data/test/conducer_test.rb +33 -43
- data/test/errors_test.rb +20 -14
- data/test/form_test.rb +22 -32
- data/test/rake_rerun_reporter.rb +74 -0
- data/test/support_test.rb +7 -14
- data/test/{testing.rb → test_helper.rb} +73 -49
- data/test/{helper.rb → util.rb} +0 -0
- data/test/validations_test.rb +12 -26
- metadata +51 -84
- data/Gemfile +0 -16
- data/Gemfile.lock +0 -118
- data/README +0 -256
data/lib/dao/_lib.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
module Dao
|
2
|
+
Version = '7.0.0' unless defined?(Version)
|
3
|
+
|
4
|
+
def version
|
5
|
+
Dao::Version
|
6
|
+
end
|
7
|
+
|
8
|
+
def dependencies
|
9
|
+
{
|
10
|
+
'rails' => [ 'rails' , ' ~> 5.2' ] ,
|
11
|
+
'map' => [ 'map' , ' ~> 6.0' ] ,
|
12
|
+
'fattr' => [ 'fattr' , ' ~> 2.2' ] ,
|
13
|
+
'coerce' => [ 'coerce' , ' ~> 0.0' ] ,
|
14
|
+
'tagz' => [ 'tagz' , ' ~> 9.9' ] ,
|
15
|
+
'multi_json' => [ 'multi_json' , ' ~> 1.0' ] ,
|
16
|
+
'uuidtools' => [ 'uuidtools' , ' ~> 2.1' ] ,
|
17
|
+
'wrap' => [ 'wrap' , ' ~> 1.5' ] ,
|
18
|
+
'rails_current' => [ 'rails_current' , ' ~> 2.0' ] ,
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
def description
|
23
|
+
"presenter, conductor, api, and better form objects for you rails' pleasure"
|
24
|
+
end
|
25
|
+
|
26
|
+
def libdir(*args, &block)
|
27
|
+
@libdir ||= File.dirname(File.expand_path(__FILE__).sub(/\.rb$/,''))
|
28
|
+
args.empty? ? @libdir : File.join(@libdir, *args)
|
29
|
+
ensure
|
30
|
+
if block
|
31
|
+
begin
|
32
|
+
$LOAD_PATH.unshift(@libdir)
|
33
|
+
block.call()
|
34
|
+
ensure
|
35
|
+
$LOAD_PATH.shift()
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def load(*libs)
|
41
|
+
libs = libs.join(' ').scan(/[^\s+]+/)
|
42
|
+
Dao.libdir{ libs.each{|lib| Kernel.load(lib) } }
|
43
|
+
end
|
44
|
+
|
45
|
+
extend Dao
|
46
|
+
end
|
data/lib/dao/active_record.rb
CHANGED
@@ -12,10 +12,10 @@ if defined?(ActiveRecord)
|
|
12
12
|
class Base
|
13
13
|
def Base.to_dao(*args)
|
14
14
|
if args.first.is_a?(Base)
|
15
|
-
record_to_dao(
|
15
|
+
record_to_dao(args.shift, *args)
|
16
16
|
else
|
17
17
|
@to_dao ||= (
|
18
|
-
|
18
|
+
column_names ### + reflect_on_all_associations.map(&:name)
|
19
19
|
)
|
20
20
|
@to_dao = Array(args) unless args.empty?
|
21
21
|
@to_dao
|
@@ -101,10 +101,10 @@ if defined?(ActiveRecord)
|
|
101
101
|
end
|
102
102
|
|
103
103
|
if attr.is_a?(Hash)
|
104
|
-
attr.each do |
|
105
|
-
v = record.send(
|
106
|
-
value = v.respond_to?(:to_dao) ? v.to_dao(*
|
107
|
-
map[
|
104
|
+
attr.each do |rel, _argv|
|
105
|
+
v = record.send(rel)
|
106
|
+
value = v.respond_to?(:to_dao) ? v.to_dao(*_argv) : v
|
107
|
+
map[rel] = value
|
108
108
|
end
|
109
109
|
next
|
110
110
|
end
|
data/lib/dao/api/call.rb
CHANGED
@@ -13,13 +13,14 @@ module Dao
|
|
13
13
|
:endpoints => Map.new,
|
14
14
|
:blocks => {},
|
15
15
|
:README => [],
|
16
|
-
:docs => []
|
16
|
+
:docs => [],
|
17
|
+
:paths => [],
|
17
18
|
}
|
18
19
|
end
|
19
20
|
|
20
21
|
def call(*args, &block)
|
21
22
|
options = Dao.options_for!(args)
|
22
|
-
path = Path.new(args.shift || raise(ArgumentError, "no path!"))
|
23
|
+
path = Path.new(args.shift || paths.shift || raise(ArgumentError, "no path!"))
|
23
24
|
|
24
25
|
api = self
|
25
26
|
|
@@ -44,7 +45,12 @@ module Dao
|
|
44
45
|
|
45
46
|
endpoints[path] = endpoint
|
46
47
|
end
|
47
|
-
|
48
|
+
|
49
|
+
def endpoint(path, &block)
|
50
|
+
paths << path.to_s
|
51
|
+
class_eval(&block)
|
52
|
+
end
|
53
|
+
#alias_method('endpoint', 'call')
|
48
54
|
|
49
55
|
def endpoints
|
50
56
|
state[:endpoints]
|
@@ -71,6 +77,10 @@ module Dao
|
|
71
77
|
state[:docs]
|
72
78
|
end
|
73
79
|
|
80
|
+
def paths
|
81
|
+
state[:paths]
|
82
|
+
end
|
83
|
+
|
74
84
|
def readme(*args)
|
75
85
|
if args.empty?
|
76
86
|
state[:README]
|
@@ -233,6 +243,7 @@ module Dao
|
|
233
243
|
# delgate some methods to the context
|
234
244
|
#
|
235
245
|
Context.attrs.each do |method|
|
246
|
+
next if %w[ status status! data data! index endpoints respond_to? parameter parameter! ].include?(method.to_s)
|
236
247
|
module_eval <<-__, __FILE__, __LINE__
|
237
248
|
def #{ method }(*args)
|
238
249
|
context.send(#{ method.inspect }, *args)
|
data/lib/dao/api/dsl.rb
CHANGED
data/lib/dao/conducer.rb
CHANGED
@@ -117,7 +117,7 @@ module Dao
|
|
117
117
|
controller.send(:action_name).to_s
|
118
118
|
end
|
119
119
|
|
120
|
-
|
120
|
+
new(Action.new(action), *args, &block)
|
121
121
|
end
|
122
122
|
|
123
123
|
def Conducer.call(*args, &block)
|
@@ -243,7 +243,7 @@ module Dao
|
|
243
243
|
end
|
244
244
|
|
245
245
|
def conduces?(model)
|
246
|
-
if @model
|
246
|
+
if defined?(@model)
|
247
247
|
@model == model
|
248
248
|
else
|
249
249
|
self.class.conduces?(model)
|
@@ -348,8 +348,8 @@ module Dao
|
|
348
348
|
def method_missing(method, *args, &block)
|
349
349
|
re = /^([^=!?]+)([=!?])?$/imox
|
350
350
|
|
351
|
-
|
352
|
-
|
351
|
+
_, key, suffix = re.match(method.to_s).to_a
|
352
|
+
|
353
353
|
case suffix
|
354
354
|
when '='
|
355
355
|
set(key, args.first)
|
@@ -10,9 +10,7 @@ module Dao
|
|
10
10
|
def install_routes!
|
11
11
|
url_helpers = Rails.application.try(:routes).try(:url_helpers)
|
12
12
|
include(url_helpers) if url_helpers
|
13
|
-
include(ActionView::Helpers) if defined?(ActionView::Helpers)
|
14
13
|
extend(url_helpers) if url_helpers
|
15
|
-
extend(ActionView::Helpers) if defined?(ActionView::Helpers)
|
16
14
|
end
|
17
15
|
end
|
18
16
|
end
|
data/lib/dao/db.rb
CHANGED
data/lib/dao/errors.rb
CHANGED
@@ -106,13 +106,13 @@ module Dao
|
|
106
106
|
list.clear if clear
|
107
107
|
list.push(message)
|
108
108
|
list.uniq!
|
109
|
-
list
|
110
109
|
self
|
111
110
|
end
|
112
111
|
alias_method('add!', 'add')
|
113
112
|
alias_method('add_to_base', 'add')
|
114
113
|
alias_method('add_to_base!', 'add!')
|
115
114
|
|
115
|
+
# FIXME - this should accept an errors object
|
116
116
|
def relay(*args)
|
117
117
|
options = args.size > 1 ? Map.options_for!(args) : Map.new
|
118
118
|
|
@@ -176,7 +176,7 @@ module Dao
|
|
176
176
|
full_messages = []
|
177
177
|
|
178
178
|
depth_first_each do |keys, value|
|
179
|
-
|
179
|
+
_ = keys.pop
|
180
180
|
key = keys
|
181
181
|
value = value.to_s
|
182
182
|
|
@@ -194,7 +194,7 @@ module Dao
|
|
194
194
|
|
195
195
|
def each_message
|
196
196
|
depth_first_each do |keys, message|
|
197
|
-
|
197
|
+
_ = keys.pop
|
198
198
|
message = message.to_s.strip
|
199
199
|
yield(keys, message)
|
200
200
|
end
|
@@ -204,7 +204,7 @@ module Dao
|
|
204
204
|
hash = Hash.new
|
205
205
|
|
206
206
|
depth_first_each do |keys, value|
|
207
|
-
|
207
|
+
_ = keys.pop
|
208
208
|
hash[keys] ||= []
|
209
209
|
hash[keys].push("#{ value }")
|
210
210
|
end
|
@@ -219,9 +219,8 @@ module Dao
|
|
219
219
|
alias_method('each_full', 'each_full_message')
|
220
220
|
|
221
221
|
def messages
|
222
|
-
|
223
|
-
|
224
|
-
select{|message| not message.strip.empty?}
|
222
|
+
(self[Global] || []).map{|message| message}
|
223
|
+
.select{|message| not message.strip.empty?}
|
225
224
|
end
|
226
225
|
|
227
226
|
def global
|
@@ -235,7 +234,7 @@ module Dao
|
|
235
234
|
# html generation methods
|
236
235
|
#
|
237
236
|
def to_html(*args)
|
238
|
-
Errors.to_html(
|
237
|
+
Errors.to_html(self, *args)
|
239
238
|
end
|
240
239
|
|
241
240
|
def Errors.to_html(*args, &block)
|
@@ -247,7 +246,7 @@ module Dao
|
|
247
246
|
end
|
248
247
|
|
249
248
|
def Errors.errors_to_html(*args)
|
250
|
-
|
249
|
+
Errors2Html.to_html(*args)
|
251
250
|
end
|
252
251
|
|
253
252
|
def to_s(format = :html, *args, &block)
|
@@ -262,7 +261,6 @@ module Dao
|
|
262
261
|
|
263
262
|
class KeyPrefixer
|
264
263
|
attr_accessor :object
|
265
|
-
attr_accessor :prefix
|
266
264
|
attr_accessor :global
|
267
265
|
|
268
266
|
def initialize(object)
|
@@ -307,7 +305,7 @@ module Dao
|
|
307
305
|
|
308
306
|
def Errors.to_hash(*args)
|
309
307
|
error = args.shift
|
310
|
-
|
308
|
+
Map.options_for!(args)
|
311
309
|
errors = [error, *args].flatten.compact
|
312
310
|
|
313
311
|
map = Map.new
|
@@ -0,0 +1,128 @@
|
|
1
|
+
module Dao
|
2
|
+
module Errors2Html
|
3
|
+
class View
|
4
|
+
def View.controller(&block)
|
5
|
+
controller = ::Current.controller ? ::Current.controller.dup : ::Current.mock_controller
|
6
|
+
block ? controller.instance_eval(&block) : controller
|
7
|
+
end
|
8
|
+
|
9
|
+
def View.render(*args)
|
10
|
+
options = args.extract_options!.to_options!
|
11
|
+
args.push(options)
|
12
|
+
|
13
|
+
unless options.has_key?(:layout)
|
14
|
+
options[:layout] = false
|
15
|
+
end
|
16
|
+
|
17
|
+
Array(View.controller{ render(*args) }).join.html_safe
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def Errors2Html.to_html(*args)
|
22
|
+
if args.size == 1
|
23
|
+
case args.first
|
24
|
+
when Array, String, Symbol
|
25
|
+
messages = Array(args.first)
|
26
|
+
args = [{:base => messages}]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
args.flatten!
|
31
|
+
args.compact!
|
32
|
+
|
33
|
+
at_least_one_error = false
|
34
|
+
|
35
|
+
errors = Map.new
|
36
|
+
errors[:global] = []
|
37
|
+
errors[:fields] = {}
|
38
|
+
|
39
|
+
args.each do |e|
|
40
|
+
flatten(e).each do |key, messages|
|
41
|
+
Array(messages).each do |message|
|
42
|
+
at_least_one_error = true
|
43
|
+
message = message.to_s.html_safe
|
44
|
+
|
45
|
+
if Array(key).join =~ /\A(?:[*]|base)\Z/iomx
|
46
|
+
errors.global.push(message).uniq!
|
47
|
+
else
|
48
|
+
(errors.fields[key] ||= []).push(message).uniq!
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
return "" unless at_least_one_error
|
55
|
+
|
56
|
+
locals = {
|
57
|
+
:errors => errors,
|
58
|
+
:global_errors => errors.global,
|
59
|
+
:fields_errors => errors.fields
|
60
|
+
}
|
61
|
+
|
62
|
+
if template
|
63
|
+
View.render(:template => template, :locals => locals, :layout => false)
|
64
|
+
else
|
65
|
+
View.render(:inline => inline, :locals => locals, :layout => false)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def Errors2Html.flatten(hashlike)
|
70
|
+
case hashlike
|
71
|
+
when Map
|
72
|
+
hash = Hash.new
|
73
|
+
hashlike.depth_first_each do |key, value|
|
74
|
+
index = key.pop if key.last.is_a?(Integer)
|
75
|
+
(hash[key] ||= []).push(value)
|
76
|
+
end
|
77
|
+
hash
|
78
|
+
else
|
79
|
+
hashlike.respond_to?(:to_hash) ? hashlike.to_hash : hashlike
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
Fattr(:inline) do
|
84
|
+
<<-erb
|
85
|
+
<div class="errors2html errors-summary">
|
86
|
+
<h4 class="errors-caption">Sorry, we encountered some errors:</h4>
|
87
|
+
|
88
|
+
<% unless errors.global.empty? %>
|
89
|
+
|
90
|
+
<ul class="errors-global-list">
|
91
|
+
<% errors.global.each do |message| %>
|
92
|
+
<li class="errors-message">
|
93
|
+
<%= message %>
|
94
|
+
</li>
|
95
|
+
<% end %>
|
96
|
+
</ul>
|
97
|
+
<% end %>
|
98
|
+
|
99
|
+
<% unless errors.fields.empty? %>
|
100
|
+
|
101
|
+
<dl class="errors-fields-list">
|
102
|
+
<%
|
103
|
+
errors.fields.each do |key, messages|
|
104
|
+
title = Array(key).join(" ").titleize
|
105
|
+
%>
|
106
|
+
<dt class="errors-title">
|
107
|
+
<%= title %>
|
108
|
+
</dt>
|
109
|
+
<% Array(messages).each do |message| %>
|
110
|
+
<dd class="errors-message">
|
111
|
+
<%= message %>
|
112
|
+
</dd>
|
113
|
+
|
114
|
+
<% end %>
|
115
|
+
<% end %>
|
116
|
+
</dl>
|
117
|
+
<% end %>
|
118
|
+
</div>
|
119
|
+
erb
|
120
|
+
end
|
121
|
+
|
122
|
+
Fattr(:template){ nil }
|
123
|
+
end
|
124
|
+
|
125
|
+
##
|
126
|
+
#
|
127
|
+
Errors2HTML = Errors2Html
|
128
|
+
end
|
data/lib/dao/form.rb
CHANGED
@@ -12,7 +12,7 @@ module Dao
|
|
12
12
|
# builder stuff for compatibity with rails' form_for()
|
13
13
|
#
|
14
14
|
class Builder < Form
|
15
|
-
def Builder.new(object_name, object, view, options, block)
|
15
|
+
def Builder.new(object_name, object, view, options, block=:rails_3_4_5)
|
16
16
|
if object.respond_to?(:form)
|
17
17
|
|
18
18
|
html = options[:html] || {}
|
@@ -40,7 +40,6 @@ module Dao
|
|
40
40
|
#
|
41
41
|
attr_accessor :object
|
42
42
|
attr_accessor :unscoped
|
43
|
-
attr_accessor :scope
|
44
43
|
|
45
44
|
def initialize(*args)
|
46
45
|
@object = args.shift
|
@@ -173,7 +172,7 @@ module Dao
|
|
173
172
|
if block.nil? and !options.has_key?(:content)
|
174
173
|
''
|
175
174
|
else
|
176
|
-
block ? block.call(
|
175
|
+
block ? block.call(self) : options.delete(:content)
|
177
176
|
end
|
178
177
|
|
179
178
|
form_(options_for(options, :action => action, :method => method, :class => klass, :id => id, :data_error => error)){ content }
|
@@ -275,7 +274,7 @@ module Dao
|
|
275
274
|
options[:checked] = checked if checked
|
276
275
|
end
|
277
276
|
|
278
|
-
input_(options_for(options, :type =>
|
277
|
+
input_(options_for(options, :type => type, :name => name, :class => klass, :id => id, :data_error => error)){}
|
279
278
|
end
|
280
279
|
|
281
280
|
def checkbox(*args, &block)
|
@@ -303,7 +302,7 @@ module Dao
|
|
303
302
|
values.map{|k, v| h[ k =~ /t|1|on|yes/ ? true : false ] = v}
|
304
303
|
h
|
305
304
|
else
|
306
|
-
t, f, *
|
305
|
+
t, f, *_ = Array(values).flatten.compact
|
307
306
|
{true => t, false => f}
|
308
307
|
end
|
309
308
|
value_for[true] ||= '1'
|
@@ -320,7 +319,7 @@ module Dao
|
|
320
319
|
input_(
|
321
320
|
options_for(
|
322
321
|
options,
|
323
|
-
:type =>
|
322
|
+
:type => type,
|
324
323
|
:name => name,
|
325
324
|
:value => value_for[true],
|
326
325
|
:class => klass,
|
@@ -367,7 +366,7 @@ module Dao
|
|
367
366
|
end
|
368
367
|
|
369
368
|
def select(*args, &block)
|
370
|
-
options = args.extract_options!.to_options!
|
369
|
+
options = args.extract_options!.to_options!
|
371
370
|
keys = scope(args)
|
372
371
|
|
373
372
|
name = options.delete(:name) || name_for(keys)
|
@@ -381,7 +380,7 @@ module Dao
|
|
381
380
|
error = error_for(keys, options.delete(:error))
|
382
381
|
|
383
382
|
if values.nil?
|
384
|
-
key = keys.map{|
|
383
|
+
key = keys.map{|k| "#{k}"}
|
385
384
|
key.last << "_options"
|
386
385
|
values = attributes.get(*key) if attributes.has?(*key)
|
387
386
|
end
|
@@ -442,7 +441,7 @@ module Dao
|
|
442
441
|
|
443
442
|
case returned
|
444
443
|
when Array
|
445
|
-
content, value, selected, *
|
444
|
+
content, value, selected, *_ = returned
|
446
445
|
if value.is_a?(Hash)
|
447
446
|
map = Map.for(value)
|
448
447
|
value = map.delete(:value)
|
@@ -506,7 +505,7 @@ module Dao
|
|
506
505
|
# html generation support methods
|
507
506
|
#
|
508
507
|
def id_for(keys)
|
509
|
-
id = [name, keys.join('-')].compact.join('
|
508
|
+
id = [name, keys.join('-')].compact.join('--')
|
510
509
|
slug_for(id)
|
511
510
|
end
|
512
511
|
|
@@ -641,7 +640,7 @@ module Dao
|
|
641
640
|
end
|
642
641
|
|
643
642
|
def attr_for(string)
|
644
|
-
slug_for(string)
|
643
|
+
slug_for(string)
|
645
644
|
end
|
646
645
|
|
647
646
|
def data_attr_for(string)
|
@@ -650,10 +649,8 @@ module Dao
|
|
650
649
|
|
651
650
|
def slug_for(string)
|
652
651
|
string = string.to_s
|
653
|
-
words = string.
|
654
|
-
words.
|
655
|
-
words.delete_if{|word| word.nil? or word.strip.empty?}
|
656
|
-
words.join('-').downcase.sub(/_+$/, '')
|
652
|
+
words = string.scan(%r/[^\s]+/)
|
653
|
+
words.join('--').downcase
|
657
654
|
end
|
658
655
|
|
659
656
|
def titleize(string)
|