volt 0.8.27.beta2 → 0.8.27.beta3
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/.ruby-version +1 -1
- data/.travis.yml +3 -0
- data/CHANGELOG.md +7 -2
- data/CONTRIBUTING.md +133 -0
- data/Gemfile +0 -1
- data/Rakefile +11 -3
- data/Readme.md +4 -4
- data/VERSION +1 -1
- data/app/volt/models/user.rb +6 -3
- data/lib/volt/cli/console.rb +21 -12
- data/lib/volt/cli/runner.rb +1 -1
- data/lib/volt/cli.rb +5 -4
- data/lib/volt/config.rb +9 -11
- data/lib/volt/controllers/model_controller.rb +16 -0
- data/lib/volt/data_stores/data_store.rb +1 -1
- data/lib/volt/extra_core/array.rb +1 -6
- data/lib/volt/extra_core/blank.rb +1 -3
- data/lib/volt/extra_core/class.rb +1 -1
- data/lib/volt/extra_core/extra_core.rb +0 -1
- data/lib/volt/extra_core/logger.rb +78 -1
- data/lib/volt/extra_core/object.rb +4 -4
- data/lib/volt/models/array_model.rb +2 -3
- data/lib/volt/models/buffer.rb +1 -2
- data/lib/volt/models/field_helpers.rb +4 -5
- data/lib/volt/models/model.rb +27 -1
- data/lib/volt/models/model_hash_behaviour.rb +3 -4
- data/lib/volt/models/persistors/array_store.rb +6 -7
- data/lib/volt/models/persistors/cookies.rb +2 -2
- data/lib/volt/models/persistors/model_store.rb +5 -6
- data/lib/volt/models/validations.rb +5 -7
- data/lib/volt/models/validators/email_validator.rb +8 -29
- data/lib/volt/models/validators/format_validator.rb +116 -0
- data/lib/volt/models/validators/numericality_validator.rb +2 -2
- data/lib/volt/models/validators/phone_number_validator.rb +8 -29
- data/lib/volt/models/validators/unique_validator.rb +2 -2
- data/lib/volt/page/bindings/content_binding.rb +1 -1
- data/lib/volt/page/bindings/each_binding.rb +1 -1
- data/lib/volt/page/bindings/template_binding/view_lookup_for_path.rb +92 -0
- data/lib/volt/page/bindings/template_binding.rb +10 -85
- data/lib/volt/page/channel.rb +0 -1
- data/lib/volt/page/page.rb +5 -7
- data/lib/volt/page/sub_context.rb +1 -1
- data/lib/volt/page/targets/base_section.rb +2 -2
- data/lib/volt/page/targets/helpers/comment_searchers.rb +2 -2
- data/lib/volt/reactive/reactive_accessors.rb +1 -1
- data/lib/volt/reactive/reactive_array.rb +6 -6
- data/lib/volt/router/routes.rb +4 -4
- data/lib/volt/server/rack/asset_files.rb +1 -2
- data/lib/volt/server/rack/component_code.rb +0 -2
- data/lib/volt/server/rack/component_paths.rb +2 -2
- data/lib/volt/server/rack/quiet_common_logger.rb +2 -2
- data/lib/volt/spec/capybara.rb +1 -1
- data/lib/volt/spec/sauce_labs.rb +6 -6
- data/lib/volt/spec/setup.rb +8 -7
- data/lib/volt/tasks/dispatcher.rb +12 -10
- data/lib/volt/tasks/task_handler.rb +1 -1
- data/lib/volt/utils/generic_pool.rb +2 -2
- data/lib/volt/volt/users.rb +7 -9
- data/lib/volt.rb +2 -4
- data/spec/apps/file_loading/app/missing_deps/config/dependencies.rb +1 -1
- data/spec/apps/kitchen_sink/Gemfile +2 -2
- data/spec/apps/kitchen_sink/app/main/config/dependencies.rb +1 -1
- data/spec/apps/kitchen_sink/app/main/config/routes.rb +0 -1
- data/spec/apps/kitchen_sink/app/main/models/user.rb +1 -1
- data/spec/apps/kitchen_sink/app/main/views/main/main.html +1 -1
- data/spec/apps/kitchen_sink/config/app.rb +1 -1
- data/spec/extra_core/array_spec.rb +4 -2
- data/spec/extra_core/blank_spec.rb +11 -0
- data/spec/extra_core/class_spec.rb +2 -2
- data/spec/extra_core/logger_spec.rb +50 -0
- data/spec/extra_core/string_transformations_spec.rb +0 -1
- data/spec/integration/cookies_spec.rb +1 -2
- data/spec/integration/flash_spec.rb +2 -3
- data/spec/integration/list_spec.rb +1 -1
- data/spec/integration/templates_spec.rb +0 -1
- data/spec/integration/url_spec.rb +1 -2
- data/spec/integration/user_spec.rb +3 -3
- data/spec/models/field_helpers_spec.rb +2 -2
- data/spec/models/model_spec.rb +21 -2
- data/spec/models/user_spec.rb +69 -0
- data/spec/models/validations_spec.rb +69 -78
- data/spec/models/validators/email_validator_spec.rb +3 -3
- data/spec/models/validators/format_validator_spec.rb +144 -0
- data/spec/models/validators/length_validator_spec.rb +82 -0
- data/spec/models/validators/phone_number_validator_spec.rb +3 -3
- data/spec/page/bindings/template_binding/view_lookup_for_path_spec.rb +149 -0
- data/spec/page/bindings/template_binding_spec.rb +0 -151
- data/spec/reactive/computation_spec.rb +46 -0
- data/spec/reactive/dependency_spec.rb +0 -1
- data/spec/reactive/reactive_array_spec.rb +0 -1
- data/spec/router/routes_spec.rb +0 -4
- data/spec/server/html_parser/view_parser_spec.rb +0 -4
- data/spec/server/rack/asset_files_spec.rb +1 -1
- data/spec/server/rack/quite_common_logger_spec.rb +55 -0
- data/spec/spec_helper.rb +2 -5
- data/spec/tasks/dispatcher_spec.rb +16 -5
- data/spec/tasks/live_query_spec.rb +0 -1
- data/spec/tasks/query_tasks.rb +0 -1
- data/spec/tasks/query_tracker_spec.rb +0 -3
- data/spec/templates/targets/binding_document/component_node_spec.rb +0 -1
- data/spec/utils/generic_counting_pool_spec.rb +0 -1
- data/spec/utils/generic_pool_spec.rb +0 -1
- data/templates/component/assets/images/.empty_directory +0 -0
- data/templates/project/README.md.tt +3 -2
- data/templates/project/app/main/assets/images/.empty_directory +0 -0
- data/templates/project/config/base/index.html +6 -7
- data/volt.gemspec +3 -5
- metadata +27 -9
- data/lib/volt/extra_core/numeric.rb +0 -9
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Volt::LengthValidator do
|
|
4
|
+
subject { Volt::LengthValidator.validate(*params) }
|
|
5
|
+
let(:params) { [model, nil, field_name, options] }
|
|
6
|
+
|
|
7
|
+
let(:model) { Volt::Model.new name: name }
|
|
8
|
+
let(:field_name) { :name }
|
|
9
|
+
let(:name) { "John Doe" }
|
|
10
|
+
|
|
11
|
+
describe '.validate' do
|
|
12
|
+
context 'when options is a Fixnum' do
|
|
13
|
+
let(:options) { 5 }
|
|
14
|
+
|
|
15
|
+
context 'when name is "John Doe"' do
|
|
16
|
+
let(:name) { "John Doe" }
|
|
17
|
+
it { expect(subject).to eq({}) }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
context 'when name is "John"' do
|
|
21
|
+
let(:name) { "John" }
|
|
22
|
+
it do
|
|
23
|
+
expect(subject).to eq({
|
|
24
|
+
name: ["must be at least 5 characters"]
|
|
25
|
+
})
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
context 'when options is a Hash' do
|
|
31
|
+
let(:options) do
|
|
32
|
+
{ length: 5, maximum: 10 }
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
context 'when name is "John Doe"' do
|
|
36
|
+
let(:name) { "John Doe" }
|
|
37
|
+
it { expect(subject).to eq({}) }
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
context 'when name is "John"' do
|
|
41
|
+
let(:name) { "John" }
|
|
42
|
+
it do
|
|
43
|
+
if RUBY_PLATFORM == 'opal'
|
|
44
|
+
expect(subject).to eq({
|
|
45
|
+
name: ["must be at least {\"length\"=>5, \"maximum\"=>10} characters"]
|
|
46
|
+
})
|
|
47
|
+
else
|
|
48
|
+
expect(subject).to eq({
|
|
49
|
+
name: ["must be at least {:length=>5, :maximum=>10} characters"]
|
|
50
|
+
})
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
context 'when name is "Zach Galifianakis"' do
|
|
56
|
+
let(:name) { "Zach Galifianakis" }
|
|
57
|
+
it do
|
|
58
|
+
if RUBY_PLATFORM == 'opal'
|
|
59
|
+
expect(subject).to eq({
|
|
60
|
+
name: ["must be less than {\"length\"=>5, \"maximum\"=>10} characters"]
|
|
61
|
+
})
|
|
62
|
+
else
|
|
63
|
+
expect(subject).to eq({
|
|
64
|
+
name: ["must be less than {:length=>5, :maximum=>10} characters"]
|
|
65
|
+
})
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
context 'when options not a Fixnum or a Hash' do
|
|
72
|
+
let(:options) { 'string' }
|
|
73
|
+
|
|
74
|
+
it "raises an exception" do
|
|
75
|
+
expect { subject }.to raise_error(
|
|
76
|
+
RuntimeError,
|
|
77
|
+
'The arguments to length must be a number or a hash'
|
|
78
|
+
)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
|
2
2
|
|
|
3
3
|
describe Volt::PhoneNumberValidator do
|
|
4
4
|
subject { Volt::PhoneNumberValidator.new(*params) }
|
|
5
|
-
let(:params) { [
|
|
5
|
+
let(:params) { [model, field_name, options] }
|
|
6
6
|
|
|
7
7
|
let(:model) { Volt::Model.new phone_number: phone_number }
|
|
8
8
|
let(:field_name) { :phone_number }
|
|
@@ -131,14 +131,14 @@ describe Volt::PhoneNumberValidator do
|
|
|
131
131
|
end
|
|
132
132
|
|
|
133
133
|
context 'when provided a custom error message' do
|
|
134
|
-
let(:options) { {
|
|
134
|
+
let(:options) { { message: custom_message } }
|
|
135
135
|
let(:custom_message) { 'this is a custom message' }
|
|
136
136
|
|
|
137
137
|
context 'and the phone number is invalid' do
|
|
138
138
|
let(:phone_number) { invalid_number }
|
|
139
139
|
|
|
140
140
|
it 'returns errors with the custom message' do
|
|
141
|
-
expect(subject.errors).to eq(phone_number: [
|
|
141
|
+
expect(subject.errors).to eq(phone_number: [custom_message])
|
|
142
142
|
end
|
|
143
143
|
end
|
|
144
144
|
end
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'volt/page/bindings/template_binding'
|
|
3
|
+
|
|
4
|
+
# Setup page stub
|
|
5
|
+
|
|
6
|
+
class Volt::Page
|
|
7
|
+
attr_accessor :templates
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
describe Volt::TemplateBinding do
|
|
11
|
+
before do
|
|
12
|
+
@page = double('volt/page')
|
|
13
|
+
expect(@page).to receive(:templates).at_least(1).times { @templates }
|
|
14
|
+
|
|
15
|
+
# TODO: We should decouple things so we don't need to allocate
|
|
16
|
+
@view_lookup = Volt::ViewLookupForPath.new(@page, 'main/main/main')
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def set_template(templates)
|
|
20
|
+
@page.instance_variable_set('@templates', templates)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it 'should lookup nested controller action' do
|
|
24
|
+
@templates = {
|
|
25
|
+
'main/main/blog/nav' => '',
|
|
26
|
+
'main/comments/new/body' => ''
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
result = @view_lookup.path_for_template('comments/new').last
|
|
30
|
+
expect(result).to eq(%w(main comments_controller new))
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it 'it should not look in the local component/controller for a specified controller/action' do
|
|
34
|
+
@templates = {
|
|
35
|
+
'main/comments/new/body' => ''
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
path, result = @view_lookup.path_for_template('comments/new')
|
|
39
|
+
expect(path).to eq('main/comments/new/body')
|
|
40
|
+
expect(result).to eq(%w(main comments_controller new))
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it 'should handle a tripple lookup' do
|
|
44
|
+
@templates = {
|
|
45
|
+
'main/comments/new/errors' => '',
|
|
46
|
+
'comments/new/errors/body' => ''
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
path, result = @view_lookup.path_for_template('comments/new/errors')
|
|
50
|
+
expect(path).to eq('main/comments/new/errors')
|
|
51
|
+
expect(result).to eq(%w(main comments_controller errors))
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it 'should handle a tripple lookup to controllers' do
|
|
55
|
+
@templates = {
|
|
56
|
+
'comments/new/errors/body' => ''
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
path, result = @view_lookup.path_for_template('comments/new/errors')
|
|
60
|
+
expect(path).to eq('comments/new/errors/body')
|
|
61
|
+
expect(result).to eq(%w(comments new_controller errors))
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it 'should find a matching component' do
|
|
65
|
+
@templates = {
|
|
66
|
+
'comments/new/index/body' => ''
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
path, result = @view_lookup.path_for_template('comments/new')
|
|
70
|
+
expect(path).to eq('comments/new/index/body')
|
|
71
|
+
expect(result).to eq(%w(comments new_controller index))
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it 'should lookup sub-templates within its own file' do
|
|
75
|
+
@templates = {
|
|
76
|
+
'main/main/blog/nav' => '',
|
|
77
|
+
'main/main/main/nav' => ''
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
expect(@view_lookup.path_for_template('nav').first).to eq('main/main/main/nav')
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it 'should lookup sub-templates within another local view' do
|
|
84
|
+
@templates = {
|
|
85
|
+
'main/main/blog/nav' => '',
|
|
86
|
+
'main/main/main/nav' => ''
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
expect(@view_lookup.path_for_template('blog/nav').first).to eq('main/main/blog/nav')
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it 'should lookup in another view' do
|
|
93
|
+
@templates = {
|
|
94
|
+
'main/main/nav/body' => ''
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
expect(@view_lookup.path_for_template('nav').first).to eq('main/main/nav/body')
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
it 'should lookup in a controller' do
|
|
101
|
+
@templates = {
|
|
102
|
+
'main/nav/index/body' => ''
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
expect(@view_lookup.path_for_template('nav').first).to eq('main/nav/index/body')
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
it 'should lookup in a controller/view' do
|
|
109
|
+
@templates = {
|
|
110
|
+
'main/blog/nav/body' => ''
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
expect(@view_lookup.path_for_template('blog/nav').first).to eq('main/blog/nav/body')
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
it 'should lookup in a controller' do
|
|
117
|
+
@templates = {
|
|
118
|
+
'main/nav/index/body' => ''
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
expect(@view_lookup.path_for_template('nav').first).to eq('main/nav/index/body')
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it 'should lookup in a component' do
|
|
125
|
+
@templates = {
|
|
126
|
+
'nav/main/index/body' => ''
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
expect(@view_lookup.path_for_template('nav').first).to eq('nav/main/index/body')
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
it 'should lookup in a component/controller/view' do
|
|
133
|
+
@templates = {
|
|
134
|
+
'nav/main/main/body' => '',
|
|
135
|
+
'auth/login/new/body' => ''
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
expect(@view_lookup.path_for_template('auth/login/new').first).to eq('auth/login/new/body')
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
it 'should let you force a sub template' do
|
|
142
|
+
@templates = {
|
|
143
|
+
'nav/main/index/title' => '',
|
|
144
|
+
'auth/login/new/title' => ''
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
expect(@view_lookup.path_for_template('nav', 'title').first).to eq('nav/main/index/title')
|
|
148
|
+
end
|
|
149
|
+
end
|
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
require 'volt/page/bindings/template_binding'
|
|
3
|
-
|
|
4
|
-
# Setup page stub
|
|
5
|
-
|
|
6
|
-
class Volt::Page
|
|
7
|
-
attr_accessor :templates
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
describe Volt::TemplateBinding do
|
|
11
|
-
before do
|
|
12
|
-
@page = double('volt/page')
|
|
13
|
-
expect(@page).to receive(:templates).at_least(1).times { @templates }
|
|
14
|
-
|
|
15
|
-
# TODO: We should decouple things so we don't need to allocate
|
|
16
|
-
@template_binding = Volt::TemplateBinding.allocate
|
|
17
|
-
@template_binding.instance_variable_set('@page', @page)
|
|
18
|
-
@template_binding.setup_path('main/main/main')
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def set_template(templates)
|
|
22
|
-
@page.instance_variable_set('@templates', templates)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
it 'should lookup nested controller action' do
|
|
26
|
-
@templates = {
|
|
27
|
-
'main/main/blog/nav' => '',
|
|
28
|
-
'main/comments/new/body' => ''
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
result = @template_binding.path_for_template('comments/new').last
|
|
32
|
-
expect(result).to eq(%w(main comments_controller new))
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
it 'it should not look in the local component/controller for a specified controller/action' do
|
|
36
|
-
@templates = {
|
|
37
|
-
'main/comments/new/body' => ''
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
path, result = @template_binding.path_for_template('comments/new')
|
|
41
|
-
expect(path).to eq('main/comments/new/body')
|
|
42
|
-
expect(result).to eq(%w(main comments_controller new))
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
it 'should handle a tripple lookup' do
|
|
46
|
-
@templates = {
|
|
47
|
-
'main/comments/new/errors' => '',
|
|
48
|
-
'comments/new/errors/body' => ''
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
path, result = @template_binding.path_for_template('comments/new/errors')
|
|
52
|
-
expect(path).to eq('main/comments/new/errors')
|
|
53
|
-
expect(result).to eq(["main", "comments_controller", "errors"])
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
it 'should handle a tripple lookup to controllers' do
|
|
57
|
-
@templates = {
|
|
58
|
-
'comments/new/errors/body' => ''
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
path, result = @template_binding.path_for_template('comments/new/errors')
|
|
62
|
-
expect(path).to eq('comments/new/errors/body')
|
|
63
|
-
expect(result).to eq(%w(comments new_controller errors))
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
it 'should find a matching component' do
|
|
67
|
-
@templates = {
|
|
68
|
-
'comments/new/index/body' => ''
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
path, result = @template_binding.path_for_template('comments/new')
|
|
72
|
-
expect(path).to eq('comments/new/index/body')
|
|
73
|
-
expect(result).to eq(%w(comments new_controller index))
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
it 'should lookup sub-templates within its own file' do
|
|
77
|
-
@templates = {
|
|
78
|
-
'main/main/blog/nav' => '',
|
|
79
|
-
'main/main/main/nav' => ''
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
expect(@template_binding.path_for_template('nav').first).to eq('main/main/main/nav')
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
it 'should lookup sub-templates within another local view' do
|
|
86
|
-
@templates = {
|
|
87
|
-
'main/main/blog/nav' => '',
|
|
88
|
-
'main/main/main/nav' => ''
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
expect(@template_binding.path_for_template('blog/nav').first).to eq('main/main/blog/nav')
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
it 'should lookup in another view' do
|
|
95
|
-
@templates = {
|
|
96
|
-
'main/main/nav/body' => ''
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
expect(@template_binding.path_for_template('nav').first).to eq('main/main/nav/body')
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
it 'should lookup in a controller' do
|
|
103
|
-
@templates = {
|
|
104
|
-
'main/nav/index/body' => ''
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
expect(@template_binding.path_for_template('nav').first).to eq('main/nav/index/body')
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
it 'should lookup in a controller/view' do
|
|
111
|
-
@templates = {
|
|
112
|
-
'main/blog/nav/body' => ''
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
expect(@template_binding.path_for_template('blog/nav').first).to eq('main/blog/nav/body')
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
it 'should lookup in a controller' do
|
|
119
|
-
@templates = {
|
|
120
|
-
'main/nav/index/body' => ''
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
expect(@template_binding.path_for_template('nav').first).to eq('main/nav/index/body')
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
it 'should lookup in a component' do
|
|
127
|
-
@templates = {
|
|
128
|
-
'nav/main/index/body' => ''
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
expect(@template_binding.path_for_template('nav').first).to eq('nav/main/index/body')
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
it 'should lookup in a component/controller/view' do
|
|
135
|
-
@templates = {
|
|
136
|
-
'nav/main/main/body' => '',
|
|
137
|
-
'auth/login/new/body' => ''
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
expect(@template_binding.path_for_template('auth/login/new').first).to eq('auth/login/new/body')
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
it 'should let you force a sub template' do
|
|
144
|
-
@templates = {
|
|
145
|
-
'nav/main/index/title' => '',
|
|
146
|
-
'auth/login/new/title' => ''
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
expect(@template_binding.path_for_template('nav', 'title').first).to eq('nav/main/index/title')
|
|
150
|
-
end
|
|
151
|
-
end
|
|
@@ -60,4 +60,50 @@ describe Volt::Computation do
|
|
|
60
60
|
Volt::Computation.flush!
|
|
61
61
|
expect(values).to eq([nil, nil, 'inner', 'outer', 'inner'])
|
|
62
62
|
end
|
|
63
|
+
|
|
64
|
+
# Currently Class#class_variable_set/get isn't in opal
|
|
65
|
+
# https://github.com/opal/opal/issues/677
|
|
66
|
+
unless RUBY_PLATFORM == 'opal'
|
|
67
|
+
describe '#invalidate!' do
|
|
68
|
+
|
|
69
|
+
let(:computation) { Volt::Computation.new ->{} }
|
|
70
|
+
|
|
71
|
+
before(:each) do
|
|
72
|
+
Volt::Computation.class_variable_set :@@flush_queue, []
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
context 'when stopped' do
|
|
76
|
+
before(:each) { computation.instance_variable_set :@stopped, true }
|
|
77
|
+
|
|
78
|
+
it "doesn't add self to flush queue" do
|
|
79
|
+
computation.invalidate!
|
|
80
|
+
|
|
81
|
+
expect(Volt::Computation.class_variable_get :@@flush_queue).to be_empty
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
context 'when computing' do
|
|
86
|
+
before(:each) { computation.instance_variable_set :@computing, true }
|
|
87
|
+
|
|
88
|
+
it "doesn't add self to flush queue" do
|
|
89
|
+
computation.invalidate!
|
|
90
|
+
|
|
91
|
+
expect(Volt::Computation.class_variable_get :@@flush_queue).to be_empty
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
context 'when not stopped and not computing' do
|
|
96
|
+
before(:each) do
|
|
97
|
+
computation.instance_variable_set :@stopped, false
|
|
98
|
+
computation.instance_variable_set :@computing, false
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
it 'adds self to flush queue' do
|
|
102
|
+
computation.invalidate!
|
|
103
|
+
|
|
104
|
+
expect(Volt::Computation.class_variable_get :@@flush_queue).to match_array([computation])
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
63
109
|
end
|
data/spec/router/routes_spec.rb
CHANGED
|
@@ -66,7 +66,6 @@ describe Volt::Routes do
|
|
|
66
66
|
|
|
67
67
|
params = @routes.url_to_params('/login/cool')
|
|
68
68
|
expect(params).to eq(false)
|
|
69
|
-
|
|
70
69
|
end
|
|
71
70
|
|
|
72
71
|
it 'should setup param matchers' do
|
|
@@ -86,7 +85,6 @@ describe Volt::Routes do
|
|
|
86
85
|
{ _view: 'blog/tag', _tag: nil },
|
|
87
86
|
{ _view: 'login', _action: 'user', _name: nil, _id: nil }
|
|
88
87
|
])
|
|
89
|
-
|
|
90
88
|
end
|
|
91
89
|
|
|
92
90
|
it 'should go from params to url' do
|
|
@@ -136,7 +134,6 @@ describe Volt::Routes do
|
|
|
136
134
|
match, params = routes.send(:check_params_match, { _view: 'blog', _id: '55', _extra: 'some value' }, _view: 'blog', _id: '55')
|
|
137
135
|
expect(match).to eq(true)
|
|
138
136
|
expect(params).to eq(_extra: 'some value')
|
|
139
|
-
|
|
140
137
|
end
|
|
141
138
|
|
|
142
139
|
it 'should match routes' do
|
|
@@ -163,6 +160,5 @@ describe Volt::Routes do
|
|
|
163
160
|
end
|
|
164
161
|
|
|
165
162
|
params = @routes.url_to_params('/blog/20')
|
|
166
|
-
|
|
167
163
|
end
|
|
168
164
|
end
|
|
@@ -51,7 +51,6 @@ describe Volt::ViewParser do
|
|
|
51
51
|
]
|
|
52
52
|
}
|
|
53
53
|
})
|
|
54
|
-
|
|
55
54
|
end
|
|
56
55
|
|
|
57
56
|
it "should handle nested if's" do
|
|
@@ -121,7 +120,6 @@ describe Volt::ViewParser do
|
|
|
121
120
|
]
|
|
122
121
|
}
|
|
123
122
|
})
|
|
124
|
-
|
|
125
123
|
end
|
|
126
124
|
|
|
127
125
|
it 'should parse a single attribute binding' do
|
|
@@ -201,7 +199,6 @@ describe Volt::ViewParser do
|
|
|
201
199
|
end
|
|
202
200
|
|
|
203
201
|
it 'should parse components' do
|
|
204
|
-
|
|
205
202
|
end
|
|
206
203
|
|
|
207
204
|
it 'should parse sections' do
|
|
@@ -221,7 +218,6 @@ describe Volt::ViewParser do
|
|
|
221
218
|
'main/main/main/body' => {
|
|
222
219
|
'html' => "\n <p>This text goes in the body</p>\n"
|
|
223
220
|
})
|
|
224
|
-
|
|
225
221
|
end
|
|
226
222
|
|
|
227
223
|
it 'should keep the html inside of a textarea if there are no bindings' do
|
|
@@ -19,7 +19,7 @@ if RUBY_PLATFORM != 'opal'
|
|
|
19
19
|
it 'should list all JS files' do
|
|
20
20
|
main = Volt::AssetFiles.new('main', @component_paths)
|
|
21
21
|
|
|
22
|
-
expect(main.javascript_files(nil)).to eq([
|
|
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'])
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
it 'should raise an exception for a missing component gem' do
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
unless RUBY_PLATFORM == 'opal'
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
require 'volt/server/rack/quiet_common_logger'
|
|
4
|
+
|
|
5
|
+
describe QuietCommonLogger do
|
|
6
|
+
subject { QuietCommonLogger.new(nil, nil) }
|
|
7
|
+
let(:fake_class) { Class.new }
|
|
8
|
+
let(:app) { double 'App', call: [:status, :header, :body] }
|
|
9
|
+
|
|
10
|
+
before(:each) do
|
|
11
|
+
allow(app).to receive(:call)
|
|
12
|
+
# puts "SUBJECT: #{subject.inspect}"
|
|
13
|
+
subject.instance_variable_set :@app, app
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe '#call' do
|
|
17
|
+
before(:each) do
|
|
18
|
+
header_hash = stub_const('Rack::Utils::HeaderHash', fake_class)
|
|
19
|
+
allow(header_hash).to receive(:new)
|
|
20
|
+
|
|
21
|
+
proxy = stub_const('Rack::BodyProxy', fake_class)
|
|
22
|
+
allow(proxy).to receive(:new)
|
|
23
|
+
|
|
24
|
+
allow(subject).to receive(:log)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
context 'when request path has no file extension and request run over web socket' do
|
|
28
|
+
let(:env) { {'REQUEST_PATH' => '/file'} }
|
|
29
|
+
|
|
30
|
+
it "calls 'log' method" do
|
|
31
|
+
expect(subject).to receive(:log)
|
|
32
|
+
subject.call env
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
context 'when request path has file extension' do
|
|
37
|
+
let(:env) { {'REQUEST_PATH' => '/file.ext'} }
|
|
38
|
+
|
|
39
|
+
it "doesn't call 'log' method" do
|
|
40
|
+
expect(subject).not_to receive(:log)
|
|
41
|
+
subject.call env
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
context 'when request run over web socket' do
|
|
46
|
+
let(:env) { {'REQUEST_PATH' => '/channel'} }
|
|
47
|
+
|
|
48
|
+
it "doesn't call 'log' method" do
|
|
49
|
+
expect(subject).not_to receive(:log)
|
|
50
|
+
subject.call env
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
require 'volt/spec/setup'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
unless RUBY_PLATFORM == 'opal'
|
|
4
|
+
require 'pry-byebug'
|
|
5
5
|
# Specs are run against the kitchen sink app
|
|
6
6
|
kitchen_sink_path = File.expand_path(File.join(File.dirname(__FILE__), 'apps/kitchen_sink'))
|
|
7
7
|
Volt.spec_setup(kitchen_sink_path)
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
if RUBY_PLATFORM != 'opal'
|
|
11
8
|
|
|
12
9
|
RSpec.configure do |config|
|
|
13
10
|
# config.before(:each) do
|
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
if RUBY_PLATFORM != 'opal'
|
|
2
2
|
class TestTask < Volt::TaskHandler
|
|
3
|
-
def allowed_method(arg1)
|
|
4
|
-
return 'yes' + arg1
|
|
3
|
+
def allowed_method(arg1, arg2)
|
|
4
|
+
return 'yes' + arg1 + arg2
|
|
5
5
|
end
|
|
6
6
|
end
|
|
7
7
|
|
|
8
|
-
|
|
9
8
|
describe Volt::Dispatcher do
|
|
9
|
+
before do
|
|
10
|
+
Volt.logger = spy('Volt::VoltLogger')
|
|
11
|
+
end
|
|
10
12
|
|
|
11
13
|
it 'should only allow method calls on TaskHandler or above in the inheritance chain' do
|
|
12
14
|
channel = double('channel')
|
|
13
15
|
|
|
14
|
-
expect(channel).to receive(:send_message).with('response', 0, 'yes works', nil)
|
|
16
|
+
expect(channel).to receive(:send_message).with('response', 0, 'yes it works', nil)
|
|
15
17
|
|
|
16
|
-
Volt::Dispatcher.new.dispatch(channel, [0, 'TestTask', :allowed_method, {}, ' works'])
|
|
18
|
+
Volt::Dispatcher.new.dispatch(channel, [0, 'TestTask', :allowed_method, {}, ' it', ' works'])
|
|
17
19
|
end
|
|
18
20
|
|
|
19
21
|
it 'should not allow eval' do
|
|
@@ -39,5 +41,14 @@ if RUBY_PLATFORM != 'opal'
|
|
|
39
41
|
|
|
40
42
|
Volt::Dispatcher.new.dispatch(channel, [0, 'TestTask', :methods])
|
|
41
43
|
end
|
|
44
|
+
|
|
45
|
+
it 'should log an info message before and after the dispatch' do
|
|
46
|
+
channel = double('channel')
|
|
47
|
+
|
|
48
|
+
allow(channel).to receive(:send_message).with('response', 0, 'yes it works', nil)
|
|
49
|
+
expect(Volt.logger).to receive(:log_dispatch)
|
|
50
|
+
|
|
51
|
+
Volt::Dispatcher.new.dispatch(channel, [0, 'TestTask', :allowed_method, {}, ' it', ' works'])
|
|
52
|
+
end
|
|
42
53
|
end
|
|
43
54
|
end
|