hanami 2.0.3 → 2.1.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +37 -2
  3. data/LICENSE.md +1 -1
  4. data/README.md +26 -10
  5. data/hanami.gemspec +2 -2
  6. data/lib/hanami/app.rb +5 -0
  7. data/lib/hanami/config/actions.rb +4 -11
  8. data/lib/hanami/config/assets.rb +84 -0
  9. data/lib/hanami/config/null_config.rb +3 -0
  10. data/lib/hanami/config/views.rb +0 -4
  11. data/lib/hanami/config.rb +71 -5
  12. data/lib/hanami/extensions/action/slice_configured_action.rb +15 -7
  13. data/lib/hanami/extensions/action.rb +8 -6
  14. data/lib/hanami/extensions/router/errors.rb +58 -0
  15. data/lib/hanami/extensions/view/context.rb +129 -60
  16. data/lib/hanami/extensions/view/part.rb +26 -0
  17. data/lib/hanami/extensions/view/scope.rb +26 -0
  18. data/lib/hanami/extensions/view/slice_configured_context.rb +0 -2
  19. data/lib/hanami/extensions/view/slice_configured_helpers.rb +44 -0
  20. data/lib/hanami/extensions/view/slice_configured_view.rb +106 -21
  21. data/lib/hanami/extensions/view/standard_helpers.rb +18 -0
  22. data/lib/hanami/extensions.rb +10 -3
  23. data/lib/hanami/helpers/assets_helper.rb +752 -0
  24. data/lib/hanami/helpers/form_helper/form_builder.rb +1391 -0
  25. data/lib/hanami/helpers/form_helper/values.rb +75 -0
  26. data/lib/hanami/helpers/form_helper.rb +213 -0
  27. data/lib/hanami/middleware/assets.rb +21 -0
  28. data/lib/hanami/middleware/public_errors_app.rb +75 -0
  29. data/lib/hanami/middleware/render_errors.rb +90 -0
  30. data/lib/hanami/providers/assets.rb +44 -0
  31. data/lib/hanami/rake_tasks.rb +19 -18
  32. data/lib/hanami/settings.rb +1 -1
  33. data/lib/hanami/slice.rb +48 -2
  34. data/lib/hanami/slice_configurable.rb +3 -2
  35. data/lib/hanami/version.rb +1 -1
  36. data/lib/hanami/web/rack_logger.rb +1 -1
  37. data/lib/hanami.rb +3 -3
  38. data/spec/integration/action/view_rendering/view_context_spec.rb +221 -0
  39. data/spec/integration/action/view_rendering_spec.rb +0 -18
  40. data/spec/integration/assets/assets_spec.rb +101 -0
  41. data/spec/integration/assets/serve_static_assets_spec.rb +152 -0
  42. data/spec/integration/logging/exception_logging_spec.rb +115 -0
  43. data/spec/integration/logging/notifications_spec.rb +68 -0
  44. data/spec/integration/logging/request_logging_spec.rb +128 -0
  45. data/spec/integration/rack_app/middleware_spec.rb +22 -22
  46. data/spec/integration/rack_app/rack_app_spec.rb +3 -220
  47. data/spec/integration/rake_tasks_spec.rb +107 -0
  48. data/spec/integration/view/config/default_context_spec.rb +149 -0
  49. data/spec/integration/view/{inflector_spec.rb → config/inflector_spec.rb} +1 -1
  50. data/spec/integration/view/config/part_class_spec.rb +147 -0
  51. data/spec/integration/view/config/part_namespace_spec.rb +103 -0
  52. data/spec/integration/view/config/paths_spec.rb +119 -0
  53. data/spec/integration/view/config/scope_class_spec.rb +147 -0
  54. data/spec/integration/view/config/scope_namespace_spec.rb +103 -0
  55. data/spec/integration/view/config/template_spec.rb +38 -0
  56. data/spec/integration/view/context/assets_spec.rb +3 -9
  57. data/spec/integration/view/context/request_spec.rb +3 -7
  58. data/spec/integration/view/helpers/form_helper_spec.rb +174 -0
  59. data/spec/integration/view/helpers/part_helpers_spec.rb +124 -0
  60. data/spec/integration/view/helpers/scope_helpers_spec.rb +84 -0
  61. data/spec/integration/view/helpers/user_defined_helpers/part_helpers_spec.rb +162 -0
  62. data/spec/integration/view/helpers/user_defined_helpers/scope_helpers_spec.rb +119 -0
  63. data/spec/integration/view/slice_configuration_spec.rb +9 -9
  64. data/spec/integration/web/render_detailed_errors_spec.rb +107 -0
  65. data/spec/integration/web/render_errors_spec.rb +242 -0
  66. data/spec/spec_helper.rb +1 -1
  67. data/spec/support/app_integration.rb +46 -2
  68. data/spec/support/matchers.rb +32 -0
  69. data/spec/unit/hanami/config/actions/content_security_policy_spec.rb +24 -36
  70. data/spec/unit/hanami/config/actions/csrf_protection_spec.rb +4 -3
  71. data/spec/unit/hanami/config/actions/default_values_spec.rb +3 -6
  72. data/spec/unit/hanami/config/render_detailed_errors_spec.rb +25 -0
  73. data/spec/unit/hanami/config/render_errors_spec.rb +25 -0
  74. data/spec/unit/hanami/config/views_spec.rb +0 -18
  75. data/spec/unit/hanami/env_spec.rb +11 -25
  76. data/spec/unit/hanami/extensions/view/context_spec.rb +59 -0
  77. data/spec/unit/hanami/helpers/assets_helper/asset_url_spec.rb +109 -0
  78. data/spec/unit/hanami/helpers/assets_helper/audio_tag_spec.rb +132 -0
  79. data/spec/unit/hanami/helpers/assets_helper/favicon_link_tag_spec.rb +91 -0
  80. data/spec/unit/hanami/helpers/assets_helper/image_tag_spec.rb +92 -0
  81. data/spec/unit/hanami/helpers/assets_helper/javascript_tag_spec.rb +143 -0
  82. data/spec/unit/hanami/helpers/assets_helper/stylesheet_link_tag_spec.rb +126 -0
  83. data/spec/unit/hanami/helpers/assets_helper/video_tag_spec.rb +132 -0
  84. data/spec/unit/hanami/helpers/form_helper_spec.rb +2826 -0
  85. data/spec/unit/hanami/router/errors/not_allowed_error_spec.rb +27 -0
  86. data/spec/unit/hanami/router/errors/not_found_error_spec.rb +22 -0
  87. data/spec/unit/hanami/slice_configurable_spec.rb +18 -0
  88. data/spec/unit/hanami/version_spec.rb +1 -1
  89. data/spec/unit/hanami/web/rack_logger_spec.rb +1 -1
  90. metadata +95 -35
  91. data/lib/hanami/assets/app_config.rb +0 -61
  92. data/lib/hanami/assets/config.rb +0 -53
  93. data/spec/integration/action/view_integration_spec.rb +0 -165
  94. data/spec/integration/view/part_namespace_spec.rb +0 -96
  95. data/spec/integration/view/path_spec.rb +0 -56
  96. data/spec/integration/view/template_spec.rb +0 -68
  97. data/spec/isolation/hanami/application/already_configured_spec.rb +0 -19
  98. data/spec/isolation/hanami/application/inherit_anonymous_class_spec.rb +0 -10
  99. data/spec/isolation/hanami/application/inherit_concrete_class_spec.rb +0 -14
  100. data/spec/isolation/hanami/application/not_configured_spec.rb +0 -9
  101. data/spec/isolation/hanami/application/routes/configured_spec.rb +0 -44
  102. data/spec/isolation/hanami/application/routes/not_configured_spec.rb +0 -16
  103. data/spec/isolation/hanami/boot/success_spec.rb +0 -50
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rack/test"
4
+
5
+ RSpec.describe "Logging / Notifications", :app_integration do
6
+ include Rack::Test::Methods
7
+
8
+ let(:app) { Hanami.app }
9
+
10
+ specify "Request logging continues even when notifications bus has already been used" do
11
+ dir = Dir.mktmpdir
12
+
13
+ with_tmp_directory(dir) do
14
+ write "config/app.rb", <<~RUBY
15
+ require "hanami"
16
+
17
+ module TestApp
18
+ class App < Hanami::App
19
+ config.actions.format :json
20
+ config.logger.options = {colorize: true}
21
+ config.logger.stream = config.root.join("test.log")
22
+ end
23
+ end
24
+ RUBY
25
+
26
+ write "config/routes.rb", <<~RUBY
27
+ module TestApp
28
+ class Routes < Hanami::Routes
29
+ post "/users", to: "users.create"
30
+ end
31
+ end
32
+ RUBY
33
+
34
+ write "app/actions/users/create.rb", <<~RUBY
35
+ module TestApp
36
+ module Actions
37
+ module Users
38
+ class Create < Hanami::Action
39
+ def handle(req, resp)
40
+ resp.body = req.params.to_h.keys
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ RUBY
47
+
48
+ require "hanami/prepare"
49
+
50
+ # Simulate any component interacting with the notifications bus such that it creates its
51
+ # internal bus with a duplicate copy of all currently registered events. This means that the
52
+ # class-level Dry::Monitor::Notification events implicitly registered by the
53
+ # Dry::Monitor::Rack::Middleware activated via the rack provider are ignored, unless our
54
+ # provider explicitly re-registers them on _instance_ of the notifications bus.
55
+ #
56
+ # See Hanami::Providers::Rack for more detail.
57
+ Hanami.app["notifications"].instrument(:sql)
58
+
59
+ logs = -> { Pathname(dir).join("test.log").realpath.read }
60
+
61
+ post "/users", JSON.generate(name: "jane", password: "secret"), {"CONTENT_TYPE" => "application/json"}
62
+ expect(logs.()).to match %r{POST 200 \d+(µs|ms) 127.0.0.1 /}
63
+ end
64
+ end
65
+ end
66
+
67
+
68
+
@@ -0,0 +1,128 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require "rack/test"
5
+ require "stringio"
6
+
7
+ RSpec.describe "Logging / Request logging", :app_integration do
8
+ include Rack::Test::Methods
9
+
10
+ let(:app) { Hanami.app }
11
+
12
+ let(:logger_stream) { StringIO.new }
13
+
14
+ def configure_logger
15
+ Hanami.app.config.logger.stream = logger_stream
16
+ end
17
+
18
+ def logs
19
+ @logs ||= (logger_stream.rewind and logger_stream.read)
20
+ end
21
+
22
+ before do
23
+ with_directory(make_tmp_directory) do
24
+ write "config/app.rb", <<~RUBY
25
+ module TestApp
26
+ class App < Hanami::App
27
+ end
28
+ end
29
+ RUBY
30
+
31
+ require "hanami/setup"
32
+ configure_logger
33
+
34
+ before_prepare if respond_to?(:before_prepare)
35
+ require "hanami/prepare"
36
+ end
37
+ end
38
+
39
+ describe "app router" do
40
+ def before_prepare
41
+ write "config/routes.rb", <<~RUBY
42
+ module TestApp
43
+ class Routes < Hanami::Routes
44
+ root to: ->(env) { [200, {}, ["OK"]] }
45
+ end
46
+ end
47
+ RUBY
48
+ end
49
+
50
+ it "logs the requests" do
51
+ get "/"
52
+
53
+ expect(logs.split("\n").length).to eq 1
54
+ expect(logs).to match %r{GET 200 \d+(µs|ms) 127.0.0.1 /}
55
+ end
56
+
57
+ context "production env" do
58
+ around do |example|
59
+ @prev_hanami_env = ENV["HANAMI_ENV"]
60
+ ENV["HANAMI_ENV"] = "production"
61
+ example.run
62
+ ensure
63
+ ENV["HANAMI_ENV"] = @prev_hanami_env
64
+ end
65
+
66
+ it "logs the requests as JSON" do
67
+ get "/"
68
+
69
+ expect(logs.split("\n").length).to eq 1
70
+
71
+ json = JSON.parse(logs, symbolize_names: true)
72
+ expect(json).to include(
73
+ verb: "GET",
74
+ path: "/",
75
+ ip: "127.0.0.1",
76
+ elapsed: Integer,
77
+ elapsed_unit: a_string_matching(/(µs|ms)/),
78
+ )
79
+ end
80
+ end
81
+ end
82
+
83
+ describe "slice router" do
84
+ let(:app) { Main::Slice.rack_app }
85
+
86
+ def before_prepare
87
+ write "slices/main/config/routes.rb", <<~RUBY
88
+ module Main
89
+ class Routes < Hanami::Routes
90
+ root to: ->(env) { [200, {}, ["OK"]] }
91
+ end
92
+ end
93
+ RUBY
94
+ end
95
+
96
+ it "logs the requests" do
97
+ get "/"
98
+
99
+ expect(logs.split("\n").length).to eq 1
100
+ expect(logs).to match %r{GET 200 \d+(µs|ms) 127.0.0.1 /}
101
+ end
102
+
103
+ context "production env" do
104
+ around do |example|
105
+ @prev_hanami_env = ENV["HANAMI_ENV"]
106
+ ENV["HANAMI_ENV"] = "production"
107
+ example.run
108
+ ensure
109
+ ENV["HANAMI_ENV"] = @prev_hanami_env
110
+ end
111
+
112
+ it "logs the requests as JSON" do
113
+ get "/"
114
+
115
+ expect(logs.split("\n").length).to eq 1
116
+
117
+ json = JSON.parse(logs, symbolize_names: true)
118
+ expect(json).to include(
119
+ verb: "GET",
120
+ path: "/",
121
+ ip: "127.0.0.1",
122
+ elapsed: Integer,
123
+ elapsed_unit: a_string_matching(/(µs|ms)/),
124
+ )
125
+ end
126
+ end
127
+ end
128
+ end
@@ -244,6 +244,7 @@ RSpec.describe "Hanami web app", :app_integration do
244
244
  module TestApp
