hanami 2.0.3 → 2.1.0.beta2
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 +37 -2
- data/LICENSE.md +1 -1
- data/README.md +26 -10
- data/hanami.gemspec +2 -2
- data/lib/hanami/app.rb +5 -0
- data/lib/hanami/config/actions.rb +4 -11
- data/lib/hanami/config/assets.rb +84 -0
- data/lib/hanami/config/null_config.rb +3 -0
- data/lib/hanami/config/views.rb +0 -4
- data/lib/hanami/config.rb +71 -5
- data/lib/hanami/extensions/action/slice_configured_action.rb +15 -7
- data/lib/hanami/extensions/action.rb +8 -6
- 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 +18 -0
- data/lib/hanami/extensions.rb +10 -3
- data/lib/hanami/helpers/assets_helper.rb +752 -0
- 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/assets.rb +21 -0
- data/lib/hanami/middleware/public_errors_app.rb +75 -0
- data/lib/hanami/middleware/render_errors.rb +90 -0
- data/lib/hanami/providers/assets.rb +44 -0
- data/lib/hanami/rake_tasks.rb +19 -18
- data/lib/hanami/settings.rb +1 -1
- data/lib/hanami/slice.rb +48 -2
- data/lib/hanami/slice_configurable.rb +3 -2
- data/lib/hanami/version.rb +1 -1
- data/lib/hanami/web/rack_logger.rb +1 -1
- data/lib/hanami.rb +3 -3
- 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/assets/assets_spec.rb +101 -0
- data/spec/integration/assets/serve_static_assets_spec.rb +152 -0
- data/spec/integration/logging/exception_logging_spec.rb +115 -0
- data/spec/integration/logging/notifications_spec.rb +68 -0
- data/spec/integration/logging/request_logging_spec.rb +128 -0
- data/spec/integration/rack_app/middleware_spec.rb +22 -22
- data/spec/integration/rack_app/rack_app_spec.rb +3 -220
- data/spec/integration/rake_tasks_spec.rb +107 -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/assets_spec.rb +3 -9
- 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 +107 -0
- data/spec/integration/web/render_errors_spec.rb +242 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/support/app_integration.rb +46 -2
- data/spec/support/matchers.rb +32 -0
- data/spec/unit/hanami/config/actions/content_security_policy_spec.rb +24 -36
- data/spec/unit/hanami/config/actions/csrf_protection_spec.rb +4 -3
- data/spec/unit/hanami/config/actions/default_values_spec.rb +3 -6
- 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/env_spec.rb +11 -25
- data/spec/unit/hanami/extensions/view/context_spec.rb +59 -0
- data/spec/unit/hanami/helpers/assets_helper/asset_url_spec.rb +109 -0
- data/spec/unit/hanami/helpers/assets_helper/audio_tag_spec.rb +132 -0
- data/spec/unit/hanami/helpers/assets_helper/favicon_link_tag_spec.rb +91 -0
- data/spec/unit/hanami/helpers/assets_helper/image_tag_spec.rb +92 -0
- data/spec/unit/hanami/helpers/assets_helper/javascript_tag_spec.rb +143 -0
- data/spec/unit/hanami/helpers/assets_helper/stylesheet_link_tag_spec.rb +126 -0
- data/spec/unit/hanami/helpers/assets_helper/video_tag_spec.rb +132 -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 +95 -35
- data/lib/hanami/assets/app_config.rb +0 -61
- data/lib/hanami/assets/config.rb +0 -53
- 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,103 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "hanami"
|
|
4
|
+
|
|
5
|
+
RSpec.describe "App view / Config / Scope namespace", :app_integration do
|
|
6
|
+
before do
|
|
7
|
+
with_directory(make_tmp_directory) do
|
|
8
|
+
write "config/app.rb", <<~RUBY
|
|
9
|
+
module TestApp
|
|
10
|
+
class App < Hanami::App
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
RUBY
|
|
14
|
+
|
|
15
|
+
write "app/view.rb", <<~RUBY
|
|
16
|
+
# auto_register: false
|
|
17
|
+
|
|
18
|
+
require "hanami/view"
|
|
19
|
+
|
|
20
|
+
module TestApp
|
|
21
|
+
class View < Hanami::View
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
RUBY
|
|
25
|
+
|
|
26
|
+
before_prepare if respond_to?(:before_prepare)
|
|
27
|
+
require "hanami/prepare"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
subject(:scope_namespace) { view_class.config.scope_namespace }
|
|
32
|
+
|
|
33
|
+
describe "app view" do
|
|
34
|
+
let(:view_class) { TestApp::View }
|
|
35
|
+
|
|
36
|
+
describe "no scope namespace defined" do
|
|
37
|
+
it "is nil" do
|
|
38
|
+
expect(scope_namespace).to be nil
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
describe "scope namespace defined" do
|
|
43
|
+
def before_prepare
|
|
44
|
+
write "app/views/scopes/player.rb", <<~RUBY
|
|
45
|
+
module TestApp
|
|
46
|
+
module Views
|
|
47
|
+
module Scopes
|
|
48
|
+
class Player < Hanami::View::Scope
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
RUBY
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "is the Views::Scopes namespace within the app" do
|
|
57
|
+
expect(scope_namespace).to eq TestApp::Views::Scopes
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
describe "slice view" do
|
|
63
|
+
def before_prepare
|
|
64
|
+
write "slices/main/view.rb", <<~RUBY
|
|
65
|
+
# auto_register: false
|
|
66
|
+
|
|
67
|
+
module Main
|
|
68
|
+
class View < TestApp::View
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
RUBY
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
let(:view_class) { Main::View }
|
|
75
|
+
|
|
76
|
+
describe "no scope namespace defined" do
|
|
77
|
+
it "is nil" do
|
|
78
|
+
expect(scope_namespace).to be nil
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
describe "scope namespace defined" do
|
|
83
|
+
def before_prepare
|
|
84
|
+
super
|
|
85
|
+
|
|
86
|
+
write "slices/main/views/scopes/player.rb", <<~RUBY
|
|
87
|
+
module Main
|
|
88
|
+
module Views
|
|
89
|
+
module Scopes
|
|
90
|
+
class Player < Hanami::View::Scope
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
RUBY
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "is the Views::Scopes namespace within the slice" do
|
|
99
|
+
expect(scope_namespace).to eq Main::Views::Scopes
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "hanami"
|
|
4
|
+
|
|
5
|
+
RSpec.describe "App view / Config / Template", :app_integration do
|
|
6
|
+
before do
|
|
7
|
+
module TestApp
|
|
8
|
+
class App < Hanami::App
|
|
9
|
+
config.root = "/test_app"
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
Hanami.app.instance_eval(&app_hook) if respond_to?(:app_hook)
|
|
14
|
+
Hanami.app.register_slice :main
|
|
15
|
+
Hanami.app.prepare
|
|
16
|
+
|
|
17
|
+
module TestApp
|
|
18
|
+
class View < Hanami::View
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
module TestApp
|
|
23
|
+
module Views
|
|
24
|
+
module Article
|
|
25
|
+
class Index < TestApp::View
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
subject(:template) { view_class.config.template }
|
|
33
|
+
let(:view_class) { TestApp::Views::Article::Index }
|
|
34
|
+
|
|
35
|
+
it "configures the tempalte to match the class name" do
|
|
36
|
+
expect(template).to eq "article/index"
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -24,21 +24,15 @@ RSpec.describe "App view / Context / Assets", :app_integration do
|
|
|
24
24
|
|
|
25
25
|
describe "#assets" do
|
|
26
26
|
context "without assets provider" do
|
|
27
|
-
|
|
27
|
+
xit "raises error" do
|
|
28
|
+
allow(Hanami).to receive(:bundled?).with("hanami-assets").and_return(false)
|
|
29
|
+
|
|
28
30
|
expect { context.assets }
|
|
29
31
|
.to raise_error(Hanami::ComponentLoadError, /hanami-assets/)
|
|
30
32
|
end
|
|
31
33
|
end
|
|
32
34
|
|
|
33
35
|
context "with assets provider" do
|
|
34
|
-
before do
|
|
35
|
-
Hanami.app.register_provider(:assets) do
|
|
36
|
-
start do
|
|
37
|
-
register "assets", Object.new
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
|
|
42
36
|
it "is the app assets by default" do
|
|
43
37
|
expect(context.assets).to be TestApp::App[:assets]
|
|
44
38
|
end
|
|
@@ -20,14 +20,10 @@ RSpec.describe "App view / Context / Request", :app_integration do
|
|
|
20
20
|
let(:context_class) { TestApp::Views::Context }
|
|
21
21
|
|
|
22
22
|
subject(:context) {
|
|
23
|
-
context_class.new(
|
|
24
|
-
request: request,
|
|
25
|
-
response: response,
|
|
26
|
-
)
|
|
23
|
+
context_class.new(request: request)
|
|
27
24
|
}
|
|
28
25
|
|
|
29
26
|
let(:request) { double(:request) }
|
|
30
|
-
let(:response) { double(:response) }
|
|
31
27
|
|
|
32
28
|
describe "#request" do
|
|
33
29
|
it "is the provided request" do
|
|
@@ -51,10 +47,10 @@ RSpec.describe "App view / Context / Request", :app_integration do
|
|
|
51
47
|
let(:flash) { double(:flash) }
|
|
52
48
|
|
|
53
49
|
before do
|
|
54
|
-
allow(
|
|
50
|
+
allow(request).to receive(:flash) { flash }
|
|
55
51
|
end
|
|
56
52
|
|
|
57
|
-
it "is the
|
|
53
|
+
it "is the request's flash" do
|
|
58
54
|
expect(context.flash).to be flash
|
|
59
55
|
end
|
|
60
56
|
end
|
|
@@ -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
|