hanami 2.0.0.beta1.1 → 2.0.0.beta3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (156) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +82 -0
  3. data/hanami.gemspec +1 -2
  4. data/lib/hanami/app.rb +76 -16
  5. data/lib/hanami/assets/{application_configuration.rb → app_configuration.rb} +1 -1
  6. data/lib/hanami/configuration/null_configuration.rb +2 -2
  7. data/lib/hanami/configuration.rb +36 -36
  8. data/lib/hanami/extensions/action/slice_configured_action.rb +44 -1
  9. data/lib/hanami/extensions/view/slice_configured_view.rb +47 -7
  10. data/lib/hanami/providers/rack.rb +2 -0
  11. data/lib/hanami/providers/settings.rb +81 -6
  12. data/lib/hanami/routes.rb +48 -21
  13. data/lib/hanami/settings/env_store.rb +32 -0
  14. data/lib/hanami/settings.rb +8 -12
  15. data/lib/hanami/setup.rb +1 -6
  16. data/lib/hanami/slice/routing/middleware/stack.rb +26 -5
  17. data/lib/hanami/slice.rb +38 -45
  18. data/lib/hanami/slice_configurable.rb +14 -1
  19. data/lib/hanami/slice_registrar.rb +65 -5
  20. data/lib/hanami/version.rb +1 -1
  21. data/lib/hanami.rb +53 -2
  22. data/spec/{new_integration → integration}/action/cookies_spec.rb +0 -0
  23. data/spec/{new_integration → integration}/action/csrf_protection_spec.rb +0 -0
  24. data/spec/{new_integration → integration}/action/routes_spec.rb +3 -5
  25. data/spec/{new_integration → integration}/action/sessions_spec.rb +0 -0
  26. data/spec/integration/action/slice_configuration_spec.rb +287 -0
  27. data/spec/{new_integration → integration}/action/view_integration_spec.rb +0 -0
  28. data/spec/{new_integration → integration}/action/view_rendering/automatic_rendering_spec.rb +0 -0
  29. data/spec/{new_integration → integration}/action/view_rendering/paired_view_inference_spec.rb +0 -0
  30. data/spec/{new_integration → integration}/action/view_rendering_spec.rb +0 -0
  31. data/spec/{new_integration → integration}/code_loading/loading_from_app_spec.rb +0 -0
  32. data/spec/integration/code_loading/loading_from_lib_spec.rb +208 -0
  33. data/spec/{new_integration → integration}/code_loading/loading_from_slice_spec.rb +0 -0
  34. data/spec/{new_integration → integration}/container/application_routes_helper_spec.rb +1 -3
  35. data/spec/{new_integration → integration}/container/auto_injection_spec.rb +0 -0
  36. data/spec/{new_integration → integration}/container/auto_registration_spec.rb +0 -0
  37. data/spec/{new_integration → integration}/container/autoloader_spec.rb +0 -0
  38. data/spec/{new_integration → integration}/container/imports_spec.rb +0 -0
  39. data/spec/{new_integration → integration}/container/prepare_container_spec.rb +0 -0
  40. data/spec/{new_integration → integration}/container/shutdown_spec.rb +0 -0
  41. data/spec/{new_integration → integration}/container/standard_bootable_components_spec.rb +0 -0
  42. data/spec/integration/dotenv_loading_spec.rb +137 -0
  43. data/spec/{new_integration → integration}/rack_app/middleware_spec.rb +9 -15
  44. data/spec/{new_integration → integration}/rack_app/non_booted_rack_app_spec.rb +3 -5
  45. data/spec/{new_integration → integration}/rack_app/rack_app_spec.rb +28 -48
  46. data/spec/integration/settings/access_to_constants_spec.rb +169 -0
  47. data/spec/integration/settings/loading_from_env_spec.rb +187 -0
  48. data/spec/integration/settings/settings_component_loading_spec.rb +113 -0
  49. data/spec/integration/settings/using_types_spec.rb +87 -0
  50. data/spec/integration/setup_spec.rb +165 -0
  51. data/spec/{new_integration → integration}/slices/external_slice_spec.rb +2 -4
  52. data/spec/{new_integration → integration}/slices/slice_configuration_spec.rb +0 -0
  53. data/spec/integration/slices/slice_loading_spec.rb +171 -0
  54. data/spec/{new_integration → integration}/slices/slice_routing_spec.rb +5 -13
  55. data/spec/{new_integration → integration}/slices/slice_settings_spec.rb +0 -0
  56. data/spec/{new_integration → integration}/slices_spec.rb +0 -0
  57. data/spec/{new_integration → integration}/view/context/assets_spec.rb +0 -0
  58. data/spec/{new_integration → integration}/view/context/inflector_spec.rb +0 -0
  59. data/spec/{new_integration → integration}/view/context/request_spec.rb +0 -0
  60. data/spec/{new_integration → integration}/view/context/routes_spec.rb +1 -3
  61. data/spec/{new_integration → integration}/view/context/settings_spec.rb +5 -1
  62. data/spec/{new_integration → integration}/view/inflector_spec.rb +0 -0
  63. data/spec/{new_integration → integration}/view/part_namespace_spec.rb +0 -0
  64. data/spec/{new_integration → integration}/view/path_spec.rb +0 -0
  65. data/spec/integration/view/slice_configuration_spec.rb +289 -0
  66. data/spec/{new_integration → integration}/view/template_spec.rb +0 -0
  67. data/spec/{new_integration → integration}/view/views_spec.rb +0 -0
  68. data/spec/support/app_integration.rb +4 -5
  69. data/spec/unit/hanami/configuration/actions_spec.rb +4 -15
  70. data/spec/unit/hanami/configuration/router_spec.rb +45 -0
  71. data/spec/unit/hanami/configuration/slices_spec.rb +34 -0
  72. data/spec/unit/hanami/configuration/views_spec.rb +4 -15
  73. data/spec/unit/hanami/settings/env_store_spec.rb +52 -0
  74. data/spec/unit/hanami/slice_configurable_spec.rb +2 -2
  75. data/spec/unit/hanami/version_spec.rb +1 -1
  76. metadata +105 -250
  77. data/lib/hanami/server.rb +0 -29
  78. data/lib/hanami/settings/dotenv_store.rb +0 -58
  79. data/spec/integration/application_middleware_stack_spec.rb +0 -84
  80. data/spec/integration/assets/cdn_spec.rb +0 -48
  81. data/spec/integration/assets/fingerprint_spec.rb +0 -42
  82. data/spec/integration/assets/helpers_spec.rb +0 -50
  83. data/spec/integration/assets/serve_spec.rb +0 -70
  84. data/spec/integration/assets/subresource_integrity_spec.rb +0 -54
  85. data/spec/integration/body_parsers_spec.rb +0 -50
  86. data/spec/integration/cli/assets/precompile_spec.rb +0 -147
  87. data/spec/integration/cli/assets_spec.rb +0 -14
  88. data/spec/integration/cli/console_spec.rb +0 -105
  89. data/spec/integration/cli/db/apply_spec.rb +0 -74
  90. data/spec/integration/cli/db/console_spec.rb +0 -40
  91. data/spec/integration/cli/db/create_spec.rb +0 -50
  92. data/spec/integration/cli/db/drop_spec.rb +0 -54
  93. data/spec/integration/cli/db/migrate_spec.rb +0 -108
  94. data/spec/integration/cli/db/prepare_spec.rb +0 -36
  95. data/spec/integration/cli/db/rollback_spec.rb +0 -96
  96. data/spec/integration/cli/db/version_spec.rb +0 -38
  97. data/spec/integration/cli/db_spec.rb +0 -21
  98. data/spec/integration/cli/destroy/action_spec.rb +0 -143
  99. data/spec/integration/cli/destroy/app_spec.rb +0 -118
  100. data/spec/integration/cli/destroy/mailer_spec.rb +0 -74
  101. data/spec/integration/cli/destroy/migration_spec.rb +0 -70
  102. data/spec/integration/cli/destroy/model_spec.rb +0 -113
  103. data/spec/integration/cli/destroy_spec.rb +0 -18
  104. data/spec/integration/cli/generate/action_spec.rb +0 -469
  105. data/spec/integration/cli/generate/app_spec.rb +0 -215
  106. data/spec/integration/cli/generate/mailer_spec.rb +0 -189
  107. data/spec/integration/cli/generate/migration_spec.rb +0 -72
  108. data/spec/integration/cli/generate/model_spec.rb +0 -290
  109. data/spec/integration/cli/generate/secret_spec.rb +0 -56
  110. data/spec/integration/cli/generate_spec.rb +0 -19
  111. data/spec/integration/cli/new/database_spec.rb +0 -235
  112. data/spec/integration/cli/new/hanami_head_spec.rb +0 -27
  113. data/spec/integration/cli/new/template_spec.rb +0 -118
  114. data/spec/integration/cli/new/test_spec.rb +0 -274
  115. data/spec/integration/cli/new_spec.rb +0 -970
  116. data/spec/integration/cli/plugins_spec.rb +0 -39
  117. data/spec/integration/cli/routes_spec.rb +0 -49
  118. data/spec/integration/cli/server_spec.rb +0 -626
  119. data/spec/integration/cli/version_spec.rb +0 -85
  120. data/spec/integration/early_hints_spec.rb +0 -35
  121. data/spec/integration/handle_exceptions_spec.rb +0 -244
  122. data/spec/integration/head_spec.rb +0 -89
  123. data/spec/integration/http_headers_spec.rb +0 -29
  124. data/spec/integration/mailer_spec.rb +0 -32
  125. data/spec/integration/middleware_spec.rb +0 -81
  126. data/spec/integration/mount_applications_spec.rb +0 -88
  127. data/spec/integration/project_initializers_spec.rb +0 -40
  128. data/spec/integration/rackup_spec.rb +0 -35
  129. data/spec/integration/rake/with_minitest_spec.rb +0 -67
  130. data/spec/integration/rake/with_rspec_spec.rb +0 -69
  131. data/spec/integration/routing_helpers_spec.rb +0 -61
  132. data/spec/integration/security/content_security_policy_spec.rb +0 -46
  133. data/spec/integration/security/csrf_protection_spec.rb +0 -42
  134. data/spec/integration/security/force_ssl_spec.rb +0 -29
  135. data/spec/integration/security/x_content_type_options_spec.rb +0 -46
  136. data/spec/integration/security/x_frame_options_spec.rb +0 -46
  137. data/spec/integration/security/x_xss_protection_spec.rb +0 -46
  138. data/spec/integration/send_file_spec.rb +0 -51
  139. data/spec/integration/sessions_spec.rb +0 -247
  140. data/spec/integration/static_middleware_spec.rb +0 -21
  141. data/spec/integration/streaming_spec.rb +0 -41
  142. data/spec/integration/unsafe_send_file_spec.rb +0 -52
  143. data/spec/new_integration/action/configuration_spec.rb +0 -26
  144. data/spec/new_integration/settings_spec.rb +0 -115
  145. data/spec/new_integration/view/configuration_spec.rb +0 -49
  146. data/spec/support/fixtures/hanami-plugin/Gemfile +0 -8
  147. data/spec/support/fixtures/hanami-plugin/README.md +0 -35
  148. data/spec/support/fixtures/hanami-plugin/Rakefile +0 -4
  149. data/spec/support/fixtures/hanami-plugin/bin/console +0 -15
  150. data/spec/support/fixtures/hanami-plugin/bin/setup +0 -8
  151. data/spec/support/fixtures/hanami-plugin/hanami-plugin.gemspec +0 -28
  152. data/spec/support/fixtures/hanami-plugin/lib/hanami/plugin/cli.rb +0 -19
  153. data/spec/support/fixtures/hanami-plugin/lib/hanami/plugin/version.rb +0 -7
  154. data/spec/support/fixtures/hanami-plugin/lib/hanami/plugin.rb +0 -8
  155. data/spec/unit/hanami/routes_spec.rb +0 -25
  156. data/spec/unit/hanami/settings/dotenv_store_spec.rb +0 -119
