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.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +31 -0
  3. data/LICENSE.md +1 -1
  4. data/README.md +25 -9
  5. data/hanami.gemspec +2 -2
  6. data/lib/hanami/config/actions.rb +0 -4
  7. data/lib/hanami/config/logger.rb +1 -1
  8. data/lib/hanami/config/views.rb +0 -4
  9. data/lib/hanami/config.rb +54 -0
  10. data/lib/hanami/extensions/action/slice_configured_action.rb +15 -7
  11. data/lib/hanami/extensions/action.rb +4 -4
  12. data/lib/hanami/extensions/router/errors.rb +58 -0
  13. data/lib/hanami/extensions/view/context.rb +129 -60
  14. data/lib/hanami/extensions/view/part.rb +26 -0
  15. data/lib/hanami/extensions/view/scope.rb +26 -0
  16. data/lib/hanami/extensions/view/slice_configured_context.rb +0 -2
  17. data/lib/hanami/extensions/view/slice_configured_helpers.rb +44 -0
  18. data/lib/hanami/extensions/view/slice_configured_view.rb +106 -21
  19. data/lib/hanami/extensions/view/standard_helpers.rb +14 -0
  20. data/lib/hanami/extensions.rb +10 -3
  21. data/lib/hanami/helpers/form_helper/form_builder.rb +1391 -0
  22. data/lib/hanami/helpers/form_helper/values.rb +75 -0
  23. data/lib/hanami/helpers/form_helper.rb +213 -0
  24. data/lib/hanami/middleware/public_errors_app.rb +75 -0
  25. data/lib/hanami/middleware/render_errors.rb +93 -0
  26. data/lib/hanami/slice.rb +28 -2
  27. data/lib/hanami/slice_configurable.rb +3 -2
  28. data/lib/hanami/version.rb +1 -1
  29. data/lib/hanami/web/rack_logger.rb +8 -20
  30. data/lib/hanami.rb +1 -1
  31. data/spec/integration/action/view_rendering/view_context_spec.rb +221 -0
  32. data/spec/integration/action/view_rendering_spec.rb +0 -18
  33. data/spec/integration/rack_app/middleware_spec.rb +23 -23
  34. data/spec/integration/rack_app/rack_app_spec.rb +5 -1
  35. data/spec/integration/slices/slice_registrations_spec.rb +80 -0
  36. data/spec/integration/view/config/default_context_spec.rb +149 -0
  37. data/spec/integration/view/{inflector_spec.rb → config/inflector_spec.rb} +1 -1
  38. data/spec/integration/view/config/part_class_spec.rb +147 -0
  39. data/spec/integration/view/config/part_namespace_spec.rb +103 -0
  40. data/spec/integration/view/config/paths_spec.rb +119 -0
  41. data/spec/integration/view/config/scope_class_spec.rb +147 -0
  42. data/spec/integration/view/config/scope_namespace_spec.rb +103 -0
  43. data/spec/integration/view/config/template_spec.rb +38 -0
  44. data/spec/integration/view/context/request_spec.rb +3 -7
  45. data/spec/integration/view/helpers/form_helper_spec.rb +174 -0
  46. data/spec/integration/view/helpers/part_helpers_spec.rb +124 -0
  47. data/spec/integration/view/helpers/scope_helpers_spec.rb +84 -0
  48. data/spec/integration/view/helpers/user_defined_helpers/part_helpers_spec.rb +162 -0
  49. data/spec/integration/view/helpers/user_defined_helpers/scope_helpers_spec.rb +119 -0
  50. data/spec/integration/view/slice_configuration_spec.rb +9 -9
  51. data/spec/integration/web/render_detailed_errors_spec.rb +90 -0
  52. data/spec/integration/web/render_errors_spec.rb +240 -0
  53. data/spec/spec_helper.rb +1 -1
  54. data/spec/support/matchers.rb +32 -0
  55. data/spec/unit/hanami/config/actions/default_values_spec.rb +0 -4
  56. data/spec/unit/hanami/config/logger_spec.rb +9 -0
  57. data/spec/unit/hanami/config/render_detailed_errors_spec.rb +25 -0
  58. data/spec/unit/hanami/config/render_errors_spec.rb +25 -0
  59. data/spec/unit/hanami/config/views_spec.rb +0 -18
  60. data/spec/unit/hanami/extensions/view/context_spec.rb +59 -0
  61. data/spec/unit/hanami/helpers/form_helper_spec.rb +2826 -0
  62. data/spec/unit/hanami/router/errors/not_allowed_error_spec.rb +27 -0
  63. data/spec/unit/hanami/router/errors/not_found_error_spec.rb +22 -0
  64. data/spec/unit/hanami/slice_configurable_spec.rb +18 -0
  65. data/spec/unit/hanami/version_spec.rb +1 -1
  66. data/spec/unit/hanami/web/rack_logger_spec.rb +1 -1
  67. metadata +67 -33
  68. data/spec/integration/action/view_integration_spec.rb +0 -165
  69. data/spec/integration/view/part_namespace_spec.rb +0 -96
  70. data/spec/integration/view/path_spec.rb +0 -56
  71. data/spec/integration/view/template_spec.rb +0 -68
  72. data/spec/isolation/hanami/application/already_configured_spec.rb +0 -19
  73. data/spec/isolation/hanami/application/inherit_anonymous_class_spec.rb +0 -10
  74. data/spec/isolation/hanami/application/inherit_concrete_class_spec.rb +0 -14
  75. data/spec/isolation/hanami/application/not_configured_spec.rb +0 -9
  76. data/spec/isolation/hanami/application/routes/configured_spec.rb +0 -44
  77. data/spec/isolation/hanami/application/routes/not_configured_spec.rb +0 -16
  78. data/spec/isolation/hanami/boot/success_spec.rb +0 -50
