volt 0.9.2 → 0.9.3.pre1
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 +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
|
|