@@ -0,0 +1,289 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe "App view / Slice configuration", :app_integration do
4
+ before do
5
+ with_directory(@dir = make_tmp_directory) do
6
+ write "config/app.rb", <<~'RUBY'
7
+ require "hanami"
8
+
9
+ module TestApp
10
+ class App < Hanami::App
11
+ end
12
+ end
13
+ RUBY
14
+
15
+ write "app/view.rb", <<~'RUBY'
16
+ require "hanami/view"
17
+
18
+ module TestApp
19
+ class View < Hanami::View
20
+ end
21
+ end
22
+ RUBY
23
+
24
+ require "hanami/setup"
25
+ end
26
+ end
27
+
28
+ def prepare_app
29
+ with_directory(@dir) { require "hanami/prepare" }
30
+ end
31
+
32
+ describe "inheriting from app-level base class" do
33
+ describe "app-level base class" do
34
+ it "applies default views config from the app", :aggregate_failures do
35
+ prepare_app
36
+
37
+ expect(TestApp::View.config.layouts_dir).to eq "layouts"
38
+ expect(TestApp::View.config.layout).to eq "app"
39
+ end
40
+
41
+ it "applies views config from the app" do
42
+ Hanami.app.config.views.layout = "app_layout"
43
+
44
+ prepare_app
45
+
46
+ expect(TestApp::View.config.layout).to eq "app_layout"
47
+ end
48
+
49
+ it "does not override config in the base class" do
50
+ Hanami.app.config.views.layout = "app_layout"
51
+
52
+ prepare_app
53
+
54
+ TestApp::View.config.layout = "custom_layout"
55
+
56
+ expect(TestApp::View.config.layout).to eq "custom_layout"
57
+ end
58
+ end
59
+
60
+ describe "subclass in app" do
61
+ before do
62
+ with_directory(@dir) do
63
+ write "app/views/articles/index.rb", <<~'RUBY'
64
+ module TestApp
65
+ module Views
66
+ module Articles
67
+ class Index < TestApp::View
68
+ end
69
+ end
70
+ end
71
+ end
72
+ RUBY
73
+ end
74
+ end
75
+
76
+ it "applies default views config from the app", :aggregate_failures do
77
+ prepare_app
78
+
79
+ expect(TestApp::Views::Articles::Index.config.layouts_dir).to eq "layouts"
80
+ expect(TestApp::Views::Articles::Index.config.layout).to eq "app"
81
+ end
82
+
83
+ it "applies views config from the app" do
84
+ Hanami.app.config.views.layout = "app_layout"
85
+
86
+ prepare_app
87
+
88
+ expect(TestApp::Views::Articles::Index.config.layout).to eq "app_layout"
89
+ end
90
+
91
+ it "applies config from the base class" do
92
+ prepare_app
93
+
94
+ TestApp::View.config.layout = "base_class_layout"
95
+
96
+ expect(TestApp::Views::Articles::Index.config.layout).to eq "base_class_layout"
97
+ end
98
+ end
99
+
100
+ describe "subclass in slice" do
101
+ before do
102
+ with_directory(@dir) do
103
+ write "slices/admin/views/articles/index.rb", <<~'RUBY'
104
+ module Admin
105
+ module Views
106
+ module Articles
107
+ class Index < TestApp::View
108
+ end
109
+ end
110
+ end
111
+ end
112
+ RUBY
113
+ end
114
+ end
115
+
116
+ it "applies default views config from the app", :aggregate_failures do
117
+ prepare_app
118
+
119
+ expect(Admin::Views::Articles::Index.config.layouts_dir).to eq "layouts"
120
+ expect(Admin::Views::Articles::Index.config.layout).to eq "app"
121
+ end
122
+
123
+ it "applies views config from the app" do
124
+ Hanami.app.config.views.layout = "app_layout"
125
+
126
+ prepare_app
127
+
128
+ expect(Admin::Views::Articles::Index.config.layout).to eq "app_layout"
129
+ end
130
+
131
+ it "applies config from the base class" do
132
+ prepare_app
133
+
134
+ TestApp::View.config.layout = "base_class_layout"
135
+
136
+ expect(Admin::Views::Articles::Index.config.layout).to eq "base_class_layout"
137
+ end
138
+ end
139
+ end
140
+
141
+ describe "inheriting from a slice-level base class, in turn inheriting from an app-level base class" do
142
+ before do
143
+ with_directory(@dir) do
144
+ write "slices/admin/view.rb", <<~'RUBY'
145
+ module Admin
146
+ class View < TestApp::View
147
+ end
148
+ end
149
+ RUBY
150
+ end
151
+ end
152
+
153
+ describe "slice-level base class" do
154
+ it "applies default views config from the app", :aggregate_failures do
155
+ prepare_app
156
+
157
+ expect(Admin::View.config.layouts_dir).to eq "layouts"
158
+ expect(Admin::View.config.layout).to eq "app"
159
+ end
160
+
161
+ it "applies views config from the app" do
162
+ Hanami.app.config.views.layout = "app_layout"
163
+
164
+ prepare_app
165
+
166
+ expect(Admin::View.config.layout).to eq "app_layout"
167
+ end
168
+
169
+ it "applies config from the app base class" do
170
+ prepare_app
171
+
172
+ TestApp::View.config.layout = "app_base_class_layout"
173
+
174
+ expect(Admin::View.config.layout).to eq "app_base_class_layout"
175
+ end
176
+
177
+ context "slice views config present" do
178
+ before do
179
+ with_directory(@dir) do
180
+ write "config/slices/admin.rb", <<~'RUBY'
181
+ module Admin
182
+ class Slice < Hanami::Slice
183
+ config.views.layout = "slice_layout"
184
+ end
185
+ end
186
+ RUBY
187
+ end
188
+ end
189
+
190
+ it "applies views config from the slice" do
191
+ prepare_app
192
+
193
+ expect(Admin::View.config.layout).to eq "slice_layout"
194
+ end
195
+
196
+ it "prefers views config from the slice over config from the app-level base class" do
197
+ prepare_app
198
+
199
+ TestApp::View.config.layout = "app_base_class_layout"
200
+
201
+ expect(Admin::View.config.layout).to eq "slice_layout"
202
+ end
203
+
204
+ it "prefers config from the base class over views config from the slice" do
205
+ prepare_app
206
+
207
+ TestApp::View.config.layout = "app_base_class_layout"
208
+ Admin::View.config.layout = "slice_base_class_layout"
209
+
210
+ expect(Admin::View.config.layout).to eq "slice_base_class_layout"
211
+ end
212
+ end
213
+ end
214
+
215
+ describe "subclass in slice" do
216
+ before do
217
+ with_directory(@dir) do
218
+ write "slices/admin/views/articles/index.rb", <<~'RUBY'
219
+ module Admin
220
+ module Views
221
+ module Articles
222
+ class Index < Admin::View
223
+ end
224
+ end
225
+ end
226
+ end
227
+ RUBY
228
+ end
229
+ end
230
+
231
+ it "applies default views config from the app", :aggregate_failures do
232
+ prepare_app
233
+
234
+ expect(Admin::Views::Articles::Index.config.layouts_dir).to eq "layouts"
235
+ expect(Admin::Views::Articles::Index.config.layout).to eq "app"
236
+ end
237
+
238
+ it "applies views config from the app" do
239
+ Hanami.app.config.views.layout = "app_layout"
240
+
241
+ prepare_app
242
+
243
+ expect(Admin::Views::Articles::Index.config.layout).to eq "app_layout"
244
+ end
245
+
246
+ it "applies views config from the slice" do
247
+ with_directory(@dir) do
248
+ write "config/slices/admin.rb", <<~'RUBY'
249
+ module Admin
250
+ class Slice < Hanami::Slice
251
+ config.views.layout = "slice_layout"
252
+ end
253
+ end
254
+ RUBY
255
+ end
256
+
257
+ prepare_app
258
+
259
+ expect(Admin::Views::Articles::Index.config.layout).to eq "slice_layout"
260
+ end
261
+
262
+ it "applies config from the slice base class" do
263
+ prepare_app
264
+
265
+ Admin::View.config.layout = "slice_base_class_layout"
266
+
267
+ expect(Admin::Views::Articles::Index.config.layout).to eq "slice_base_class_layout"
268
+ end
269
+
270
+ it "prefers config from the slice base class over views config from the slice" do
271
+ with_directory(@dir) do
272
+ write "config/slices/admin.rb", <<~'RUBY'
273
+ module Admin
274
+ class Slice < Hanami::Slice
275
+ config.views.layout = "slice_layout"
276
+ end
277
+ end
278
+ RUBY
279
+ end
280
+
281
+ prepare_app
282
+
283
+ Admin::View.config.layout = "slice_base_class_layout"
284
+
285
+ expect(Admin::Views::Articles::Index.config.layout).to eq "slice_base_class_layout"
286
+ end
287
+ end
288
+ end
289
+ end
@@ -20,7 +20,7 @@ module RSpec
20
20
  end
