hanami 2.0.2 → 2.1.0.beta1
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/CHANGELOG.md +31 -0
- data/LICENSE.md +1 -1
- data/README.md +25 -9
- data/hanami.gemspec +2 -2
- data/lib/hanami/config/actions.rb +0 -4
- data/lib/hanami/config/logger.rb +1 -1
- data/lib/hanami/config/views.rb +0 -4
- data/lib/hanami/config.rb +54 -0
- data/lib/hanami/extensions/action/slice_configured_action.rb +15 -7
- data/lib/hanami/extensions/action.rb +4 -4
- data/lib/hanami/extensions/router/errors.rb +58 -0
- data/lib/hanami/extensions/view/context.rb +129 -60
- data/lib/hanami/extensions/view/part.rb +26 -0
- data/lib/hanami/extensions/view/scope.rb +26 -0
- data/lib/hanami/extensions/view/slice_configured_context.rb +0 -2
- data/lib/hanami/extensions/view/slice_configured_helpers.rb +44 -0
- data/lib/hanami/extensions/view/slice_configured_view.rb +106 -21
- data/lib/hanami/extensions/view/standard_helpers.rb +14 -0
- data/lib/hanami/extensions.rb +10 -3
- data/lib/hanami/helpers/form_helper/form_builder.rb +1391 -0
- data/lib/hanami/helpers/form_helper/values.rb +75 -0
- data/lib/hanami/helpers/form_helper.rb +213 -0
- data/lib/hanami/middleware/public_errors_app.rb +75 -0
- data/lib/hanami/middleware/render_errors.rb +93 -0
- data/lib/hanami/slice.rb +28 -2
- data/lib/hanami/slice_configurable.rb +3 -2
- data/lib/hanami/version.rb +1 -1
- data/lib/hanami/web/rack_logger.rb +8 -20
- data/lib/hanami.rb +1 -1
- data/spec/integration/action/view_rendering/view_context_spec.rb +221 -0
- data/spec/integration/action/view_rendering_spec.rb +0 -18
- data/spec/integration/rack_app/middleware_spec.rb +23 -23
- data/spec/integration/rack_app/rack_app_spec.rb +5 -1
- data/spec/integration/slices/slice_registrations_spec.rb +80 -0
- data/spec/integration/view/config/default_context_spec.rb +149 -0
- data/spec/integration/view/{inflector_spec.rb → config/inflector_spec.rb} +1 -1
- data/spec/integration/view/config/part_class_spec.rb +147 -0
- data/spec/integration/view/config/part_namespace_spec.rb +103 -0
- data/spec/integration/view/config/paths_spec.rb +119 -0
- data/spec/integration/view/config/scope_class_spec.rb +147 -0
- data/spec/integration/view/config/scope_namespace_spec.rb +103 -0
- data/spec/integration/view/config/template_spec.rb +38 -0
- data/spec/integration/view/context/request_spec.rb +3 -7
- data/spec/integration/view/helpers/form_helper_spec.rb +174 -0
- data/spec/integration/view/helpers/part_helpers_spec.rb +124 -0
- data/spec/integration/view/helpers/scope_helpers_spec.rb +84 -0
- data/spec/integration/view/helpers/user_defined_helpers/part_helpers_spec.rb +162 -0
- data/spec/integration/view/helpers/user_defined_helpers/scope_helpers_spec.rb +119 -0
- data/spec/integration/view/slice_configuration_spec.rb +9 -9
- data/spec/integration/web/render_detailed_errors_spec.rb +90 -0
- data/spec/integration/web/render_errors_spec.rb +240 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/support/matchers.rb +32 -0
- data/spec/unit/hanami/config/actions/default_values_spec.rb +0 -4
- data/spec/unit/hanami/config/logger_spec.rb +9 -0
- data/spec/unit/hanami/config/render_detailed_errors_spec.rb +25 -0
- data/spec/unit/hanami/config/render_errors_spec.rb +25 -0
- data/spec/unit/hanami/config/views_spec.rb +0 -18
- data/spec/unit/hanami/extensions/view/context_spec.rb +59 -0
- data/spec/unit/hanami/helpers/form_helper_spec.rb +2826 -0
- data/spec/unit/hanami/router/errors/not_allowed_error_spec.rb +27 -0
- data/spec/unit/hanami/router/errors/not_found_error_spec.rb +22 -0
- data/spec/unit/hanami/slice_configurable_spec.rb +18 -0
- data/spec/unit/hanami/version_spec.rb +1 -1
- data/spec/unit/hanami/web/rack_logger_spec.rb +1 -1
- metadata +67 -33
- data/spec/integration/action/view_integration_spec.rb +0 -165
- data/spec/integration/view/part_namespace_spec.rb +0 -96
- data/spec/integration/view/path_spec.rb +0 -56
- data/spec/integration/view/template_spec.rb +0 -68
- data/spec/isolation/hanami/application/already_configured_spec.rb +0 -19
- data/spec/isolation/hanami/application/inherit_anonymous_class_spec.rb +0 -10
- data/spec/isolation/hanami/application/inherit_concrete_class_spec.rb +0 -14
- data/spec/isolation/hanami/application/not_configured_spec.rb +0 -9
- data/spec/isolation/hanami/application/routes/configured_spec.rb +0 -44
- data/spec/isolation/hanami/application/routes/not_configured_spec.rb +0 -16
- data/spec/isolation/hanami/boot/success_spec.rb +0 -50
@@ -0,0 +1,174 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rack/test"
|
4
|
+
require "stringio"
|
5
|
+
|
6
|
+
RSpec.describe "Helpers / FormHelper", :app_integration do
|
7
|
+
include Rack::Test::Methods
|
8
|
+
let(:app) { Hanami.app }
|
9
|
+
|
10
|
+
before do
|
11
|
+
with_directory(make_tmp_directory) do
|
12
|
+
write "config/app.rb", <<~RUBY
|
13
|
+
module TestApp
|
14
|
+
class App < Hanami::App
|
15
|
+
config.logger.stream = StringIO.new
|
16
|
+
end
|
17
|
+
end
|
18
|
+
RUBY
|
19
|
+
|
20
|
+
write "config/routes.rb", <<~RUBY
|
21
|
+
module TestApp
|
22
|
+
class Routes < Hanami::Routes
|
23
|
+
get "posts/:id/edit", to: "posts.edit"
|
24
|
+
put "posts/:id", to: "posts.update"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
RUBY
|
28
|
+
|
29
|
+
write "app/action.rb", <<~RUBY
|
30
|
+
# auto_register: false
|
31
|
+
|
32
|
+
require "hanami/action"
|
33
|
+
|
34
|
+
module TestApp
|
35
|
+
class Action < Hanami::Action
|
36
|
+
end
|
37
|
+
end
|
38
|
+
RUBY
|
39
|
+
|
40
|
+
write "app/view.rb", <<~RUBY
|
41
|
+
# auto_register: false
|
42
|
+
|
43
|
+
require "hanami/view"
|
44
|
+
|
45
|
+
module TestApp
|
46
|
+
class View < Hanami::View
|
47
|
+
config.layout = nil
|
48
|
+
end
|
49
|
+
end
|
50
|
+
RUBY
|
51
|
+
|
52
|
+
write "app/actions/posts/edit.rb", <<~RUBY
|
53
|
+
module TestApp
|
54
|
+
module Actions
|
55
|
+
module Posts
|
56
|
+
class Edit < TestApp::Action
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
RUBY
|
62
|
+
|
63
|
+
write "app/actions/posts/update.rb", <<~RUBY
|
64
|
+
module TestApp
|
65
|
+
module Actions
|
66
|
+
module Posts
|
67
|
+
class Update < TestApp::Action
|
68
|
+
def handle(request, response)
|
69
|
+
if valid?(request.params[:post])
|
70
|
+
response.redirect_to "/posts/x/edit"
|
71
|
+
else
|
72
|
+
response.render view
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def valid?(post)
|
79
|
+
post.to_h[:title].to_s.length > 0
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
RUBY
|
86
|
+
|
87
|
+
write "app/views/posts/edit.rb", <<~RUBY
|
88
|
+
module TestApp
|
89
|
+
module Views
|
90
|
+
module Posts
|
91
|
+
class Edit < TestApp::View
|
92
|
+
expose :post do
|
93
|
+
Struct.new(:title, :body).new("Hello <world>", "This is the post.")
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
RUBY
|
100
|
+
|
101
|
+
write "app/templates/posts/edit.html.erb", <<~ERB
|
102
|
+
<h1>Edit post</h1>
|
103
|
+
|
104
|
+
<%= form_for("/posts") do |f| %>
|
105
|
+
<div>
|
106
|
+
Title:
|
107
|
+
<%= f.text_field "post.title" %>
|
108
|
+
</div>
|
109
|
+
<div>
|
110
|
+
Body:
|
111
|
+
<%= f.text_area "post.body" %>
|
112
|
+
</div>
|
113
|
+
<% end %>
|
114
|
+
ERB
|
115
|
+
|
116
|
+
before_prepare if respond_to?(:before_prepare)
|
117
|
+
require "hanami/prepare"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
it "does not have a _csrf_token field when no sessions are configured" do
|
122
|
+
get "/posts/123/edit"
|
123
|
+
|
124
|
+
html = Capybara.string(last_response.body)
|
125
|
+
|
126
|
+
expect(html).to have_no_selector("input[type='hidden'][name='_csrf_token']")
|
127
|
+
end
|
128
|
+
|
129
|
+
it "uses the value from the view's locals" do
|
130
|
+
get "/posts/123/edit"
|
131
|
+
|
132
|
+
html = Capybara.string(last_response.body)
|
133
|
+
|
134
|
+
title_field = html.find("input[name='post[title]']")
|
135
|
+
expect(title_field.value).to eq "Hello <world>"
|
136
|
+
|
137
|
+
body_field = html.find("textarea[name='post[body]']")
|
138
|
+
expect(body_field.value).to eq "This is the post."
|
139
|
+
end
|
140
|
+
|
141
|
+
it "prefers the values from the request params" do
|
142
|
+
put "/posts/123", post: {title: "", body: "This is the UPDATED post."}
|
143
|
+
|
144
|
+
html = Capybara.string(last_response.body)
|
145
|
+
|
146
|
+
title_field = html.find("input[name='post[title]']")
|
147
|
+
expect(title_field.value).to eq ""
|
148
|
+
|
149
|
+
body_field = html.find("textarea[name='post[body]']")
|
150
|
+
expect(body_field.value).to eq "This is the UPDATED post."
|
151
|
+
end
|
152
|
+
|
153
|
+
context "sessions enabled" do
|
154
|
+
def before_prepare
|
155
|
+
write "config/app.rb", <<~RUBY
|
156
|
+
module TestApp
|
157
|
+
class App < Hanami::App
|
158
|
+
config.logger.stream = StringIO.new
|
159
|
+
config.actions.sessions = :cookie, {secret: "xyz"}
|
160
|
+
end
|
161
|
+
end
|
162
|
+
RUBY
|
163
|
+
end
|
164
|
+
|
165
|
+
it "inserts a CSRF token field" do
|
166
|
+
get "/posts/123/edit"
|
167
|
+
|
168
|
+
html = Capybara.string(last_response.body)
|
169
|
+
|
170
|
+
csrf_field = html.find("input[type='hidden'][name='_csrf_token']", visible: false)
|
171
|
+
expect(csrf_field.value).to match(/[a-z0-9]{10,}/i)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "ostruct"
|
4
|
+
|
5
|
+
# rubocop:disable Style/OpenStructUse
|
6
|
+
|
7
|
+
RSpec.describe "App view / Helpers / Part helpers", :app_integration do
|
8
|
+
before do
|
9
|
+
with_directory(make_tmp_directory) do
|
10
|
+
write "config/app.rb", <<~RUBY
|
11
|
+
module TestApp
|
12
|
+
class App < Hanami::App
|
13
|
+
end
|
14
|
+
end
|
15
|
+
RUBY
|
16
|
+
|
17
|
+
write "app/view.rb", <<~RUBY
|
18
|
+
# auto_register: false
|
19
|
+
|
20
|
+
require "hanami/view"
|
21
|
+
|
22
|
+
module TestApp
|
23
|
+
class View < Hanami::View
|
24
|
+
config.layout = nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
RUBY
|
28
|
+
|
29
|
+
before_prepare if respond_to?(:before_prepare)
|
30
|
+
require "hanami/prepare"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "app view and parts" do
|
35
|
+
def before_prepare
|
36
|
+
write "app/views/posts/show.rb", <<~RUBY
|
37
|
+
module TestApp
|
38
|
+
module Views
|
39
|
+
module Posts
|
40
|
+
class Show < TestApp::View
|
41
|
+
expose :post
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
RUBY
|
47
|
+
|
48
|
+
write "app/views/parts/post.rb", <<~RUBY
|
49
|
+
module TestApp
|
50
|
+
module Views
|
51
|
+
module Parts
|
52
|
+
class Post < TestApp::Views::Part
|
53
|
+
def number
|
54
|
+
format_number(value.number)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
RUBY
|
61
|
+
|
62
|
+
write "app/templates/posts/show.html.erb", <<~ERB
|
63
|
+
<h1><%= post.number %></h1>
|
64
|
+
ERB
|
65
|
+
end
|
66
|
+
|
67
|
+
it "makes default helpers available in parts" do
|
68
|
+
post = OpenStruct.new(number: 12_345)
|
69
|
+
output = TestApp::App["views.posts.show"].call(post: post).to_s.strip
|
70
|
+
|
71
|
+
expect(output).to eq "<h1>12,345</h1>"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "slice view and parts" do
|
76
|
+
def before_prepare
|
77
|
+
write "slices/main/view.rb", <<~RUBY
|
78
|
+
module Main
|
79
|
+
class View < TestApp::View
|
80
|
+
end
|
81
|
+
end
|
82
|
+
RUBY
|
83
|
+
|
84
|
+
write "slices/main/views/posts/show.rb", <<~RUBY
|
85
|
+
module Main
|
86
|
+
module Views
|
87
|
+
module Posts
|
88
|
+
class Show < Main::View
|
89
|
+
expose :post
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
RUBY
|
95
|
+
|
96
|
+
write "slices/main/views/parts/post.rb", <<~RUBY
|
97
|
+
module Main
|
98
|
+
module Views
|
99
|
+
module Parts
|
100
|
+
class Post < Main::Views::Part
|
101
|
+
def number
|
102
|
+
format_number(value.number)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
RUBY
|
109
|
+
|
110
|
+
write "slices/main/templates/posts/show.html.erb", <<~ERB
|
111
|
+
<h1><%= post.number %></h1>
|
112
|
+
ERB
|
113
|
+
end
|
114
|
+
|
115
|
+
it "makes default helpers available in parts" do
|
116
|
+
post = OpenStruct.new(number: 12_345)
|
117
|
+
output = Main::Slice["views.posts.show"].call(post: post).to_s.strip
|
118
|
+
|
119
|
+
expect(output).to eq "<h1>12,345</h1>"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# rubocop:enable Style/OpenStructUse
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe "App view / Helpers / Scope helpers", :app_integration do
|
4
|
+
before do
|
5
|
+
with_directory(make_tmp_directory) do
|
6
|
+
write "config/app.rb", <<~RUBY
|
7
|
+
module TestApp
|
8
|
+
class App < Hanami::App
|
9
|
+
end
|
10
|
+
end
|
11
|
+
RUBY
|
12
|
+
|
13
|
+
write "app/view.rb", <<~RUBY
|
14
|
+
# auto_register: false
|
15
|
+
|
16
|
+
require "hanami/view"
|
17
|
+
|
18
|
+
module TestApp
|
19
|
+
class View < Hanami::View
|
20
|
+
config.layout = nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
RUBY
|
24
|
+
|
25
|
+
before_prepare if respond_to?(:before_prepare)
|
26
|
+
require "hanami/prepare"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "app view" do
|
31
|
+
def before_prepare
|
32
|
+
write "app/views/posts/show.rb", <<~RUBY
|
33
|
+
module TestApp
|
34
|
+
module Views
|
35
|
+
module Posts
|
36
|
+
class Show < TestApp::View
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
RUBY
|
42
|
+
|
43
|
+
write "app/templates/posts/show.html.erb", <<~ERB
|
44
|
+
<h1><%= format_number(12_345) %></h1>
|
45
|
+
ERB
|
46
|
+
end
|
47
|
+
|
48
|
+
it "makes default helpers available in templates" do
|
49
|
+
output = TestApp::App["views.posts.show"].call.to_s.strip
|
50
|
+
expect(output).to eq "<h1>12,345</h1>"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "slice view" do
|
55
|
+
def before_prepare
|
56
|
+
write "slices/main/view.rb", <<~RUBY
|
57
|
+
module Main
|
58
|
+
class View < TestApp::View
|
59
|
+
end
|
60
|
+
end
|
61
|
+
RUBY
|
62
|
+
|
63
|
+
write "slices/main/views/posts/show.rb", <<~RUBY
|
64
|
+
module Main
|
65
|
+
module Views
|
66
|
+
module Posts
|
67
|
+
class Show < Main::View
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
RUBY
|
73
|
+
|
74
|
+
write "slices/main/templates/posts/show.html.erb", <<~ERB
|
75
|
+
<h1><%= format_number(12_345) %></h1>
|
76
|
+
ERB
|
77
|
+
end
|
78
|
+
|
79
|
+
it "makes default helpers available in templates" do
|
80
|
+
output = Main::Slice["views.posts.show"].call.to_s.strip
|
81
|
+
expect(output).to eq "<h1>12,345</h1>"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,162 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "ostruct"
|
4
|
+
|
5
|
+
# rubocop:disable Style/OpenStructUse
|
6
|
+
|
7
|
+
RSpec.describe "App view / Helpers / User-defined helpers / Scope helpers", :app_integration do
|
8
|
+
before do
|
9
|
+
with_directory(make_tmp_directory) do
|
10
|
+
write "config/app.rb", <<~RUBY
|
11
|
+
module TestApp
|
12
|
+
class App < Hanami::App
|
13
|
+
end
|
14
|
+
end
|
15
|
+
RUBY
|
16
|
+
|
17
|
+
write "app/view.rb", <<~RUBY
|
18
|
+
# auto_register: false
|
19
|
+
|
20
|
+
require "hanami/view"
|
21
|
+
|
22
|
+
module TestApp
|
23
|
+
class View < Hanami::View
|
24
|
+
config.layout = nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
RUBY
|
28
|
+
|
29
|
+
write "app/views/helpers.rb", <<~'RUBY'
|
30
|
+
# auto_register: false
|
31
|
+
|
32
|
+
module TestApp
|
33
|
+
module Views
|
34
|
+
module Helpers
|
35
|
+
def exclaim_from_app(str)
|
36
|
+
tag.h1("#{str}! (app helper)")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
RUBY
|
42
|
+
|
43
|
+
before_prepare if respond_to?(:before_prepare)
|
44
|
+
require "hanami/prepare"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "app view and parts" do
|
49
|
+
def before_prepare
|
50
|
+
write "app/views/posts/show.rb", <<~RUBY
|
51
|
+
module TestApp
|
52
|
+
module Views
|
53
|
+
module Posts
|
54
|
+
class Show < TestApp::View
|
55
|
+
expose :post
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
RUBY
|
61
|
+
|
62
|
+
write "app/views/parts/post.rb", <<~RUBY
|
63
|
+
module TestApp
|
64
|
+
module Views
|
65
|
+
module Parts
|
66
|
+
class Post < TestApp::Views::Part
|
67
|
+
def title
|
68
|
+
exclaim_from_app(value.title)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
RUBY
|
75
|
+
|
76
|
+
write "app/templates/posts/show.html.erb", <<~ERB
|
77
|
+
<%= post.title %>
|
78
|
+
ERB
|
79
|
+
end
|
80
|
+
|
81
|
+
it "makes user-defined helpers available in parts" do
|
82
|
+
post = OpenStruct.new(title: "Hello world")
|
83
|
+
output = TestApp::App["views.posts.show"].call(post: post).to_s.strip
|
84
|
+
|
85
|
+
expect(output).to eq "<h1>Hello world! (app helper)</h1>"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "slice view and parts" do
|
90
|
+
def before_prepare
|
91
|
+
write "slices/main/view.rb", <<~RUBY
|
92
|
+
module Main
|
93
|
+
class View < TestApp::View
|
94
|
+
# FIXME: base slice views should override paths from the base app view
|
95
|
+
config.paths = [File.join(File.expand_path(__dir__), "templates")]
|
96
|
+
end
|
97
|
+
end
|
98
|
+
RUBY
|
99
|
+
|
100
|
+
write "slices/main/views/helpers.rb", <<~'RUBY'
|
101
|
+
# auto_register: false
|
102
|
+
|
103
|
+
module Main
|
104
|
+
module Views
|
105
|
+
module Helpers
|
106
|
+
def exclaim_from_slice(str)
|
107
|
+
tag.h1("#{str}! (slice helper)")
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
RUBY
|
113
|
+
|
114
|
+
write "slices/main/views/posts/show.rb", <<~RUBY
|
115
|
+
module Main
|
116
|
+
module Views
|
117
|
+
module Posts
|
118
|
+
class Show < Main::View
|
119
|
+
expose :post
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
RUBY
|
125
|
+
|
126
|
+
write "slices/main/views/parts/post.rb", <<~RUBY
|
127
|
+
module Main
|
128
|
+
module Views
|
129
|
+
module Parts
|
130
|
+
class Post < Main::Views::Part
|
131
|
+
def title
|
132
|
+
exclaim_from_slice(value.title)
|
133
|
+
end
|
134
|
+
|
135
|
+
def title_from_app
|
136
|
+
exclaim_from_app(value.title)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
RUBY
|
143
|
+
|
144
|
+
write "slices/main/templates/posts/show.html.erb", <<~ERB
|
145
|
+
<%= post.title %>
|
146
|
+
<%= post.title_from_app %>
|
147
|
+
ERB
|
148
|
+
end
|
149
|
+
|
150
|
+
it "makes user-defined helpers (from app as well as slice) available in parts" do
|
151
|
+
post = OpenStruct.new(title: "Hello world")
|
152
|
+
output = Main::Slice["views.posts.show"].call(post: post).to_s
|
153
|
+
|
154
|
+
expect(output).to eq <<~HTML
|
155
|
+
<h1>Hello world! (slice helper)</h1>
|
156
|
+
<h1>Hello world! (app helper)</h1>
|
157
|
+
HTML
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
# rubocop:enable Style/OpenStructUse
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe "App view / Helpers / User-defined helpers / Scope helpers", :app_integration do
|
4
|
+
before do
|
5
|
+
with_directory(make_tmp_directory) do
|
6
|
+
write "config/app.rb", <<~RUBY
|
7
|
+
module TestApp
|
8
|
+
class App < Hanami::App
|
9
|
+
end
|
10
|
+
end
|
11
|
+
RUBY
|
12
|
+
|
13
|
+
write "app/view.rb", <<~RUBY
|
14
|
+
# auto_register: false
|
15
|
+
|
16
|
+
require "hanami/view"
|
17
|
+
|
18
|
+
module TestApp
|
19
|
+
class View < Hanami::View
|
20
|
+
config.layout = nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
RUBY
|
24
|
+
|
25
|
+
write "app/views/helpers.rb", <<~'RUBY'
|
26
|
+
# auto_register: false
|
27
|
+
|
28
|
+
module TestApp
|
29
|
+
module Views
|
30
|
+
module Helpers
|
31
|
+
def exclaim_from_app(str)
|
32
|
+
tag.h1("#{str}! (app helper)")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
RUBY
|
38
|
+
|
39
|
+
before_prepare if respond_to?(:before_prepare)
|
40
|
+
require "hanami/prepare"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "app view" do
|
45
|
+
def before_prepare
|
46
|
+
write "app/views/posts/show.rb", <<~RUBY
|
47
|
+
module TestApp
|
48
|
+
module Views
|
49
|
+
module Posts
|
50
|
+
class Show < TestApp::View
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
RUBY
|
56
|
+
|
57
|
+
write "app/templates/posts/show.html.erb", <<~ERB
|
58
|
+
<%= exclaim_from_app("Hello world") %>
|
59
|
+
ERB
|
60
|
+
end
|
61
|
+
|
62
|
+
it "makes user-defined helpers available in templates" do
|
63
|
+
output = TestApp::App["views.posts.show"].call.to_s.strip
|
64
|
+
expect(output).to eq "<h1>Hello world! (app helper)</h1>"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "slice view" do
|
69
|
+
def before_prepare
|
70
|
+
write "slices/main/view.rb", <<~RUBY
|
71
|
+
module Main
|
72
|
+
class View < TestApp::View
|
73
|
+
# FIXME: base slice views should override paths from the base app view
|
74
|
+
config.paths = [File.join(File.expand_path(__dir__), "templates")]
|
75
|
+
end
|
76
|
+
end
|
77
|
+
RUBY
|
78
|
+
|
79
|
+
write "slices/main/views/helpers.rb", <<~'RUBY'
|
80
|
+
# auto_register: false
|
81
|
+
|
82
|
+
module Main
|
83
|
+
module Views
|
84
|
+
module Helpers
|
85
|
+
def exclaim_from_slice(str)
|
86
|
+
tag.h1("#{str}! (slice helper)")
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
RUBY
|
92
|
+
|
93
|
+
write "slices/main/views/posts/show.rb", <<~RUBY
|
94
|
+
module Main
|
95
|
+
module Views
|
96
|
+
module Posts
|
97
|
+
class Show < Main::View
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
RUBY
|
103
|
+
|
104
|
+
write "slices/main/templates/posts/show.html.erb", <<~ERB
|
105
|
+
<%= exclaim_from_slice("Hello world") %>
|
106
|
+
<%= exclaim_from_app("Hello world") %>
|
107
|
+
ERB
|
108
|
+
end
|
109
|
+
|
110
|
+
it "makes user-defined helpers (from app as well as slice) available in templates" do
|
111
|
+
output = Main::Slice["views.posts.show"].call.to_s
|
112
|
+
|
113
|
+
expect(output).to eq <<~HTML
|
114
|
+
<h1>Hello world! (slice helper)</h1>
|
115
|
+
<h1>Hello world! (app helper)</h1>
|
116
|
+
HTML
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|