volt 0.9.2 → 0.9.3.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/CONTRIBUTING.md +4 -0
- data/Gemfile +3 -0
- data/app/volt/assets/js/volt_js_polyfills.js +0 -1
- data/app/volt/assets/js/volt_watch.js +217 -0
- data/app/volt/models/user.rb +7 -2
- data/app/volt/tasks/query_tasks.rb +6 -0
- data/lib/volt/boot.rb +1 -1
- data/lib/volt/cli/generate.rb +1 -1
- data/lib/volt/config.rb +12 -2
- data/lib/volt/controllers/model_controller.rb +1 -1
- data/lib/volt/data_stores/base_adaptor_client.rb +34 -0
- data/lib/volt/data_stores/{base.rb → base_adaptor_server.rb} +1 -1
- data/lib/volt/data_stores/data_store.rb +23 -7
- data/lib/volt/models/array_model.rb +3 -2
- data/lib/volt/models/model.rb +29 -91
- data/lib/volt/models/{dirty.rb → model_helpers/dirty.rb} +0 -0
- data/lib/volt/models/{listener_tracker.rb → model_helpers/listener_tracker.rb} +0 -0
- data/lib/volt/models/model_helpers/model_change_helpers.rb +76 -0
- data/lib/volt/models/{model_helpers.rb → model_helpers/model_helpers.rb} +0 -0
- data/lib/volt/models/persistors/array_store.rb +2 -23
- data/lib/volt/models/persistors/query/normalizer.rb +0 -44
- data/{templates/project/lib/.empty_directory → lib/volt/models/validations/errors.rb} +0 -0
- data/lib/volt/models/{validations.rb → validations/validations.rb} +80 -26
- data/lib/volt/page/bindings/attribute_binding.rb +17 -3
- data/lib/volt/page/page.rb +1 -0
- data/lib/volt/reactive/eventable.rb +1 -0
- data/lib/volt/server.rb +2 -1
- data/lib/volt/server/component_templates.rb +66 -16
- data/lib/volt/server/forking_server.rb +16 -14
- data/lib/volt/server/html_parser/sandlebars_parser.rb +2 -0
- data/lib/volt/server/html_parser/view_scope.rb +2 -0
- data/lib/volt/server/rack/component_paths.rb +4 -2
- data/lib/volt/server/rack/opal_files.rb +4 -2
- data/lib/volt/server/socket_connection_handler.rb +5 -1
- data/lib/volt/server/template_handlers/handlers.rb +0 -0
- data/lib/volt/spec/setup.rb +23 -8
- data/lib/volt/tasks/dispatcher.rb +4 -0
- data/lib/volt/utils/promise_patch.rb +3 -0
- data/lib/volt/version.rb +1 -1
- data/spec/apps/kitchen_sink/Gemfile +5 -0
- data/spec/apps/kitchen_sink/app/main/config/routes.rb +1 -0
- data/spec/apps/kitchen_sink/app/main/controllers/main_controller.rb +10 -0
- data/spec/apps/kitchen_sink/app/main/views/main/bindings.html +20 -0
- data/spec/apps/kitchen_sink/app/main/views/main/form.html +73 -0
- data/spec/apps/kitchen_sink/app/main/views/main/main.html +1 -0
- data/spec/integration/bindings_spec.rb +33 -0
- data/spec/integration/user_spec.rb +51 -21
- data/spec/models/associations_spec.rb +8 -0
- data/spec/models/model_spec.rb +7 -0
- data/spec/models/user_spec.rb +20 -0
- data/spec/models/validations_spec.rb +2 -1
- data/spec/models/validators/block_validations_spec.rb +53 -0
- data/spec/page/bindings/template_binding/view_lookup_for_path_spec.rb +10 -0
- data/spec/page/path_string_renderer_spec.rb +6 -0
- data/spec/reactive/eventable_spec.rb +24 -6
- data/spec/server/component_templates_spec.rb +21 -0
- data/spec/server/html_parser/sandlebars_parser_spec.rb +12 -13
- data/spec/server/html_parser/view_parser_spec.rb +3 -0
- data/spec/server/rack/asset_files_spec.rb +2 -2
- data/spec/server/rack/http_resource_spec.rb +10 -0
- data/spec/tasks/dispatcher_spec.rb +5 -0
- data/spec/tasks/user_tasks_spec.rb +59 -0
- data/spec/utils/task_argument_filtererer_spec.rb +6 -0
- data/templates/newgem/app/newgem/config/initializers/boot.rb +10 -0
- data/templates/newgem/lib/newgem.rb.tt +13 -0
- data/templates/project/Gemfile.tt +3 -0
- data/templates/project/app/main/lib/.empty_directory +0 -0
- data/volt.gemspec +3 -1
- metadata +24 -25
- data/lib/volt/data_stores/mongo_driver.rb +0 -69
@@ -1,8 +1,9 @@
|
|
1
1
|
require 'volt/reactive/reactive_array'
|
2
2
|
require 'volt/models/model_wrapper'
|
3
|
-
require 'volt/models/model_helpers'
|
3
|
+
require 'volt/models/model_helpers/model_helpers'
|
4
4
|
require 'volt/models/state_manager'
|
5
5
|
require 'volt/models/state_helpers'
|
6
|
+
require 'volt/data_stores/data_store'
|
6
7
|
|
7
8
|
module Volt
|
8
9
|
class ArrayModel < ReactiveArray
|
@@ -40,7 +41,7 @@ module Volt
|
|
40
41
|
end
|
41
42
|
|
42
43
|
proxy_with_root_dep :[], :size, :first, :last, :state_for, :reverse
|
43
|
-
proxy_to_persistor :
|
44
|
+
proxy_to_persistor :then, :fetch, :fetch_first, :fetch_each
|
44
45
|
|
45
46
|
def initialize(array = [], options = {})
|
46
47
|
@options = options
|
data/lib/volt/models/model.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'volt/models/model_wrapper'
|
2
2
|
require 'volt/models/array_model'
|
3
|
-
require 'volt/models/model_helpers'
|
3
|
+
require 'volt/models/model_helpers/model_helpers'
|
4
4
|
require 'volt/models/model_hash_behaviour'
|
5
|
-
require 'volt/models/validations'
|
5
|
+
require 'volt/models/validations/validations'
|
6
6
|
require 'volt/utils/modes'
|
7
7
|
require 'volt/models/state_manager'
|
8
8
|
require 'volt/models/state_helpers'
|
@@ -10,8 +10,9 @@ require 'volt/models/buffer'
|
|
10
10
|
require 'volt/models/field_helpers'
|
11
11
|
require 'volt/reactive/reactive_hash'
|
12
12
|
require 'volt/models/validators/user_validation'
|
13
|
-
require 'volt/models/dirty'
|
14
|
-
require 'volt/models/listener_tracker'
|
13
|
+
require 'volt/models/model_helpers/dirty'
|
14
|
+
require 'volt/models/model_helpers/listener_tracker'
|
15
|
+
require 'volt/models/model_helpers/model_change_helpers'
|
15
16
|
require 'volt/models/permissions'
|
16
17
|
require 'volt/models/associations'
|
17
18
|
require 'volt/reactive/class_eventable'
|
@@ -45,6 +46,7 @@ module Volt
|
|
45
46
|
include Permissions
|
46
47
|
include Associations
|
47
48
|
include ReactiveAccessors
|
49
|
+
include ModelChangeHelpers
|
48
50
|
|
49
51
|
attr_reader :attributes, :parent, :path, :persistor, :options
|
50
52
|
|
@@ -149,24 +151,7 @@ module Volt
|
|
149
151
|
@deps.changed_all!
|
150
152
|
@deps = HashDependency.new
|
151
153
|
|
152
|
-
|
153
|
-
if initial_setup
|
154
|
-
# Run initial validation
|
155
|
-
if Volt.in_mode?(:no_validate)
|
156
|
-
# No validate, resolve nil
|
157
|
-
Promise.new.resolve(nil)
|
158
|
-
else
|
159
|
-
return validate!.then do |errs|
|
160
|
-
if errs && errs.size > 0
|
161
|
-
Promise.new.reject(errs)
|
162
|
-
else
|
163
|
-
Promise.new.resolve(nil)
|
164
|
-
end
|
165
|
-
end
|
166
|
-
end
|
167
|
-
else
|
168
|
-
return run_changed
|
169
|
-
end
|
154
|
+
run_initial_setup(initial_setup)
|
170
155
|
end
|
171
156
|
|
172
157
|
alias_method :attributes=, :assign_attributes
|
@@ -353,6 +338,28 @@ module Volt
|
|
353
338
|
end
|
354
339
|
|
355
340
|
private
|
341
|
+
def run_initial_setup(initial_setup)
|
342
|
+
|
343
|
+
# Save the changes
|
344
|
+
if initial_setup
|
345
|
+
# Run initial validation
|
346
|
+
if Volt.in_mode?(:no_validate)
|
347
|
+
# No validate, resolve nil
|
348
|
+
Promise.new.resolve(nil)
|
349
|
+
else
|
350
|
+
return validate!.then do |errs|
|
351
|
+
if errs && errs.size > 0
|
352
|
+
Promise.new.reject(errs)
|
353
|
+
else
|
354
|
+
Promise.new.resolve(nil)
|
355
|
+
end
|
356
|
+
end
|
357
|
+
end
|
358
|
+
else
|
359
|
+
return run_changed
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
356
363
|
|
357
364
|
# Volt provides a few access methods to get more data about the model,
|
358
365
|
# we want to prevent these from being assigned or accessed through
|
@@ -363,17 +370,6 @@ module Volt
|
|
363
370
|
end
|
364
371
|
end
|
365
372
|
|
366
|
-
def setup_buffer(model)
|
367
|
-
Volt::Model.no_validate do
|
368
|
-
model.assign_attributes(attributes, true)
|
369
|
-
end
|
370
|
-
|
371
|
-
model.change_state_to(:loaded_state, :loaded)
|
372
|
-
|
373
|
-
# Set new to the same as the main model the buffer is from
|
374
|
-
model.instance_variable_set('@new', @new)
|
375
|
-
end
|
376
|
-
|
377
373
|
# Takes the persistor if there is one and
|
378
374
|
def setup_persistor(persistor)
|
379
375
|
@persistor = persistor.new(self) if persistor
|
@@ -398,63 +394,5 @@ module Volt
|
|
398
394
|
end
|
399
395
|
end
|
400
396
|
end
|
401
|
-
|
402
|
-
# Called when something in the model changes. Saves
|
403
|
-
# the model if there is a persistor, and changes the
|
404
|
-
# model to not be new.
|
405
|
-
#
|
406
|
-
# @return [Promise|nil] a promise for when the save is
|
407
|
-
# complete
|
408
|
-
def run_changed(attribute_name = nil)
|
409
|
-
# no_validate mode should only be used internally. no_validate mode is a
|
410
|
-
# performance optimization that prevents validation from running after each
|
411
|
-
# change when assigning multile attributes.
|
412
|
-
unless Volt.in_mode?(:no_validate)
|
413
|
-
# Run the validations for all fields
|
414
|
-
result = nil
|
415
|
-
return validate!.then do
|
416
|
-
# Buffers are allowed to be in an invalid state
|
417
|
-
unless buffer?
|
418
|
-
# First check that all local validations pass
|
419
|
-
if error_in_changed_attributes?
|
420
|
-
# Some errors are present, revert changes
|
421
|
-
revert_changes!
|
422
|
-
|
423
|
-
# After we revert, we need to validate again to get the error messages back
|
424
|
-
# TODO: Could probably cache the previous errors.
|
425
|
-
result = validate!.then do
|
426
|
-
# Reject the promise with the errors
|
427
|
-
Promise.new.reject(errs)
|
428
|
-
end
|
429
|
-
else
|
430
|
-
# No errors, tell the persistor to handle the change (usually save)
|
431
|
-
|
432
|
-
# Don't save right now if we're in a nosave block
|
433
|
-
unless Volt.in_mode?(:no_save)
|
434
|
-
# the changed method on a persistor should return a promise that will
|
435
|
-
# be resolved when the save is complete, or fail with a hash of errors.
|
436
|
-
if @persistor
|
437
|
-
result = @persistor.changed(attribute_name)
|
438
|
-
else
|
439
|
-
result = Promise.new.resolve(nil)
|
440
|
-
end
|
441
|
-
|
442
|
-
# Saved, no longer new
|
443
|
-
@new = false
|
444
|
-
|
445
|
-
# Clear the change tracking
|
446
|
-
clear_tracked_changes!
|
447
|
-
end
|
448
|
-
end
|
449
|
-
end
|
450
|
-
|
451
|
-
# Return result inside of the validate! promise
|
452
|
-
result
|
453
|
-
end
|
454
|
-
end
|
455
|
-
|
456
|
-
# Didn't run validations
|
457
|
-
nil
|
458
|
-
end
|
459
397
|
end
|
460
398
|
end
|
File without changes
|
File without changes
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# ModelChangeHelpers handle validating and persisting the data in a model
|
2
|
+
# when it is changed. #run_changed will be called from the model.
|
3
|
+
|
4
|
+
module Volt
|
5
|
+
module ModelChangeHelpers
|
6
|
+
private
|
7
|
+
|
8
|
+
# Called when something in the model changes. Saves
|
9
|
+
# the model if there is a persistor, and changes the
|
10
|
+
# model to not be new.
|
11
|
+
#
|
12
|
+
# @return [Promise|nil] a promise for when the save is
|
13
|
+
# complete
|
14
|
+
def run_changed(attribute_name = nil)
|
15
|
+
# no_validate mode should only be used internally. no_validate mode is a
|
16
|
+
# performance optimization that prevents validation from running after each
|
17
|
+
# change when assigning multile attributes.
|
18
|
+
unless Volt.in_mode?(:no_validate)
|
19
|
+
# Run the validations for all fields
|
20
|
+
result = nil
|
21
|
+
return validate!.then do
|
22
|
+
# Buffers are allowed to be in an invalid state
|
23
|
+
unless buffer?
|
24
|
+
# First check that all local validations pass
|
25
|
+
if error_in_changed_attributes?
|
26
|
+
# Some errors are present, revert changes
|
27
|
+
revert_changes!
|
28
|
+
|
29
|
+
# After we revert, we need to validate again to get the error messages back
|
30
|
+
# TODO: Could probably cache the previous errors.
|
31
|
+
result = validate!.then do
|
32
|
+
# Reject the promise with the errors
|
33
|
+
Promise.new.reject(errs)
|
34
|
+
end
|
35
|
+
else
|
36
|
+
result = persist_changes(attribute_name)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Return result inside of the validate! promise
|
41
|
+
result
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Didn't run validations
|
46
|
+
nil
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
# Should only be called from run_changed. Saves the changes back to the persistor
|
51
|
+
# and clears the tracked changes.
|
52
|
+
def persist_changes(attribute_name)
|
53
|
+
# No errors, tell the persistor to handle the change (usually save)
|
54
|
+
|
55
|
+
# Don't save right now if we're in a nosave block
|
56
|
+
unless Volt.in_mode?(:no_save)
|
57
|
+
# the changed method on a persistor should return a promise that will
|
58
|
+
# be resolved when the save is complete, or fail with a hash of errors.
|
59
|
+
if @persistor
|
60
|
+
result = @persistor.changed(attribute_name)
|
61
|
+
else
|
62
|
+
result = Promise.new.resolve(nil)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Saved, no longer new
|
66
|
+
@new = false
|
67
|
+
|
68
|
+
# Clear the change tracking
|
69
|
+
clear_tracked_changes!
|
70
|
+
end
|
71
|
+
|
72
|
+
result
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
File without changes
|
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'volt/models/persistors/store'
|
2
2
|
require 'volt/models/persistors/store_state'
|
3
|
-
require 'volt/models/persistors/query/normalizer'
|
4
3
|
require 'volt/models/persistors/query/query_listener_pool'
|
5
4
|
require 'volt/utils/timers'
|
6
5
|
|
@@ -9,6 +8,7 @@ module Volt
|
|
9
8
|
class ArrayStore < Store
|
10
9
|
include StoreState
|
11
10
|
|
11
|
+
|
12
12
|
@@query_pool = QueryListenerPool.new
|
13
13
|
|
14
14
|
attr_reader :model, :root_dep
|
@@ -141,7 +141,7 @@ module Volt
|
|
141
141
|
end
|
142
142
|
end
|
143
143
|
|
144
|
-
query =
|
144
|
+
query = Volt::DataStore.adaptor_client.normalize_query(query)
|
145
145
|
|
146
146
|
@query_listener ||= @@query_pool.lookup(collection, query) do
|
147
147
|
# Create if it does not exist
|
@@ -153,27 +153,6 @@ module Volt
|
|
153
153
|
@query_listener
|
154
154
|
end
|
155
155
|
|
156
|
-
# Find takes a query object
|
157
|
-
def where(query = nil)
|
158
|
-
query ||= {}
|
159
|
-
|
160
|
-
add_query_part(:find, query)
|
161
|
-
end
|
162
|
-
alias_method :find, :where
|
163
|
-
|
164
|
-
def limit(limit)
|
165
|
-
add_query_part(:limit, limit)
|
166
|
-
end
|
167
|
-
|
168
|
-
def skip(skip)
|
169
|
-
add_query_part(:skip, skip)
|
170
|
-
end
|
171
|
-
|
172
|
-
# .sort is already a ruby method, so we use order instead
|
173
|
-
def order(sort)
|
174
|
-
add_query_part(:sort, sort)
|
175
|
-
end
|
176
|
-
|
177
156
|
# Add query part adds a [method_name, *arguments] array to the query.
|
178
157
|
# This will then be passed to the backend to run the query.
|
179
158
|
#
|
@@ -2,50 +2,6 @@ module Volt
|
|
2
2
|
module Query
|
3
3
|
# Normalizes queries so queries that are the same have the same order and parts
|
4
4
|
class Normalizer
|
5
|
-
def self.normalize(query)
|
6
|
-
query = merge_finds_and_move_to_front(query)
|
7
|
-
|
8
|
-
query = reject_skip_zero(query)
|
9
|
-
|
10
|
-
query
|
11
|
-
end
|
12
|
-
|
13
|
-
def self.merge_finds_and_move_to_front(query)
|
14
|
-
# Map first parts to string
|
15
|
-
query = query.map { |v| v[0] = v[0].to_s; v }
|
16
|
-
has_find = query.find { |v| v[0] == 'find' }
|
17
|
-
|
18
|
-
if has_find
|
19
|
-
# merge any finds
|
20
|
-
merged_find_query = {}
|
21
|
-
query = query.reject do |query_part|
|
22
|
-
if query_part[0] == 'find'
|
23
|
-
# on a find, merge into finds
|
24
|
-
find_query = query_part[1]
|
25
|
-
merged_find_query.merge!(find_query) if find_query
|
26
|
-
|
27
|
-
# reject
|
28
|
-
true
|
29
|
-
else
|
30
|
-
false
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
# Add finds to the front
|
35
|
-
query.insert(0, ['find', merged_find_query])
|
36
|
-
else
|
37
|
-
# No find was done, add it in the first position
|
38
|
-
query.insert(0, ['find'])
|
39
|
-
end
|
40
|
-
|
41
|
-
query
|
42
|
-
end
|
43
|
-
|
44
|
-
def self.reject_skip_zero(query)
|
45
|
-
query.reject do |query_part|
|
46
|
-
query_part[0] == 'skip' && query_part[1] == 0
|
47
|
-
end
|
48
|
-
end
|
49
5
|
end
|
50
6
|
end
|
51
7
|
end
|
File without changes
|
@@ -11,6 +11,8 @@ module Volt
|
|
11
11
|
# Include in any class to get validation logic
|
12
12
|
module Validations
|
13
13
|
module ClassMethods
|
14
|
+
# Validate is called directly on the class and sets up the validation to be run
|
15
|
+
# each time validate! is called on the class.
|
14
16
|
def validate(field_name = nil, options = nil, &block)
|
15
17
|
if block
|
16
18
|
if field_name || options
|
@@ -19,16 +21,47 @@ module Volt
|
|
19
21
|
self.custom_validations ||= []
|
20
22
|
custom_validations << block
|
21
23
|
else
|
22
|
-
self.
|
23
|
-
|
24
|
-
|
24
|
+
self.validations_to_run ||= {}
|
25
|
+
validations_to_run[field_name] ||= {}
|
26
|
+
validations_to_run[field_name].merge!(options)
|
25
27
|
end
|
26
28
|
end
|
29
|
+
|
30
|
+
# Validations takes a block, and can contain validate calls inside of it
|
31
|
+
# which will conditionally be run based on the code in the block. The
|
32
|
+
# context of the block will be the current model.
|
33
|
+
def validations(*run_in_actions, &block)
|
34
|
+
unless block_given?
|
35
|
+
raise 'validations must take a block, use `validate` to setup a validation on a class directly.'
|
36
|
+
end
|
37
|
+
|
38
|
+
# Add a validation block to run during each validation
|
39
|
+
validate do
|
40
|
+
action = new? ? :create : :update
|
41
|
+
|
42
|
+
if run_in_actions.size == 0 || run_in_actions.include?(action)
|
43
|
+
@instance_validations = {}
|
44
|
+
|
45
|
+
instance_exec(action, &block)
|
46
|
+
|
47
|
+
result = run_validations(@instance_validations)
|
48
|
+
|
49
|
+
@instance_validations = nil
|
50
|
+
|
51
|
+
result
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def validate(field_name = nil, options = nil)
|
58
|
+
@instance_validations[field_name] ||= {}
|
59
|
+
@instance_validations[field_name].merge!(options)
|
27
60
|
end
|
28
61
|
|
29
62
|
def self.included(base)
|
30
63
|
base.send :extend, ClassMethods
|
31
|
-
base.class_attribute(:custom_validations, :
|
64
|
+
base.class_attribute(:custom_validations, :validations_to_run)
|
32
65
|
end
|
33
66
|
|
34
67
|
# Once a field is ready, we can use include_in_errors! to start
|
@@ -43,11 +76,21 @@ module Volt
|
|
43
76
|
|
44
77
|
# Marks all fields, useful for when a model saves.
|
45
78
|
def mark_all_fields!
|
46
|
-
|
79
|
+
# TODO: We can use a Set here, but set was having issues. Check in a
|
80
|
+
# later version of opal.
|
81
|
+
fields_to_mark = []
|
82
|
+
|
83
|
+
# Look at each validation
|
84
|
+
validations = self.class.validations_to_run
|
47
85
|
if validations
|
48
|
-
validations.
|
49
|
-
|
50
|
-
|
86
|
+
fields_to_mark += validations.keys
|
87
|
+
end
|
88
|
+
|
89
|
+
# Also include any current fields
|
90
|
+
fields_to_mark += attributes.keys
|
91
|
+
|
92
|
+
fields_to_mark.each do |key|
|
93
|
+
mark_field!(key.to_sym)
|
51
94
|
end
|
52
95
|
end
|
53
96
|
|
@@ -110,31 +153,42 @@ module Volt
|
|
110
153
|
private
|
111
154
|
|
112
155
|
# Runs through each of the normal validations.
|
156
|
+
# @param [Array] An array of validations to run
|
113
157
|
# @return [Promise] a promsie to run all validations
|
114
|
-
def run_validations
|
115
|
-
|
158
|
+
def run_validations(validations = nil)
|
159
|
+
# Default to running the class level validations
|
160
|
+
validations ||= self.class.validations_to_run
|
116
161
|
|
117
|
-
|
162
|
+
promise = Promise.new.resolve(nil)
|
118
163
|
if validations
|
119
164
|
|
120
165
|
# Run through each validation
|
121
166
|
validations.each_pair do |field_name, options|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
167
|
+
promise = promise.then { run_validation(field_name, options) }
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
promise
|
172
|
+
end
|
173
|
+
|
174
|
+
# Runs an individual validation
|
175
|
+
# @returns [Promise]
|
176
|
+
def run_validation(field_name, options)
|
177
|
+
promise = Promise.new.resolve(nil)
|
178
|
+
options.each_pair do |validation, args|
|
179
|
+
# Call the specific validator, then merge the results back
|
180
|
+
# into one large errors hash.
|
181
|
+
klass = validation_class(validation, args)
|
182
|
+
|
183
|
+
if klass
|
184
|
+
# Chain on the promises
|
185
|
+
promise = promise.then do
|
186
|
+
klass.validate(self, field_name, args)
|
187
|
+
end.then do |errs|
|
188
|
+
errors.merge!(errs)
|
137
189
|
end
|
190
|
+
else
|
191
|
+
fail "validation type #{validation} is not specified."
|
138
192
|
end
|
139
193
|
end
|
140
194
|
|