@@ -3,7 +3,7 @@
3
3
  RSpec.describe "App view / Slice configuration", :app_integration do
4
4
  before do
5
5
  with_directory(@dir = make_tmp_directory) do
6
- write "config/app.rb", <<~'RUBY'
6
+ write "config/app.rb", <<~RUBY
7
7
  require "hanami"
8
8
 
9
9
  module TestApp
@@ -12,7 +12,7 @@ RSpec.describe "App view / Slice configuration", :app_integration do
12
12
  end
13
13
  RUBY
14
14
 
15
- write "app/view.rb", <<~'RUBY'
15
+ write "app/view.rb", <<~RUBY
16
16
  require "hanami/view"
17
17
 
18
18
  module TestApp
@@ -60,7 +60,7 @@ RSpec.describe "App view / Slice configuration", :app_integration do
60
60
  describe "subclass in app" do
61
61
  before do
62
62
  with_directory(@dir) do
63
- write "app/views/articles/index.rb", <<~'RUBY'
63
+ write "app/views/articles/index.rb", <<~RUBY
64
64
  module TestApp
65
65
  module Views
66
66
  module Articles
@@ -100,7 +100,7 @@ RSpec.describe "App view / Slice configuration", :app_integration do
100
100
  describe "subclass in slice" do
101
101
  before do
102
102
  with_directory(@dir) do
103
- write "slices/admin/views/articles/index.rb", <<~'RUBY'
103
+ write "slices/admin/views/articles/index.rb", <<~RUBY
104
104
  module Admin
105
105
  module Views
106
106
  module Articles
@@ -141,7 +141,7 @@ RSpec.describe "App view / Slice configuration", :app_integration do
141
141
  describe "inheriting from a slice-level base class, in turn inheriting from an app-level base class" do
142
142
  before do
143
143
  with_directory(@dir) do
144
- write "slices/admin/view.rb", <<~'RUBY'
144
+ write "slices/admin/view.rb", <<~RUBY
145
145
  module Admin
146
146
  class View < TestApp::View
147
147
  end
@@ -177,7 +177,7 @@ RSpec.describe "App view / Slice configuration", :app_integration do
177
177
  context "slice views config present" do
178
178
  before do
179
179
  with_directory(@dir) do