245
245
  class App < Hanami::App
246
246
  config.logger.stream = File.new("/dev/null", "w")
247
+ config.render_errors = true
247
248
  end
248
249
  end
249
250
  RUBY
@@ -317,7 +318,6 @@ RSpec.describe "Hanami web app", :app_integration do
317
318
  get "/foo"
318
319
 
319
320
  expect(last_response.status).to eq 404
320
- expect(last_response.body).to eq "Not Found"
321
321
  expect(last_response.headers).to_not have_key("X-Auth-User-ID")
322
322
  end
323
323
 
@@ -330,12 +330,11 @@ RSpec.describe "Hanami web app", :app_integration do
330
330
  expect(last_response.headers).to have_key("X-Auth-User-ID")
331
331
  end
332
332
 
333
- it "uses Rack middleware for not found paths" do
333
+ it "does not uses the Rack middleware for not found paths" do
334
334
  get "/admin/users"
335
335
 
336
- expect(last_response.status).to be(404)
337
- expect(last_response.body).to eq "Not Found"
338
- expect(last_response.headers).to have_key("X-Auth-User-ID")
336
+ expect(last_response.status).to eq 404
337
+ expect(last_response.headers).not_to have_key("X-Auth-User-ID")
339
338
  end
340
339
  end
341
340
  end
