hanami 2.3.2 → 3.0.0.rc1

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 (184) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +55 -19
  3. data/LICENSE +20 -0
  4. data/README.md +18 -35
  5. data/hanami.gemspec +36 -37
  6. data/lib/hanami/config/db.rb +2 -0
  7. data/lib/hanami/config/i18n.rb +138 -0
  8. data/lib/hanami/config/logger.rb +15 -7
  9. data/lib/hanami/config/null_config.rb +1 -1
  10. data/lib/hanami/config/views.rb +17 -0
  11. data/lib/hanami/config.rb +66 -22
  12. data/lib/hanami/errors.rb +6 -0
  13. data/lib/hanami/extensions/action/slice_configured_action.rb +1 -1
  14. data/lib/hanami/extensions/action.rb +2 -2
  15. data/lib/hanami/extensions/mailer/slice_configured_mailer.rb +120 -0
  16. data/lib/hanami/extensions/mailer.rb +28 -0
  17. data/lib/hanami/extensions/operation/slice_configured_db_operation.rb +2 -0
  18. data/lib/hanami/extensions/view/context.rb +26 -4
  19. data/lib/hanami/extensions/view/part.rb +2 -0
  20. data/lib/hanami/extensions/view/slice_configured_context.rb +7 -0
  21. data/lib/hanami/extensions/view/slice_configured_part.rb +2 -0
  22. data/lib/hanami/extensions/view/slice_configured_view.rb +8 -8
  23. data/lib/hanami/extensions/view/standard_helpers.rb +4 -0
  24. data/lib/hanami/extensions.rb +6 -1
  25. data/lib/hanami/helpers/assets_helper.rb +0 -4
  26. data/lib/hanami/helpers/form_helper.rb +1 -1
  27. data/lib/hanami/helpers/i18n_helper.rb +176 -0
  28. data/lib/hanami/logger/rack_formatter.rb +73 -0
  29. data/lib/hanami/logger/sql_formatter.rb +80 -0
  30. data/lib/hanami/logger/sql_logger.rb +48 -0
  31. data/lib/hanami/middleware/render_errors.rb +2 -2
  32. data/lib/hanami/providers/db.rb +7 -2
  33. data/lib/hanami/providers/db_logging.rb +4 -7
  34. data/lib/hanami/providers/i18n/backend.rb +369 -0
  35. data/lib/hanami/providers/i18n/locale/en.yml +57 -0
  36. data/lib/hanami/providers/i18n.rb +114 -0
  37. data/lib/hanami/providers/mailers.rb +101 -0
  38. data/lib/hanami/routes.rb +1 -0
  39. data/lib/hanami/settings/composite_store.rb +53 -0
  40. data/lib/hanami/settings.rb +4 -4
  41. data/lib/hanami/slice/router.rb +15 -10
  42. data/lib/hanami/slice.rb +71 -11
  43. data/lib/hanami/slice_registrar.rb +2 -2
  44. data/lib/hanami/universal_logger.rb +250 -0
  45. data/lib/hanami/version.rb +1 -1
  46. data/lib/hanami/web/rack_logger.rb +2 -80
  47. data/lib/hanami/web/welcome.html.erb +443 -58
  48. data/lib/hanami.rb +4 -2
  49. metadata +28 -276
  50. data/CODE_OF_CONDUCT.md +0 -74
  51. data/FEATURES.md +0 -269
  52. data/LICENSE.md +0 -22
  53. data/spec/integration/action/cookies_spec.rb +0 -58
  54. data/spec/integration/action/csrf_protection_spec.rb +0 -54
  55. data/spec/integration/action/format_config_spec.rb +0 -129
  56. data/spec/integration/action/routes_spec.rb +0 -71
  57. data/spec/integration/action/sessions_spec.rb +0 -50
  58. data/spec/integration/action/slice_configuration_spec.rb +0 -284
  59. data/spec/integration/action/view_rendering/automatic_rendering_spec.rb +0 -247
  60. data/spec/integration/action/view_rendering/paired_view_inference_spec.rb +0 -115
  61. data/spec/integration/action/view_rendering/view_context_spec.rb +0 -221
  62. data/spec/integration/action/view_rendering_spec.rb +0 -89
  63. data/spec/integration/assets/assets_spec.rb +0 -155
  64. data/spec/integration/assets/cross_slice_assets_helpers_spec.rb +0 -129
  65. data/spec/integration/assets/serve_static_assets_spec.rb +0 -152
  66. data/spec/integration/code_loading/loading_from_app_spec.rb +0 -152
  67. data/spec/integration/code_loading/loading_from_lib_spec.rb +0 -242
  68. data/spec/integration/code_loading/loading_from_slice_spec.rb +0 -165
  69. data/spec/integration/container/application_routes_helper_spec.rb +0 -48
  70. data/spec/integration/container/auto_injection_spec.rb +0 -53
  71. data/spec/integration/container/auto_registration_spec.rb +0 -86
  72. data/spec/integration/container/autoloader_spec.rb +0 -82
  73. data/spec/integration/container/imports_spec.rb +0 -253
  74. data/spec/integration/container/prepare_container_spec.rb +0 -125
  75. data/spec/integration/container/provider_environment_spec.rb +0 -52
  76. data/spec/integration/container/provider_lifecycle_spec.rb +0 -61
  77. data/spec/integration/container/shutdown_spec.rb +0 -91
  78. data/spec/integration/container/standard_providers/rack_provider_spec.rb +0 -44
  79. data/spec/integration/container/standard_providers_spec.rb +0 -124
  80. data/spec/integration/db/auto_registration_spec.rb +0 -39
  81. data/spec/integration/db/commands_spec.rb +0 -80
  82. data/spec/integration/db/db_inflector_spec.rb +0 -57
  83. data/spec/integration/db/db_slices_spec.rb +0 -398
  84. data/spec/integration/db/db_spec.rb +0 -245
  85. data/spec/integration/db/gateways_spec.rb +0 -361
  86. data/spec/integration/db/logging_spec.rb +0 -301
  87. data/spec/integration/db/mappers_spec.rb +0 -84
  88. data/spec/integration/db/provider_config_spec.rb +0 -88
  89. data/spec/integration/db/provider_spec.rb +0 -35
  90. data/spec/integration/db/relations_spec.rb +0 -60
  91. data/spec/integration/db/repo_spec.rb +0 -300
  92. data/spec/integration/db/slices_importing_from_parent.rb +0 -130
  93. data/spec/integration/dotenv_loading_spec.rb +0 -138
  94. data/spec/integration/logging/exception_logging_spec.rb +0 -120
  95. data/spec/integration/logging/notifications_spec.rb +0 -68
  96. data/spec/integration/logging/request_logging_spec.rb +0 -202
  97. data/spec/integration/operations/extension_spec.rb +0 -122
  98. data/spec/integration/rack_app/body_parser_spec.rb +0 -108
  99. data/spec/integration/rack_app/method_override_spec.rb +0 -97
  100. data/spec/integration/rack_app/middleware_spec.rb +0 -720
  101. data/spec/integration/rack_app/non_booted_rack_app_spec.rb +0 -104
  102. data/spec/integration/rack_app/rack_app_spec.rb +0 -442
  103. data/spec/integration/rake_tasks_spec.rb +0 -107
  104. data/spec/integration/router/resource_routes_spec.rb +0 -281
  105. data/spec/integration/settings/access_in_slice_class_body_spec.rb +0 -83
  106. data/spec/integration/settings/access_to_constants_spec.rb +0 -46
  107. data/spec/integration/settings/loading_from_env_spec.rb +0 -188
  108. data/spec/integration/settings/settings_component_loading_spec.rb +0 -113
  109. data/spec/integration/settings/slice_registration_spec.rb +0 -145
  110. data/spec/integration/settings/using_types_spec.rb +0 -80
  111. data/spec/integration/setup_spec.rb +0 -165
  112. data/spec/integration/slices/external_slice_spec.rb +0 -91
  113. data/spec/integration/slices/slice_configuration_spec.rb +0 -42
  114. data/spec/integration/slices/slice_loading_spec.rb +0 -171
  115. data/spec/integration/slices/slice_registrations_spec.rb +0 -80
  116. data/spec/integration/slices/slice_routing_spec.rb +0 -219
  117. data/spec/integration/slices_spec.rb +0 -471
  118. data/spec/integration/view/config/default_context_spec.rb +0 -149
  119. data/spec/integration/view/config/inflector_spec.rb +0 -57
  120. data/spec/integration/view/config/part_class_spec.rb +0 -147
  121. data/spec/integration/view/config/part_namespace_spec.rb +0 -103
  122. data/spec/integration/view/config/paths_spec.rb +0 -119
  123. data/spec/integration/view/config/scope_class_spec.rb +0 -147
  124. data/spec/integration/view/config/scope_namespace_spec.rb +0 -103
  125. data/spec/integration/view/config/template_spec.rb +0 -38
  126. data/spec/integration/view/context/assets_spec.rb +0 -79
  127. data/spec/integration/view/context/inflector_spec.rb +0 -40
  128. data/spec/integration/view/context/request_spec.rb +0 -57
  129. data/spec/integration/view/context/routes_spec.rb +0 -84
  130. data/spec/integration/view/helpers/form_helper_spec.rb +0 -174
  131. data/spec/integration/view/helpers/part_helpers_spec.rb +0 -124
  132. data/spec/integration/view/helpers/scope_helpers_spec.rb +0 -84
  133. data/spec/integration/view/helpers/user_defined_helpers/part_helpers_spec.rb +0 -162
  134. data/spec/integration/view/helpers/user_defined_helpers/scope_helpers_spec.rb +0 -119
  135. data/spec/integration/view/parts/default_rendering_spec.rb +0 -138
  136. data/spec/integration/view/slice_configuration_spec.rb +0 -289
  137. data/spec/integration/view/views_spec.rb +0 -103
  138. data/spec/integration/web/content_security_policy_nonce_spec.rb +0 -251
  139. data/spec/integration/web/render_detailed_errors_spec.rb +0 -107
  140. data/spec/integration/web/render_errors_spec.rb +0 -242
  141. data/spec/integration/web/welcome_view_spec.rb +0 -84
  142. data/spec/spec_helper.rb +0 -28
  143. data/spec/support/app_integration.rb +0 -157
  144. data/spec/support/coverage.rb +0 -1
  145. data/spec/support/matchers.rb +0 -32
  146. data/spec/support/rspec.rb +0 -27
  147. data/spec/unit/hanami/config/actions/content_security_policy_spec.rb +0 -96
  148. data/spec/unit/hanami/config/actions/cookies_spec.rb +0 -46
  149. data/spec/unit/hanami/config/actions/csrf_protection_spec.rb +0 -58
  150. data/spec/unit/hanami/config/actions/default_values_spec.rb +0 -43
  151. data/spec/unit/hanami/config/actions/sessions_spec.rb +0 -48
  152. data/spec/unit/hanami/config/actions_spec.rb +0 -52
  153. data/spec/unit/hanami/config/base_url_spec.rb +0 -25
  154. data/spec/unit/hanami/config/console_spec.rb +0 -22
  155. data/spec/unit/hanami/config/db_spec.rb +0 -38
  156. data/spec/unit/hanami/config/inflector_spec.rb +0 -35
  157. data/spec/unit/hanami/config/logger_spec.rb +0 -195
  158. data/spec/unit/hanami/config/render_detailed_errors_spec.rb +0 -25
  159. data/spec/unit/hanami/config/render_errors_spec.rb +0 -25
  160. data/spec/unit/hanami/config/router_spec.rb +0 -44
  161. data/spec/unit/hanami/config/slices_spec.rb +0 -34
  162. data/spec/unit/hanami/config/views_spec.rb +0 -80
  163. data/spec/unit/hanami/env_spec.rb +0 -37
  164. data/spec/unit/hanami/extensions/view/context_spec.rb +0 -59
  165. data/spec/unit/hanami/helpers/assets_helper/asset_url_spec.rb +0 -120
  166. data/spec/unit/hanami/helpers/assets_helper/audio_tag_spec.rb +0 -132
  167. data/spec/unit/hanami/helpers/assets_helper/favicon_tag_spec.rb +0 -87
  168. data/spec/unit/hanami/helpers/assets_helper/image_tag_spec.rb +0 -92
  169. data/spec/unit/hanami/helpers/assets_helper/javascript_tag_spec.rb +0 -143
  170. data/spec/unit/hanami/helpers/assets_helper/stylesheet_tag_spec.rb +0 -126
  171. data/spec/unit/hanami/helpers/assets_helper/video_tag_spec.rb +0 -136
  172. data/spec/unit/hanami/helpers/form_helper_spec.rb +0 -2857
  173. data/spec/unit/hanami/port_spec.rb +0 -117
  174. data/spec/unit/hanami/providers/db/config/default_config_spec.rb +0 -100
  175. data/spec/unit/hanami/providers/db/config/gateway_spec.rb +0 -73
  176. data/spec/unit/hanami/providers/db/config_spec.rb +0 -143
  177. data/spec/unit/hanami/router/errors/not_allowed_error_spec.rb +0 -27
  178. data/spec/unit/hanami/router/errors/not_found_error_spec.rb +0 -22
  179. data/spec/unit/hanami/settings/env_store_spec.rb +0 -52
  180. data/spec/unit/hanami/settings_spec.rb +0 -111
  181. data/spec/unit/hanami/slice_configurable_spec.rb +0 -141
  182. data/spec/unit/hanami/slice_name_spec.rb +0 -47
  183. data/spec/unit/hanami/slice_spec.rb +0 -99
  184. data/spec/unit/hanami/web/rack_logger_spec.rb +0 -99