21
21
 
22
22
  RSpec.shared_context "Application integration" do
23
- let(:application_modules) { %i[TestApp Admin Main Search] }
23
+ let(:app_modules) { %i[TestApp Admin Main Search] }
24
24
  end
25
25
 
26
26
  RSpec.configure do |config|
@@ -52,9 +52,8 @@ RSpec.configure do |config|
52
52
  Zeitwerk::ExplicitNamespace.cpaths.clear
53
53
  Zeitwerk::ExplicitNamespace.tracer.disable
54
54
 
55
- if Hanami.instance_variable_defined?(:@_app)
56
- Hanami.remove_instance_variable(:@_app)
57
- end
55
+ Hanami.instance_variable_set(:@_bundled, {})
56
+ Hanami.remove_instance_variable(:@_app) if Hanami.instance_variable_defined?(:@_app)
58
57
 
59
58
  $LOAD_PATH.replace(@load_paths)
60
59
 
@@ -68,7 +67,7 @@ RSpec.configure do |config|
68
67
  }
69
68
  $LOADED_FEATURES.replace(@loaded_features + new_features_to_keep)
70
69
 
71
- application_modules.each do |app_module_name|
70
+ app_modules.each do |app_module_name|
72
71
  next unless Object.const_defined?(app_module_name)