@@ -350,6 +349,7 @@ RSpec.describe "Hanami web app", :app_integration do
350
349
  module TestApp
351
350
  class App < Hanami::App
352
351
  config.logger.stream = File.new("/dev/null", "w")
352
+ config.render_errors = true
353
353
  end
354
354
  end
355
355
  RUBY
@@ -597,15 +597,15 @@ RSpec.describe "Hanami web app", :app_integration do
597
597
  expect(last_response.headers).to_not have_key("X-API-Version")
598
598
  end
599
599
 
600
- it "uses Rack middleware for other paths" do
601
- get "/foo"
600
+ it "does not use Rack middleware for other paths" do
601
+ get "/__not_found__"
602
602
 
603
- expect(last_response.status).to be(404)
604
- expect(last_response.headers["X-Identifier-Root"]).to eq("true")
605
- expect(last_response.headers).to have_key("X-Elapsed")
606
- expect(last_response.headers).to_not have_key("X-Auth-User-ID")
607
- expect(last_response.headers).to_not have_key("X-API-Rate-Limit-Quota")
608
- expect(last_response.headers).to_not have_key("X-API-Version")
603
+ expect(last_response.status).to eq 404
604
+ expect(last_response.headers).not_to have_key("X-Identifier-Root")
605
+ expect(last_response.headers).not_to have_key("X-Elapsed")
606
+ expect(last_response.headers).not_to have_key("X-Auth-User-ID")
607
+ expect(last_response.headers).not_to have_key("X-API-Rate-Limit-Quota")
608
+ expect(last_response.headers).not_to have_key("X-API-Version")
609
609
  end