180
- write "config/slices/admin.rb", <<~'RUBY'
180
+ write "config/slices/admin.rb", <<~RUBY
181
181
  module Admin
182
182
  class Slice < Hanami::Slice
183
183
  config.views.layout = "slice_layout"
@@ -215,7 +215,7 @@ RSpec.describe "App view / Slice configuration", :app_integration do
215
215
  describe "subclass in slice" do
216
216
  before do
217
217
  with_directory(@dir) do
218
- write "slices/admin/views/articles/index.rb", <<~'RUBY'
218
+ write "slices/admin/views/articles/index.rb", <<~RUBY
219
219
  module Admin
220
220
  module Views
221
221
  module Articles
@@ -245,7 +245,7 @@ RSpec.describe "App view / Slice configuration", :app_integration do
245
245
 
246
246
  it "applies views config from the slice" do
247
247
  with_directory(@dir) do
248
- write "config/slices/admin.rb", <<~'RUBY'
248
+ write "config/slices/admin.rb", <<~RUBY
249
249
  module Admin
250
250
  class Slice < Hanami::Slice
251
251
  config.views.layout = "slice_layout"
@@ -269,7 +269,7 @@ RSpec.describe "App view / Slice configuration", :app_integration do
269
269
 
270
270
  it "prefers config from the slice base class over views config from the slice" do
271
271
  with_directory(@dir) do
272
- write "config/slices/admin.rb", <<~'RUBY'
272
+ write "config/slices/admin.rb", <<~RUBY
273
273
  module Admin
274
274
  class Slice < Hanami::Slice