73
72
 
74
73
  Object.const_get(app_module_name).tap do |mod|
@@ -10,7 +10,7 @@ RSpec.describe Hanami::Configuration, "#actions" do
10
10
 
11
11
  subject(:actions) { configuration.actions }
12
12
 
13
- context "Hanami::Action available" do
13
+ context "hanami-controller is bundled" do
14
14
  it "is a full actions configuration" do
15
15
  is_expected.to be_an_instance_of(Hanami::Configuration::Actions)
16
16
 
@@ -48,21 +48,10 @@ RSpec.describe Hanami::Configuration, "#actions" do
48
48
  end
49
49
  end
50
50
 
51
- context "Hanami::Action not available" do
51
+ context "hanami-controller is not bundled" do
52
52
  before do
53
- load_error = LoadError.new.tap do |error|
54
- error.instance_variable_set :@path, "hanami/action"
55
- end
56
-
57
- allow_any_instance_of(described_class)
58
- .to receive(:require)
59
- .with(anything)
60
- .and_call_original
61
-
62
- allow_any_instance_of(described_class)
63
- .to receive(:require)
64
- .with("hanami/action")
65
- .and_raise load_error
53
+ allow(Hanami).to receive(:bundled?).and_call_original
54
+ expect(Hanami).to receive(:bundled?).with("hanami-controller").and_return(false)
66
55
  end