@@ -1,284 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe "App action / 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/action.rb", <<~'RUBY'
16
- require "hanami/action"
17
-
18
- module TestApp
19
- class Action < Hanami::Action
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 actions config from the app", :aggregate_failures do
35
- prepare_app
36
-
37
- expect(TestApp::Action.config.formats.accepted).to eq []
38
- end
39
-
40
- it "applies actions config from the app" do
41
- Hanami.app.config.actions.formats.accepted = [:json]
42
-
43
- prepare_app
44
-
45
- expect(TestApp::Action.config.formats.accepted).to eq [:json]
46
- end
47
-
48
- it "does not override config in the base class" do
49
- Hanami.app.config.actions.formats.accepted = [:csv]
50
-
51
- prepare_app
52
-
53
- TestApp::Action.config.formats.accepted = [:json]
54
-
55
- expect(TestApp::Action.config.formats.accepted).to eq [:json]
56
- end
57
- end
58
-
59
- describe "subclass in app" do
60
- before do
61
- with_directory(@dir) do
62
- write "app/actions/articles/index.rb", <<~'RUBY'
63
- module TestApp
64
- module Actions
65
- module Articles
66
- class Index < TestApp::Action
67
- end
68
- end
69
- end
70
- end
71
- RUBY
72
- end
73
- end
74
-
75
- it "applies default actions config from the app", :aggregate_failures do
76
- prepare_app
77
-
78
- expect(TestApp::Actions::Articles::Index.config.formats.accepted).to eq []
79
- end
80
-
81
- it "applies actions config from the app" do
82
- Hanami.app.config.actions.formats.accepted = [:json]
83
-
84
- prepare_app
85
-
86
- expect(TestApp::Actions::Articles::Index.config.formats.accepted).to eq [:json]
87
- end
88
-
89
- it "applies config from the base class" do
90
- prepare_app
91
-
92
- TestApp::Action.config.formats.accepted = [:json]
93
-
94
- expect(TestApp::Actions::Articles::Index.config.formats.accepted).to eq [:json]
95
- end
96
- end
97
-
98
- describe "subclass in slice" do
99
- before do
100
- with_directory(@dir) do
101
- write "slices/admin/actions/articles/index.rb", <<~'RUBY'
102
- module Admin
103
- module Actions
104
- module Articles
105
- class Index < TestApp::Action
106
- end
107
- end
108
- end
109
- end
110
- RUBY
111
- end
112
- end
113
-
114
- it "applies default actions config from the app", :aggregate_failures do
115
- prepare_app
116
-
117
- expect(Admin::Actions::Articles::Index.config.formats.accepted).to eq []
118
- end
119
-
120
- it "applies actions config from the app" do
121
- Hanami.app.config.actions.formats.accepted = [:json]
122
-
123
- prepare_app
124
-
125
- expect(Admin::Actions::Articles::Index.config.formats.accepted).to eq [:json]
126
- end
127
-
128
- it "applies config from the base class" do
129
- prepare_app
130
-
131
- TestApp::Action.config.formats.accepted = [:json]
132
-
133
- expect(Admin::Actions::Articles::Index.config.formats.accepted).to eq [:json]
134
- end
135
- end
136
- end
137
-
138
- describe "inheriting from a slice-level base class, in turn inheriting from an app-level base class" do
139
- before do
140
- with_directory(@dir) do
141
- write "slices/admin/action.rb", <<~'RUBY'
142
- module Admin
143
- class Action < TestApp::Action
144
- end
145
- end
146
- RUBY
147
- end
148
- end
149
-
150
- describe "slice-level base class" do
151
- it "applies default actions config from the app", :aggregate_failures do
152
- prepare_app
153
-
154
- expect(Admin::Action.config.formats.accepted).to eq []
155
- end
156
-
157
- it "applies actions config from the app" do
158
- Hanami.app.config.actions.formats.accepted = [:json]
159
-
160
- prepare_app
161
-
162
- expect(Admin::Action.config.formats.accepted).to eq [:json]
163
- end
164
-
165
- it "applies config from the app base class" do
166
- prepare_app
167
-
168
- TestApp::Action.config.formats.accepted = [:json]
169
-
170
- expect(Admin::Action.config.formats.accepted).to eq [:json]
171
- end
172
-
173
- context "slice actions config present" do
174
- before do
175
- with_directory(@dir) do
176
- write "config/slices/admin.rb", <<~'RUBY'
177
- module Admin
178
- class Slice < Hanami::Slice
179
- config.actions.format :csv
180
- end
181
- end
182
- RUBY
183
- end
184
- end
185
-
186
- it "applies actions config from the slice" do
187
- prepare_app
188
-
189
- expect(Admin::Action.config.formats.accepted).to eq [:csv]
190
- end
191
-
192
- it "prefers actions config from the slice over config from the app-level base class" do
193
- prepare_app
194
-
195
- TestApp::Action.config.formats.accepted = [:json]
196
-
197
- expect(Admin::Action.config.formats.accepted).to eq [:csv]
198
- end
199
-
200
- it "prefers config from the base class over actions config from the slice" do
201
- prepare_app
202
-
203
- TestApp::Action.config.formats.accepted = [:csv]
204
- Admin::Action.config.formats.accepted = [:json]
205
-
206
- expect(Admin::Action.config.formats.accepted).to eq [:json]
207
- end
208
- end
209
- end
210
-
211
- describe "subclass in slice" do
212
- before do
213
- with_directory(@dir) do
214
- write "slices/admin/actions/articles/index.rb", <<~'RUBY'
215
- module Admin
216
- module Actions
217
- module Articles
218
- class Index < Admin::Action
219
- end
220
- end
221
- end
222
- end
223
- RUBY
224
- end
225
- end
226
-
227
- it "applies default actions config from the app", :aggregate_failures do
228
- prepare_app
229
-
230
- expect(Admin::Actions::Articles::Index.config.formats.accepted).to eq []
231
- end
232
-
233
- it "applies actions config from the app" do
234
- Hanami.app.config.actions.formats.accepted = [:json]
235
-
236
- prepare_app
237
-
238
- expect(Admin::Actions::Articles::Index.config.formats.accepted).to eq [:json]
239
- end
240
-
241
- it "applies actions config from the slice" do
242
- with_directory(@dir) do
243
- write "config/slices/admin.rb", <<~'RUBY'
244
- module Admin
245
- class Slice < Hanami::Slice
246
- config.actions.formats.accepted = [:json]
247
- end
248
- end
249
- RUBY
250
- end
251
-
252
- prepare_app
253
-
254
- expect(Admin::Actions::Articles::Index.config.formats.accepted).to eq [:json]
255
- end
256
-
257
- it "applies config from the slice base class" do
258
- prepare_app
259
-
260
- Admin::Action.config.formats.accepted = [:json]
261
-
262
- expect(Admin::Actions::Articles::Index.config.formats.accepted).to eq [:json]
263
- end
264
-
265
- it "prefers config from the slice base class over actions config from the slice" do
266
- with_directory(@dir) do
267
- write "config/slices/admin.rb", <<~'RUBY'
268
- module Admin
269
- class Slice < Hanami::Slice
270
- config.actions.format :csv
271
- end
272
- end
273
- RUBY
274
- end
275
-
276
- prepare_app
277
-
278
- Admin::Action.config.formats.accepted = [:json]
279
-
280
- expect(Admin::Actions::Articles::Index.config.formats.accepted).to eq [:json]
281
- end
282
- end
283
- end
284
- end
@@ -1,247 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe "App action / View rendering / Automatic rendering", :app_integration do
4
- it "Renders a view automatically, passing all params and exposures" do
5
- within_app do
6
- write "app/actions/profile/show.rb", <<~RUBY
7
- module TestApp
8
- module Actions
9
- module Profile
10
- class Show < TestApp::Action
11
- def handle(req, res)
12
- res[:favorite_number] = 123
13
- end
14
- end
15
- end
16
- end
17
- end
18
- RUBY
19
-
20
- write "app/views/profile/show.rb", <<~RUBY
21
- module TestApp
22
- module Views
23
- module Profile
24
- class Show < TestApp::View
25
- expose :name, :favorite_number
26
- end
27
- end
28
- end
29
- end
30
- RUBY
31
-
32
- write "app/templates/profile/show.html.slim", <<~'SLIM'
33
- h1 Hello, #{name}. Your favorite number is #{favorite_number}, right?
34
- SLIM
35
-
36
- require "hanami/prepare"
37
-
38
- action = TestApp::App["actions.profile.show"]
39
- response = action.(name: "Jennifer")
40
- rendered = response.body[0]
41
-
42
- expect(rendered).to eq "<html><body><h1>Hello, Jennifer. Your favorite number is 123, right?</h1></body></html>"
43
- expect(response.status).to eq 200
44
- end
45
- end
46
-
47
- it "Does not render a view automatically when #render? returns false " do
48
- within_app do
49
- write "app/actions/profile/show.rb", <<~RUBY
50
- module TestApp
51
- module Actions
52
- module Profile
53
- class Show < TestApp::Action
54
- def handle(req, res)
55
- res[:favorite_number] = 123
56
- end
57
-
58
- def auto_render?(_res)
59
- false
60
- end
61
- end
62
- end
63
- end
64
- end
65
- RUBY
66
-
67
- write "app/views/profile/show.rb", <<~RUBY
68
- module TestApp
69
- module Views
70
- module Profile
71
- class Show < TestApp::View
72
- expose :name, :favorite_number
73
- end
74
- end
75
- end
76
- end
77
- RUBY
78
-
79
- write "app/templates/profile/show.html.slim", <<~'SLIM'
80
- h1 Hello, #{name}. Your favorite number is #{favorite_number}, right?
81
- SLIM
82
-
83
- require "hanami/prepare"
84
-
85
- action = TestApp::App["actions.profile.show"]
86
- response = action.(name: "Jennifer")
87
-
88
- expect(response.body).to eq []
89
- expect(response.status).to eq 200
90
- end
91
- end
92
-
93
- it "Doesn't render view automatically when body is already assigned" do
94
- within_app do
95
- write "app/actions/profile/show.rb", <<~RUBY
96
- module TestApp
97
- module Actions
98
- module Profile
99
- class Show < TestApp::Action
100
- def handle(req, res)
101
- res.body = "200: Okay okay okay"
102
- end
103
- end
104
- end
105
- end
106
- end
107
- RUBY
108
-
109
- write "app/views/profile/show.rb", <<~RUBY
110
- module TestApp
111
- module Views
112
- module Profile
113
- class Show < TestApp::View
114
- expose :name, :favorite_number
115
- end
116
- end
117
- end
118
- end
119
- RUBY
120
-
121
- write "app/templates/profile/show.html.slim", <<~'SLIM'
122
- h1 Hello, #{name}. Your favorite number is #{favorite_number}, right?
123
- SLIM
124
-
125
- require "hanami/prepare"
126
-
127
- action = TestApp::App["actions.profile.show"]
128
- response = action.(name: "Jennifer")
129
- rendered = response.body[0]
130
-
131
- expect(rendered).to eq "200: Okay okay okay"
132
- expect(response.status).to eq 200
133
- end
134
- end
135
-
136
- it "Doesn't render view automatically when halt is called" do
137
- within_app do
138
- write "app/actions/profile/show.rb", <<~RUBY
139
- module TestApp
140
- module Actions
141
- module Profile
142
- class Show < TestApp::Action
143
- def handle(req, res)
144
- halt 404
145
- end
146
- end
147
- end
148
- end
149
- end
150
- RUBY
151
-
152
- write "app/views/profile/show.rb", <<~RUBY
153
- module TestApp
154
- module Views
155
- module Profile
156
- class Show < TestApp::View
157
- expose :name
158
- end
159
- end
160
- end
161
- end
162
- RUBY
163
-
164
- # This template will crash if not rendered with a valid `name` string. The absence
165
- # of a crash here tells us that the view was never rendered.
166
- write "app/templates/profile/show.html.slim", <<~'SLIM'
167
- h1 Hello, #{name.to_str}!
168
- SLIM
169
-
170
- require "hanami/prepare"
171
-
172
- # Call the action without a `name` param, thereby ensuring the view will raise an
173
- # error if rendered
174
- action = TestApp::App["actions.profile.show"]
175
- response = action.({})
176
- rendered = response.body[0]
177
-
178
- aggregate_failures do
179
- expect(rendered).to eq "Not Found"
180
- expect(response.status).to eq 404
181
- end
182
- end
183
- end
184
-
185
- it "Does not render if no view is available" do
186
- within_app do
187
- write "app/actions/profile/show.rb", <<~RUBY
188
- module TestApp
189
- module Actions
190
- module Profile
191
- class Show < TestApp::Action
192
- end
193
- end
194
- end
195
- end
196
- RUBY
197
-
198
- require "hanami/prepare"
199
-
200
- action = TestApp::App["actions.profile.show"]
201
- response = action.({})
202
- expect(response.body).to eq []
203
- expect(response.status).to eq 200
204
- end
205
- end
206
-
207
- def within_app
208
- with_tmp_directory(Dir.mktmpdir) do
209
- write "config/app.rb", <<~RUBY
210
- require "hanami"
211
-
212
- module TestApp
213
- class App < Hanami::App
214
- end
215
- end
216
- RUBY
217
-
218
- write "app/action.rb", <<~RUBY
219
- # auto_register: false
220
-
221
- module TestApp
222
- class Action < Hanami::Action
223
- end
224
- end
225
- RUBY
226
-
227
- write "app/view.rb", <<~RUBY
228
- # auto_register: false
229
-
230
- require "hanami/view"
231
-
232
- module TestApp
233
- class View < Hanami::View
234
- end
235
- end
236
- RUBY
237
-
238
- write "app/templates/layouts/app.html.slim", <<~SLIM
239
- html
240
- body
241
- == yield
242
- SLIM
243
-
244
- yield
245
- end
246
- end
247
- end
@@ -1,115 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "hanami"
4
-
5
- RSpec.describe "App action / View rendering / Paired view inference", :app_integration do
6
- before do
7
- module TestApp
8
- class App < Hanami::App
9
- end
10
- end
11
-
12
- Hanami.app.prepare
13
-
14
- module TestApp
15
- class Action < Hanami::Action
16
- end
17
- end
18
- end
19
-
20
- let(:action) { action_class.new }
21
-
22
- describe "Ordinary action" do
23
- before do
24
- module TestApp
25
- module Actions
26
- module Articles
27
- class Index < TestApp::Action
28
- end
29
- end
30
- end
31
- end
32
- end
33
-
34
- let(:action_class) { TestApp::Actions::Articles::Index }
35
-
36
- context "Paired view exists" do
37
- before do
38
- TestApp::App.register "views.articles.index", view
39
- end
40
-
41
- let(:view) { double(:view) }
42
-
43
- it "auto-injects a paired view from a matching container identifier" do
44
- expect(action.view).to be view
45
- end
46
-
47
- context "Another view explicitly auto-injected" do
48
- before do
49
- module TestApp
50
- module Actions
51
- module Articles
52
- class Index < TestApp::Action
53
- include Deps[view: "views.articles.custom"]
54
- end
55
- end
56
- end
57
- end
58
-
59
- TestApp::App.register "views.articles.custom", explicit_view
60
- end
61
-
62
- let(:action_class) { TestApp::Actions::Articles::Index }
63
- let(:explicit_view) { double(:explicit_view) }
64
-
65
- it "respects the explicitly auto-injected view" do
66
- expect(action.view).to be explicit_view
67
- end
68
- end
69
- end
70
-
71
- context "No paired view exists" do
72
- it "does not auto-inject any view" do
73
- expect(action.view).to be_nil
74
- end
75
- end
76
- end
77
-
78
- describe "RESTful action" do
79
- before do
80
- module TestApp
81
- module Actions
82
- module Articles
83
- class Create < TestApp::Action
84
- end
85
- end
86
- end
87
- end
88
- end
89
-
90
- let(:action_class) { TestApp::Actions::Articles::Create }
91
- let(:direct_paired_view) { double(:direct_paired_view) }
92
- let(:alternative_paired_view) { double(:alternative_paired_view) }
93
-
94
- context "Direct paired view exists" do
95
- before do
96
- TestApp::App.register "views.articles.create", direct_paired_view
97
- TestApp::App.register "views.articles.new", alternative_paired_view
98
- end
99
-
100
- it "auto-injects the directly paired view" do
101
- expect(action.view).to be direct_paired_view
102
- end
103
- end
104
-
105
- context "Alternative paired view exists" do
106
- before do
107
- TestApp::App.register "views.articles.new", alternative_paired_view
108
- end
109
-
110
- it "auto-injects the alternative paired view" do
111
- expect(action.view).to be alternative_paired_view
112
- end
113
- end
114
- end
115
- end