volt 0.9.0.pre3 → 0.9.0.pre4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -7
- data/VERSION +1 -1
- data/app/volt/tasks/user_tasks.rb +7 -2
- data/lib/volt.rb +1 -0
- data/lib/volt/cli/generate.rb +28 -10
- data/lib/volt/controllers/http_controller.rb +1 -1
- data/lib/volt/extra_core/logger.rb +14 -11
- data/lib/volt/models/persistors/query/query_listener.rb +7 -1
- data/lib/volt/page/bindings/component_binding.rb +2 -2
- data/lib/volt/page/bindings/{template_binding.rb → view_binding.rb} +3 -3
- data/lib/volt/page/bindings/{template_binding → view_binding}/grouped_controllers.rb +0 -0
- data/lib/volt/page/bindings/{template_binding → view_binding}/view_lookup_for_path.rb +0 -0
- data/lib/volt/page/page.rb +1 -1
- data/lib/volt/server/html_parser/view_scope.rb +4 -1
- data/lib/volt/server/rack/component_paths.rb +1 -1
- data/lib/volt/spec/setup.rb +10 -2
- data/lib/volt/tasks/dispatcher.rb +10 -3
- data/lib/volt/utils/logging/task_argument_filterer.rb +42 -0
- data/lib/volt/utils/logging/task_logger.rb +14 -0
- data/lib/volt/utils/volt_user_error.rb +4 -0
- data/lib/volt/volt/users.rb +2 -2
- data/spec/apps/kitchen_sink/app/main/config/routes.rb +1 -0
- data/spec/apps/kitchen_sink/app/main/controllers/server/simple_http_controller.rb +1 -1
- data/spec/apps/kitchen_sink/app/main/views/main/first_last.html +13 -0
- data/spec/apps/kitchen_sink/app/main/views/main/main.html +2 -2
- data/spec/controllers/http_controller_spec.rb +2 -2
- data/spec/integration/bindings_spec.rb +154 -156
- data/spec/integration/cookies_spec.rb +28 -30
- data/spec/integration/first_last_spec.rb +14 -0
- data/spec/integration/http_endpoints_spec.rb +22 -24
- data/spec/integration/templates_spec.rb +7 -9
- data/spec/integration/user_spec.rb +49 -52
- data/spec/integration/yield_spec.rb +12 -14
- data/spec/page/bindings/template_binding/view_lookup_for_path_spec.rb +2 -2
- data/spec/server/html_parser/view_parser_spec.rb +2 -2
- data/spec/server/rack/http_resource_spec.rb +2 -2
- data/spec/utils/task_argument_filtererer_spec.rb +17 -0
- data/templates/component/config/routes.rb +0 -5
- data/templates/component/controllers/server/.empty_directory +0 -0
- data/templates/component/lib/.empty_directory +0 -0
- data/templates/component_specs/controllers/server/.empty_directory +0 -0
- data/templates/component_specs/integration/.empty_directory +0 -0
- data/templates/component_specs/models/.empty_directory +0 -0
- data/templates/component_specs/tasks/.empty_directory +0 -0
- data/templates/controller/http_controller.rb.tt +1 -1
- data/templates/controller/http_controller_spec.rb.tt +5 -0
- data/templates/controller/model_controller.rb.tt +1 -1
- data/templates/controller/model_controller_spec.rb.tt +5 -0
- data/templates/model/model.rb.tt +1 -1
- data/templates/model/model_spec.rb.tt +5 -0
- data/templates/newgem/app/newgem/controllers/server/.empty_directory +0 -0
- data/templates/newgem/app/newgem/lib/.empty_directory +0 -0
- data/templates/newgem/lib/newgem.rb.tt +1 -1
- data/templates/project/app/main/views/main/main.html.tt +2 -2
- data/templates/project/config/app.rb.tt +5 -0
- data/templates/project/spec/app/main/controllers/server/sample_http_controller_spec.rb +5 -0
- data/templates/project/spec/app/main/tasks/sample_task_spec.rb +5 -0
- data/templates/task/task.rb.tt +0 -1
- data/templates/task/task_spec.rb.tt +5 -0
- data/templates/view/index.html.tt +5 -0
- metadata +29 -6
- data/templates/view/view.rb.tt +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e4d4f11c399ddcd63de7bc157707e0b1e5a91561
|
4
|
+
data.tar.gz: 773ade706e860021c11bf7d22c78e868fa51d139
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0542352171aa44247b3471c8e3ea3838e6d2127f896c56312b127936d523840c6d6e76c7ad16126e46844322004ef119bc1949696e83563b9754db8bc014cbf0
|
7
|
+
data.tar.gz: fcb365747674befac85bf8a8b08bf64addb800fb193500e822a8f4cb7cad4ea20ee51f67688d4aedcb47bc89b189867b9c18d39e65ac79c1f2a680ffb457845a
|
data/CHANGELOG.md
CHANGED
@@ -2,18 +2,15 @@
|
|
2
2
|
|
3
3
|
## 0.9.0.pre1
|
4
4
|
### Added
|
5
|
+
- the permissions api has been added!
|
5
6
|
- added has_many and belongs_to on models. See docs.
|
6
7
|
- you can now serve http/rest from Volt. Thanks to @jfahrer for his great work. Docs coming soon.
|
7
8
|
- there is now a generator for controllers and HttpControllers.
|
8
|
-
- the following were renamed to follow gem naming conventions:
|
9
|
-
- volt-user-templates (now volt-user_templates)
|
10
|
-
- volt-bootstrap-jumbotron-theme (now volt-bootstrap_jumbotron_theme)
|
11
9
|
- fixed generated component code
|
12
10
|
- added .order for sorting on the data store (since .sort is a ruby Enum method)
|
13
11
|
- calling .then on ArrayModels has been changed to calling .fetch and .fetch_first. These both return a promise, and take an optional block
|
14
12
|
- added .sync for synchronusly waiting on promises on the server only
|
15
13
|
- added the ability to pass content into tags: (https://github.com/voltrb/docs/blob/master/en/docs/yield_binding.md)
|
16
|
-
- the {action}_remove method had been changed to before_{action}_remove and after_{action}_remove to provide more hooks and a clearer understanding of when it is happening.
|
17
14
|
- Changed it so content bindings escape all html (for CSRF - thanks @ChaosData)
|
18
15
|
- Added formats, email, phone validators (thanks @lexun and @kxcrl)
|
19
16
|
- each_with_index is now supported in views and the ```index``` value is no longer provided by default.
|
@@ -24,24 +21,31 @@
|
|
24
21
|
- bindings will now resolve any values that are promises. (currently only content and attribute, if, each, and template coming soon)
|
25
22
|
- ```store``` is now available inside of specs. If it is accessed in a spec, the database will be cleaned after the spec.
|
26
23
|
- ```the_page``` is a shortcut to the page collection inside of specs. (Unfortunately, ```page``` is used by capybara, so for now we're using ```the_page```, we'll find a better solution in the future.)
|
24
|
+
- Add filtering to logging on password, and option to configure filtered args. Also, improve the way errors are displayed.
|
27
25
|
|
28
26
|
### Changed
|
27
|
+
- template bindings have been renamed to view. ```{{ view "path/for/view" }}``` instead of ```{{ template "path/for/view" }}```
|
28
|
+
- the {action}_remove method had been changed to before_{action}_remove and after_{action}_remove to provide more hooks and a clearer understanding of when it is happening.
|
29
|
+
- the following were renamed to follow gem naming conventions:
|
30
|
+
- volt-user-templates (now volt-user_templates)
|
31
|
+
- volt-bootstrap-jumbotron-theme (now volt-bootstrap_jumbotron_theme)
|
29
32
|
- all plural attributes now return an empty ArrayModel. This is to simplify implementation and to unify store's interface.
|
30
33
|
- main_path in generated projects now includes the a component param that can be used to easily point at controllers/views in other components.
|
31
34
|
- previously the main component's controllers were not namespaced. We changed it so all controllers (including those in main) are namespaced. This is makes things more consistent and keeps expectations when working with components.
|
32
35
|
- model attributes no longer return NilModels. Instead they just return nil. You can however add an ! to the end to "expand" the model to an empty model.
|
33
36
|
|
34
|
-
```page._new_todo # => now returns nil```
|
37
|
+
```page._new_todo # => now returns nil```
|
35
38
|
|
36
|
-
```page._new_todo! # => returns an empty model```
|
39
|
+
```page._new_todo! # => returns an empty model```
|
37
40
|
|
38
|
-
So if you wanted to use a property on ```_new_todo``` without initializing ```_new_todo```, you could add the ! to the lookup.
|
41
|
+
So if you wanted to use a property on ```_new_todo``` without initializing ```_new_todo```, you could add the ! to the lookup.
|
39
42
|
- Volt.user has been renamed to Volt.current_user so its clearer what it returns
|
40
43
|
- _'s are no longer required for route constraints (so just use ```controller: 'main', action: 'index'``` now)
|
41
44
|
- the underlying way queries are normalized and passed to the server has changed (no external api changes)
|
42
45
|
- changed .find to .where to not conflict with ruby Enum's .find
|
43
46
|
- Volt::TaskHandler is now Volt::Task
|
44
47
|
- Move testing gems to the generated Gemfile for projects
|
48
|
+
- ```if ENV['BROWSER']``` is no longer required around integration tests. We now use rspec filtering on ```type: :feature``` if you aren't running with ENV['BROWSER']
|
45
49
|
|
46
50
|
### Removed
|
47
51
|
- .false?, .true?, .or, and .and were removed since NilModels were removed. This means you get back a real nil value when accessing an undefined model attribute.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.9.0.
|
1
|
+
0.9.0.pre4
|
@@ -1,13 +1,18 @@
|
|
1
1
|
class UserTasks < Volt::Task
|
2
2
|
# Login a user, takes a login and password. Login can be either a username
|
3
3
|
# or an e-mail based on Volt.config.public.auth.use_username
|
4
|
-
|
4
|
+
#
|
5
|
+
# login_info is a key with login and password (login may be e-mail)
|
6
|
+
def login(login_info)
|
7
|
+
login = login_info['login']
|
8
|
+
password = login_info['password']
|
9
|
+
|
5
10
|
query = { User.login_field => login }
|
6
11
|
|
7
12
|
# During login we need access to the user's info even though we aren't the user
|
8
13
|
Volt.skip_permissions do
|
9
14
|
store._users.where(query).fetch_first do |user|
|
10
|
-
fail 'User could not be found' unless user
|
15
|
+
fail VoltUserError, 'User could not be found' unless user
|
11
16
|
|
12
17
|
match_pass = BCrypt::Password.new(user._hashed_password)
|
13
18
|
fail 'Password did not match' unless match_pass == password
|
data/lib/volt.rb
CHANGED
data/lib/volt/cli/generate.rb
CHANGED
@@ -6,7 +6,9 @@ class Generate < Thor
|
|
6
6
|
method_option :component, type: :string, default: 'main', banner: 'The component the model should be created in.', required: false
|
7
7
|
def model(name, component = 'main')
|
8
8
|
output_file = Dir.pwd + "/app/#{component.underscore}/models/#{name.underscore.singularize}.rb"
|
9
|
+
spec_file = Dir.pwd + "/spec/app/#{component.underscore}/models/#{name.underscore.pluralize}_spec.rb"
|
9
10
|
template('model/model.rb.tt', output_file, model_name: name.camelize.singularize)
|
11
|
+
template('model/model_spec.rb.tt', spec_file, model_name: name.camelize.singularize)
|
10
12
|
end
|
11
13
|
|
12
14
|
desc 'component NAME', 'Creates a component named NAME in the app folder.'
|
@@ -14,8 +16,10 @@ class Generate < Thor
|
|
14
16
|
def component(name)
|
15
17
|
name = name.underscore
|
16
18
|
component_folder = Dir.pwd + "/app/#{name}"
|
19
|
+
component_spec_folder = Dir.pwd + '/spec/app/' + name
|
17
20
|
@component_name = name
|
18
21
|
directory('component', component_folder, component_name: name)
|
22
|
+
directory('component_specs', component_spec_folder)
|
19
23
|
end
|
20
24
|
|
21
25
|
|
@@ -31,7 +35,7 @@ class Generate < Thor
|
|
31
35
|
require 'volt/cli/new_gem'
|
32
36
|
|
33
37
|
if name =~ /[-]/
|
34
|
-
Volt.logger.error("Gem names should use underscores for their names. Currently volt only supports a single namespace for a
|
38
|
+
Volt.logger.error("Gem names should use underscores for their names. Currently volt only supports a single namespace for a component.")
|
35
39
|
return
|
36
40
|
end
|
37
41
|
|
@@ -46,37 +50,51 @@ class Generate < Thor
|
|
46
50
|
method_option :name, type: :string, banner: 'The name of the HTTP Controller.'
|
47
51
|
method_option :component, type: :string, default: 'main', banner: 'The component the http_controller should be created in.', required: false
|
48
52
|
def http_controller(name, component = 'main')
|
49
|
-
|
50
|
-
|
53
|
+
name = name.underscore.pluralize + '_controller' unless name =~ /_controller$/
|
54
|
+
|
55
|
+
output_file = Dir.pwd + "/app/#{component}/controllers/server/#{name.underscore}.rb"
|
56
|
+
spec_file = Dir.pwd + "/spec/app/#{component.underscore}/controllers/server/#{name}_spec.rb"
|
57
|
+
|
58
|
+
template('controller/http_controller.rb.tt', output_file, component_module: component.camelize, http_controller_name: name.camelize)
|
59
|
+
template('controller/http_controller_spec.rb.tt', spec_file, component_module: component.camelize, http_controller_name: name.camelize)
|
51
60
|
end
|
52
61
|
|
53
62
|
desc 'controller NAME COMPONENT', 'Creates a model controller named NAME in the app folder of the component named COMPONENT.'
|
54
63
|
method_option :name, type: :string, banner: 'The name of the model controller.'
|
55
64
|
method_option :component, type: :string, default: 'main', banner: 'The component the controller should be created in.', required: false
|
56
65
|
def controller(name, component = 'main')
|
57
|
-
|
58
|
-
|
66
|
+
controller_name = name.underscore.singularize + '_controller' unless name =~ /_controller$/
|
67
|
+
output_file = Dir.pwd + "/app/#{component.underscore}/controllers/#{controller_name}.rb"
|
68
|
+
spec_file = Dir.pwd + "/spec/app/#{component.underscore}/integration/#{name.underscore.pluralize}_spec.rb"
|
69
|
+
|
70
|
+
template('controller/model_controller.rb.tt', output_file, component_module: component.camelize, model_controller_name: controller_name.camelize)
|
71
|
+
template('controller/model_controller_spec.rb.tt', spec_file, describe: name.underscore.pluralize )
|
59
72
|
end
|
60
73
|
|
61
74
|
desc 'task NAME COMPONENT', 'Creates a task named NAME in the app folder of the component named COMPONENT.'
|
62
75
|
method_option :name, type: :string, banner: 'The name of the task.'
|
63
76
|
method_option :component, type: :string, default: 'main', banner: 'The component the task should be created in.', required: false
|
64
77
|
def task(name, component = 'main')
|
65
|
-
|
78
|
+
name = name.underscore.singularize
|
79
|
+
output_file = Dir.pwd + "/app/#{component}/tasks/#{name}.rb"
|
80
|
+
spec_file = Dir.pwd + "/spec/app/#{component}/tasks/#{name}_spec.rb"
|
66
81
|
template('task/task.rb.tt', output_file, task_name: name.camelize.singularize)
|
82
|
+
template('task/task_spec.rb.tt', spec_file, task_name: name.camelize.singularize)
|
67
83
|
end
|
68
84
|
|
69
85
|
desc 'view NAME COMPONENT', 'Creates a view named NAME in the app folder of the component named COMPONENT.'
|
70
86
|
method_option :name, type: :string, banner: 'The name of the view.'
|
71
87
|
method_option :component, type: :string, default: 'main', banner: 'The component the view should be created in.', required: false
|
72
88
|
def view(name, component = 'main')
|
73
|
-
|
74
|
-
|
75
|
-
|
89
|
+
name = name.underscore.singularize
|
90
|
+
view_folder = Dir.pwd + "/app/#{component}/views/#{name}/"
|
91
|
+
directory('view', view_folder, view_name: name, component: component)
|
92
|
+
controller(name, component) unless controller_exists?(name, component)
|
76
93
|
end
|
77
94
|
|
78
95
|
private
|
79
|
-
|
96
|
+
|
97
|
+
def controller_exists?(name, component = 'main')
|
80
98
|
dir = Dir.pwd + "/app/#{component}/controllers/"
|
81
99
|
File.exists?(dir + name.downcase.underscore.singularize + '.rb')
|
82
100
|
end
|
@@ -12,7 +12,7 @@ module Volt
|
|
12
12
|
@response_headers = HttpResponseHeader.new
|
13
13
|
@response_body = []
|
14
14
|
@request = request
|
15
|
-
@params = params.symbolize_keys.merge(request.params)
|
15
|
+
@params = Volt::Model.new(params.symbolize_keys.merge(request.params))
|
16
16
|
end
|
17
17
|
|
18
18
|
def perform(action)
|
@@ -27,7 +27,7 @@ else
|
|
27
27
|
@formatter = Volt::VoltLoggerFormatter.new
|
28
28
|
end
|
29
29
|
|
30
|
-
def log_dispatch(class_name, method_name, run_time, args)
|
30
|
+
def log_dispatch(class_name, method_name, run_time, args, error)
|
31
31
|
@current = {
|
32
32
|
args: args,
|
33
33
|
class_name: class_name,
|
@@ -35,7 +35,19 @@ else
|
|
35
35
|
run_time: run_time
|
36
36
|
}
|
37
37
|
|
38
|
-
|
38
|
+
level = error ? Logger::ERROR : Logger::INFO
|
39
|
+
text = TaskLogger.task_dispatch_message(self, args)
|
40
|
+
|
41
|
+
|
42
|
+
if error
|
43
|
+
text += "\n" + colorize(error.to_s, :red)
|
44
|
+
if error.is_a?(Exception) && !error.is_a?(VoltUserError)
|
45
|
+
text += "\n" + colorize(error.backtrace.join("\n"), :red)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
log(level, text)
|
50
|
+
|
39
51
|
end
|
40
52
|
|
41
53
|
def args
|
@@ -75,15 +87,6 @@ else
|
|
75
87
|
string.to_s
|
76
88
|
end
|
77
89
|
end
|
78
|
-
|
79
|
-
def task_dispatch_message
|
80
|
-
msg = "task #{class_name}##{method_name} in #{run_time}\n"
|
81
|
-
if args.size > 0
|
82
|
-
arg_str = args.map {|v| v.inspect }.join(', ')
|
83
|
-
msg += "with args: #{arg_str}\n"
|
84
|
-
end
|
85
|
-
msg
|
86
|
-
end
|
87
90
|
end
|
88
91
|
|
89
92
|
class VoltLoggerFormatter < Logger::Formatter
|
@@ -42,7 +42,13 @@ module Volt
|
|
42
42
|
end.fail do |err|
|
43
43
|
# TODO: need to make it so we can re-raise out of this promise
|
44
44
|
Volt.logger.error("Error adding listener: #{err.inspect}")
|
45
|
-
Volt.logger.error(err.backtrace)
|
45
|
+
Volt.logger.error(err.backtrace) if err.respond_to?(:backtrace)
|
46
|
+
|
47
|
+
# If we get back that the user signature is wrong, log the user out.
|
48
|
+
if err.to_s.start_with?('user id or hash is incorrectly signed')
|
49
|
+
# Delete the invalid cookie
|
50
|
+
$page.cookies.delete(:user_id)
|
51
|
+
end
|
46
52
|
|
47
53
|
raise err
|
48
54
|
end
|
@@ -1,7 +1,7 @@
|
|
1
|
-
require 'volt/page/bindings/
|
1
|
+
require 'volt/page/bindings/view_binding'
|
2
2
|
|
3
3
|
# Component bindings are the same as template bindings, but handle components.
|
4
4
|
module Volt
|
5
|
-
class ComponentBinding <
|
5
|
+
class ComponentBinding < ViewBinding
|
6
6
|
end
|
7
7
|
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
require 'volt/page/bindings/base_binding'
|
2
2
|
require 'volt/page/template_renderer'
|
3
|
-
require 'volt/page/bindings/
|
4
|
-
require 'volt/page/bindings/
|
3
|
+
require 'volt/page/bindings/view_binding/grouped_controllers'
|
4
|
+
require 'volt/page/bindings/view_binding/view_lookup_for_path'
|
5
5
|
|
6
6
|
|
7
7
|
module Volt
|
8
|
-
class
|
8
|
+
class ViewBinding < BaseBinding
|
9
9
|
|
10
10
|
# @param [String] binding_in_path is the path this binding was rendered from. Used to
|
11
11
|
# lookup paths in ViewLookupForPath
|
File without changes
|
File without changes
|
data/lib/volt/page/page.rb
CHANGED
@@ -9,7 +9,7 @@ require 'volt/page/bindings/attribute_binding'
|
|
9
9
|
require 'volt/page/bindings/content_binding'
|
10
10
|
require 'volt/page/bindings/each_binding'
|
11
11
|
require 'volt/page/bindings/if_binding'
|
12
|
-
require 'volt/page/bindings/
|
12
|
+
require 'volt/page/bindings/view_binding'
|
13
13
|
require 'volt/page/bindings/yield_binding'
|
14
14
|
require 'volt/page/bindings/component_binding'
|
15
15
|
require 'volt/page/bindings/event_binding'
|
@@ -38,7 +38,10 @@ module Volt
|
|
38
38
|
else
|
39
39
|
fail "else does not take a conditional, #{content} was provided."
|
40
40
|
end
|
41
|
+
when 'view'
|
42
|
+
add_template(args)
|
41
43
|
when 'template'
|
44
|
+
Volt.logger.warn('Deprecation warning: The template binding has been renamed to view. Please update any views accordingly.')
|
42
45
|
add_template(args)
|
43
46
|
when 'yield'
|
44
47
|
add_yield(args)
|
@@ -91,7 +94,7 @@ module Volt
|
|
91
94
|
content = content.strip.gsub(/^\(/, '').gsub(/\)$/, '')
|
92
95
|
|
93
96
|
@handler.html << "<!-- $#{@binding_number} --><!-- $/#{@binding_number} -->"
|
94
|
-
save_binding(@binding_number, "lambda { |__p, __t, __c, __id| Volt::
|
97
|
+
save_binding(@binding_number, "lambda { |__p, __t, __c, __id| Volt::ViewBinding.new(__p, __t, __c, __id, #{@path.inspect}, Proc.new { [#{content}] }) }")
|
95
98
|
|
96
99
|
@binding_number += 1
|
97
100
|
end
|
@@ -62,7 +62,7 @@ module Volt
|
|
62
62
|
$LOAD_PATH.unshift(app_folder)
|
63
63
|
|
64
64
|
# Sort so we get consistent load order across platforms
|
65
|
-
Dir["#{app_folder}/*/{controllers,models,tasks}/*.rb"].each do |ruby_file|
|
65
|
+
Dir["#{app_folder}/*/{lib,controllers,models,tasks}/*.rb"].each do |ruby_file|
|
66
66
|
path = ruby_file.gsub(/^#{app_folder}\//, '')[0..-4]
|
67
67
|
require(path)
|
68
68
|
end
|
data/lib/volt/spec/setup.rb
CHANGED
@@ -12,11 +12,19 @@ module Volt
|
|
12
12
|
Volt.boot(app_path)
|
13
13
|
|
14
14
|
unless RUBY_PLATFORM == 'opal'
|
15
|
-
|
15
|
+
begin
|
16
|
+
require 'volt/spec/capybara'
|
16
17
|
|
17
|
-
|
18
|
+
setup_capybara(app_path)
|
19
|
+
rescue LoadError => e
|
20
|
+
Volt.logger.warn("unable to load capybara, if you wish to use it for tests, be sure it is in the app's Gemfile")
|
21
|
+
end
|
18
22
|
end
|
19
23
|
|
24
|
+
unless ENV['BROWSER']
|
25
|
+
# Not running integration tests with ENV['BROWSER']
|
26
|
+
RSpec.configuration.filter_run_excluding :type => :feature
|
27
|
+
end
|
20
28
|
|
21
29
|
# Setup the spec collection accessors
|
22
30
|
# RSpec.shared_context "volt collections", {} do
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# require 'ruby-prof'
|
2
|
+
require 'volt/utils/logging/task_logger'
|
2
3
|
|
3
4
|
module Volt
|
4
5
|
# The task dispatcher is responsible for taking incoming messages
|
@@ -47,14 +48,20 @@ module Volt
|
|
47
48
|
# Unsafe method
|
48
49
|
promise.reject(RuntimeError.new("unsafe method: #{method_name}"))
|
49
50
|
end
|
51
|
+
|
52
|
+
# Called after task runs or fails
|
53
|
+
finish = proc do |error|
|
54
|
+
run_time = ((Time.now.to_f - start_time) * 1000).round(3)
|
55
|
+
Volt.logger.log_dispatch(class_name, method_name, run_time, args, error)
|
56
|
+
end
|
57
|
+
|
50
58
|
# Run the promise and pass the return value/error back to the client
|
51
59
|
promise.then do |result|
|
52
60
|
channel.send_message('response', callback_id, result, nil)
|
53
61
|
|
54
|
-
|
55
|
-
Volt.logger.log_dispatch(class_name, method_name, run_time, args)
|
62
|
+
finish.call
|
56
63
|
end.fail do |error|
|
57
|
-
|
64
|
+
finish.call(error)
|
58
65
|
channel.send_message('response', callback_id, nil, error)
|
59
66
|
end
|
60
67
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# TaskArgumentFilterer will recursively walk any arguemnts to a task and filter any
|
2
|
+
# hashes with a filtered key. By default only :password is filtered, but you can add
|
3
|
+
# more with Volt.config.filter_keys
|
4
|
+
class TaskArgumentFilterer
|
5
|
+
def self.filter(args)
|
6
|
+
self.new(args).run
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(args)
|
10
|
+
# # Cache the filter args
|
11
|
+
@@filter_args ||= begin
|
12
|
+
# Load, with default, convert to symbols
|
13
|
+
arg_names = (Volt.config.filter_keys || [:password]).map(&:to_sym)
|
14
|
+
end
|
15
|
+
|
16
|
+
@args = args
|
17
|
+
end
|
18
|
+
|
19
|
+
def run
|
20
|
+
filter_args(@args)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def filter_args(args)
|
26
|
+
if args.is_a?(Array)
|
27
|
+
args.map {|v| filter_args(v) }
|
28
|
+
elsif args.is_a?(Hash)
|
29
|
+
args.map do |k,v|
|
30
|
+
if @@filter_args.include?(k.to_sym)
|
31
|
+
# filter
|
32
|
+
[k, '[FILTERED]']
|
33
|
+
else
|
34
|
+
# retunr unfiltered
|
35
|
+
[k, filter_args(v)]
|
36
|
+
end
|
37
|
+
end.to_h # <= convert back to hash
|
38
|
+
else
|
39
|
+
return args
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'volt/utils/logging/task_argument_filterer'
|
2
|
+
|
3
|
+
module Volt
|
4
|
+
class TaskLogger
|
5
|
+
def self.task_dispatch_message(logger, args)
|
6
|
+
msg = "task #{logger.class_name}##{logger.method_name} in #{logger.run_time}\n"
|
7
|
+
if args.size > 0
|
8
|
+
arg_str = TaskArgumentFilterer.filter(args).map {|v| v.inspect }.join(', ')
|
9
|
+
msg += "with args: #{arg_str}\n"
|
10
|
+
end
|
11
|
+
msg
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|