275
275
  config.views.layout = "slice_layout"
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require "rack/test"
5
+
6
+ RSpec.describe "Web / Rendering detailed errors", :app_integration do
7
+ include Rack::Test::Methods
8
+
9
+ let(:app) { Hanami.app }
10
+
11
+ before do
12
+ with_directory(@dir = make_tmp_directory) do
13
+ write "config/app.rb", <<~RUBY
14
+ require "hanami"
15
+
16
+ module TestApp
17
+ class App < Hanami::App
18
+ config.logger.stream = File.new("/dev/null", "w")
19
+ config.render_detailed_errors = true
20
+ end
21
+ end
22
+ RUBY
23
+
24
+ write "config/routes.rb", <<~RUBY
25
+ module TestApp
26
+ class Routes < Hanami::Routes
27
+ get "error", to: "error"
28
+ end
29
+ end
30
+ RUBY
31
+
32
+ write "app/actions/error.rb", <<~RUBY
33
+ module TestApp
34
+ module Actions
35
+ class Error < Hanami::Action
36
+ def handle(*)
37
+ raise "oops"
38
+ end
39
+ end
40
+ end
41
+ end
42
+ RUBY
43
+
44
+ before_prepare if respond_to?(:before_prepare)
45
+ require "hanami/prepare"
46
+ end
47
+ end
48
+
49
+ describe "HTML request" do
50
+ it "renders a detailed HTML error page" do
51
+ get "/error", {}, "HTTP_ACCEPT" => "text/html"
52
+
53
+ expect(last_response.status).to eq 500
54
+
55
+ html = Capybara.string(last_response.body)
56
+ expect(html).to have_selector("header", text: "RuntimeError at /error")
57
+ expect(html).to have_selector("ul.frames li.application", text: "app/actions/error.rb")
58
+ end
59
+ end
60
+
61
+ describe "Other request types" do
62
+ it "renders a detailed error page in text" do
63
+ get "/error", {}, "HTTP_ACCEPT" => "application/json"
64
+
65
+ expect(last_response.status).to eq 500
66
+
67
+ expect(last_response.body).to include "RuntimeError at /error"
68
+ expect(last_response.body).to match %r{App backtrace.+app/actions/error.rb}m
69
+ end
70
+ end
71
+
72
+ describe "render_detailed_errors config disabled" do
73
+ def before_prepare
74
+ write "config/app.rb", <<~RUBY
75
+ require "hanami"
76
+
77
+ module TestApp
78
+ class App < Hanami::App
79
+ config.logger.stream = File.new("/dev/null", "w")
80
+ config.render_detailed_errors = false
81
+ end
82
+ end
83
+ RUBY
84
+ end
85
+
86
+ it "raises errors from within the app" do
87
+ expect { get "/error" }.to raise_error(RuntimeError, "oops")
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,240 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require "rack/test"
5
+
6
+ RSpec.describe "Web / Rendering errors", :app_integration do
7
+ include Rack::Test::Methods
8
+
9
+ let(:app) { Hanami.app }
10
+
11
+ before do
12
+ with_directory(@dir = make_tmp_directory) do
13
+ write "config/app.rb", <<~RUBY
14
+ require "hanami"
15
+
16
+ module TestApp
17
+ class App < Hanami::App
18
+ config.logger.stream = File.new("/dev/null", "w")
19
+ config.render_errors = true
20
+ config.render_detailed_errors = false
21
+ end
22
+ end
23
+ RUBY
24
+
25
+ write "config/routes.rb", <<~RUBY
26
+ module TestApp
27
+ class Routes < Hanami::Routes
28
+ get "index", to: "index"
29
+ get "error", to: "error"
30
+ end
31
+ end
32
+ RUBY
33
+
34
+ write "app/actions/index.rb", <<~RUBY
35
+ module TestApp
36
+ module Actions
37
+ class Index < Hanami::Action
38
+ def handle(*, response)
39
+ response.body = "Hello"
40
+ end
41
+ end
42
+ end
43
+ end
44
+ RUBY
45
+
46
+ write "app/actions/error.rb", <<~RUBY
47
+ module TestApp
48
+ module Actions
49
+ class Error < Hanami::Action
50
+ def handle(*)
51
+ raise "oops"
52
+ end
53
+ end
54
+ end
55
+ end
56
+ RUBY
57
+
58
+ before_prepare if respond_to?(:before_prepare)
59
+ require "hanami/prepare"
60
+ end
61
+ end
62
+
63
+ describe "HTML request" do
64
+ context "error pages present" do
65
+ def before_prepare
66
+ write "public/404.html", <<~HTML
67
+ <h1>Not found</h1>
68
+ HTML
69
+
70
+ write "public/500.html", <<~HTML
71
+ <h1>Error</h1>
72
+ HTML
73
+ end
74
+
75
+ it "responds with the HTML for a 404 from a not found error" do
76
+ get "/__not_found__"
77
+
78
+ expect(last_response.status).to eq 404
79
+ expect(last_response.body.strip).to eq "<h1>Not found</h1>"
80
+ expect(last_response.get_header("Content-Type")).to eq "text/html; charset=utf-8"
81
+ expect(last_response.get_header("Content-Length")).to eq "19"
82
+ end
83
+
84
+ it "responds with the HTML for a 404 from a method not allowed error" do
85
+ post "/index"
86
+
87
+ expect(last_response.status).to eq 404
88
+ expect(last_response.body.strip).to eq "<h1>Not found</h1>"
89
+ expect(last_response.get_header("Content-Type")).to eq "text/html; charset=utf-8"
90
+ expect(last_response.get_header("Content-Length")).to eq "19"
91
+ end
92
+
93
+ it "responds with the HTML for a 500" do
94
+ get "/error"
95
+
96
+ expect(last_response.status).to eq 500
97
+ expect(last_response.body.strip).to eq "<h1>Error</h1>"
98
+ expect(last_response.get_header("Content-Type")).to eq "text/html; charset=utf-8"
99
+ expect(last_response.get_header("Content-Length")).to eq "15"
100
+ end
101
+ end
102
+
103
+ context "error pages missing" do
104
+ it "responds with default text for a 404 from a not found error" do
105
+ get "/__not_found__"
106
+
107
+ expect(last_response.status).to eq 404
108
+ expect(last_response.body.strip).to eq "Not Found"
109
+ expect(last_response.get_header("Content-Type")).to eq "text/html; charset=utf-8"
110
+ expect(last_response.get_header("Content-Length")).to eq "9"
111
+ end
112
+
113
+ it "responds with default text for a 404 from a metohd not allowed error" do
114
+ post "/index"
115
+
116
+ expect(last_response.status).to eq 404
117
+ expect(last_response.body.strip).to eq "Not Found"
118
+ expect(last_response.get_header("Content-Type")).to eq "text/html; charset=utf-8"
119
+ expect(last_response.get_header("Content-Length")).to eq "9"
120
+ end
121
+
122
+ it "responds with default text for a 500" do
123
+ get "/error"
124
+
125
+ expect(last_response.status).to eq 500
126
+ expect(last_response.body.strip).to eq "Internal Server Error"
127
+ expect(last_response.get_header("Content-Type")).to eq "text/html; charset=utf-8"
128
+ expect(last_response.get_header("Content-Length")).to eq "21"
129
+ end
130
+ end
131
+ end
132
+
133
+ describe "JSON request" do
134
+ it "renders a JSON response for a 404 from a not found error" do
135
+ get "/__not_found__", {}, "HTTP_ACCEPT" => "application/json"
136
+
137
+ expect(last_response.status).to eq 404
138
+ expect(last_response.body.strip).to eq %({"status":404,"error":"Not Found"})
139
+ expect(last_response.get_header("Content-Type")).to eq "application/json; charset=utf-8"
140
+ expect(last_response.get_header("Content-Length")).to eq "34"
141
+ end
142
+
143
+ it "renders a JSON response for a 404 from a metnod not allowed error" do
144
+ post "/index", {}, "HTTP_ACCEPT" => "application/json"
145
+
146
+ expect(last_response.status).to eq 404
147
+ expect(last_response.body.strip).to eq %({"status":404,"error":"Not Found"})
148
+ expect(last_response.get_header("Content-Type")).to eq "application/json; charset=utf-8"
149
+ expect(last_response.get_header("Content-Length")).to eq "34"
150
+ end
151
+
152
+ it "renders a JSON response for a 500" do
153
+ get "/error", {}, "HTTP_ACCEPT" => "application/json"
154
+
155
+ expect(last_response.status).to eq 500
156
+ expect(last_response.body.strip).to eq %({"status":500,"error":"Internal Server Error"})
157
+ expect(last_response.get_header("Content-Type")).to eq "application/json; charset=utf-8"
158
+ expect(last_response.get_header("Content-Length")).to eq "46"
159
+ end
160
+ end
161
+
162
+ describe "configuring error responses" do
163
+ def before_prepare
164
+ write "config/app.rb", <<~RUBY
165
+ require "hanami"
166
+
167
+ module TestApp
168
+ CustomNotFoundError = Class.new(StandardError)
169
+
170
+ class App < Hanami::App
171
+ config.logger.stream = File.new("/dev/null", "w")
172
+ config.render_errors = true
173
+ config.render_error_responses["TestApp::CustomNotFoundError"] = :not_found
174
+ config.render_detailed_errors = false
175
+ end
176
+ end
177
+ RUBY
178
+
179
+ write "app/actions/error.rb", <<~RUBY
180
+ module TestApp
181
+ module Actions
182
+ class Error < Hanami::Action
183
+ def handle(*)
184
+ raise CustomNotFoundError
185
+ end
186
+ end
187
+ end
188
+ end
189
+ RUBY
190
+
191
+ write "public/404.html", <<~HTML
192
+ <h1>Not found</h1>
193
+ HTML
194
+ end
195
+
196
+ it "uses the configured errors to determine the response" do
197
+ get "/error"
198
+
199
+ expect(last_response.status).to eq 404
200
+ expect(last_response.body.strip).to eq "<h1>Not found</h1>"
201
+ end
202
+ end
203
+
204
+ describe "render_errors config disabled" do
205
+ def before_prepare
206
+ write "config/app.rb", <<~RUBY
207
+ require "hanami"
208
+
209
+ module TestApp
210
+ class App < Hanami::App
211
+ config.logger.stream = File.new("/dev/null", "w")
212
+ config.render_errors = false
213
+ config.render_detailed_errors = false
214
+ end
215
+ end
216
+ RUBY
217
+
218
+ # Include error pages here to prove they are _not_ used
219
+ write "public/404.html", <<~HTML
220
+ <h1>Not found</h1>
221
+ HTML
222
+
223
+ write "public/500.html", <<~HTML
224
+ <h1>Error</h1>
225
+ HTML
226
+ end
227
+
228
+ it "raises a Hanami::Router::NotFoundError for a 404" do
229
+ expect { get "/__not_found__" }.to raise_error(Hanami::Router::NotFoundError)
230
+ end
231
+
232
+ it "raises a Hanami::Router::NotAllowedError for a 405" do
233
+ expect { post "/index" }.to raise_error(Hanami::Router::NotAllowedError)
234
+ end
235
+
236
+ it "raises the original error for a 500" do
237
+ expect { get "/error" }.to raise_error(RuntimeError, "oops")
238
+ end
239
+ end
240
+ end
data/spec/spec_helper.rb CHANGED
@@ -23,6 +23,6 @@ RSpec.configure do |config|
23
23
  # TODO: Find out what causes logger to create this dir when running specs.