67
56
 
68
57
  it "does not expose any settings" do
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "hanami/configuration"
4
+ require "hanami/configuration/router"
5
+
6
+ RSpec.describe Hanami::Configuration, "#router" do
7
+ let(:configuration) { described_class.new(app_name: app_name, env: :development) }
8
+ let(:app_name) { "MyApp::app" }
9
+
10
+ subject(:router) { configuration.router }
11
+
12
+ context "hanami-router is bundled" do
13
+ it "is a full router configuration" do
14
+ is_expected.to be_an_instance_of(Hanami::Configuration::Router)
15
+
16
+ is_expected.to respond_to(:resolver)
17
+ end
18
+
19
+ it "loads the middleware stack" do
20
+ subject
21
+
22
+ expect(configuration.middleware_stack).not_to be_nil
23
+ end
24
+
25
+ it "can be finalized" do
26
+ is_expected.to respond_to(:finalize!)
27
+ end
28
+ end
29
+
30
+ context "hanami-router is not bundled" do
31
+ before do
32
+ allow(Hanami).to receive(:bundled?).and_call_original
33
+ expect(Hanami).to receive(:bundled?).with("hanami-router").and_return(false)
34
+ end
35
+
36
+ it "does not expose any settings" do
37
+ is_expected.not_to be_an_instance_of(Hanami::Configuration::Router)
38
+ is_expected.not_to respond_to(:resolver)
39
+ end
40
+
41
+ it "can be finalized" do
42
+ is_expected.to respond_to(:finalize!)
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/inflector"
4
+ require "hanami/configuration"
5
+ require "hanami/slice_name"
6
+
7
+ RSpec.describe Hanami::Configuration, "#slices" do
8
+ subject(:config) { described_class.new(app_name: app_name, env: :development) }
9
+ let(:app_name) { Hanami::SliceName.new(double(name: "MyApp::App"), inflector: Dry::Inflector.new) }
10
+
11
+ subject(:slices) { config.slices }
12
+
13
+ before do
14
+ @orig_env = ENV.to_h
15
+ end
16
+
17
+ after do
18
+ ENV.replace(@orig_env)
19
+ end
20
+
21
+ it "is nil by default" do
22
+ is_expected.to be nil
23
+ end
24
+
25
+ it "defaults to the HANAMI_LOAD_SLICES env var, separated by commas" do
26
+ ENV["HANAMI_SLICES"] = "main,admin"
27
+ is_expected.to eq %w[main admin]
28
+ end
29
+
30
+ it "strips spaces from HANAMI_LOAD_SLICES env var entries" do
31
+ ENV["HANAMI_SLICES"] = "main, admin"
32
+ is_expected.to eq %w[main admin]
33
+ end
34
+ end
@@ -10,7 +10,7 @@ RSpec.describe Hanami::Configuration, "#views" do
10
10
 
