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.
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,242 @@
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 "renders the hanami-router default 404 response for a not found error" do
229
+ get "/__not_found__"
230
+ expect(last_response.status).to eq 404
231
+ end
232
+
233
+ it "renders the hanami-router default 405 response for a not allowed error" do
234
+ post "/index"
235
+ expect(last_response.status).to eq 405
236
+ end
237
+
238
+ it "raises the original error for a 500" do
239
+ expect { get "/error" }.to raise_error(RuntimeError, "oops")
240
+ end
241
+ end
242
+ 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
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "hanami/devtools/integration/files"
4
4
  require "hanami/devtools/integration/with_tmp_directory"
5
+ require "json"
5
6
  require "tmpdir"
6
7
  require "zeitwerk"
7
8
 
@@ -16,10 +17,52 @@ module RSpec
16
17
  end
17
18
  end
18
19
  end
20
+
21
+ module App
22
+ def self.included(base)
23
+ super
24
+
25
+ base.class_eval do
26
+ let!(:node_modules_path) { File.join(Dir.pwd, "node_modules") }
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def stub_assets(*assets)
33
+ manifest_hash = assets.each_with_object({}) { |source_path, hsh|
34
+ hsh[source_path] = {url: File.join("/assets", source_path)}
35
+ }
36
+
37
+ write "public/assets.json", JSON.generate(manifest_hash)
38
+ end
39
+
40
+ def compile_assets!
41
+ link_node_modules
42
+
43
+ require "hanami/cli/command"
44
+ require "hanami/cli/commands/app/command"
45
+ require "hanami/cli/commands/app/assets/compile"
46
+ compiler = Hanami::CLI::Commands::App::Assets::Compile.new(config: Hanami.app.config.assets)
47
+
48
+ with_directory(Hanami.app.root) do
49
+ compiler.call
50
+ end
51
+ end
52
+
53
+ def link_node_modules
54
+ root = Hanami.app.root
55
+
56
+ return if File.exist?(File.join(root, "node_modules", "hanami-assets", "dist", "hanami-assets.js"))
57
+
58
+ FileUtils.ln_s(node_modules_path, root)
59
+ rescue Errno::EEXIST # rubocop:disable Lint/SuppressedException
60
+ end
61
+ end
19
62
  end
20
63
  end
21
64
 
22
- RSpec.shared_context "Application integration" do
65
+ RSpec.shared_context "App integration" do
23
66
  let(:app_modules) { %i[TestApp Admin Main Search] }
24
67
  end
25
68
 
@@ -35,7 +78,8 @@ end
35
78
  RSpec.configure do |config|
36
79
  config.include RSpec::Support::Files, :app_integration
37
80
  config.include RSpec::Support::WithTmpDirectory, :app_integration
38
- config.include_context "Application integration", :app_integration
81
+ config.include RSpec::Support::App, :app_integration
82
+ config.include_context "App integration", :app_integration
39
83
 
40
84
  config.before :each, :app_integration do
41
85
  # Conditionally assign these in case they have been assigned earlier for specific
@@ -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
@@ -3,43 +3,31 @@
3
3
  require "hanami/config/actions"
4
4
 
5
5
  RSpec.describe Hanami::Config::Actions, "#content_security_policy" do
6
- let(:config) { described_class.new }
6
+ let(:app_config) { Hanami::Config.new(app_name: "MyApp::App", env: :development) }
7
+ let(:config) { app_config.actions }
7
8
  subject(:content_security_policy) { config.content_security_policy }
8
9
 
9
10
  context "no CSP config specified" do
10
- context "without assets_server_url" do
11
-
12
- it "has defaults" do
13
- expect(content_security_policy[:base_uri]).to eq("'self'")
14
-
15
- expected = [
16
- %(base-uri 'self'),
17
- %(child-src 'self'),
18
- %(connect-src 'self'),
19
- %(default-src 'none'),
20
- %(font-src 'self'),
21
- %(form-action 'self'),
22
- %(frame-ancestors 'self'),
23
- %(frame-src 'self'),
24
- %(img-src 'self' https: data:),
25
- %(media-src 'self'),
26
- %(object-src 'none'),
27
- %(script-src 'self'),
28
- %(style-src 'self' 'unsafe-inline' https:)
29
- ].join(";")
30
-
31
- expect(content_security_policy.to_s).to eq(expected)
32
- end
33
- end
34
-
35
- context "with assets_server_url" do
36
- let(:config) { described_class.new(assets_server_url: assets_server_url) }
37
- let(:assets_server_url) { "http://localhost:8080" }
38
-
39
- it "includes server url" do
40
- expect(content_security_policy[:script_src]).to eq("'self' #{assets_server_url}")
41
- expect(content_security_policy[:style_src]).to eq("'self' 'unsafe-inline' https: #{assets_server_url}")
42
- end
11
+ it "has defaults" do
12
+ expect(content_security_policy[:base_uri]).to eq("'self'")
13
+
14
+ expected = [
15
+ %(base-uri 'self'),
16
+ %(child-src 'self'),
17
+ %(connect-src 'self'),
18
+ %(default-src 'none'),
19
+ %(font-src 'self'),
20
+ %(form-action 'self'),
21
+ %(frame-ancestors 'self'),
22
+ %(frame-src 'self'),
23
+ %(img-src 'self' https: data:),
24
+ %(media-src 'self'),
25
+ %(object-src 'none'),
26
+ %(script-src 'self'),
27
+ %(style-src 'self' 'unsafe-inline' https:)
28
+ ].join(";")
29
+
30
+ expect(content_security_policy.to_s).to eq(expected)
43
31
  end