610
610
 
611
611
  context "scoped" do
@@ -621,15 +621,15 @@ RSpec.describe "Hanami web app", :app_integration do
621
621
  end
622
622
 
623
623
  it "uses Rack middleware for other paths" do
624
- get "/admin/users"
625
-
626
- expect(last_response.status).to be(404)
627
- expect(last_response.headers["X-Identifier-Admin"]).to eq("true")
628
- expect(last_response.headers).to have_key("X-Elapsed")
629
- expect(last_response.headers).to have_key("X-Elapsed")
630
- expect(last_response.headers).to have_key("X-Auth-User-ID")
631
- expect(last_response.headers).to_not have_key("X-API-Rate-Limit-Quota")
632
- expect(last_response.headers).to_not have_key("X-API-Version")
624
+ get "/admin/__not_found__"
625
+
626
+ expect(last_response.status).to eq 404
627
+ expect(last_response.headers).not_to have_key("X-Identifier-Admin")
628
+ expect(last_response.headers).not_to have_key("X-Elapsed")
629
+ expect(last_response.headers).not_to have_key("X-Elapsed")
630
+ expect(last_response.headers).not_to have_key("X-Auth-User-ID")
631
+ expect(last_response.headers).not_to have_key("X-API-Rate-Limit-Quota")
632
+ expect(last_response.headers).not_to have_key("X-API-Version")
633
633
  end