11
11
  subject(:views) { configuration.views }
12
12
 
13
- context "Hanami::View available" do
13
+ context "hanami-view is bundled" do
14
14
  it "exposes Hanami::Views's app configuration" do
15
15
  is_expected.to be_an_instance_of(Hanami::Configuration::Views)
16
16
 
@@ -90,21 +90,10 @@ RSpec.describe Hanami::Configuration, "#views" do
90
90
  end
91
91
  end
92
92
 
93
- context "Hanami::View not available" do
93
+ context "hanami-view is not bundled" do
94
94
  before do
95
- load_error = LoadError.new.tap do |error|
96
- error.instance_variable_set :@path, "hanami/view"
97
- end
98
-
99
- allow_any_instance_of(described_class)
100
- .to receive(:require)
101
- .with(anything)
102
- .and_call_original
103
-
104
- allow_any_instance_of(described_class)
105
- .to receive(:require)
106
- .with("hanami/view")
107
- .and_raise load_error
95
+ allow(Hanami).to receive(:bundled?).and_call_original
96
+ expect(Hanami).to receive(:bundled?).with("hanami-view").and_return(false)
108
97
  end
109
98
 
110
99
  it "does not expose any settings" do
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "hanami/settings/env_store"
4
+
5
+ RSpec.describe Hanami::Settings::EnvStore do
6
+ it "defaults to using ENV as the store" do
7
+ orig_env = ENV.to_h
8
+
9
+ ENV["FOO"] = "bar"
10
+ expect(described_class.new.fetch("FOO")).to eq "bar"
11
+
12
+ ENV.replace(orig_env)
13
+ end
14
+
15
+ describe "#fetch" do
16
+ it "fetches from ENV" do
17
+ store = described_class.new(store: {"FOO" => "bar"})
18
+
19
+ expect(store.fetch("FOO")).to eq("bar")
20
+ end
21
+
22
+ it "capitalizes name" do
23
+ store = described_class.new(store: {"FOO" => "bar"})
24
+
25
+ expect(store.fetch("foo")).to eq("bar")
26
+ end
27
+
28
+ it "coerces name to string" do
29
+ store = described_class.new(store: {"FOO" => "bar"})
30
+
31
+ expect(store.fetch(:foo)).to eq("bar")
32
+ end
33
+
34
+ it "returns default when value is not found" do
35
+ store = described_class.new(store: {"FOO" => "bar"})
36
+
37
+ expect(store.fetch("BAZ", "qux")).to eq("qux")
38
+ end
39
+
40
+ it "returns the block execution when value is not found" do
41
+ store = described_class.new(store: {"FOO" => "bar"})
42
+
43
+ expect(store.fetch("BAZ") { "qux" }).to eq("qux") # rubocop:disable Style/RedundantFetchBlock
44
+ end
45
+
46
+ it "raises KeyError when value is not found and no default is given" do
47
+ store = described_class.new(store: {"FOO" => "bar"})
48
+
49
+ expect { store.fetch("BAZ") }.to raise_error(KeyError)
50
+ end
51
+ end
52
+ end
@@ -54,8 +54,8 @@ RSpec.describe Hanami::SliceConfigurable, :app_integration do
54
54
 
55
55
  subject(:subclass) { Main::MySubSubclass }
56
56
 
57
- it "calls `configure_for_slice` again for the same slice" do
58
- expect(subclass.traces).to eq [Main::Slice, Main::Slice]
57
+ it "does not call `configure_for_slice` again" do
58
+ expect(subclass.traces).to eq [Main::Slice]
59
59
  end
60
60
  end
61
61
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  RSpec.describe "Hanami::VERSION" do
4
4
  it "returns current version" do
5
- expect(Hanami::VERSION).to eq("2.0.0.beta1.1")
5
+ expect(Hanami::VERSION).to eq("2.0.0.beta3")
6
6
  end
7
7
  end