volt 0.8.22 → 0.8.23
Sign up to get free protection for your applications and to get access to all the features.
- 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
|