volt 0.9.0.pre7 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7b1a1de6a4ca5bb3040697994dc02235caef5df1
4
- data.tar.gz: 560933928252e51c201ffc9f0167d7a81255c415
3
+ metadata.gz: 1a09dcf76510b9f9be2a538e6dfc437cf74ccd1b
4
+ data.tar.gz: c6982a5ceaf9fd3a4ae463f185141e789bd93fb9
5
5
  SHA512:
6
- metadata.gz: 55024841e17f8e8f267f5728f5ed46ac81254c29c4fb3f494a840b2c337d5cbe901204bdac3396380465460b03cc2ebcaabc886d6a77b234ec50ce96d1b4a6be
7
- data.tar.gz: 72dccab3dfa677e6b444e152ca9b3654cf48317de5a65a2ac2494b6084bc862301dbedce6d8663a803c0e46b0bb0167a5549f042724c768975877f6fc89d7c94
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. Docs coming soon.
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
+ [![Gratipay](http://img.shields.io/gratipay/voltframework.svg)](https://www.gratipay.com/voltframework/)
1
2
  [![Gem Version](https://badge.fury.io/rb/volt.svg)](http://badge.fury.io/rb/volt)
2
3
  [![Code Climate](https://codeclimate.com/github/voltrb/volt/badges/gpa.svg)](https://codeclimate.com/github/voltrb/volt)
3
4
  [![Build Status](http://img.shields.io/travis/voltrb/volt/master.svg?style=flat)](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=Tg-EtRnMz7o)
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/todos3
24
- - https://github.com/voltrb/contactsdemo
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
- [![Pledgie](https://pledgie.com/campaigns/26731.png?skin_name=chrome)](https://pledgie.com/campaigns/26731)
38
+
39
+ [![Gratipay](//img.shields.io/gratipay/voltframework.svg)](https://www.gratipay.com/voltframework/)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.9.0.pre7
1
+ 0.9.0
@@ -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
- # Get errors from validate
13
- errors = self.errors.to_h
14
-
15
- result = nil
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
- 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
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
- result = promise.then do |new_model|
29
- # The main model saved, so mark the buffer as not new
30
- @new = false
32
+ if new_model
33
+ # Mark the model as loaded
34
+ new_model.change_state_to(:loaded_state, :loaded)
31
35
 
32
- if new_model
33
- # Mark the model as loaded
34
- new_model.change_state_to(:loaded_state, :loaded)
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
- # 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
41
+ nil
42
+ end.fail do |errors|
43
+ if errors.is_a?(Hash)
44
+ server_errors.replace(errors)
45
+ end
40
46
 
41
- nil
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
- promise_for_errors(errors)
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
- fail 'Model is not a buffer, can not be saved, modifications should be persisted as they are made.'
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
- # If passed a block, call then on it with the block.
58
- result = result.then(&block) if block
57
+ # If passed a block, call then on it with the block.
58
+ result = result.then(&block) if block
59
59
 
60
- return result
60
+ result
61
+ end
61
62
  end
62
63
 
63
64
  # When errors come in, we mark all fields and return a rejected promise.
@@ -152,12 +152,17 @@ module Volt
152
152
  # Save the changes
153
153
  if initial_setup
154
154
  # Run initial validation
155
- errs = Volt.in_mode?(:no_validate) ? nil : validate!
156
-
157
- if errs && errs.size > 0
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 Promise.new.resolve(nil)
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
- validate!
415
-
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
- errs = validate!
426
-
427
- result = Promise.new.reject(errs)
428
- else
429
- # No errors, tell the persistor to handle the change (usually save)
430
-
431
- # Don't save right now if we're in a nosave block
432
- unless Volt.in_mode?(:no_save)
433
- # the changed method on a persistor should return a promise that will
434
- # be resolved when the save is complete, or fail with a hash of errors.
435
- if @persistor
436
- result = @persistor.changed(attribute_name)
437
- else
438
- result = Promise.new.resolve(nil)
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
- return result
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
- # 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)
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
- result = klass.validate(self, field_name, args)
127
- errors.merge!(result)
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
- errors
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
- # Run the validator in the context of the model
144
- result = instance_exec(&custom_validation)
145
- errors.merge!(result)
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)
@@ -68,7 +68,7 @@ module Volt
68
68
  current_value = value
69
69
  end
70
70
 
71
- if current_value && !current_value.nil? && !current_value.is_a?(Exception)
71
+ if current_value && !current_value.is_a?(Exception)
72
72
  # This branch is currently true
73
73
  true_template = template_name
74
74
  break
@@ -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)
@@ -4,7 +4,7 @@ module Volt
4
4
 
5
5
  def initialize(controller, action)
6
6
  @controller = controller
7
- @action = action.to_sym
7
+ @action = action.to_sym if action
8
8
  end
9
9
 
10
10
  def call_action(stage_prefix=nil, stage_suffix=nil)
@@ -57,9 +57,7 @@ module Volt
57
57
  unless @invalidated
58
58
  @invalidated = true
59
59
 
60
- unless @stopped || @computing
61
- queue_flush!
62
- end
60
+ queue_flush! unless @stopped
63
61
 
64
62
  invalidations = @invalidations
65
63
  @invalidations = []
@@ -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 "doesn't add self to flush queue" do
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).to be_empty
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.pre7
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-16 00:00:00.000000000 Z
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: 1.3.1
832
+ version: '0'
833
833
  requirements: []
834
834
  rubyforge_project:
835
835
  rubygems_version: 2.4.5