24
24
  # There's probably a test app class being created somewhere with root
25
25
  # not pointing to a tmp dir.
26
- FileUtils.rm_r(LOG_DIR) if LOG_DIR.exist?
26
+ FileUtils.rm_rf(LOG_DIR) if LOG_DIR.exist?
27
27
  end
28
28
  end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RSpec
4
+ module Support
5
+ module Matchers
6
+ module HTML
7
+ def squish_html(str)
8
+ str
9
+ .gsub(/^[[:space:]]+/, "")
10
+ .gsub(/>[[:space:]]+</m, "><")
11
+ .strip
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+
18
+ RSpec::Matchers.define :eq_html do |expected_html|
19
+ include RSpec::Support::Matchers::HTML
20
+
21
+ match do |actual_html|
22
+ squish_html(actual_html) == squish_html(expected_html)
23
+ end
24
+ end
25
+
26
+ RSpec::Matchers.define :include_html do |expected_html|
27
+ include RSpec::Support::Matchers::HTML
28
+
29
+ match do |actual_html|
30
+ squish_html(actual_html).include?(squish_html(expected_html))
31
+ end
32
+ end
@@ -13,10 +13,6 @@ RSpec.describe Hanami::Config::Actions, "default values" do
13
13
  specify { expect(config.name_inference_base).to eq "actions" }
