dao 5.6.1 → 7.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|