44
32
  end
45
33
 
@@ -84,7 +72,7 @@ RSpec.describe Hanami::Config::Actions, "#content_security_policy" do
84
72
 
85
73
  context "with CSP enabled" do
86
74
  it "sets default header" do
87
- config.finalize!
75
+ app_config.finalize!
88
76
 
89
77
  expect(config.default_headers.fetch("Content-Security-Policy")).to eq(content_security_policy.to_s)
90
78
  end
@@ -93,7 +81,7 @@ RSpec.describe Hanami::Config::Actions, "#content_security_policy" do
93
81
  context "with CSP disabled" do
94
82
  it "doesn't set default header" do
95
83
  config.content_security_policy = false
96
- config.finalize!
84
+ app_config.finalize!
97
85
 
98
86
  expect(config.default_headers.key?("Content-Security-Policy")).to be(false)
99
87
  end
@@ -3,7 +3,8 @@
3
3
  require "hanami/config/actions"
4
4
 
5
5
  RSpec.describe Hanami::Config::Actions, "#csrf_protection" do
6
- let(:config) { described_class.new }
6
+ let(:app_config) { Hanami::Config.new(app_name: "MyApp::App", env: :development) }
7
+ let(:config) { app_config.actions }
7
8
  subject(:value) { config.csrf_protection }
8
9
 
9
10
  context "non-finalized config" do
@@ -26,7 +27,7 @@ RSpec.describe Hanami::Config::Actions, "#csrf_protection" do
26
27
  context "sessions enabled" do
27
28
  before do
28
29
  config.sessions = :cookie, {secret: "abc"}
29
- config.finalize!
30
+ app_config.finalize!
30
31
  end
31
32
 
32
33
  it "is true" do
@@ -46,7 +47,7 @@ RSpec.describe Hanami::Config::Actions, "#csrf_protection" do
46
47
 
47
48
  context "sessions not enabled" do
48
49
  before do
49
- config.finalize!
50
+ app_config.finalize!
50
51
  end
51
52
 
52
53
  it "is true" do
@@ -3,7 +3,8 @@
3
3
  require "hanami/config/actions"
4
4
 
5
5
  RSpec.describe Hanami::Config::Actions, "default values" do
6
- subject(:config) { described_class.new }
6
+ let(:app_config) { Hanami::Config.new(app_name: "MyApp::App", env: :development) }
7
+ subject(:config) { app_config.actions }
7
8
 
8
9
  describe "sessions" do
9
10
  specify { expect(config.sessions).not_to be_enabled }
@@ -13,10 +14,6 @@ RSpec.describe Hanami::Config::Actions, "default values" do
13
14
  specify { expect(config.name_inference_base).to eq "actions" }
14
15
  end
15
16
 
16
- describe "view_context_identifier" do
17
- specify { expect(config.view_context_identifier).to eq "views.context" }
18
- end
19
-
20
17
  describe "view_name_inferrer" do
21
18
  specify { expect(config.view_name_inferrer).to eq Hanami::Slice::ViewNameInferrer }
22
19
  end
@@ -32,7 +29,7 @@ RSpec.describe Hanami::Config::Actions, "default values" do
32
29
 
33
30
  describe "default_headers" do
34
31
  specify {
35
- config.finalize!
32
+ app_config.finalize!
36
33
 
37
34
  expect(config.default_headers).to eq(
38
35
  "X-Frame-Options" => "DENY",
@@ -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
@@ -1,54 +1,40 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  RSpec.describe Hanami, ".env" do
4
- subject(:env) { described_class.env }
5
-
6
- before do
7
- @orig_env = ENV.to_h
8
- end
9
-
10
- after do
11
- ENV.replace(@orig_env)
12
- end
4
+ subject { described_class.env(e: env) }
13
5
 
14
6
  context "HANAMI_ENV in ENV" do
15
- before do
16
- ENV["HANAMI_ENV"] = "test"
17
- end
7
+ let(:env) { {"HANAMI_ENV" => "test"} }
18
8
 
19
9
  it "is the value of HANAMI_ENV" do
20
- is_expected.to eq :test
10
+ is_expected.to eq(:test)
21
11
  end
22
12
  end
23
13
 
24
14
  context "RACK_ENV in ENV" do
25
- before do
26
- ENV["RACK_ENV"] = "test"
27
- end
15
+ let(:env) { {"HANAMI_ENV" => "test"} }
28
16
 
29
17
  it "is the value of RACK_ENV" do
30
- is_expected.to eq :test
18
+ is_expected.to eq(:test)
31
19
  end
32
20
  end
33
21
 
34
22
  context "both HANAMI_ENV and RACK_ENV in ENV" do
35
- before do
36
- ENV["HANAMI_ENV"] = "test"
37
- ENV["RACK_ENV"] = "production"
23
+ let(:env) do
24
+ {"HANAMI_ENV" => "test",
25
+ "RACK_ENV" => "production"}
38
26
  end
39
27
 
40
28
  it "is the value of HANAMI_ENV" do
41
- is_expected.to eq :test
29
+ is_expected.to eq(:test)
42
30
  end
43
31
  end
44
32
 
45
33
  context "no ENV vars set" do
46
- before do
47
- ENV.delete("HANAMI_ENV")
48
- end
34
+ let(:env) { {} }
49
35
 
50
36
  it "defaults to \"development\"" do
51
- is_expected.to eq :development
37
+ is_expected.to eq(:development)
52
38
  end
53
39
  end
54
40
  end