14
14
  end
15
15
 
16
- describe "view_context_identifier" do
17
- specify { expect(config.view_context_identifier).to eq "views.context" }
18
- end
19
-
20
16
  describe "view_name_inferrer" do
21
17
  specify { expect(config.view_name_inferrer).to eq Hanami::Slice::ViewNameInferrer }
22
18
  end
@@ -182,5 +182,14 @@ RSpec.describe Hanami::Config do
182
182
  .to change { config.logger_instance }
183
183
  .to logger_instance
184
184
  end
185
+
186
+ context "unrecognized :env" do
187
+ let(:env) { :staging }
188
+
189
+ it "provides a fail-safe configuration" do
190
+ expect { config.logger_instance }.to_not raise_error
191
+ expect(config.logger_instance).to be_a(Dry::Logger::Dispatcher)
192
+ end
193
+ end
185
194
  end
186
195
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/inflector"
4
+
5
+ RSpec.describe Hanami::Config, "#render_detailed_errors" do
6
+ let(:config) { described_class.new(app_name: app_name, env: env) }
7
+ let(:app_name) { Hanami::SliceName.new(double(name: "MyApp::App"), inflector: Dry::Inflector.new) }
8
+
9
+ subject(:render_detailed_errors) { config.render_detailed_errors }
10
+
11
+ context "development mode" do
12
+ let(:env) { :development }
13
+ it { is_expected.to be true }
14
+ end
15
+
16
+ context "test mode" do
17
+ let(:env) { :test }
18
+ it { is_expected.to be true }
19
+ end
20
+
21
+ context "production mode" do
22
+ let(:env) { :production }
23
+ it { is_expected.to be false }
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/inflector"
4
+
5
+ RSpec.describe Hanami::Config, "#render_errors" do
6
+ let(:config) { described_class.new(app_name: app_name, env: env) }
7
+ let(:app_name) { Hanami::SliceName.new(double(name: "MyApp::App"), inflector: Dry::Inflector.new) }
8
+
9
+ subject(:render_errors) { config.render_errors }
10
+
11
+ context "development mode" do
12
+ let(:env) { :development }
13
+ it { is_expected.to be false }
14
+ end
15
+
16
+ context "test mode" do
17
+ let(:env) { :test }
18
+ it { is_expected.to be false }
19
+ end
20
+
21
+ context "production mode" do
22
+ let(:env) { :production }
23
+ it { is_expected.to be true }
24
+ end
25
+ end
@@ -39,20 +39,6 @@ RSpec.describe Hanami::Config, "#views" do
39
39
  end
