volt 0.9.0.pre7 → 0.9.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 +4 -4
- data/CHANGELOG.md +1 -1
- data/README.md +7 -4
- data/VERSION +1 -1
- data/lib/volt/models/buffer.rb +41 -40
- data/lib/volt/models/model.rb +49 -39
- data/lib/volt/models/validations.rb +30 -14
- data/lib/volt/page/bindings/if_binding.rb +1 -1
- data/lib/volt/page/bindings/view_binding.rb +0 -1
- data/lib/volt/page/bindings/view_binding/controller_handler.rb +1 -1
- data/lib/volt/reactive/computation.rb +1 -3
- data/spec/models/validations_spec.rb +22 -0
- data/spec/reactive/computation_spec.rb +2 -2
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1a09dcf76510b9f9be2a538e6dfc437cf74ccd1b
|
4
|
+
data.tar.gz: c6982a5ceaf9fd3a4ae463f185141e789bd93fb9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ba21338f15fece2dbfa90951956f9a73e93ead112259ffc87e7944a9f43368412f66f319fe265117b67d43bf783813058c3e1ea9b1b11403a666353718d4ee38
|
7
|
+
data.tar.gz: 2eb8459d1199bf301536c79335d1554ca7f84211251b5c772bef6637ee4440107bd1260880593537c656179d11c2580618b1d1c2495bad9ef9e43a2c4d95e369
|
data/CHANGELOG.md
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
### Added
|
5
5
|
- the permissions api has been added!
|
6
6
|
- added has_many and belongs_to on models. See docs.
|
7
|
-
- you can now serve http/rest from Volt. Thanks to @jfahrer for his great work.
|
7
|
+
- you can now serve http/rest from Volt. Thanks to @jfahrer for his great work. More docs coming soon.
|
8
8
|
- there is now a generator for controllers and HttpControllers.
|
9
9
|
- fixed generated component code
|
10
10
|
- added .order for sorting on the data store (since .sort is a ruby Enum method)
|
data/README.md
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
[](https://www.gratipay.com/voltframework/)
|
1
2
|
[](http://badge.fury.io/rb/volt)
|
2
3
|
[](https://codeclimate.com/github/voltrb/volt)
|
3
4
|
[](https://travis-ci.org/voltrb/volt)
|
@@ -12,7 +13,8 @@ Instead of syncing data between the client and server via HTTP, Volt uses a pers
|
|
12
13
|
Pages HTML is written in a template language where you can put Ruby between `{{` and `}}`. Volt uses data flow/reactive programming to automatically and intelligently propagate changes to the DOM (or any other code wanting to know when a value updates). When something in the DOM changes, Volt intelligently updates only the nodes that need to be changed.
|
13
14
|
|
14
15
|
See some demo videos here:
|
15
|
-
- [Volt Todos Example](https://www.youtube.com/watch?v=
|
16
|
+
- [Volt Todos Example](https://www.youtube.com/watch?v=KbFtIt7-ge8)
|
17
|
+
- [What Is Volt in 6 Minutes](https://www.youtube.com/watch?v=P27EPQ4ne7o)
|
16
18
|
- [Pagination Example](https://www.youtube.com/watch?v=1uanfzMLP9g)
|
17
19
|
- [Routes and Templates](https://www.youtube.com/watch?v=1yNMP3XR6jU)
|
18
20
|
- [Isomorphic App Development - RubyConf 2014](https://www.youtube.com/watch?v=7i6AL7Walc4)
|
@@ -20,8 +22,8 @@ See some demo videos here:
|
|
20
22
|
**Note:** The blog video is outdated, expect an updated version soon.
|
21
23
|
|
22
24
|
Check out demo apps:
|
23
|
-
- https://github.com/voltrb/
|
24
|
-
- https://github.com/voltrb/
|
25
|
+
- https://github.com/voltrb/todomvc
|
26
|
+
- https://github.com/voltrb/blog5
|
25
27
|
|
26
28
|
# Docs
|
27
29
|
|
@@ -33,4 +35,5 @@ There is also a [work in progress tutorial](https://github.com/rhgraysonii/volt_
|
|
33
35
|
|
34
36
|
You want to contribute? Great! Thanks for being awesome! At the moment, we have a big internal todo list, hop on https://gitter.im/voltrb/volt so we don't duplicate work. Pull requests are always welcome, but asking about helping on Gitter should save some duplication.
|
35
37
|
|
36
|
-
|
38
|
+
|
39
|
+
[](https://www.gratipay.com/voltframework/)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.9.0
|
1
|
+
0.9.0
|
data/lib/volt/models/buffer.rb
CHANGED
@@ -7,57 +7,58 @@ module Volt
|
|
7
7
|
def save!(&block)
|
8
8
|
# TODO: this shouldn't need to be run, but if no attributes are assigned, then
|
9
9
|
# if needs to be run. Maybe there's a better way to handle it.
|
10
|
-
validate
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
10
|
+
return validate!.then do
|
11
|
+
|
12
|
+
# Get errors from validate
|
13
|
+
errors = self.errors.to_h
|
14
|
+
|
15
|
+
result = nil
|
16
|
+
|
17
|
+
if errors.size == 0
|
18
|
+
save_to = options[:save_to]
|
19
|
+
if save_to
|
20
|
+
if save_to.is_a?(ArrayModel)
|
21
|
+
# Add to the collection
|
22
|
+
promise = save_to.append(attributes)
|
23
|
+
else
|
24
|
+
# We have a saved model
|
25
|
+
promise = save_to.assign_attributes(attributes)
|
26
|
+
end
|
16
27
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
if save_to.is_a?(ArrayModel)
|
21
|
-
# Add to the collection
|
22
|
-
promise = save_to.append(attributes)
|
23
|
-
else
|
24
|
-
# We have a saved model
|
25
|
-
promise = save_to.assign_attributes(attributes)
|
26
|
-
end
|
28
|
+
result = promise.then do |new_model|
|
29
|
+
# The main model saved, so mark the buffer as not new
|
30
|
+
@new = false
|
27
31
|
|
28
|
-
|
29
|
-
|
30
|
-
|
32
|
+
if new_model
|
33
|
+
# Mark the model as loaded
|
34
|
+
new_model.change_state_to(:loaded_state, :loaded)
|
31
35
|
|
32
|
-
|
33
|
-
|
34
|
-
|
36
|
+
# Set the buffer's id to track the main model's id
|
37
|
+
attributes[:_id] = new_model._id
|
38
|
+
options[:save_to] = new_model
|
39
|
+
end
|
35
40
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
41
|
+
nil
|
42
|
+
end.fail do |errors|
|
43
|
+
if errors.is_a?(Hash)
|
44
|
+
server_errors.replace(errors)
|
45
|
+
end
|
40
46
|
|
41
|
-
|
42
|
-
end.fail do |errors|
|
43
|
-
if errors.is_a?(Hash)
|
44
|
-
server_errors.replace(errors)
|
47
|
+
promise_for_errors(errors)
|
45
48
|
end
|
46
|
-
|
47
|
-
|
49
|
+
else
|
50
|
+
fail 'Model is not a buffer, can not be saved, modifications should be persisted as they are made.'
|
48
51
|
end
|
49
52
|
else
|
50
|
-
|
53
|
+
# Some errors, mark all fields
|
54
|
+
result = promise_for_errors(errors)
|
51
55
|
end
|
52
|
-
else
|
53
|
-
# Some errors, mark all fields
|
54
|
-
result = promise_for_errors(errors)
|
55
|
-
end
|
56
56
|
|
57
|
-
|
58
|
-
|
57
|
+
# If passed a block, call then on it with the block.
|
58
|
+
result = result.then(&block) if block
|
59
59
|
|
60
|
-
|
60
|
+
result
|
61
|
+
end
|
61
62
|
end
|
62
63
|
|
63
64
|
# When errors come in, we mark all fields and return a rejected promise.
|
data/lib/volt/models/model.rb
CHANGED
@@ -152,12 +152,17 @@ module Volt
|
|
152
152
|
# Save the changes
|
153
153
|
if initial_setup
|
154
154
|
# Run initial validation
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
return Promise.new.reject(errs)
|
155
|
+
if Volt.in_mode?(:no_validate)
|
156
|
+
# No validate, resolve nil
|
157
|
+
Promise.new.resolve(nil)
|
159
158
|
else
|
160
|
-
return
|
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
|
161
166
|
end
|
162
167
|
else
|
163
168
|
return run_changed
|
@@ -404,51 +409,56 @@ module Volt
|
|
404
409
|
# @return [Promise|nil] a promise for when the save is
|
405
410
|
# complete
|
406
411
|
def run_changed(attribute_name=nil)
|
407
|
-
result = nil
|
408
|
-
|
409
412
|
# no_validate mode should only be used internally. no_validate mode is a
|
410
413
|
# performance optimization that prevents validation from running after each
|
411
414
|
# change when assigning multile attributes.
|
412
415
|
unless Volt.in_mode?(:no_validate)
|
413
416
|
# Run the validations for all fields
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
#
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
417
|
+
result = nil
|
418
|
+
return validate!.then do
|
419
|
+
|
420
|
+
# Buffers are allowed to be in an invalid state
|
421
|
+
unless buffer?
|
422
|
+
# First check that all local validations pass
|
423
|
+
if error_in_changed_attributes?
|
424
|
+
# Some errors are present, revert changes
|
425
|
+
revert_changes!
|
426
|
+
|
427
|
+
# After we revert, we need to validate again to get the error messages back
|
428
|
+
# TODO: Could probably cache the previous errors.
|
429
|
+
result = validate!.then do
|
430
|
+
# Reject the promise with the errors
|
431
|
+
Promise.new.reject(errs)
|
432
|
+
end
|
433
|
+
else
|
434
|
+
# No errors, tell the persistor to handle the change (usually save)
|
435
|
+
|
436
|
+
# Don't save right now if we're in a nosave block
|
437
|
+
unless Volt.in_mode?(:no_save)
|
438
|
+
# the changed method on a persistor should return a promise that will
|
439
|
+
# be resolved when the save is complete, or fail with a hash of errors.
|
440
|
+
if @persistor
|
441
|
+
result = @persistor.changed(attribute_name)
|
442
|
+
else
|
443
|
+
result = Promise.new.resolve(nil)
|
444
|
+
end
|
445
|
+
|
446
|
+
# Saved, no longer new
|
447
|
+
@new = false
|
448
|
+
|
449
|
+
# Clear the change tracking
|
450
|
+
clear_tracked_changes!
|
439
451
|
end
|
440
|
-
|
441
|
-
# Saved, no longer new
|
442
|
-
@new = false
|
443
|
-
|
444
|
-
# Clear the change tracking
|
445
|
-
clear_tracked_changes!
|
446
452
|
end
|
447
453
|
end
|
454
|
+
|
455
|
+
# Return result inside of the validate! promise
|
456
|
+
result
|
448
457
|
end
|
449
458
|
end
|
450
459
|
|
451
|
-
|
460
|
+
# Didn't run validations
|
461
|
+
return nil
|
452
462
|
end
|
453
463
|
end
|
454
464
|
end
|
@@ -82,16 +82,18 @@ module Volt
|
|
82
82
|
def validate!
|
83
83
|
errors.clear
|
84
84
|
|
85
|
-
run_validations
|
85
|
+
run_validations.then do
|
86
86
|
|
87
|
-
|
88
|
-
|
89
|
-
|
87
|
+
# See if any server errors are in place and merge them in if they are
|
88
|
+
if Volt.client?
|
89
|
+
errors.merge!(server_errors.to_h)
|
90
|
+
end
|
91
|
+
end.then do
|
92
|
+
run_custom_validations
|
93
|
+
end.then do
|
94
|
+
# Return the errors object
|
95
|
+
errors
|
90
96
|
end
|
91
|
-
|
92
|
-
run_custom_validations
|
93
|
-
|
94
|
-
errors
|
95
97
|
end
|
96
98
|
|
97
99
|
# Returns true if any of the changed fields now has an error
|
@@ -111,7 +113,10 @@ module Volt
|
|
111
113
|
private
|
112
114
|
|
113
115
|
# Runs through each of the normal validations.
|
116
|
+
# @return [Promise] a promsie to run all validations
|
114
117
|
def run_validations
|
118
|
+
promise = Promise.new.resolve(nil)
|
119
|
+
|
115
120
|
validations = self.class.validations
|
116
121
|
if validations
|
117
122
|
|
@@ -123,8 +128,12 @@ module Volt
|
|
123
128
|
klass = validation_class(validation, args)
|
124
129
|
|
125
130
|
if klass
|
126
|
-
|
127
|
-
|
131
|
+
# Chain on the promises
|
132
|
+
promise = promise.then do
|
133
|
+
klass.validate(self, field_name, args)
|
134
|
+
end.then do |errs|
|
135
|
+
errors.merge!(errs)
|
136
|
+
end
|
128
137
|
else
|
129
138
|
fail "validation type #{validation} is not specified."
|
130
139
|
end
|
@@ -132,19 +141,26 @@ module Volt
|
|
132
141
|
end
|
133
142
|
end
|
134
143
|
|
135
|
-
|
144
|
+
return promise
|
136
145
|
end
|
137
146
|
|
138
147
|
def run_custom_validations
|
148
|
+
promise = Promise.new.resolve(nil)
|
139
149
|
# Call all of the custom validations
|
140
150
|
custom_validations = self.class.custom_validations
|
141
151
|
if custom_validations
|
142
152
|
custom_validations.each do |custom_validation|
|
143
|
-
#
|
144
|
-
|
145
|
-
|
153
|
+
# Add to the promise chain
|
154
|
+
promise = promise.then do
|
155
|
+
# Run the validator in the context of the model
|
156
|
+
instance_exec(&custom_validation)
|
157
|
+
end.then do |errs|
|
158
|
+
errors.merge!(errs)
|
159
|
+
end
|
146
160
|
end
|
147
161
|
end
|
162
|
+
|
163
|
+
return promise
|
148
164
|
end
|
149
165
|
|
150
166
|
def validation_class(validation, args)
|
@@ -85,7 +85,6 @@ module Volt
|
|
85
85
|
remove_starting_controller
|
86
86
|
else
|
87
87
|
# None of the actions stopped the chain
|
88
|
-
|
89
88
|
# Wait until the controller is loaded before we actually render.
|
90
89
|
@waiting_for_load = -> { @starting_controller_handler.controller.loaded? }.watch_until!(true) do
|
91
90
|
render_next_template(full_path, path)
|
@@ -15,6 +15,19 @@ describe Volt::Model do
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
+
let(:test_model_with_promises) do
|
19
|
+
Class.new(Volt::Model) do
|
20
|
+
attr_accessor :ran_promise
|
21
|
+
validate do
|
22
|
+
|
23
|
+
Promise.new.then do
|
24
|
+
self.ran_promise = true
|
25
|
+
{name: 'Invalid'}
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
18
31
|
it 'should return errors for all failed validations' do
|
19
32
|
model.validate!
|
20
33
|
expect(model.errors).to eq(
|
@@ -37,6 +50,15 @@ describe Volt::Model do
|
|
37
50
|
)
|
38
51
|
end
|
39
52
|
|
53
|
+
it 'should resolve promises returned from inside of validations' do
|
54
|
+
model = test_model_with_promises.new
|
55
|
+
|
56
|
+
model.validate!.then do |errs|
|
57
|
+
expect(errs).to eq({name: 'Invalid'})
|
58
|
+
expect(model.ran_promise).to eq(true)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
40
62
|
describe 'builtin validations' do
|
41
63
|
shared_examples_for 'a built in validation' do |field, message|
|
42
64
|
specify do
|
@@ -150,10 +150,10 @@ describe Volt::Computation do
|
|
150
150
|
describe 'when computing' do
|
151
151
|
before(:each) { computation.instance_variable_set :@computing, true }
|
152
152
|
|
153
|
-
it "
|
153
|
+
it "should still add itself to flush queue" do
|
154
154
|
computation.invalidate!
|
155
155
|
|
156
|
-
expect(Volt::Computation.class_variable_get :@@flush_queue).
|
156
|
+
expect(Volt::Computation.class_variable_get :@@flush_queue).not_to be_empty
|
157
157
|
end
|
158
158
|
end
|
159
159
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: volt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.0
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Stout
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-04-
|
11
|
+
date: 2015-04-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -827,9 +827,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
827
827
|
version: '0'
|
828
828
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
829
829
|
requirements:
|
830
|
-
- - "
|
830
|
+
- - ">="
|
831
831
|
- !ruby/object:Gem::Version
|
832
|
-
version:
|
832
|
+
version: '0'
|
833
833
|
requirements: []
|
834
834
|
rubyforge_project:
|
835
835
|
rubygems_version: 2.4.5
|