634
634
 
635
635
  # See: https://github.com/hanami/api/issues/8
@@ -33,226 +33,6 @@ RSpec.describe "Hanami web app", :app_integration do
33
33
  end
34
34
  end
35
35
 
36
- specify "Has rack monitor preconfigured with default request logging" do
37
- dir = Dir.mktmpdir
38
-
39
- with_tmp_directory(dir) do
40
- write "config/app.rb", <<~RUBY
41
- require "hanami"
42
-
43
- module TestApp
44
- class App < Hanami::App
45
- config.actions.format :json
46
- config.logger.options = {colorize: true}
47
- config.logger.stream = config.root.join("test.log")
48
- end
49
- end
50
- RUBY
51
-
52
- write "app/actions/users/index.rb", <<~RUBY
53
- module TestApp
54
- module Actions
55
- module Users
56
- class Index < Hanami::Action
57
- def handle(req, _resp)
58
- raise StandardError, "OH NOEZ"
59
- end
60
- end
61
- end
62
- end
63
- end
64
- RUBY
65
-
66
- write "app/actions/users/create.rb", <<~RUBY
67
- module TestApp
68
- module Actions
69
- module Users
70
- class Create < Hanami::Action
71
- def handle(req, resp)
72
- resp.body = req.params.to_h.keys
73
- end
74
- end
75
- end
76
- end
77
- end
78
- RUBY
79
-
80
- write "config/routes.rb", <<~RUBY
81
- module TestApp
82
- class Routes < Hanami::Routes
83
- root to: ->(env) { [200, {}, ["OK"]] }
84
- get "/users", to: "users.index"
85
- post "/users", to: "users.create"
86
- end
87
- end
88
- RUBY
89
-
90
- require "hanami/prepare"
91
-
92
- expect(Hanami.app["rack.monitor"]).to be_instance_of(Dry::Monitor::Rack::Middleware)
93
-
94
- get "/"
95
-
96
- logs = -> { Pathname(dir).join("test.log").realpath.read }
97
-
98
- expect(logs.()).to match %r{GET 200 \d+(µs|ms) 127.0.0.1 /}
99
-
100
- post "/users", JSON.generate(name: "jane", password: "secret"), {"CONTENT_TYPE" => "application/json"}
101
-
102
- expect(logs.()).to match %r{POST 200 \d+(µs|ms) 127.0.0.1 /}
103
-
104
- begin
105
- get "/users"
106
- rescue => e # rubocop:disable Style/RescueStandardError
107
- raise unless e.to_s == "OH NOEZ"
108
- end
109
-
110
- err_log = logs.()
111
-
112
- expect(err_log).to include("OH NOEZ")
113
- expect(err_log).to include("app/actions/users/index.rb:6:in `handle'")
114
- end
115
- end
116
-
117
- specify "Logging via the rack monitor even when notifications bus has already been used" do
118
- dir = Dir.mktmpdir
119
-
120
- with_tmp_directory(dir) do
121
- write "config/app.rb", <<~RUBY
122
- require "hanami"
123
-
124
- module TestApp
125
- class App < Hanami::App
126
- config.actions.format :json
127
- config.logger.options = {colorize: true}
128
- config.logger.stream = config.root.join("test.log")
129
- end
130
- end
131
- RUBY
132
-
133
- write "config/routes.rb", <<~RUBY
134
- module TestApp
135
- class Routes < Hanami::Routes
136
- post "/users", to: "users.create"
137
- end
138
- end
139
- RUBY
140
-
141
- write "app/actions/users/create.rb", <<~RUBY
142
- module TestApp
143
- module Actions
144
- module Users
145
- class Create < Hanami::Action
146
- def handle(req, resp)
147
- resp.body = req.params.to_h.keys
148
- end
149
- end
150
- end
151
- end
152
- end
153
- RUBY
154
-
155
- require "hanami/prepare"
156
-
157
- # Simulate any component interacting with the notifications bus such that it creates its
158
- # internal bus with a duplicate copy of all currently registered events. This means that the
159
- # class-level Dry::Monitor::Notification events implicitly registered by the
160
- # Dry::Monitor::Rack::Middleware activated via the rack provider are ignored, unless our
161
- # provider explicitly re-registers them on _instance_ of the notifications bus.
162
- #
163
- # See Hanami::Providers::Rack for more detail.
164
- Hanami.app["notifications"].instrument(:sql)
165
-
166
- logs = -> { Pathname(dir).join("test.log").realpath.read }
167
-
168
- post "/users", JSON.generate(name: "jane", password: "secret"), {"CONTENT_TYPE" => "application/json"}
169
- expect(logs.()).to match %r{POST 200 \d+(µs|ms) 127.0.0.1 /}
170
- end
171
- end
172
-
173
- describe "Request logging when using slice router" do
174
- let(:app) { Main::Slice.rack_app }
175
-
176
- specify "Has rack monitor preconfigured with default request logging (when used via a slice)" do
177
- dir = Dir.mktmpdir
178
-
179
- with_tmp_directory(dir) do
180
- write "config/app.rb", <<~RUBY
181
- require "hanami"
182
-
183
- module TestApp
184
- class App < Hanami::App
185
- config.logger.stream = config.root.join("test.log")
186
- end
187
- end
188
- RUBY
189
-
190
- write "slices/main/config/routes.rb", <<~RUBY
191
- module Main
192
- class Routes < Hanami::Routes
193
- root to: ->(env) { [200, {}, ["OK"]] }
194
- end
195
- end
196
- RUBY
197
-
198
- require "hanami/prepare"
199
-
200
- get "/"
201
-
202
- logs = -> { Pathname(dir).join("test.log").realpath.read }
203
-
204
- expect(logs.()).to match %r{GET 200 \d+(µs|ms) 127.0.0.1 /}
205
- end
206
- end
207
- end
208
-
209
- describe "Request logging on production" do
210
- let(:app) { Main::Slice.rack_app }
211
-
212
- around do |example|
213
- ENV["HANAMI_ENV"] = "production"
214
- example.run
215
- ensure
216
- ENV["HANAMI_ENV"] = "test"
217
- end
218
-
219
- specify "Has rack monitor preconfigured with default request logging (when used via a slice)" do
220
- dir = Dir.mktmpdir
221
-
222
- with_tmp_directory(dir) do
223
- write "config/app.rb", <<~RUBY
224
- require "hanami"
225
-
226
- module TestApp
227
- class App < Hanami::App
228
- config.logger.stream = config.root.join("test.log")
229
- end
230
- end
231
- RUBY
232
-
233
- write "slices/main/config/routes.rb", <<~RUBY
234
- module Main
235
- class Routes < Hanami::Routes
236
- root to: ->(env) { [200, {}, ["OK"]] }
237
- end
238
- end
239
- RUBY
240
-
241
- require "hanami/boot"
242
-
243
- get "/"
244
-
245
- logs = -> { Pathname(dir).join("test.log").realpath.read }
246
-
247
- log_content = logs.()
248
-
249
- expect(log_content).to match(%r["verb":"GET"])
250
- expect(log_content).to match(%r["path":"/"])
251
- expect(log_content).to match(%r[elapsed":\d+,"elapsed_unit":"µs"])
252
- end
253
- end
254
- end
255
-
256
36
  specify "Routing to actions based on their container identifiers" do
257
37
  with_tmp_directory(Dir.mktmpdir) do
258
38
  write "config/app.rb", <<~RUBY
@@ -569,6 +349,7 @@ RSpec.describe "Hanami web app", :app_integration do
569
349
 
570
350
  module TestApp
571
351
  class App < Hanami::App
352
+ config.render_detailed_errors = false
572
353
  end
573
354
  end
574
355
  RUBY
@@ -600,6 +381,8 @@ RSpec.describe "Hanami web app", :app_integration do
600
381
 
601
382
  module TestApp
602
383
  class App < Hanami::App
384
+ config.render_detailed_errors = false
385
+
603
386
  register_slice :admin
604
387
  end
605
388
  end
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rake"
4
+ require "hanami/cli/bundler"
5
+
6
+ RSpec.describe "Rake tasks", :app_integration do
7
+ describe "assets:precompile" do
8
+ before do
9
+ allow(Hanami).to receive(:bundled?)
10
+ allow(Hanami).to receive(:bundled?).with("hanami-assets").and_return(hanami_assets_bundled)
11
+ end
12
+
13
+ context "when hanami-assets is bundled" do
14
+ let(:hanami_assets_bundled) { true }
15
+
16
+ xit "compiles assets" do
17
+ with_tmp_directory(Dir.mktmpdir) do
18
+ write "config/app.rb", <<~'RUBY'
19
+ require "hanami"
20
+
21
+ module TestApp
22
+ class App < Hanami::App
23
+ end
24
+ end
25
+ RUBY
26
+
27
+ write "Rakefile", <<~RUBY
28
+ # frozen_string_literal: true
29
+
30
+ require "hanami/rake_tasks"
31
+ RUBY
32
+
33
+ write "app/assets/js/app.js", <<~JS
34
+ console.log("Hello from index.js");
35
+ JS
36
+
37
+ before_prepare if respond_to?(:before_prepare)
38
+ require "hanami/prepare"
39
+
40
+ expect_any_instance_of(Hanami::CLI::Bundler).to receive(:hanami_exec).with("assets compile").and_return(true)
41
+
42
+ Rake::Task["assets:precompile"].invoke
43
+ end
44
+ end
45
+
46
+ it "doesn't list the task" do
47
+ with_tmp_directory(Dir.mktmpdir) do
48
+ write "config/app.rb", <<~'RUBY'
49
+ require "hanami"
50
+
51
+ module TestApp
52
+ class App < Hanami::App
53
+ end
54
+ end
55
+ RUBY
56
+
57
+ write "Rakefile", <<~RUBY
58
+ # frozen_string_literal: true
59
+
60
+ require "hanami/rake_tasks"
61
+ RUBY
62
+
63
+ before_prepare if respond_to?(:before_prepare)
64
+ require "hanami/prepare"
65
+
66
+ output = `bundle exec rake -T`
67
+ expect(output).to_not include("assets:precompile")
68
+ end
69
+ end
70
+ end
71
+
72
+ context "when hanami-assets is not bundled" do
73
+ let(:hanami_assets_bundled) { false }
74
+
75
+ it "raises error" do
76
+ with_tmp_directory(Dir.mktmpdir) do
77
+ write "config/app.rb", <<~'RUBY'
78
+ require "hanami"
79
+
80
+ module TestApp
81
+ class App < Hanami::App
82
+ end
83
+ end
84
+ RUBY
85
+
86
+ write "Rakefile", <<~RUBY
87
+ # frozen_string_literal: true
88
+
89
+ require "hanami/rake_tasks"
90
+ RUBY
91
+
92
+ write "app/assets/js/app.js", <<~JS
93
+ console.log("Hello from index.js");
94
+ JS
95
+
96
+ before_prepare if respond_to?(:before_prepare)
97
+ require "hanami/prepare"
98
+
99
+ expect { Rake::Task["assets:precompile"].invoke }.to raise_error do |exception|
100
+ expect(exception).to be_a(RuntimeError)
101
+ expect(exception.message).to match(/Don't know how to build task 'assets:precompile'/)
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end