40
40
 
41
41
  describe "specialised default values" do
42
- describe "paths" do
43
- it 'is ["templates"]' do
44
- expect(views.paths).to match [
45
- an_object_satisfying { |path| path.dir.to_s == "templates" }
46
- ]
47
- end
48
- end
49
-
50
- describe "template_inference_base" do
51
- it 'is "views"' do
52
- expect(views.template_inference_base).to eq "views"
53
- end
54
- end
55
-
56
42
  describe "layout" do
57
43
  it 'is "app"' do
58
44
  expect(views.layout).to eq "app"
@@ -69,10 +55,6 @@ RSpec.describe Hanami::Config, "#views" do
69
55
  expect(views).to be_frozen
70
56
  end
71
57
 
72
- it "does not allow changes to locally defined settings" do
73
- expect { views.parts_path = "parts" }.to raise_error(Dry::Configurable::FrozenConfigError)
74
- end
75
-
76
58
  it "does not allow changes to base view settings" do
77
59
  expect { views.paths = [] }.to raise_error(Dry::Configurable::FrozenConfigError)
78
60
  end
@@ -0,0 +1,59 @@
1
+ require "hanami/view"
2
+ require "hanami/view/context"
3
+ require "hanami/extensions/view/context"
4
+
5
+ RSpec.describe(Hanami::View::Context) do
6
+ subject(:context) { described_class.new(**args) }
7
+ let(:args) { {} }
8
+
9
+ describe "#assets" do
10
+ context "assets given" do
11
+ let(:args) { {assets: assets} }
12
+ let(:assets) { double(:assets) }
13
+
14
+ it "returns the assets" do
15
+ expect(context.assets).to be assets
16
+ end
17
+ end
18
+
19
+ context "no assets given" do
20
+ it "raises a Hanami::ComponentLoadError" do
21
+ expect { context.assets }.to raise_error Hanami::ComponentLoadError
22
+ end
23
+ end
24
+ end
25
+
26
+ describe "#request" do
27
+ context "request given" do
28
+ let(:args) { {request: request} }
29
+ let(:request) { double(:request) }
30
+
31
+ it "returns the request" do
32
+ expect(context.request).to be request
33
+ end
34
+ end
35
+
36
+ context "no request given" do
37
+ it "raises a Hanami::ComponentLoadError" do
38
+ expect { context.request }.to raise_error Hanami::ComponentLoadError
39
+ end
40
+ end
41
+ end
42
+
43
+ describe "#routes" do
44
+ context "routes given" do
45
+ let(:args) { {routes: routes} }
46
+ let(:routes) { double(:routes) }
47
+
48
+ it "returns the routes" do
49
+ expect(context.routes).to be routes
50
+ end
51
+ end
52
+
53
+ context "no routes given" do
54
+ it "raises a Hanami::ComponentLoadError" do
55
+ expect { context.routes }.to raise_error Hanami::ComponentLoadError
56
+ end
57
+ end
58
+ end
59
+ end