dao 3.3.0 → 4.2.1
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/README +7 -0
- data/Rakefile +36 -17
- data/b.rb +38 -0
- data/dao.gemspec +41 -13
- data/lib/dao.rb +44 -13
- data/lib/dao/api.rb +1 -1
- data/lib/dao/api/context.rb +35 -45
- data/lib/dao/api/endpoints.rb +225 -91
- data/lib/dao/conducer.rb +437 -0
- data/lib/dao/conducer/attributes.rb +21 -0
- data/lib/dao/conducer/crud.rb +70 -0
- data/lib/dao/current.rb +66 -0
- data/lib/dao/db.rb +44 -5
- data/lib/dao/endpoint.rb +13 -1
- data/lib/dao/errors.rb +74 -59
- data/lib/dao/exceptions.rb +1 -2
- data/lib/dao/extractor.rb +68 -0
- data/lib/dao/form.rb +139 -46
- data/lib/dao/image_cache.rb +193 -0
- data/lib/dao/instance_exec.rb +1 -1
- data/lib/dao/name.rb +7 -0
- data/lib/dao/params.rb +16 -66
- data/lib/dao/rack.rb +3 -0
- data/lib/dao/rack/middleware.rb +5 -0
- data/lib/dao/rack/middleware/params_parser.rb +24 -0
- data/lib/dao/rails.rb +22 -5
- data/lib/dao/rails/lib/generators/dao/USAGE +2 -6
- data/lib/dao/rails/lib/generators/dao/dao_generator.rb +52 -7
- data/lib/dao/rails/lib/generators/dao/templates/api.rb +23 -7
- data/lib/dao/rails/lib/generators/dao/templates/api_controller.rb +24 -7
- data/lib/dao/rails/lib/generators/dao/templates/conducer.rb +64 -0
- data/lib/dao/rails/lib/generators/dao/templates/conducer_controller.rb +79 -0
- data/lib/dao/rails/lib/generators/dao/templates/dao.js +13 -6
- data/lib/dao/rails/lib/generators/dao/templates/dao_helper.rb +75 -11
- data/lib/dao/result.rb +1 -26
- data/lib/dao/slug.rb +37 -8
- data/lib/dao/status.rb +4 -0
- data/lib/dao/support.rb +155 -0
- data/lib/dao/validations.rb +48 -157
- data/lib/dao/validations/callback.rb +30 -0
- data/lib/dao/validations/common.rb +322 -320
- data/lib/dao/validations/validator.rb +219 -0
- data/test/active_model_conducer_lint_test.rb +19 -0
- data/test/api_test.rb +261 -0
- data/test/conducer_test.rb +205 -0
- data/test/db.yml +9 -0
- data/test/form_test.rb +42 -0
- data/test/support_test.rb +52 -0
- data/test/testing.rb +145 -24
- data/test/validations_test.rb +156 -0
- metadata +138 -21
- data/TODO +0 -33
- data/a.rb +0 -80
- data/db/dao.yml +0 -5
- data/lib/dao/api/interfaces.rb +0 -306
- data/lib/dao/interface.rb +0 -28
- data/lib/dao/presenter.rb +0 -129
- data/lib/dao/rails/lib/generators/dao/api_generator.rb +0 -3
- data/lib/dao/validations/base.rb +0 -68
- data/test/dao_test.rb +0 -506
data/lib/dao/validations/base.rb
DELETED
@@ -1,68 +0,0 @@
|
|
1
|
-
module Dao
|
2
|
-
# objects must have and errors object and a status object to use this mixin
|
3
|
-
#
|
4
|
-
module Validations::Base
|
5
|
-
def validations
|
6
|
-
@validations ||= Validations.for(self)
|
7
|
-
end
|
8
|
-
|
9
|
-
def is_valid=(boolean)
|
10
|
-
@is_valid = !!boolean
|
11
|
-
end
|
12
|
-
|
13
|
-
def is_valid(*bool)
|
14
|
-
@is_valid ||= nil
|
15
|
-
@is_valid = !!bool.first unless bool.empty?
|
16
|
-
@is_valid
|
17
|
-
end
|
18
|
-
|
19
|
-
def valid!
|
20
|
-
@forcing_validity = true
|
21
|
-
end
|
22
|
-
|
23
|
-
def forcing_validity?
|
24
|
-
defined?(@forcing_validity) and @forcing_validity
|
25
|
-
end
|
26
|
-
|
27
|
-
def valid?(*args)
|
28
|
-
if forcing_validity?
|
29
|
-
true
|
30
|
-
else
|
31
|
-
options = Dao.options_for!(args)
|
32
|
-
validate unless validations.ran?
|
33
|
-
validate if options[:validate]
|
34
|
-
errors.empty? and status.ok?
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def validate(*args, &block)
|
39
|
-
if !args.empty?
|
40
|
-
validations.add(*args, &block)
|
41
|
-
else
|
42
|
-
validations.run
|
43
|
-
status.update(420) if(status.ok? and !errors.empty?)
|
44
|
-
errors.empty? and status.ok?
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
# TODO - consider how to factor out this throw...
|
49
|
-
#
|
50
|
-
def validate!(*args, &block)
|
51
|
-
if !args.empty?
|
52
|
-
validations.add(*args, &block)
|
53
|
-
end
|
54
|
-
@forcing_validity = false
|
55
|
-
validations.run!
|
56
|
-
status.update(420) if(status.ok? and !errors.empty?)
|
57
|
-
throw(:result, nil) unless(errors.empty? and status.ok?)
|
58
|
-
end
|
59
|
-
|
60
|
-
def validates(*args, &block)
|
61
|
-
validations.add(*args, &block)
|
62
|
-
end
|
63
|
-
|
64
|
-
def validations
|
65
|
-
@validations ||= Validations.for(self)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
data/test/dao_test.rb
DELETED
@@ -1,506 +0,0 @@
|
|
1
|
-
testdir = File.dirname(File.expand_path(__FILE__))
|
2
|
-
rootdir = File.dirname(testdir)
|
3
|
-
libdir = File.join(rootdir, 'lib')
|
4
|
-
|
5
|
-
require File.join(libdir, 'dao')
|
6
|
-
require File.join(testdir, 'testing')
|
7
|
-
require File.join(testdir, 'helper')
|
8
|
-
|
9
|
-
|
10
|
-
Testing Dao do
|
11
|
-
## api
|
12
|
-
#
|
13
|
-
testing 'that an api class for your application can be built using a simple dsl' do
|
14
|
-
assert{
|
15
|
-
api_class =
|
16
|
-
Dao.api do
|
17
|
-
### dsl
|
18
|
-
end
|
19
|
-
}
|
20
|
-
end
|
21
|
-
|
22
|
-
testing 'that apis can have callable interfaces added to them which accept params and return results' do
|
23
|
-
captured = []
|
24
|
-
|
25
|
-
api_class =
|
26
|
-
assert{
|
27
|
-
Dao.api do
|
28
|
-
interface(:foo) do |params, result|
|
29
|
-
captured.push(params, result)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
}
|
33
|
-
api = assert{ api_class.new }
|
34
|
-
result = assert{ api.call(:foo, {}) }
|
35
|
-
assert{ result.is_a?(Hash) }
|
36
|
-
end
|
37
|
-
|
38
|
-
testing 'that interfaces are automatically called according to arity' do
|
39
|
-
api = assert{ Class.new(Dao.api) }
|
40
|
-
assert{ api.class_eval{ interface(:zero){|| result.update :args => [] } } }
|
41
|
-
assert{ api.class_eval{ interface(:one){|a| result.update :args => [a]} } }
|
42
|
-
assert{ api.class_eval{ interface(:two){|a,b| result.update :args => [a,b]} } }
|
43
|
-
|
44
|
-
assert{ api.new.call(:zero).args.size == 0 }
|
45
|
-
assert{ api.new.call(:one).args.size == 1 }
|
46
|
-
assert{ api.new.call(:two).args.size == 2 }
|
47
|
-
end
|
48
|
-
|
49
|
-
testing 'that interfaces have an auto-vivifying params/result' do
|
50
|
-
api = assert{ Class.new(Dao.api) }
|
51
|
-
assert{ api.class_eval{ interface(:foo){ params; result; } } }
|
52
|
-
result = assert{ api.new.call(:foo) }
|
53
|
-
assert{ result.path.to_s =~ /foo/ }
|
54
|
-
end
|
55
|
-
|
56
|
-
testing 'that an api can be called with different modes' do
|
57
|
-
api_class =
|
58
|
-
assert{
|
59
|
-
Dao.api do
|
60
|
-
call(:foo) do
|
61
|
-
data.modes = []
|
62
|
-
|
63
|
-
Dao::Mode.list.each do |mode|
|
64
|
-
send(mode){ data.modes.push(mode) }
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
}
|
69
|
-
api = assert{ api_class.new }
|
70
|
-
|
71
|
-
Dao::Mode.list.each do |mode|
|
72
|
-
result = api.mode(mode).call(:foo)
|
73
|
-
assert{ result.data.modes.include?(mode) }
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
testing 'that options/head/get are considered read modes' do
|
78
|
-
read_mode = assert{ Dao::Mode.read }
|
79
|
-
|
80
|
-
api_class =
|
81
|
-
assert{
|
82
|
-
Dao.api do
|
83
|
-
call(:foo) do
|
84
|
-
data.update :modes => []
|
85
|
-
read { data.modes.push(read_mode) }
|
86
|
-
end
|
87
|
-
end
|
88
|
-
}
|
89
|
-
api = assert{ api_class.new }
|
90
|
-
|
91
|
-
Dao::Mode::Read.each do |mode|
|
92
|
-
result = assert{ api.mode(mode).call(:foo) }
|
93
|
-
assert{ result.data.modes == [read_mode] }
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
testing 'that post/put/delete/trace/connect are considered write modes' do
|
98
|
-
write_mode = assert{ Dao::Mode.write }
|
99
|
-
|
100
|
-
api_class =
|
101
|
-
assert{
|
102
|
-
Dao.api do
|
103
|
-
call(:foo) do
|
104
|
-
data.update :modes => []
|
105
|
-
write { data.modes.push(write_mode) }
|
106
|
-
end
|
107
|
-
end
|
108
|
-
}
|
109
|
-
api = assert{ api_class.new }
|
110
|
-
|
111
|
-
Dao::Mode::Write.each do |mode|
|
112
|
-
result = assert{ api.mode(mode).call(:foo) }
|
113
|
-
assert{ result.data.modes == [write_mode] }
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
testing 'that the first, most specific, mode block encountered fires first' do
|
118
|
-
api_class =
|
119
|
-
assert{
|
120
|
-
Dao.api do
|
121
|
-
call(:foo) do
|
122
|
-
data.update :modes => []
|
123
|
-
Dao::Mode::Read.each do |mode|
|
124
|
-
send(mode){ data.modes.push(mode) }
|
125
|
-
end
|
126
|
-
read { data.modes.push(Dao::Mode.read) }
|
127
|
-
end
|
128
|
-
end
|
129
|
-
}
|
130
|
-
api = assert{ api_class.new }
|
131
|
-
|
132
|
-
read = Dao::Mode.read
|
133
|
-
result = assert{ api.mode(read).call(:foo) }
|
134
|
-
assert{ result.data.modes == [read] }
|
135
|
-
|
136
|
-
Dao::Mode::Read.each do |mode|
|
137
|
-
result = assert{ api.mode(mode).call(:foo) }
|
138
|
-
assert{ result.data.modes == [mode] }
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
## results
|
143
|
-
#
|
144
|
-
testing 'that results can be created' do
|
145
|
-
result = assert{ Dao::Result.new }
|
146
|
-
assert{ result.path }
|
147
|
-
assert{ result.status }
|
148
|
-
assert{ result.errors }
|
149
|
-
assert{ result.params }
|
150
|
-
assert{ result.data }
|
151
|
-
end
|
152
|
-
|
153
|
-
testing 'that results can be created with a path' do
|
154
|
-
result = assert{ Dao::Result.new('/api/foo/bar') }
|
155
|
-
assert{ result.path == '/api/foo/bar' }
|
156
|
-
end
|
157
|
-
|
158
|
-
## paths
|
159
|
-
#
|
160
|
-
testing 'that simple paths can be contstructed/compiled' do
|
161
|
-
path = assert{ Dao::Path.for('./api/../foo/bar') }
|
162
|
-
assert{ path =~ %r|^/| }
|
163
|
-
assert{ path !~ %r|[.]| }
|
164
|
-
assert{ path.params.is_a?(Hash) }
|
165
|
-
assert{ path.keys.is_a?(Array) }
|
166
|
-
assert{ path.pattern.is_a?(Regexp) }
|
167
|
-
end
|
168
|
-
|
169
|
-
## routes
|
170
|
-
#
|
171
|
-
testing 'that an api has a list of routes' do
|
172
|
-
api_class =
|
173
|
-
assert{
|
174
|
-
Dao.api do
|
175
|
-
end
|
176
|
-
}
|
177
|
-
assert{ api_class.routes.is_a?(Array) }
|
178
|
-
end
|
179
|
-
|
180
|
-
testing 'that routed interfaces call be declared' do
|
181
|
-
api_class =
|
182
|
-
assert{
|
183
|
-
Dao.api do
|
184
|
-
call('/users/:user_id/comments/:comment_id') do
|
185
|
-
data.update(params)
|
186
|
-
end
|
187
|
-
end
|
188
|
-
}
|
189
|
-
api = api_class.new
|
190
|
-
end
|
191
|
-
|
192
|
-
testing 'that routed methods can be called with embedded params' do
|
193
|
-
api_class =
|
194
|
-
assert{
|
195
|
-
Dao.api do
|
196
|
-
call('/users/:user_id/comments/:comment_id') do
|
197
|
-
data.update(params)
|
198
|
-
end
|
199
|
-
end
|
200
|
-
}
|
201
|
-
api = api_class.new
|
202
|
-
|
203
|
-
{
|
204
|
-
'/users/4/comments/2' => {},
|
205
|
-
#'/users/comments' => {:user_id => 4, :comment_id => 2},
|
206
|
-
'/users/:user_id/comments/:comment_id' => {:user_id => 4, :comment_id => 2},
|
207
|
-
}.each do |path, params|
|
208
|
-
result = assert{ api.call(path, params) }
|
209
|
-
assert{ result.data.user_id.to_s =~ /4/ }
|
210
|
-
assert{ result.data.comment_id.to_s =~ /2/ }
|
211
|
-
assert{ result.path == '/users/4/comments/2' }
|
212
|
-
end
|
213
|
-
end
|
214
|
-
|
215
|
-
|
216
|
-
## status
|
217
|
-
#
|
218
|
-
testing 'Status.for' do
|
219
|
-
assert{ Dao::Status.for(:unauthorized).code == 401 }
|
220
|
-
assert{ Dao::Status.for(:UNAUTHORIZED).code == 401 }
|
221
|
-
assert{ Dao::Status.for('unauthorized').code == 401 }
|
222
|
-
assert{ Dao::Status.for('UNAUTHORIZED').code == 401 }
|
223
|
-
assert{ Dao::Status.for('Unauthorized').code == 401 }
|
224
|
-
assert{ Dao::Status.for(:Unauthorized).code == 401 }
|
225
|
-
assert{ Dao::Status.for(:No_Content).code == 204 }
|
226
|
-
assert{ Dao::Status.for(:no_content).code == 204 }
|
227
|
-
end
|
228
|
-
|
229
|
-
testing 'status equality operator' do
|
230
|
-
s = Dao::Status.for(401)
|
231
|
-
assert{ s == :unauthorized }
|
232
|
-
assert{ s == 401 }
|
233
|
-
assert{ s != Array.new }
|
234
|
-
end
|
235
|
-
|
236
|
-
## parser
|
237
|
-
#
|
238
|
-
testing 'parsing a simple hash by key' do
|
239
|
-
params = {
|
240
|
-
'key(a)' => 40,
|
241
|
-
'key(b)' => 2
|
242
|
-
}
|
243
|
-
parsed = Dao.parse(:key, params)
|
244
|
-
expected = {'a' => 40, 'b' => 2}
|
245
|
-
assert{ parsed =~ expected }
|
246
|
-
end
|
247
|
-
|
248
|
-
testing 'parsing a nested hash by key' do
|
249
|
-
params = {
|
250
|
-
'key(a,x)' => 40,
|
251
|
-
'key(a,y)' => 2
|
252
|
-
}
|
253
|
-
parsed = Dao.parse(:key, params)
|
254
|
-
expected = {'a' => {'x' => 40, 'y' => 2}}
|
255
|
-
assert{ parsed =~ expected }
|
256
|
-
end
|
257
|
-
|
258
|
-
testing 'parsing a deeply nested hash by key' do
|
259
|
-
params = {
|
260
|
-
'key(a,b,x)' => 40,
|
261
|
-
'key(a,b,y)' => 2
|
262
|
-
}
|
263
|
-
parsed = Dao.parse(:key, params)
|
264
|
-
expected = {'a' => {'b' => {'x' => 40, 'y' => 2}}}
|
265
|
-
assert{ parsed =~ expected }
|
266
|
-
end
|
267
|
-
|
268
|
-
testing 'that params are auto-parsed if the api detects that they need to be ' do
|
269
|
-
assert{
|
270
|
-
api_class =
|
271
|
-
Dao.api do
|
272
|
-
call('/foobar'){
|
273
|
-
data.update(params)
|
274
|
-
}
|
275
|
-
end
|
276
|
-
api = api_class.new
|
277
|
-
|
278
|
-
result = assert{ api.call('/foobar', 'key' => 'val') }
|
279
|
-
assert{ result.data =~ {'key' => 'val'} }
|
280
|
-
|
281
|
-
result = assert{ api.call('/foobar', '/foobar(key)' => 'val', '/foobar(a,0)' => 42, '/foobar(a,1)' => 42.0) }
|
282
|
-
assert{ result.data =~ {'key' => 'val', 'a' => [42, 42.0]} }
|
283
|
-
}
|
284
|
-
end
|
285
|
-
|
286
|
-
testing 'that parsing folds in top level keys by default' do
|
287
|
-
params = {
|
288
|
-
'key(a)' => 40,
|
289
|
-
'key(b)' => 2,
|
290
|
-
'a' => 'clobbered',
|
291
|
-
'b' => 'clobbered',
|
292
|
-
'c' => 42
|
293
|
-
}
|
294
|
-
parsed = Dao.parse(:key, params)
|
295
|
-
expected = {'a' => 40, 'b' => 2, 'c' => 42}
|
296
|
-
assert{ parsed =~ expected }
|
297
|
-
end
|
298
|
-
|
299
|
-
testing 'that parsing can have folding turned off' do
|
300
|
-
params = {
|
301
|
-
'key(a)' => 40,
|
302
|
-
'key(b)' => 2,
|
303
|
-
'a' => 'clobbered',
|
304
|
-
'b' => 'clobbered',
|
305
|
-
'c' => 42
|
306
|
-
}
|
307
|
-
parsed = Dao.parse(:key, params, :fold => false)
|
308
|
-
expected = {'a' => 40, 'b' => 2}
|
309
|
-
assert{ parsed =~ expected }
|
310
|
-
end
|
311
|
-
|
312
|
-
testing 'that parse folding can be white list-ly selective' do
|
313
|
-
params = {
|
314
|
-
'key(a)' => 40,
|
315
|
-
'key(b)' => 2,
|
316
|
-
'a' => 'clobbered',
|
317
|
-
'b' => 'clobbered',
|
318
|
-
'c' => 42,
|
319
|
-
'd' => 'not included...'
|
320
|
-
}
|
321
|
-
parsed = Dao.parse(:key, params, :include => [:c])
|
322
|
-
expected = {'a' => 40, 'b' => 2, 'c' => 42}
|
323
|
-
assert{ parsed =~ expected }
|
324
|
-
end
|
325
|
-
|
326
|
-
testing 'that parse folding can be black list-ly selective' do
|
327
|
-
params = {
|
328
|
-
'key(a)' => 40,
|
329
|
-
'key(b)' => 2,
|
330
|
-
'a' => 'clobbered',
|
331
|
-
'b' => 'clobbered',
|
332
|
-
'c' => 42,
|
333
|
-
'd' => 'rejected...',
|
334
|
-
'e' => 'rejected...'
|
335
|
-
}
|
336
|
-
parsed = Dao.parse(:key, params, :except => [:d, :e])
|
337
|
-
expected = {'a' => 40, 'b' => 2, 'c' => 42}
|
338
|
-
assert{ parsed =~ expected }
|
339
|
-
end
|
340
|
-
|
341
|
-
## errors
|
342
|
-
#
|
343
|
-
testing 'that clear does not drop sticky errors' do
|
344
|
-
errors = Dao::Errors.new
|
345
|
-
errors.add! 'sticky', 'error'
|
346
|
-
errors.add 'not-sticky', 'error'
|
347
|
-
errors.clear
|
348
|
-
assert{ errors['sticky'].first == 'error' }
|
349
|
-
assert{ errors['not-sticky'].nil? }
|
350
|
-
end
|
351
|
-
|
352
|
-
testing 'that clear! ***does*** drop sticky errors' do
|
353
|
-
errors = Dao::Errors.new
|
354
|
-
errors.add! 'sticky', 'error'
|
355
|
-
errors.add 'not-sticky', 'error'
|
356
|
-
errors.clear!
|
357
|
-
assert{ errors['sticky'].nil? }
|
358
|
-
assert{ errors['not-sticky'].nil? }
|
359
|
-
end
|
360
|
-
|
361
|
-
testing 'that global errors are sticky' do
|
362
|
-
errors = Dao::Errors.new
|
363
|
-
global = Dao::Errors::Global
|
364
|
-
errors.add! 'global-error'
|
365
|
-
errors.clear
|
366
|
-
assert{ errors[global].first == 'global-error' }
|
367
|
-
errors.clear!
|
368
|
-
assert{ errors[global].nil? }
|
369
|
-
end
|
370
|
-
|
371
|
-
## validations
|
372
|
-
#
|
373
|
-
testing 'that simple validations work' do
|
374
|
-
params = Dao::Params.new
|
375
|
-
assert{ params.validates(:password){|password| password=='haxor'} }
|
376
|
-
params.set(:password, 'haxor')
|
377
|
-
assert{ params.valid? }
|
378
|
-
end
|
379
|
-
|
380
|
-
testing 'that validations have some syntax sugar' do
|
381
|
-
assert{
|
382
|
-
api_class =
|
383
|
-
Dao.api do
|
384
|
-
interface('/foobar'){
|
385
|
-
params.validate(:a)
|
386
|
-
validates(:b)
|
387
|
-
validate!
|
388
|
-
}
|
389
|
-
end
|
390
|
-
api = api_class.new
|
391
|
-
|
392
|
-
result = assert{ api.call('/foobar', 'a' => true, 'b' => true) }
|
393
|
-
assert{ result.status.ok? }
|
394
|
-
|
395
|
-
result = assert{ api.call('/foobar') }
|
396
|
-
assert{ !result.status.ok? }
|
397
|
-
assert{ result.errors.size==2 }
|
398
|
-
}
|
399
|
-
end
|
400
|
-
|
401
|
-
testing 'that validations use instance_exec' do
|
402
|
-
a, b = nil
|
403
|
-
|
404
|
-
api_class =
|
405
|
-
Dao.api do
|
406
|
-
interface('/foobar'){
|
407
|
-
params.validate(:a){ b = get(:b) }
|
408
|
-
params.validate(:b){ a = get(:a) }
|
409
|
-
validate!
|
410
|
-
}
|
411
|
-
end
|
412
|
-
api = api_class.new
|
413
|
-
|
414
|
-
result = assert{ api.call('/foobar', 'a' => 40, 'b' => 2) }
|
415
|
-
assert{ result.status.ok? }
|
416
|
-
assert{ a == 40 }
|
417
|
-
assert{ b == 2 }
|
418
|
-
end
|
419
|
-
|
420
|
-
testing 'simple validates_confirmation_of' do
|
421
|
-
api_class =
|
422
|
-
Dao.api do
|
423
|
-
interface('/foobar'){
|
424
|
-
params.validates_as_email(:email)
|
425
|
-
params.validates_confirmation_of(:email)
|
426
|
-
validate!
|
427
|
-
}
|
428
|
-
end
|
429
|
-
api = api_class.new
|
430
|
-
|
431
|
-
result = assert{ api.call('/foobar', 'email' => 'ara.t.howard@gmail.com', 'email_confirmation' => 'ara.t.howard@gmail.com') }
|
432
|
-
assert{ result.status.ok? }
|
433
|
-
assert{ result.errors.empty? }
|
434
|
-
|
435
|
-
result = assert{ api.call('/foobar', 'email' => 'ara.t.howard@gmail.com', 'email_confirmation' => 'ara@dojo4.com') }
|
436
|
-
assert{ !result.status.ok? }
|
437
|
-
assert{ !result.errors.empty? }
|
438
|
-
end
|
439
|
-
|
440
|
-
## validating
|
441
|
-
#
|
442
|
-
testing 'that validations can be cleared and do not clobber manually added errors' do
|
443
|
-
params = Dao::Params.new
|
444
|
-
errors = params.errors
|
445
|
-
|
446
|
-
assert{ params.validates(:email){|email| email.to_s.split(/@/).size == 2} }
|
447
|
-
assert{ params.validates(:password){|password| password == 'pa$$w0rd'} }
|
448
|
-
|
449
|
-
params.set(:email => 'ara@dojo4.com', :password => 'pa$$w0rd')
|
450
|
-
assert{ params.valid? }
|
451
|
-
|
452
|
-
params.set(:password => 'haxor')
|
453
|
-
assert{ !params.valid?(:validate => true) }
|
454
|
-
|
455
|
-
errors.add(:name, 'ara')
|
456
|
-
assert{ not params.valid? }
|
457
|
-
end
|
458
|
-
|
459
|
-
## doc
|
460
|
-
#
|
461
|
-
testing 'that apis can be documented via the api' do
|
462
|
-
api_class =
|
463
|
-
assert {
|
464
|
-
Dao.api {
|
465
|
-
description 'foobar'
|
466
|
-
doc 'signature' => {'read' => '...', 'write' => '...'}
|
467
|
-
interface('/barfoo'){}
|
468
|
-
}
|
469
|
-
}
|
470
|
-
api_class_index = assert{ api_class.index.is_a?(Hash) }
|
471
|
-
api = assert{ api_class.new }
|
472
|
-
api_index = assert{ api.index.is_a?(Hash) }
|
473
|
-
assert{ api_class_index==api_index }
|
474
|
-
end
|
475
|
-
|
476
|
-
=begin
|
477
|
-
|
478
|
-
# cloning
|
479
|
-
#
|
480
|
-
testing 'simple cloning' do
|
481
|
-
data = Dao.data(:foo)
|
482
|
-
clone = assert{ data.clone }
|
483
|
-
assert{ data.path == clone.path }
|
484
|
-
assert{ data.errors == clone.errors }
|
485
|
-
assert{ data.errors.object_id != clone.errors.object_id }
|
486
|
-
assert{ data.validations == clone.validations }
|
487
|
-
assert{ data.validations.object_id != clone.validations.object_id }
|
488
|
-
assert{ data.form != clone.form }
|
489
|
-
assert{ data.form.object_id != clone.form.object_id }
|
490
|
-
assert{ data.status == clone.status }
|
491
|
-
assert{ data.status.object_id != clone.status.object_id }
|
492
|
-
assert{ data == clone }
|
493
|
-
end
|
494
|
-
|
495
|
-
=end
|
496
|
-
|
497
|
-
def hash_equal(a, b)
|
498
|
-
array = lambda{|h| h.to_a.map{|k,v| [k.to_s, v]}.sort}
|
499
|
-
array[a] == array[b]
|
500
|
-
end
|
501
|
-
|
502
|
-
def api(&block)
|
503
|
-
api_class = assert{ Dao.api(&block) }
|
504
|
-
api = assert{ api_class.new }
|
505
|
-
end
|
506
|
-
end
|