volt 0.7.4 → 0.7.5
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/VERSION +1 -1
- data/app/volt/tasks/query_tasks.rb +11 -2
- data/app/volt/tasks/store_tasks.rb +1 -1
- data/lib/volt/models/array_model.rb +4 -4
- data/lib/volt/models/model.rb +7 -3
- data/lib/volt/models/persistors/array_store.rb +12 -6
- data/lib/volt/models/persistors/model_store.rb +1 -1
- data/lib/volt/models/persistors/query/query_listener.rb +1 -1
- data/lib/volt/models/persistors/store_state.rb +3 -3
- data/lib/volt/models/{validations/validations.rb → validations.rb} +22 -6
- data/lib/volt/models/validators/length_validator.rb +28 -0
- data/lib/volt/models/validators/presence_validator.rb +17 -0
- data/lib/volt/page/bindings/component_binding.rb +1 -33
- data/lib/volt/page/bindings/template_binding.rb +1 -1
- data/spec/models/validations_spec.rb +44 -7
- data/templates/project/app/home/config/routes.rb +1 -1
- data/templates/project/app/home/views/index/index.html +6 -6
- metadata +5 -5
- data/lib/volt/models/validations/errors.rb +0 -0
- data/lib/volt/models/validations/length.rb +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6cb6fdeeaa6a10b0a3d1c81805a3feda5df1f60d
|
4
|
+
data.tar.gz: b833be5d63e7db1d7b8f9a1af8afee11d526e8d5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 29913c4b065abdc2960154fbace2edb83a8ea92e6f7955d538541b05227875770d327136d9d2e02e3d6c00642894545d0b917b63f085456dacbd5f1a37f11275
|
7
|
+
data.tar.gz: 1a73d3935e08f24fc64aa2f7dbca692d4cd27aeda930e9d1045c4e47938fea9ef47badd3ffeebbbea8b4fc004efd6d1a7d5e8dea69bc5a6496c06f0522df023e
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.7.
|
1
|
+
0.7.5
|
@@ -22,8 +22,17 @@ class QueryTasks
|
|
22
22
|
puts "Load data on #{collection.inspect} - #{query.inspect}"
|
23
23
|
live_query.add_channel(@channel)
|
24
24
|
|
25
|
-
|
26
|
-
|
25
|
+
errors = {}
|
26
|
+
|
27
|
+
begin
|
28
|
+
# Get the initial data
|
29
|
+
initial_data = live_query.initial_data
|
30
|
+
rescue => exception
|
31
|
+
# Capture and pass up any exceptions
|
32
|
+
error = {:error => exception.message}
|
33
|
+
end
|
34
|
+
|
35
|
+
return initial_data, error
|
27
36
|
end
|
28
37
|
|
29
38
|
def initial_data
|
@@ -49,14 +49,14 @@ class ArrayModel < ReactiveArray
|
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
|
-
tag_method(:
|
52
|
+
tag_method(:then) do
|
53
53
|
destructive!
|
54
54
|
end
|
55
|
-
def
|
55
|
+
def then(*args, &block)
|
56
56
|
if @persistor
|
57
|
-
return @persistor.
|
57
|
+
return @persistor.then(*args, &block)
|
58
58
|
else
|
59
|
-
raise "this model's persistance layer does not support
|
59
|
+
raise "this model's persistance layer does not support then, try using store"
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
data/lib/volt/models/model.rb
CHANGED
@@ -3,7 +3,7 @@ require 'volt/models/array_model'
|
|
3
3
|
require 'volt/models/model_helpers'
|
4
4
|
require 'volt/reactive/object_tracking'
|
5
5
|
require 'volt/models/model_hash_behaviour'
|
6
|
-
require 'volt/models/validations
|
6
|
+
require 'volt/models/validations'
|
7
7
|
require 'volt/models/model_state'
|
8
8
|
|
9
9
|
|
@@ -60,7 +60,11 @@ class Model
|
|
60
60
|
trigger!('changed')
|
61
61
|
|
62
62
|
# Let the persistor know something changed
|
63
|
-
|
63
|
+
if @persistor
|
64
|
+
# the changed method on a persistor should return a promise that will
|
65
|
+
# be resolved when the save is complete, or fail with a hash of errors.
|
66
|
+
return @persistor.changed
|
67
|
+
end
|
64
68
|
end
|
65
69
|
end
|
66
70
|
alias_method :assign_attributes, :attributes=
|
@@ -306,7 +310,7 @@ class Model
|
|
306
310
|
if state == :loaded
|
307
311
|
setup_buffer(model)
|
308
312
|
else
|
309
|
-
self.parent.
|
313
|
+
self.parent.then do
|
310
314
|
setup_buffer(model)
|
311
315
|
end
|
312
316
|
end
|
@@ -106,18 +106,24 @@ module Persistors
|
|
106
106
|
return ReactiveValue.new(model)
|
107
107
|
end
|
108
108
|
|
109
|
-
#
|
110
|
-
# the
|
111
|
-
def
|
109
|
+
# Returns a promise that is resolved/rejected when the query is complete. Any
|
110
|
+
# passed block will be passed to the promises then. Then will be passed the model.
|
111
|
+
def then(&block)
|
112
|
+
promise = Promise.new
|
113
|
+
|
114
|
+
promise = promise.then(&block) if block
|
115
|
+
|
112
116
|
# puts "FETCH: #{@state.inspect}"
|
113
117
|
if @state == :loaded
|
114
|
-
|
118
|
+
promise.resolve(@model)
|
115
119
|
else
|
116
|
-
@
|
117
|
-
@
|
120
|
+
@fetch_promises ||= []
|
121
|
+
@fetch_promises << promise
|
118
122
|
|
119
123
|
load_data
|
120
124
|
end
|
125
|
+
|
126
|
+
return promise
|
121
127
|
end
|
122
128
|
|
123
129
|
# Called from backend
|
@@ -15,7 +15,7 @@ class QueryListener
|
|
15
15
|
|
16
16
|
def add_listener
|
17
17
|
@listening = true
|
18
|
-
@tasks.call('QueryTasks', 'add_listener', @collection, @query) do |results|
|
18
|
+
@tasks.call('QueryTasks', 'add_listener', @collection, @query) do |results, errors|
|
19
19
|
# When the initial data comes back, add it into the stores.
|
20
20
|
@stores.each do |store|
|
21
21
|
store.model.clear
|
@@ -17,10 +17,10 @@ module StoreState
|
|
17
17
|
# Trigger changed on the 'state' method
|
18
18
|
@model.trigger_for_methods!('changed', :state, :loaded?)
|
19
19
|
|
20
|
-
if @state == :loaded && @
|
20
|
+
if @state == :loaded && @fetch_promises
|
21
21
|
# Trigger each waiting fetch
|
22
|
-
@
|
23
|
-
@
|
22
|
+
@fetch_promises.compact.each {|fp| fp.resolve(@model) }
|
23
|
+
@fetch_promises = nil
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# require 'volt/models/validations/errors'
|
2
|
-
require 'volt/models/
|
2
|
+
require 'volt/models/validators/length_validator'
|
3
|
+
require 'volt/models/validators/presence_validator'
|
3
4
|
|
4
5
|
# Include in any class to get validation logic
|
5
6
|
module Validations
|
@@ -67,16 +68,31 @@ module Validations
|
|
67
68
|
options.each_pair do |validation, args|
|
68
69
|
# Call the specific validator, then merge the results back
|
69
70
|
# into one large errors hash.
|
70
|
-
|
71
|
-
|
72
|
-
|
71
|
+
klass = validation_class(validation, args)
|
72
|
+
|
73
|
+
if klass
|
74
|
+
validate_with(merge, klass, field_name, args)
|
75
|
+
else
|
76
|
+
raise "validtion type #{validation} is not specified."
|
73
77
|
end
|
74
78
|
end
|
75
79
|
end
|
76
80
|
end
|
77
81
|
|
78
|
-
# puts "ERROR: #{errors.inspect}"
|
79
|
-
|
80
82
|
return errors
|
81
83
|
end
|
84
|
+
|
85
|
+
private
|
86
|
+
# calls the validate method on the class, passing the right arguments.
|
87
|
+
def validate_with(merge, klass, field_name, args)
|
88
|
+
return merge.call(klass.validate(self, field_name, args))
|
89
|
+
end
|
90
|
+
|
91
|
+
def validation_class(validation, args)
|
92
|
+
begin
|
93
|
+
Object.const_get(:"#{validation.camelize}Validator")
|
94
|
+
rescue NameError => e
|
95
|
+
puts "Unable to find #{validation} validator"
|
96
|
+
end
|
97
|
+
end
|
82
98
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class LengthValidator
|
2
|
+
def self.validate(model, field_name, args)
|
3
|
+
errors = {}
|
4
|
+
value = model.send(field_name)
|
5
|
+
|
6
|
+
if args.is_a?(Fixnum)
|
7
|
+
min = args
|
8
|
+
max = nil
|
9
|
+
message = nil
|
10
|
+
elsif args.is_a?(Hash)
|
11
|
+
min = args[:length] || args[:minimum]
|
12
|
+
max = args[:maximum]
|
13
|
+
raise "length or minimum must be specified" unless min.is_a?(Fixnum)
|
14
|
+
|
15
|
+
message = args[:message]
|
16
|
+
else
|
17
|
+
raise "The arguments to length must be a number or a hash"
|
18
|
+
end
|
19
|
+
|
20
|
+
if !value || value.size < min
|
21
|
+
errors[field_name] = [message || "must be at least #{args} characters"]
|
22
|
+
elsif max && value.size > max
|
23
|
+
errors[field_name] = [message || "must be less than #{args} characters"]
|
24
|
+
end
|
25
|
+
|
26
|
+
return errors
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class PresenceValidator
|
2
|
+
def self.validate(model, field_name, args)
|
3
|
+
errors = {}
|
4
|
+
value = model.send(field_name)
|
5
|
+
if !value || value.blank?
|
6
|
+
if args.is_a?(Hash) && args[:message]
|
7
|
+
message = args[:message]
|
8
|
+
else
|
9
|
+
message = "must be specified"
|
10
|
+
end
|
11
|
+
|
12
|
+
errors[field_name] = [message]
|
13
|
+
end
|
14
|
+
|
15
|
+
return errors
|
16
|
+
end
|
17
|
+
end
|
@@ -1,37 +1,5 @@
|
|
1
1
|
require 'volt/page/bindings/template_binding'
|
2
2
|
|
3
|
-
# Component bindings are the same as template bindings, but handle components
|
4
|
-
# and do not pass their context through
|
3
|
+
# Component bindings are the same as template bindings, but handle components.
|
5
4
|
class ComponentBinding < TemplateBinding
|
6
|
-
# The context for a component binding can be either the controller, or the
|
7
|
-
# component arguments (@arguments), with the $page as the context. This gives
|
8
|
-
# components access to the page collections.
|
9
|
-
# def render_template(full_path, controller_path)
|
10
|
-
# # TODO: at the moment a :body section and a :title will both initialize different
|
11
|
-
# # controllers. Maybe we should have a way to tie them together?
|
12
|
-
# controller_class, action = get_controller(controller_path)
|
13
|
-
#
|
14
|
-
# model_with_parent = {parent: @context}.merge(@arguments || {})
|
15
|
-
#
|
16
|
-
# if controller_class
|
17
|
-
# # The user provided a controller, pass in the model as an argument (in a
|
18
|
-
# # sub-context)
|
19
|
-
# args = []
|
20
|
-
# args << SubContext.new(model_with_parent) if @arguments
|
21
|
-
#
|
22
|
-
# current_context = controller_class.new(*args)
|
23
|
-
# @controller = current_context
|
24
|
-
#
|
25
|
-
# # Trigger the action
|
26
|
-
# @controller.send(action) if @controller.respond_to?(action)
|
27
|
-
# else
|
28
|
-
# # There is not a controller
|
29
|
-
# current_context = SubContext.new(model_with_parent, @page)
|
30
|
-
# @controller = nil
|
31
|
-
# end
|
32
|
-
#
|
33
|
-
# @current_template = TemplateRenderer.new(@page, @target, current_context, @binding_name, full_path)
|
34
|
-
#
|
35
|
-
# call_ready
|
36
|
-
# end
|
37
5
|
end
|
@@ -12,7 +12,7 @@ class TemplateBinding < BaseBinding
|
|
12
12
|
@current_template = nil
|
13
13
|
|
14
14
|
# Find the source for the getter binding
|
15
|
-
@path, section = value_from_getter(getter)
|
15
|
+
@path, section, @options = value_from_getter(getter)
|
16
16
|
|
17
17
|
if section.is_a?(String)
|
18
18
|
# Render this as a section
|
@@ -2,11 +2,20 @@ require 'volt/models'
|
|
2
2
|
|
3
3
|
class TestModel < Model
|
4
4
|
validate :_name, length: 4
|
5
|
+
validate :_description, length: {message: 'needs to be longer', length: 50}
|
6
|
+
validate :_username, presence: true
|
5
7
|
end
|
6
8
|
|
9
|
+
|
7
10
|
describe Model do
|
8
11
|
it "should validate the name" do
|
9
|
-
expect(TestModel.new.errors).to eq(
|
12
|
+
expect(TestModel.new.errors).to eq(
|
13
|
+
{
|
14
|
+
:_name => ["must be at least 4 characters"],
|
15
|
+
:_description => ["needs to be longer"],
|
16
|
+
:_username => ["must be specified"]
|
17
|
+
}
|
18
|
+
)
|
10
19
|
end
|
11
20
|
|
12
21
|
it "should show marked validations once they are marked" do
|
@@ -18,7 +27,7 @@ describe Model do
|
|
18
27
|
|
19
28
|
expect(model.marked_errors).to eq(
|
20
29
|
{
|
21
|
-
:_name => ["must be at least 4
|
30
|
+
:_name => ["must be at least 4 characters"]
|
22
31
|
}
|
23
32
|
)
|
24
33
|
end
|
@@ -30,10 +39,38 @@ describe Model do
|
|
30
39
|
|
31
40
|
model.save!
|
32
41
|
|
33
|
-
expect(model.marked_errors).to eq(
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
42
|
+
expect(model.marked_errors.keys).to eq([:_name, :_description, :_username])
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "length" do
|
46
|
+
it "should allow custom errors on length" do
|
47
|
+
model = TestModel.new
|
48
|
+
|
49
|
+
expect(model.marked_errors).to eq({})
|
50
|
+
|
51
|
+
model.mark_field!(:_description)
|
52
|
+
|
53
|
+
expect(model.marked_errors).to eq(
|
54
|
+
{
|
55
|
+
:_description => ["needs to be longer"]
|
56
|
+
}
|
57
|
+
)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "presence" do
|
62
|
+
it "should validate presence" do
|
63
|
+
model = TestModel.new
|
64
|
+
|
65
|
+
expect(model.marked_errors).to eq({})
|
66
|
+
|
67
|
+
model.mark_field!(:_username)
|
68
|
+
|
69
|
+
expect(model.marked_errors).to eq(
|
70
|
+
{
|
71
|
+
:_username => ["must be specified"]
|
72
|
+
}
|
73
|
+
)
|
74
|
+
end
|
38
75
|
end
|
39
76
|
end
|
@@ -1,19 +1,19 @@
|
|
1
1
|
<:Title>
|
2
|
-
{#template params._controller.or('
|
2
|
+
{#template params._controller.or('index') + '/' + params._action.or('home'), "title"}
|
3
3
|
|
4
4
|
<:Body>
|
5
5
|
<div class="container">
|
6
6
|
<div class="header">
|
7
7
|
<ul class="nav nav-pills pull-right">
|
8
|
-
<:nav
|
9
|
-
<:nav
|
8
|
+
<:nav action="" text="Home" />
|
9
|
+
<:nav action="about" text="About" />
|
10
10
|
</ul>
|
11
11
|
<h3 class="text-muted">Project name</h3>
|
12
12
|
</div>
|
13
13
|
|
14
14
|
<:volt:notices />
|
15
15
|
|
16
|
-
{#template params._controller.or('
|
16
|
+
{#template params._controller.or('index') + '/' + params._action.or('home')}
|
17
17
|
|
18
18
|
<div class="footer">
|
19
19
|
<p>© Company 2014</p>
|
@@ -23,7 +23,7 @@
|
|
23
23
|
|
24
24
|
|
25
25
|
<:Nav>
|
26
|
-
<li class="{#if params.
|
27
|
-
<a href="/{@
|
26
|
+
<li class="{#if params._action.or('') == @action}active{/}">
|
27
|
+
<a href="/{@action}">{@text}</a>
|
28
28
|
</li>
|
29
29
|
|
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.7.
|
4
|
+
version: 0.7.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Stout
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-03-
|
11
|
+
date: 2014-03-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -397,9 +397,9 @@ files:
|
|
397
397
|
- lib/volt/models/persistors/store_factory.rb
|
398
398
|
- lib/volt/models/persistors/store_state.rb
|
399
399
|
- lib/volt/models/url.rb
|
400
|
-
- lib/volt/models/validations
|
401
|
-
- lib/volt/models/
|
402
|
-
- lib/volt/models/
|
400
|
+
- lib/volt/models/validations.rb
|
401
|
+
- lib/volt/models/validators/length_validator.rb
|
402
|
+
- lib/volt/models/validators/presence_validator.rb
|
403
403
|
- lib/volt/page/bindings/attribute_binding.rb
|
404
404
|
- lib/volt/page/bindings/base_binding.rb
|
405
405
|
- lib/volt/page/bindings/component_binding.rb
|
File without changes
|
@@ -1,13 +0,0 @@
|
|
1
|
-
module Validations
|
2
|
-
class Length
|
3
|
-
def self.validate(model, field_name, args)
|
4
|
-
errors = {}
|
5
|
-
value = model.send(field_name)
|
6
|
-
if !value || value.size < args
|
7
|
-
errors[field_name] = ["must be at least #{args} chars"]
|
8
|
-
end
|
9
|
-
|
10
|
-
return errors
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|