volt 0.8.22 → 0.8.23
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/.gitignore +2 -0
- data/.rubocop.yml +4 -1
- data/.ruby-version +1 -1
- data/.travis.yml +1 -0
- data/CHANGELOG.md +7 -1
- data/Gemfile +2 -1
- data/Rakefile +6 -1
- data/VERSION +1 -1
- data/app/volt/models/user.rb +1 -4
- data/app/volt/tasks/live_query/data_store.rb +1 -1
- data/app/volt/tasks/live_query/live_query.rb +2 -4
- data/app/volt/tasks/live_query/query_tracker.rb +7 -9
- data/app/volt/tasks/store_tasks.rb +3 -4
- data/app/volt/tasks/user_tasks.rb +20 -21
- data/lib/volt/cli.rb +2 -2
- data/lib/volt/controllers/model_controller.rb +8 -0
- data/lib/volt/models/url.rb +10 -5
- data/lib/volt/models/validations.rb +3 -1
- data/lib/volt/models/validators/numericality_validator.rb +53 -0
- data/lib/volt/page/page.rb +2 -1
- data/lib/volt/server/component_templates.rb +2 -2
- data/lib/volt/server/html_parser/attribute_scope.rb +12 -7
- data/lib/volt/server/rack/asset_files.rb +14 -3
- data/lib/volt/server/rack/component_code.rb +3 -3
- data/lib/volt/server/rack/component_paths.rb +17 -12
- data/lib/volt/volt/users.rb +1 -3
- data/spec/apps/file_loading/app/missing_deps/config/dependencies.rb +1 -0
- data/spec/models/validations_spec.rb +19 -2
- data/spec/server/rack/asset_files_spec.rb +20 -1
- data/templates/project/app/main/config/dependencies.rb +1 -1
- data/templates/project/app/main/config/routes.rb +2 -2
- data/templates/project/app/main/controllers/main_controller.rb +2 -1
- data/templates/project/app/main/models/user.rb +2 -3
- data/volt.gemspec +1 -0
- metadata +19 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f81d53a357d5bc17689ca9a67aa8d0bcb9c390df
|
4
|
+
data.tar.gz: 449b98ecf2be170abd4cd584619674e1c96927fb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7b582e21873ed85930b44e66d327fd036a447a6a3d2b49a8d2f5869d865b3bc1b38d9f7f97265d0cf694af5aa2d76a037aabf4165b0d6d9ec30213a04f138cf3
|
7
|
+
data.tar.gz: c318c757c0ab8de3b72e6e1d6e41b6515c978c8c91c3b3378ed779537d6081563cf1c4f7a55fb97338e25335feea69c651623ce2119302e014c4c27bb19a4fd8
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.1.
|
1
|
+
2.1.5
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,11 +1,17 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
-
## 0.8.
|
3
|
+
## 0.8.33 - 2014-11-30
|
4
|
+
### Added
|
5
|
+
- Added url_for and url_with to controllers. (See docs under Controllers)
|
6
|
+
|
7
|
+
## 0.8.22 - 2014-11-16
|
4
8
|
### Added
|
5
9
|
- Volt.config is now accessable from the client.
|
6
10
|
- Added ```.try``` to Object
|
7
11
|
- Added Volt.login
|
8
12
|
- successful asset loads are not logged in development
|
13
|
+
- Basics of users is now place, along with including the default user templates gem
|
14
|
+
- more user related helpers in the works
|
9
15
|
|
10
16
|
## 0.8.21 - 2014-11-05
|
11
17
|
### Changed
|
data/Gemfile
CHANGED
@@ -6,6 +6,7 @@ group :development do
|
|
6
6
|
# For testing the kitchen sink app
|
7
7
|
# Twitter bootstrap
|
8
8
|
gem 'volt-bootstrap'
|
9
|
+
gem 'byebug'
|
9
10
|
|
10
11
|
# Simple theme for bootstrap, remove to theme yourself.
|
11
12
|
gem 'volt-bootstrap-jumbotron-theme'
|
@@ -22,4 +23,4 @@ end
|
|
22
23
|
|
23
24
|
group :development, :test do
|
24
25
|
gem 'bson_ext'
|
25
|
-
end
|
26
|
+
end
|
data/Rakefile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
require 'rubygems'
|
2
1
|
require 'bundler'
|
3
2
|
require 'bundler/gem_tasks'
|
3
|
+
require 'rubocop/rake_task'
|
4
4
|
Bundler.require(:development)
|
5
5
|
|
6
6
|
require 'opal'
|
@@ -31,3 +31,8 @@ task :test do
|
|
31
31
|
puts "--------------------------\nRun specs in Opal\n--------------------------"
|
32
32
|
Rake::Task['opal:rspec'].invoke
|
33
33
|
end
|
34
|
+
|
35
|
+
# Rubocop task
|
36
|
+
RuboCop::RakeTask.new(:rubocop) do |task|
|
37
|
+
task.options = ['--display-cop-names']
|
38
|
+
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.8.
|
1
|
+
0.8.23
|
data/app/volt/models/user.rb
CHANGED
@@ -66,10 +66,8 @@ class LiveQuery
|
|
66
66
|
def remove_channel(channel)
|
67
67
|
@channels.delete(channel)
|
68
68
|
|
69
|
-
|
70
|
-
|
71
|
-
@pool.remove(@collection, @query)
|
72
|
-
end
|
69
|
+
# remove this query, no one is listening anymore
|
70
|
+
@pool.remove(@collection, @query) if @channels.empty?
|
73
71
|
end
|
74
72
|
|
75
73
|
def notify!(skip_channel = nil, only_channel = nil)
|
@@ -2,6 +2,7 @@
|
|
2
2
|
# that take place.
|
3
3
|
class QueryTracker
|
4
4
|
attr_accessor :results
|
5
|
+
|
5
6
|
def initialize(live_query, data_store)
|
6
7
|
@live_query = live_query
|
7
8
|
@data_store = data_store
|
@@ -31,13 +32,11 @@ class QueryTracker
|
|
31
32
|
# Looks at the changes in the last run and sends out notices
|
32
33
|
# all changes.
|
33
34
|
def process_changes(skip_channel)
|
34
|
-
|
35
|
-
detect_removed(skip_channel)
|
36
|
-
|
37
|
-
detect_added_and_moved(skip_channel)
|
35
|
+
return unless @previous_ids
|
38
36
|
|
39
|
-
|
40
|
-
|
37
|
+
detect_removed(skip_channel)
|
38
|
+
detect_added_and_moved(skip_channel)
|
39
|
+
detect_changed(skip_channel)
|
41
40
|
end
|
42
41
|
|
43
42
|
def detect_removed(skip_channel)
|
@@ -48,7 +47,7 @@ class QueryTracker
|
|
48
47
|
end
|
49
48
|
|
50
49
|
# Update @previous_ids to relect the removed
|
51
|
-
@previous_ids
|
50
|
+
@previous_ids &= @current_ids
|
52
51
|
end
|
53
52
|
|
54
53
|
# Loop through the new list, tracking in the old, notifies of any that
|
@@ -67,9 +66,8 @@ class QueryTracker
|
|
67
66
|
if @previous_ids.include?(id)
|
68
67
|
# The location from the previous has changed, move to correct location.
|
69
68
|
|
70
|
-
# Remove from previous_ids,
|
69
|
+
# Remove from previous_ids, as it will be moved and we will be past it.
|
71
70
|
@previous_ids.delete(id)
|
72
|
-
|
73
71
|
@live_query.notify_moved(id, index, skip_channel)
|
74
72
|
else
|
75
73
|
# TODO: Faster lookup
|
@@ -18,19 +18,18 @@ class StoreTasks < Volt::TaskHandler
|
|
18
18
|
collection = store.send(:"_#{path[-2]}")
|
19
19
|
|
20
20
|
# See if the model has already been made
|
21
|
-
model = collection.find_one(
|
21
|
+
model = collection.find_one(_id: data[:_id])
|
22
22
|
|
23
23
|
# Otherwise assign to the collection
|
24
24
|
model ||= collection
|
25
25
|
|
26
|
-
|
27
26
|
# Create a buffer
|
28
27
|
buffer = model.buffer
|
29
28
|
|
30
29
|
# Assign the data
|
31
30
|
buffer.attributes = data
|
32
31
|
|
33
|
-
|
32
|
+
buffer
|
34
33
|
end
|
35
34
|
|
36
35
|
def save(collection, path, data)
|
@@ -52,7 +51,7 @@ class StoreTasks < Volt::TaskHandler
|
|
52
51
|
|
53
52
|
Thread.current['in_channel'] = nil
|
54
53
|
|
55
|
-
|
54
|
+
promise
|
56
55
|
end
|
57
56
|
|
58
57
|
def delete(collection, id)
|
@@ -1,31 +1,30 @@
|
|
1
1
|
class UserTasks < Volt::TaskHandler
|
2
|
-
|
3
|
-
#
|
4
|
-
# based on Volt.config.public.auth.use_username
|
2
|
+
# Login a user, takes a login and password. Login can be either a username
|
3
|
+
# or an e-mail based on Volt.config.public.auth.use_username
|
5
4
|
def login(login, password)
|
6
|
-
query = {User.login_field => login}
|
5
|
+
query = { User.login_field => login }
|
7
6
|
|
8
|
-
|
7
|
+
store._users.find(query).then do |users|
|
9
8
|
user = users.first
|
9
|
+
fail 'User could not be found' unless user
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
raise "app_secret is not configured" unless Volt.config.app_secret
|
15
|
-
|
16
|
-
# TODO: returning here should be possible, but causes some issues
|
11
|
+
match_pass = BCrypt::Password.new(user._hashed_password)
|
12
|
+
fail 'Password did not match' unless match_pass == password
|
13
|
+
fail 'app_secret is not configured' unless Volt.config.app_secret
|
17
14
|
|
18
|
-
|
19
|
-
|
15
|
+
# TODO: returning here should be possible, but causes some issues
|
16
|
+
# Salt the user id with the app_secret so the end user can't
|
17
|
+
# tamper with the cookie
|
18
|
+
signature = BCrypt::Password.create(salty_password(user._id))
|
20
19
|
|
21
|
-
|
22
|
-
|
23
|
-
else
|
24
|
-
raise "Password did not match"
|
25
|
-
end
|
26
|
-
else
|
27
|
-
raise "User could not be found"
|
28
|
-
end
|
20
|
+
# Return user_id:hash on user id
|
21
|
+
next "#{user._id}:#{signature}"
|
29
22
|
end
|
30
23
|
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def salty_password(user_id)
|
28
|
+
"#{Volt.config.app_secret}::#{user_id}"
|
29
|
+
end
|
31
30
|
end
|
data/lib/volt/cli.rb
CHANGED
@@ -59,8 +59,8 @@ module Volt
|
|
59
59
|
Thread.stop
|
60
60
|
else
|
61
61
|
ENV['SERVER'] = 'true'
|
62
|
-
args
|
63
|
-
|
62
|
+
args = ['start', '--threaded', '--max-persistent-conns', '300']
|
63
|
+
args += ['--max-conns', '400'] unless Gem.win_platform?
|
64
64
|
if options[:port]
|
65
65
|
args += ['-p', options[:port].to_s]
|
66
66
|
end
|
@@ -108,6 +108,14 @@ module Volt
|
|
108
108
|
@controller ||= Model.new
|
109
109
|
end
|
110
110
|
|
111
|
+
def url_for(params)
|
112
|
+
$page.url.url_for(params)
|
113
|
+
end
|
114
|
+
|
115
|
+
def url_with(params)
|
116
|
+
$page.url.url_with(params)
|
117
|
+
end
|
118
|
+
|
111
119
|
def loaded?
|
112
120
|
respond_to?(:state) && state == :loaded
|
113
121
|
end
|
data/lib/volt/models/url.rb
CHANGED
@@ -57,12 +57,13 @@ module Volt
|
|
57
57
|
true
|
58
58
|
end
|
59
59
|
|
60
|
-
# Full url rebuilds the url from it's constituent parts
|
61
|
-
|
60
|
+
# Full url rebuilds the url from it's constituent parts.
|
61
|
+
# The params passed in are used to generate the urls.
|
62
|
+
def url_for(params)
|
62
63
|
host_with_port = host
|
63
64
|
host_with_port += ":#{port}" if port && port != 80
|
64
65
|
|
65
|
-
|
66
|
+
path, params = @router.params_to_url(params)
|
66
67
|
|
67
68
|
new_url = "#{scheme}://#{host_with_port}#{path.chomp('/')}"
|
68
69
|
|
@@ -77,7 +78,7 @@ module Volt
|
|
77
78
|
end
|
78
79
|
|
79
80
|
if query_parts.size > 0
|
80
|
-
|
81
|
+
query = query_parts.join('&')
|
81
82
|
new_url += '?' + query
|
82
83
|
end
|
83
84
|
end
|
@@ -89,12 +90,16 @@ module Volt
|
|
89
90
|
new_url
|
90
91
|
end
|
91
92
|
|
93
|
+
def url_with(params)
|
94
|
+
url_for(@params.to_h.merge(params))
|
95
|
+
end
|
96
|
+
|
92
97
|
# Called when the state has changed and the url in the
|
93
98
|
# browser should be updated
|
94
99
|
# Called when an attribute changes to update the url
|
95
100
|
def update!
|
96
101
|
if Volt.client?
|
97
|
-
new_url =
|
102
|
+
new_url = url_for(@params.to_h)
|
98
103
|
|
99
104
|
# Push the new url if pushState is supported
|
100
105
|
# TODO: add fragment fallback
|
@@ -2,6 +2,7 @@
|
|
2
2
|
require 'volt/models/validators/length_validator'
|
3
3
|
require 'volt/models/validators/presence_validator'
|
4
4
|
require 'volt/models/validators/unique_validator'
|
5
|
+
require 'volt/models/validators/numericality_validator'
|
5
6
|
|
6
7
|
module Volt
|
7
8
|
# Include in any class to get validation logic
|
@@ -140,7 +141,8 @@ module Volt
|
|
140
141
|
custom_validations.each do |custom_validation|
|
141
142
|
# Run the validator in the context of the model, passes in
|
142
143
|
# the old_model as an argument
|
143
|
-
result =
|
144
|
+
result = instance_exec(old_model, &custom_validation)
|
145
|
+
|
144
146
|
if result
|
145
147
|
errors = merge.call(result)
|
146
148
|
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Volt
|
2
|
+
class NumericalityValidator
|
3
|
+
def self.validate(model, old_model, field_name, args)
|
4
|
+
# Construct the class and return the errors
|
5
|
+
self.new(model, field_name, args).errors
|
6
|
+
end
|
7
|
+
|
8
|
+
attr_reader :errors
|
9
|
+
|
10
|
+
def initialize(model, field_name, args)
|
11
|
+
@field_name = field_name
|
12
|
+
@args = args
|
13
|
+
@errors = {}
|
14
|
+
|
15
|
+
@value = model.read_attribute(field_name)
|
16
|
+
|
17
|
+
# Convert to float if it is a string for a float
|
18
|
+
@value = Kernel.Float(@value) rescue nil
|
19
|
+
|
20
|
+
check_errors
|
21
|
+
end
|
22
|
+
|
23
|
+
def add_error(error)
|
24
|
+
field_errors = (@errors[@field_name] ||= [])
|
25
|
+
field_errors << error
|
26
|
+
end
|
27
|
+
|
28
|
+
# Looks at the value
|
29
|
+
def check_errors
|
30
|
+
if @value && @value.is_a?(Numeric)
|
31
|
+
if @args.is_a?(Hash)
|
32
|
+
|
33
|
+
@args.each do |arg, val|
|
34
|
+
case arg
|
35
|
+
when :min
|
36
|
+
if @value < val
|
37
|
+
add_error("number must be greater than #{val}")
|
38
|
+
end
|
39
|
+
when :max
|
40
|
+
if @value > val
|
41
|
+
add_error("number must be less than #{val}")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
else
|
48
|
+
message = (@args.is_a?(Hash) && @args[:message]) || 'must be a number'
|
49
|
+
add_error(message)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/volt/page/page.rb
CHANGED
@@ -13,10 +13,10 @@ module Volt
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def code
|
16
|
-
code = generate_view_code
|
16
|
+
code = generate_routes_code + generate_view_code
|
17
17
|
if @client
|
18
18
|
# On the backend, we just need the views
|
19
|
-
code << generate_controller_code + generate_model_code +
|
19
|
+
code << generate_controller_code + generate_model_code + generate_tasks_code
|
20
20
|
end
|
21
21
|
|
22
22
|
code
|
@@ -64,16 +64,21 @@ module Volt
|
|
64
64
|
|
65
65
|
# TODO: We should use a real parser for this
|
66
66
|
def getter_to_setter(getter)
|
67
|
-
getter = getter.strip
|
67
|
+
getter = getter.strip.gsub(/\(\s*\)/, '')
|
68
68
|
|
69
|
-
#
|
70
|
-
if getter
|
71
|
-
|
69
|
+
# Check to see if this can be converted to a setter
|
70
|
+
if getter[0] =~ /^[a-z_]/ && getter[-1] != ')'
|
71
|
+
# Convert a getter into a setter
|
72
|
+
if getter.index('.') || getter.index('@')
|
73
|
+
prefix = ''
|
74
|
+
else
|
75
|
+
prefix = 'self.'
|
76
|
+
end
|
77
|
+
|
78
|
+
"#{prefix}#{getter}=(val)"
|
72
79
|
else
|
73
|
-
|
80
|
+
"raise \"could not auto generate setter for `#{getter}`\""
|
74
81
|
end
|
75
|
-
|
76
|
-
"#{prefix}#{getter}=(val)"
|
77
82
|
end
|
78
83
|
|
79
84
|
# Add an attribute binding on the tag, bind directly to the getter in the binding
|
@@ -22,7 +22,7 @@ module Volt
|
|
22
22
|
if File.exist?(dependencies_file)
|
23
23
|
# Run the dependencies file in this asset files context
|
24
24
|
code = File.read(dependencies_file)
|
25
|
-
instance_eval(code)
|
25
|
+
instance_eval(code, dependencies_file, 0)
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
@@ -32,7 +32,13 @@ module Volt
|
|
32
32
|
@included_components[name] = true
|
33
33
|
|
34
34
|
# Get the path to the component
|
35
|
-
@component_paths.component_paths(name)
|
35
|
+
component_path = @component_paths.component_paths(name)
|
36
|
+
|
37
|
+
unless component_path
|
38
|
+
raise "Unable to find component '#{name}', make sure the gem is included in your Gemfile"
|
39
|
+
end
|
40
|
+
|
41
|
+
component_path.each do |path|
|
36
42
|
|
37
43
|
# Load the dependencies
|
38
44
|
load_dependencies(path)
|
@@ -96,7 +102,12 @@ module Volt
|
|
96
102
|
@assets.each do |type, path|
|
97
103
|
case type
|
98
104
|
when :folder
|
99
|
-
|
105
|
+
# Don't import any css/scss files that start with an underscore, so scss partials
|
106
|
+
# aren't imported by default:
|
107
|
+
# http://sass-lang.com/guide
|
108
|
+
css_files += Dir["#{path}/**/[^_]*.{css,scss}"].sort.map do |folder|
|
109
|
+
'/assets' + folder[path.size..-1].gsub(/[.]scss$/, '')
|
110
|
+
end
|
100
111
|
when :css_file
|
101
112
|
css_files << path
|
102
113
|
end
|
@@ -13,13 +13,13 @@ module Volt
|
|
13
13
|
end
|
14
14
|
|
15
15
|
# The client argument is for if this code is being generated for the client
|
16
|
-
def code
|
16
|
+
def code
|
17
17
|
# Start with config code
|
18
|
-
code = generate_config_code
|
18
|
+
code = @client ? generate_config_code : ''
|
19
19
|
|
20
20
|
asset_files = AssetFiles.new(@component_name, @component_paths)
|
21
21
|
asset_files.component_paths.each do |component_path, component_name|
|
22
|
-
code << ComponentTemplates.new(component_path, component_name, client).code
|
22
|
+
code << ComponentTemplates.new(component_path, component_name, @client).code
|
23
23
|
code << "\n\n"
|
24
24
|
end
|
25
25
|
|
@@ -77,18 +77,23 @@ module Volt
|
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
#
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
80
|
+
load_views_and_routes
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def load_views_and_routes
|
85
|
+
component_names = []
|
86
|
+
app_folders do |app_folder|
|
87
|
+
Dir["#{app_folder}/*"].map {|cp| cp[/[^\/]+$/] }.each do |component_name|
|
88
|
+
component_names << component_name
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Load in all views and routes
|
93
|
+
# TODO: Nested components listed twice are are loaded multiple times
|
94
|
+
component_names.uniq.each do |component_name|
|
95
|
+
code = Volt::ComponentCode.new(component_name, self, false).code
|
96
|
+
eval(code)
|
92
97
|
end
|
93
98
|
end
|
94
99
|
|
data/lib/volt/volt/users.rb
CHANGED
@@ -14,7 +14,7 @@ module Volt
|
|
14
14
|
hash = user_id_signature[(index+1)..-1]
|
15
15
|
|
16
16
|
# Make sure the user hash matches
|
17
|
-
if BCrypt::Password.new(hash) != "#{Volt.config.app_secret}::#{
|
17
|
+
if BCrypt::Password.new(hash) != "#{Volt.config.app_secret}::#{user_id}"
|
18
18
|
# user id has been tampered with, reject
|
19
19
|
raise "user id or hash has been tampered with"
|
20
20
|
end
|
@@ -57,8 +57,6 @@ module Volt
|
|
57
57
|
end
|
58
58
|
|
59
59
|
|
60
|
-
private
|
61
|
-
|
62
60
|
# Fetches the user_id+signature from the correct spot depending on client
|
63
61
|
# or server, does not verify it.
|
64
62
|
def user_id_signature
|
@@ -0,0 +1 @@
|
|
1
|
+
component 'a-gem-that-isnt-in-the-gemfile'
|
@@ -4,6 +4,7 @@ class TestModel < Volt::Model
|
|
4
4
|
validate :name, length: 4
|
5
5
|
validate :description, length: { message: 'needs to be longer', length: 50 }
|
6
6
|
validate :username, presence: true
|
7
|
+
validate :count, numericality: { min: 5, max: 10 }
|
7
8
|
end
|
8
9
|
|
9
10
|
describe Volt::Model do
|
@@ -11,7 +12,8 @@ describe Volt::Model do
|
|
11
12
|
expect(TestModel.new.errors).to eq(
|
12
13
|
name: ['must be at least 4 characters'],
|
13
14
|
description: ['needs to be longer'],
|
14
|
-
username: ['must be specified']
|
15
|
+
username: ['must be specified'],
|
16
|
+
count: ['must be a number']
|
15
17
|
)
|
16
18
|
end
|
17
19
|
|
@@ -34,7 +36,7 @@ describe Volt::Model do
|
|
34
36
|
|
35
37
|
model.save!
|
36
38
|
|
37
|
-
expect(model.marked_errors.keys).to eq([:name, :description, :username])
|
39
|
+
expect(model.marked_errors.keys).to eq([:name, :description, :username, :count])
|
38
40
|
end
|
39
41
|
|
40
42
|
describe 'length' do
|
@@ -64,4 +66,19 @@ describe Volt::Model do
|
|
64
66
|
)
|
65
67
|
end
|
66
68
|
end
|
69
|
+
|
70
|
+
describe 'numericality' do
|
71
|
+
it 'should validate numericality' do
|
72
|
+
model = TestModel.new
|
73
|
+
|
74
|
+
expect(model.marked_errors).to eq({})
|
75
|
+
|
76
|
+
model.mark_field!(:count)
|
77
|
+
|
78
|
+
expect(model.marked_errors).to eq(
|
79
|
+
count: ['must be a number']
|
80
|
+
)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
67
84
|
end
|
@@ -6,7 +6,6 @@ if RUBY_PLATFORM != 'opal'
|
|
6
6
|
before do
|
7
7
|
spec_app_root = File.join(File.dirname(__FILE__), '../../apps/file_loading')
|
8
8
|
|
9
|
-
path_to_main = File.join(File.dirname(__FILE__), '../../apps/file_loading/app/main')
|
10
9
|
@component_paths = Volt::ComponentPaths.new(spec_app_root)
|
11
10
|
end
|
12
11
|
|
@@ -22,5 +21,25 @@ if RUBY_PLATFORM != 'opal'
|
|
22
21
|
|
23
22
|
expect(main.javascript_files(nil)).to eq(["/assets/js/jquery-2.0.3.js", "/assets/js/sockjs-0.3.4.min.js", "/assets/js/volt_js_polyfills.js", "/assets/js/bootstrap.js", "/assets/js/test2.js", "/assets/js/test3.js", "/assets/js/test1.js", "/assets/volt/page/page.js", "/components/main.js"])
|
24
23
|
end
|
24
|
+
|
25
|
+
it 'should raise an exception for a missing component gem' do
|
26
|
+
main = Volt::AssetFiles.new('main', @component_paths)
|
27
|
+
|
28
|
+
relative_dep_path = '../../apps/file_loading/app/missing_deps'
|
29
|
+
path_to_missing_deps = File.join(File.dirname(__FILE__), relative_dep_path)
|
30
|
+
expect do
|
31
|
+
main.load_dependencies(path_to_missing_deps)
|
32
|
+
end.to raise_error("Unable to find component 'a-gem-that-isnt-in-the-gemfile', make sure the gem is included in your Gemfile")
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should not raise an exception for a dependency file with valid components' do
|
36
|
+
main = Volt::AssetFiles.new('main', @component_paths)
|
37
|
+
|
38
|
+
path_to_main = File.join(File.dirname(__FILE__), '../../apps/file_loading/app/main')
|
39
|
+
path_to_missing_deps = File.join(File.dirname(__FILE__), path_to_main)
|
40
|
+
expect do
|
41
|
+
main.load_dependencies(path_to_missing_deps)
|
42
|
+
end.to_not raise_error
|
43
|
+
end
|
25
44
|
end
|
26
45
|
end
|
@@ -6,6 +6,6 @@ get '/about', _action: 'about'
|
|
6
6
|
get '/signup', _controller: 'user-templates', _action: 'signup'
|
7
7
|
get '/login', _controller: 'user-templates', _action: 'login'
|
8
8
|
|
9
|
-
|
10
|
-
#
|
9
|
+
# The main route, this should be last. It will match any params not
|
10
|
+
# previously matched.
|
11
11
|
get '/', {}
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# By default Volt generates this controller for your Main component
|
1
2
|
class MainController < Volt::ModelController
|
2
3
|
def index
|
3
4
|
# Add code for when the index view is loaded
|
@@ -9,7 +10,7 @@ class MainController < Volt::ModelController
|
|
9
10
|
|
10
11
|
private
|
11
12
|
|
12
|
-
#
|
13
|
+
# The main template contains a #template binding that shows another
|
13
14
|
# template. This is the path to that template. It may change based
|
14
15
|
# on the params._controller and params._action values.
|
15
16
|
def main_path
|
data/volt.gemspec
CHANGED
@@ -50,6 +50,7 @@ Gem::Specification.new do |spec|
|
|
50
50
|
spec.add_development_dependency 'yard', '~> 0.8.7.0'
|
51
51
|
spec.add_development_dependency 'sauce', '~> 3.5.3'
|
52
52
|
spec.add_development_dependency 'sauce-connect', '~> 3.5.0'
|
53
|
+
spec.add_development_dependency 'byebug', '~> 3.5.1'
|
53
54
|
|
54
55
|
|
55
56
|
end
|
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.8.
|
4
|
+
version: 0.8.23
|
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-11-
|
11
|
+
date: 2014-11-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -402,6 +402,20 @@ dependencies:
|
|
402
402
|
- - "~>"
|
403
403
|
- !ruby/object:Gem::Version
|
404
404
|
version: 3.5.0
|
405
|
+
- !ruby/object:Gem::Dependency
|
406
|
+
name: byebug
|
407
|
+
requirement: !ruby/object:Gem::Requirement
|
408
|
+
requirements:
|
409
|
+
- - "~>"
|
410
|
+
- !ruby/object:Gem::Version
|
411
|
+
version: 3.5.1
|
412
|
+
type: :development
|
413
|
+
prerelease: false
|
414
|
+
version_requirements: !ruby/object:Gem::Requirement
|
415
|
+
requirements:
|
416
|
+
- - "~>"
|
417
|
+
- !ruby/object:Gem::Version
|
418
|
+
version: 3.5.1
|
405
419
|
description:
|
406
420
|
email:
|
407
421
|
- ryan@agileproductions.com
|
@@ -496,6 +510,7 @@ files:
|
|
496
510
|
- lib/volt/models/url.rb
|
497
511
|
- lib/volt/models/validations.rb
|
498
512
|
- lib/volt/models/validators/length_validator.rb
|
513
|
+
- lib/volt/models/validators/numericality_validator.rb
|
499
514
|
- lib/volt/models/validators/presence_validator.rb
|
500
515
|
- lib/volt/models/validators/unique_validator.rb
|
501
516
|
- lib/volt/page/bindings/attribute_binding.rb
|
@@ -572,6 +587,7 @@ files:
|
|
572
587
|
- spec/apps/file_loading/app/bootstrap/assets/js/bootstrap.js
|
573
588
|
- spec/apps/file_loading/app/main/assets/js/test1.js
|
574
589
|
- spec/apps/file_loading/app/main/config/dependencies.rb
|
590
|
+
- spec/apps/file_loading/app/missing_deps/config/dependencies.rb
|
575
591
|
- spec/apps/file_loading/app/shared/assets/js/test2.js
|
576
592
|
- spec/apps/file_loading/app/shared/config/dependencies.rb
|
577
593
|
- spec/apps/file_loading/app/slideshow/assets/js/test3.js
|
@@ -717,6 +733,7 @@ test_files:
|
|
717
733
|
- spec/apps/file_loading/app/bootstrap/assets/js/bootstrap.js
|
718
734
|
- spec/apps/file_loading/app/main/assets/js/test1.js
|
719
735
|
- spec/apps/file_loading/app/main/config/dependencies.rb
|
736
|
+
- spec/apps/file_loading/app/missing_deps/config/dependencies.rb
|
720
737
|
- spec/apps/file_loading/app/shared/assets/js/test2.js
|
721
738
|
- spec/apps/file_loading/app/shared/config/dependencies.rb
|
722
739
|
- spec/apps/file_loading/app/slideshow/assets/js/test3.js
|