hanami 2.3.2 → 3.0.0

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 (189) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +103 -19
  3. data/LICENSE +20 -0
  4. data/README.md +18 -35
  5. data/hanami.gemspec +36 -37
  6. data/lib/hanami/app.rb +12 -2
  7. data/lib/hanami/config/db.rb +2 -0
  8. data/lib/hanami/config/i18n.rb +138 -0
  9. data/lib/hanami/config/logger.rb +15 -7
  10. data/lib/hanami/config/null_config.rb +1 -1
  11. data/lib/hanami/config/views.rb +17 -0
  12. data/lib/hanami/config.rb +66 -22
  13. data/lib/hanami/errors.rb +6 -0
  14. data/lib/hanami/extensions/action/i18n_helper.rb +64 -0
  15. data/lib/hanami/extensions/action/name_inferrer.rb +34 -0
  16. data/lib/hanami/extensions/action/slice_configured_action.rb +31 -2
  17. data/lib/hanami/extensions/action.rb +20 -7
  18. data/lib/hanami/extensions/mailer/slice_configured_mailer.rb +134 -0
  19. data/lib/hanami/extensions/mailer.rb +28 -0
  20. data/lib/hanami/extensions/operation/slice_configured_db_operation.rb +2 -0
  21. data/lib/hanami/extensions/view/context.rb +26 -4
  22. data/lib/hanami/extensions/view/part.rb +2 -0
  23. data/lib/hanami/extensions/view/slice_configured_context.rb +7 -0
  24. data/lib/hanami/extensions/view/slice_configured_part.rb +2 -0
  25. data/lib/hanami/extensions/view/slice_configured_view.rb +8 -8
  26. data/lib/hanami/extensions/view/standard_helpers.rb +4 -0
  27. data/lib/hanami/extensions.rb +6 -1
  28. data/lib/hanami/helpers/assets_helper.rb +0 -4
  29. data/lib/hanami/helpers/form_helper.rb +1 -1
  30. data/lib/hanami/helpers/i18n_helper.rb +241 -0
  31. data/lib/hanami/logger/rack_formatter.rb +73 -0
  32. data/lib/hanami/logger/sql_formatter.rb +80 -0
  33. data/lib/hanami/logger/sql_logger.rb +48 -0
  34. data/lib/hanami/middleware/render_errors.rb +2 -2
  35. data/lib/hanami/providers/db.rb +7 -2
  36. data/lib/hanami/providers/db_logging.rb +4 -7
  37. data/lib/hanami/providers/i18n/backend.rb +373 -0
  38. data/lib/hanami/providers/i18n/locale/en.yml +57 -0
  39. data/lib/hanami/providers/i18n.rb +114 -0
  40. data/lib/hanami/providers/logger.rb +23 -1
  41. data/lib/hanami/providers/mailers.rb +101 -0
  42. data/lib/hanami/routes.rb +1 -0
  43. data/lib/hanami/settings/composite_store.rb +53 -0
  44. data/lib/hanami/settings.rb +4 -4
  45. data/lib/hanami/slice/router.rb +15 -10
  46. data/lib/hanami/slice.rb +102 -11
  47. data/lib/hanami/slice_configurable.rb +1 -3
  48. data/lib/hanami/slice_registrar.rb +2 -2
  49. data/lib/hanami/universal_logger.rb +250 -0
  50. data/lib/hanami/version.rb +1 -1
  51. data/lib/hanami/web/rack_logger.rb +2 -80
  52. data/lib/hanami/web/welcome.html.erb +443 -58
  53. data/lib/hanami.rb +4 -2
  54. metadata +34 -280
  55. data/CODE_OF_CONDUCT.md +0 -74
  56. data/FEATURES.md +0 -269
  57. data/LICENSE.md +0 -22
  58. data/spec/integration/action/cookies_spec.rb +0 -58
  59. data/spec/integration/action/csrf_protection_spec.rb +0 -54
  60. data/spec/integration/action/format_config_spec.rb +0 -129
  61. data/spec/integration/action/routes_spec.rb +0 -71
  62. data/spec/integration/action/sessions_spec.rb +0 -50
  63. data/spec/integration/action/slice_configuration_spec.rb +0 -284
  64. data/spec/integration/action/view_rendering/automatic_rendering_spec.rb +0 -247
  65. data/spec/integration/action/view_rendering/paired_view_inference_spec.rb +0 -115
  66. data/spec/integration/action/view_rendering/view_context_spec.rb +0 -221
  67. data/spec/integration/action/view_rendering_spec.rb +0 -89
  68. data/spec/integration/assets/assets_spec.rb +0 -155
  69. data/spec/integration/assets/cross_slice_assets_helpers_spec.rb +0 -129
  70. data/spec/integration/assets/serve_static_assets_spec.rb +0 -152
  71. data/spec/integration/code_loading/loading_from_app_spec.rb +0 -152
  72. data/spec/integration/code_loading/loading_from_lib_spec.rb +0 -242
  73. data/spec/integration/code_loading/loading_from_slice_spec.rb +0 -165
  74. data/spec/integration/container/application_routes_helper_spec.rb +0 -48
  75. data/spec/integration/container/auto_injection_spec.rb +0 -53
  76. data/spec/integration/container/auto_registration_spec.rb +0 -86
  77. data/spec/integration/container/autoloader_spec.rb +0 -82
  78. data/spec/integration/container/imports_spec.rb +0 -253
  79. data/spec/integration/container/prepare_container_spec.rb +0 -125
  80. data/spec/integration/container/provider_environment_spec.rb +0 -52
  81. data/spec/integration/container/provider_lifecycle_spec.rb +0 -61
  82. data/spec/integration/container/shutdown_spec.rb +0 -91
  83. data/spec/integration/container/standard_providers/rack_provider_spec.rb +0 -44
  84. data/spec/integration/container/standard_providers_spec.rb +0 -124
  85. data/spec/integration/db/auto_registration_spec.rb +0 -39
  86. data/spec/integration/db/commands_spec.rb +0 -80
  87. data/spec/integration/db/db_inflector_spec.rb +0 -57
  88. data/spec/integration/db/db_slices_spec.rb +0 -398
  89. data/spec/integration/db/db_spec.rb +0 -245
  90. data/spec/integration/db/gateways_spec.rb +0 -361
  91. data/spec/integration/db/logging_spec.rb +0 -301
  92. data/spec/integration/db/mappers_spec.rb +0 -84
  93. data/spec/integration/db/provider_config_spec.rb +0 -88
  94. data/spec/integration/db/provider_spec.rb +0 -35
  95. data/spec/integration/db/relations_spec.rb +0 -60
  96. data/spec/integration/db/repo_spec.rb +0 -300
  97. data/spec/integration/db/slices_importing_from_parent.rb +0 -130
  98. data/spec/integration/dotenv_loading_spec.rb +0 -138
  99. data/spec/integration/logging/exception_logging_spec.rb +0 -120
  100. data/spec/integration/logging/notifications_spec.rb +0 -68
  101. data/spec/integration/logging/request_logging_spec.rb +0 -202
  102. data/spec/integration/operations/extension_spec.rb +0 -122
  103. data/spec/integration/rack_app/body_parser_spec.rb +0 -108
  104. data/spec/integration/rack_app/method_override_spec.rb +0 -97
  105. data/spec/integration/rack_app/middleware_spec.rb +0 -720
  106. data/spec/integration/rack_app/non_booted_rack_app_spec.rb +0 -104
  107. data/spec/integration/rack_app/rack_app_spec.rb +0 -442
  108. data/spec/integration/rake_tasks_spec.rb +0 -107
  109. data/spec/integration/router/resource_routes_spec.rb +0 -281
  110. data/spec/integration/settings/access_in_slice_class_body_spec.rb +0 -83
  111. data/spec/integration/settings/access_to_constants_spec.rb +0 -46
  112. data/spec/integration/settings/loading_from_env_spec.rb +0 -188
  113. data/spec/integration/settings/settings_component_loading_spec.rb +0 -113
  114. data/spec/integration/settings/slice_registration_spec.rb +0 -145
  115. data/spec/integration/settings/using_types_spec.rb +0 -80
  116. data/spec/integration/setup_spec.rb +0 -165
  117. data/spec/integration/slices/external_slice_spec.rb +0 -91
  118. data/spec/integration/slices/slice_configuration_spec.rb +0 -42
  119. data/spec/integration/slices/slice_loading_spec.rb +0 -171
  120. data/spec/integration/slices/slice_registrations_spec.rb +0 -80
  121. data/spec/integration/slices/slice_routing_spec.rb +0 -219
  122. data/spec/integration/slices_spec.rb +0 -471
  123. data/spec/integration/view/config/default_context_spec.rb +0 -149
  124. data/spec/integration/view/config/inflector_spec.rb +0 -57
  125. data/spec/integration/view/config/part_class_spec.rb +0 -147
  126. data/spec/integration/view/config/part_namespace_spec.rb +0 -103
  127. data/spec/integration/view/config/paths_spec.rb +0 -119
  128. data/spec/integration/view/config/scope_class_spec.rb +0 -147
  129. data/spec/integration/view/config/scope_namespace_spec.rb +0 -103
  130. data/spec/integration/view/config/template_spec.rb +0 -38
  131. data/spec/integration/view/context/assets_spec.rb +0 -79
  132. data/spec/integration/view/context/inflector_spec.rb +0 -40
  133. data/spec/integration/view/context/request_spec.rb +0 -57
  134. data/spec/integration/view/context/routes_spec.rb +0 -84
  135. data/spec/integration/view/helpers/form_helper_spec.rb +0 -174
  136. data/spec/integration/view/helpers/part_helpers_spec.rb +0 -124
  137. data/spec/integration/view/helpers/scope_helpers_spec.rb +0 -84
  138. data/spec/integration/view/helpers/user_defined_helpers/part_helpers_spec.rb +0 -162
  139. data/spec/integration/view/helpers/user_defined_helpers/scope_helpers_spec.rb +0 -119
  140. data/spec/integration/view/parts/default_rendering_spec.rb +0 -138
  141. data/spec/integration/view/slice_configuration_spec.rb +0 -289
  142. data/spec/integration/view/views_spec.rb +0 -103
  143. data/spec/integration/web/content_security_policy_nonce_spec.rb +0 -251
  144. data/spec/integration/web/render_detailed_errors_spec.rb +0 -107
  145. data/spec/integration/web/render_errors_spec.rb +0 -242
  146. data/spec/integration/web/welcome_view_spec.rb +0 -84
  147. data/spec/spec_helper.rb +0 -28
  148. data/spec/support/app_integration.rb +0 -157
  149. data/spec/support/coverage.rb +0 -1
  150. data/spec/support/matchers.rb +0 -32
  151. data/spec/support/rspec.rb +0 -27
  152. data/spec/unit/hanami/config/actions/content_security_policy_spec.rb +0 -96
  153. data/spec/unit/hanami/config/actions/cookies_spec.rb +0 -46
  154. data/spec/unit/hanami/config/actions/csrf_protection_spec.rb +0 -58
  155. data/spec/unit/hanami/config/actions/default_values_spec.rb +0 -43
  156. data/spec/unit/hanami/config/actions/sessions_spec.rb +0 -48
  157. data/spec/unit/hanami/config/actions_spec.rb +0 -52
  158. data/spec/unit/hanami/config/base_url_spec.rb +0 -25
  159. data/spec/unit/hanami/config/console_spec.rb +0 -22
  160. data/spec/unit/hanami/config/db_spec.rb +0 -38
  161. data/spec/unit/hanami/config/inflector_spec.rb +0 -35
  162. data/spec/unit/hanami/config/logger_spec.rb +0 -195
  163. data/spec/unit/hanami/config/render_detailed_errors_spec.rb +0 -25
  164. data/spec/unit/hanami/config/render_errors_spec.rb +0 -25
  165. data/spec/unit/hanami/config/router_spec.rb +0 -44
  166. data/spec/unit/hanami/config/slices_spec.rb +0 -34
  167. data/spec/unit/hanami/config/views_spec.rb +0 -80
  168. data/spec/unit/hanami/env_spec.rb +0 -37
  169. data/spec/unit/hanami/extensions/view/context_spec.rb +0 -59
  170. data/spec/unit/hanami/helpers/assets_helper/asset_url_spec.rb +0 -120
  171. data/spec/unit/hanami/helpers/assets_helper/audio_tag_spec.rb +0 -132
  172. data/spec/unit/hanami/helpers/assets_helper/favicon_tag_spec.rb +0 -87
  173. data/spec/unit/hanami/helpers/assets_helper/image_tag_spec.rb +0 -92
  174. data/spec/unit/hanami/helpers/assets_helper/javascript_tag_spec.rb +0 -143
  175. data/spec/unit/hanami/helpers/assets_helper/stylesheet_tag_spec.rb +0 -126
  176. data/spec/unit/hanami/helpers/assets_helper/video_tag_spec.rb +0 -136
  177. data/spec/unit/hanami/helpers/form_helper_spec.rb +0 -2857
  178. data/spec/unit/hanami/port_spec.rb +0 -117
  179. data/spec/unit/hanami/providers/db/config/default_config_spec.rb +0 -100
  180. data/spec/unit/hanami/providers/db/config/gateway_spec.rb +0 -73
  181. data/spec/unit/hanami/providers/db/config_spec.rb +0 -143
  182. data/spec/unit/hanami/router/errors/not_allowed_error_spec.rb +0 -27
  183. data/spec/unit/hanami/router/errors/not_found_error_spec.rb +0 -22
  184. data/spec/unit/hanami/settings/env_store_spec.rb +0 -52
  185. data/spec/unit/hanami/settings_spec.rb +0 -111
  186. data/spec/unit/hanami/slice_configurable_spec.rb +0 -141
  187. data/spec/unit/hanami/slice_name_spec.rb +0 -47
  188. data/spec/unit/hanami/slice_spec.rb +0 -99
  189. data/spec/unit/hanami/web/rack_logger_spec.rb +0 -99
@@ -1,281 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "dry/inflector"
4
- require "hanami/slice/router"
5
- require "json"
6
-
7
- RSpec.describe "Router / Resource routes" do
8
- let(:router) { Hanami::Slice::Router.new(routes:, resolver:, inflector: Dry::Inflector.new) { } }
9
-
10
- let(:resolver) { Hanami::Slice::Routing::Resolver.new(slice:) }
11
- let(:slice) {
12
- Class.new(Hanami::Slice).tap { |slice|
13
- allow(slice).to receive(:container) { actions_container }
14
- allow(slice).to receive(:slices) { {reviews: child_slice} }
15
- }
16
- }
17
- let(:child_slice) {
18
- Class.new(Hanami::Slice).tap { |slice|
19
- allow(slice).to receive(:container) { actions_container("[reviews]") }
20
- }
21
- }
22
- def actions_container(prefix = nil)
23
- Hash.new { |_hsh, key|
24
- Class.new { |klass|
25
- klass.define_method(:call) do |env|
26
- body = key
27
- body = "#{body} #{JSON.generate(env["router.params"])}" if env["router.params"].any?
28
- body = "#{prefix}#{body}" if prefix
29
- [200, {}, body]
30
- end
31
- }.new
32
- }.tap { |container|
33
- def container.resolve(key) = self[key]
34
- }
35
- end
36
-
37
- let(:app) { Rack::MockRequest.new(router) }
38
- def routed(method, url)
39
- app.request(method, url).body
40
- end
41
-
42
- describe "resources" do
43
- let(:routes) { proc { resources :posts } }
44
-
45
- it "routes all RESTful actions to the resource" do
46
- expect(routed("GET", "/posts")).to eq %(actions.posts.index)
47
- expect(routed("GET", "/posts/new")).to eq %(actions.posts.new)
48
- expect(routed("POST", "/posts")).to eq %(actions.posts.create)
49
- expect(routed("GET", "/posts/1")).to eq %(actions.posts.show {"id":"1"})
50
- expect(routed("GET", "/posts/1/edit")).to eq %(actions.posts.edit {"id":"1"})
51
- expect(routed("PATCH", "/posts/1")).to eq %(actions.posts.update {"id":"1"})
52
- expect(routed("DELETE", "/posts/1")).to eq %(actions.posts.destroy {"id":"1"})
53
-
54
- expect(router.path("posts")).to eq "/posts"
55
- expect(router.path("new_post")).to eq "/posts/new"
56
- expect(router.path("edit_post", id: 1)).to eq "/posts/1/edit"
57
- end
58
-
59
- describe "with :only" do
60
- let(:routes) { proc { resources :posts, only: %i(index show) } }
61
-
62
- it "routes only the given actions to the resource" do
63
- expect(routed("GET", "/posts")).to eq %(actions.posts.index)
64
- expect(routed("GET", "/posts/1")).to eq %(actions.posts.show {"id":"1"})
65
-
66
- expect(routed("GET", "/posts/new")).not_to eq %(actions.posts.new)
67
- expect(routed("POST", "/posts")).to eq "Method Not Allowed"
68
- expect(routed("GET", "/posts/1/edit")).to eq "Not Found"
69
- expect(routed("PATCH", "/posts/1")).to eq "Method Not Allowed"
70
- expect(routed("DELETE", "/posts/1")).to eq "Method Not Allowed"
71
- end
72
- end
73
-
74
- describe "with :except" do
75
- let(:routes) { proc { resources :posts, except: %i(edit update destroy) } }
76
-
77
- it "routes all except the given actions to the resource" do
78
- expect(routed("GET", "/posts")).to eq %(actions.posts.index)
79
- expect(routed("GET", "/posts/new")).to eq %(actions.posts.new)
80
- expect(routed("POST", "/posts")).to eq %(actions.posts.create)
81
- expect(routed("GET", "/posts/1")).to eq %(actions.posts.show {"id":"1"})
82
-
83
- expect(routed("GET", "/posts/1/edit")).to eq "Not Found"
84
- expect(routed("PATCH", "/posts/1")).to eq "Method Not Allowed"
85
- expect(routed("DELETE", "/posts/1")).to eq "Method Not Allowed"
86
- end
87
- end
88
-
89
- describe "with :to" do
90
- let(:routes) { proc { resources :posts, to: "articles" } }
91
-
92
- it "uses actions from the given container key namespace" do
93
- expect(routed("GET", "/posts")).to eq %(actions.articles.index)
94
- expect(routed("GET", "/posts/new")).to eq %(actions.articles.new)
95
- expect(routed("POST", "/posts")).to eq %(actions.articles.create)
96
- expect(routed("GET", "/posts/1")).to eq %(actions.articles.show {"id":"1"})
97
- expect(routed("GET", "/posts/1/edit")).to eq %(actions.articles.edit {"id":"1"})
98
- expect(routed("PATCH", "/posts/1")).to eq %(actions.articles.update {"id":"1"})
99
- expect(routed("DELETE", "/posts/1")).to eq %(actions.articles.destroy {"id":"1"})
100
- end
101
- end
102
-
103
- describe "witih :path" do
104
- let(:routes) { proc { resources :posts, path: "articles" } }
105
-
106
- it "uses the given path for the routes" do
107
- expect(routed("GET", "/articles")).to eq %(actions.posts.index)
108
- expect(routed("GET", "/articles/new")).to eq %(actions.posts.new)
109
- expect(routed("POST", "/articles")).to eq %(actions.posts.create)
110
- expect(routed("GET", "/articles/1")).to eq %(actions.posts.show {"id":"1"})
111
- expect(routed("GET", "/articles/1/edit")).to eq %(actions.posts.edit {"id":"1"})
112
- expect(routed("PATCH", "/articles/1")).to eq %(actions.posts.update {"id":"1"})
113
- expect(routed("DELETE", "/articles/1")).to eq %(actions.posts.destroy {"id":"1"})
114
- end
115
- end
116
- end
117
-
118
- describe "resource" do
119
- let(:routes) { proc { resource :profile } }
120
-
121
- it "routes all RESTful actions (except index) to the resource" do
122
- expect(routed("GET", "/profile/new")).to eq %(actions.profile.new)
123
- expect(routed("POST", "/profile")).to eq %(actions.profile.create)
124
- expect(routed("GET", "/profile")).to eq %(actions.profile.show)
125
- expect(routed("GET", "/profile/edit")).to eq %(actions.profile.edit)
126
- expect(routed("PATCH", "/profile")).to eq %(actions.profile.update)
127
- expect(routed("DELETE", "/profile")).to eq %(actions.profile.destroy)
128
-
129
- expect(routed("GET", "/profiles")).to eq "Not Found"
130
- expect(routed("GET", "/profiles/1")).to eq "Not Found"
131
- expect(routed("GET", "/profile/1")).to eq "Not Found"
132
-
133
- expect(router.path("profile")).to eq "/profile"
134
- expect(router.path("new_profile")).to eq "/profile/new"
135
- expect(router.path("edit_profile")).to eq "/profile/edit"
136
- end
137
-
138
- describe "with :only" do
139
- let(:routes) { proc { resource :profile, only: %i(show edit update) } }
140
-
141
- it "routes only the given actions to the resource" do
142
- expect(routed("GET", "/profile")).to eq %(actions.profile.show)
143
- expect(routed("GET", "/profile/edit")).to eq %(actions.profile.edit)
144
- expect(routed("PATCH", "/profile")).to eq %(actions.profile.update)
145
-
146
- expect(routed("GET", "/profile/new")).to eq "Not Found"
147
- expect(routed("POST", "/profile")).to eq "Method Not Allowed"
148
- expect(routed("DELETE", "/profile")).to eq "Method Not Allowed"
149
- end
150
- end
151
-
152
- describe "with :except" do
153
- let(:routes) { proc { resource :profile, except: %i(edit update destroy) } }
154
-
155
- it "routes all except the given actions to the resource" do
156
- expect(routed("GET", "/profile/new")).to eq %(actions.profile.new)
157
- expect(routed("POST", "/profile")).to eq %(actions.profile.create)
158
- expect(routed("GET", "/profile")).to eq %(actions.profile.show)
159
-
160
- expect(routed("GET", "/profile/edit")).to eq "Not Found"
161
- expect(routed("PATCH", "/profile")).to eq "Method Not Allowed"
162
- expect(routed("DELETE", "/profile")).to eq "Method Not Allowed"
163
- end
164
- end
165
-
166
- describe "with :to" do
167
- let(:routes) { proc { resource :profile, to: "user" } }
168
-
169
- it "uses actions from the given container key namespace" do
170
- expect(routed("GET", "/profile/new")).to eq %(actions.user.new)
171
- expect(routed("POST", "/profile")).to eq %(actions.user.create)
172
- expect(routed("GET", "/profile")).to eq %(actions.user.show)
173
- expect(routed("GET", "/profile/edit")).to eq %(actions.user.edit)
174
- expect(routed("PATCH", "/profile")).to eq %(actions.user.update)
175
- expect(routed("DELETE", "/profile")).to eq %(actions.user.destroy)
176
- end
177
- end
178
-
179
- describe "with :path" do
180
- let(:routes) { proc { resource :profile, path: "user"} }
181
-
182
- it "uses the given path for the routes" do
183
- expect(routed("GET", "/user/new")).to eq %(actions.profile.new)
184
- expect(routed("POST", "/user")).to eq %(actions.profile.create)
185
- expect(routed("GET", "/user")).to eq %(actions.profile.show)
186
- expect(routed("GET", "/user/edit")).to eq %(actions.profile.edit)
187
- expect(routed("PATCH", "/user")).to eq %(actions.profile.update)
188
- expect(routed("DELETE", "/user")).to eq %(actions.profile.destroy)
189
- end
190
- end
191
- end
192
-
193
- describe "nested resources" do
194
- let(:routes) {
195
- proc {
196
- resources :cafes, only: :show do
197
- resources :reviews, only: :index do
198
- resources :comments, only: [:index, :new, :create]
199
- end
200
- end
201
-
202
- resource :profile, only: :show do
203
- resource :avatar, only: :show do
204
- resources :comments, only: :index
205
- end
206
- end
207
- }
208
- }
209
-
210
- it "routes to the nested resources" do
211
- expect(routed("GET", "/cafes/1")).to eq %(actions.cafes.show {"id":"1"})
212
- expect(routed("GET", "/cafes/1/reviews")).to eq %(actions.cafes.reviews.index {"cafe_id":"1"})
213
- expect(routed("GET", "/cafes/1/reviews/2/comments")).to eq %(actions.cafes.reviews.comments.index {"cafe_id":"1","review_id":"2"})
214
-
215
- expect(router.path("cafe", id: 1)).to eq "/cafes/1"
216
- expect(router.path("cafe_reviews", cafe_id: 1)).to eq "/cafes/1/reviews"
217
- expect(router.path("cafe_review_comments", cafe_id: 1, review_id: 1)).to eq "/cafes/1/reviews/1/comments"
218
- expect(router.path("new_cafe_review_comment", cafe_id: 1, review_id: 1)).to eq "/cafes/1/reviews/1/comments/new"
219
-
220
- expect(routed("GET", "/profile")).to eq %(actions.profile.show)
221
- expect(routed("GET", "/profile/avatar")).to eq %(actions.profile.avatar.show)
222
- expect(routed("GET", "/profile/avatar/comments")).to eq %(actions.profile.avatar.comments.index)
223
- end
224
- end
225
-
226
- describe "standalone routes nested under resources" do
227
- let(:routes) {
228
- proc {
229
- resources :cafes, only: :show do
230
- get "/top-reviews", to: "cafes.top_reviews.index", as: :top_reviews
231
- end
232
- }
233
- }
234
-
235
- it "nests the standalone route under the resource" do
236
- expect(routed("GET", "/cafes/1")).to eq %(actions.cafes.show {"id":"1"})
237
- expect(routed("GET", "/cafes/1/top-reviews")).to eq %(actions.cafes.top_reviews.index {"cafe_id":"1"})
238
-
239
- expect(router.path("cafe_top_reviews", cafe_id: 1)).to eq "/cafes/1/top-reviews"
240
- end
241
- end
242
-
243
- describe "resources nested under scopes" do
244
- let(:routes) {
245
- proc {
246
- scope "coffee-lovers" do
247
- resources :cafes, only: :show do
248
- get "/top-reviews", to: "cafes.top_reviews.index", as: :top_reviews
249
- end
250
- end
251
- }
252
- }
253
-
254
- it "routes to the resources under the scope" do
255
- expect(routed("GET", "/coffee-lovers/cafes/1")).to eq %(actions.cafes.show {"id":"1"})
256
- expect(routed("GET", "/coffee-lovers/cafes/1/top-reviews")).to eq %(actions.cafes.top_reviews.index {"cafe_id":"1"})
257
-
258
- expect(router.path("coffee_lovers_cafe", id: 1)).to eq "/coffee-lovers/cafes/1"
259
- expect(router.path("coffee_lovers_cafe_top_reviews", cafe_id: 1)).to eq "/coffee-lovers/cafes/1/top-reviews"
260
- end
261
- end
262
-
263
- describe "slices nested under resources" do
264
- let(:routes) {
265
- proc {
266
- resources :cafes, only: :show do
267
- slice :reviews, at: "" do
268
- resources :reviews, only: :index
269
- end
270
- end
271
- }
272
- }
273
-
274
- it "routes to actions within the nested slice" do
275
- expect(routed("GET", "/cafes/1")).to eq %(actions.cafes.show {"id":"1"})
276
- expect(routed("GET", "/cafes/1/reviews")).to eq %([reviews]actions.cafes.reviews.index {"cafe_id":"1"})
277
-
278
- expect(router.path("cafe_reviews", cafe_id: 1)).to eq "/cafes/1/reviews"
279
- end
280
- end
281
- end
@@ -1,83 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe "Settings / Access within slice class bodies", :app_integration do
4
- before do
5
- @env = ENV.to_h
6
- allow(Hanami::Env).to receive(:loaded?).and_return(false)
7
- end
8
-
9
- after do
10
- ENV.replace(@env)
11
- end
12
-
13
- context "app class" do
14
- it "provides access to the settings inside the class body" do
15
- with_directory(make_tmp_directory) do
16
- write "config/app.rb", <<~'RUBY'
17
- require "hanami"
18
-
19
- module TestApp
20
- class App < Hanami::App
21
- @some_flag = settings.some_flag
22
- end
23
- end
24
- RUBY
25
-
26
- write ".env", <<~'TEXT'
27
- SOME_FLAG=true
28
- TEXT
29
-
30
- write "config/settings.rb", <<~'RUBY'
31
- module TestApp
32
- class Settings < Hanami::Settings
33
- setting :some_flag
34
- end
35
- end
36
- RUBY
37
-
38
- require "hanami/setup"
39
-
40
- expect(Hanami.app.instance_variable_get(:@some_flag)).to eq "true"
41
- end
42
- end
43
- end
44
-
45
- context "slice class" do
46
- it "provides access to the settings inside the class body" do
47
- with_directory(make_tmp_directory) do
48
- write "config/app.rb", <<~'RUBY'
49
- require "hanami"
50
-
51
- module TestApp
52
- class App < Hanami::App
53
- end
54
- end
55
- RUBY
56
-
57
- write "config/slices/main.rb", <<~'RUBY'
58
- module Main
59
- class Slice < Hanami::Slice
60
- @some_flag = settings.some_flag
61
- end
62
- end
63
- RUBY
64
-
65
- write ".env", <<~'TEXT'
66
- SOME_FLAG=true
67
- TEXT
68
-
69
- write "slices/main/config/settings.rb", <<~'RUBY'
70
- module Main
71
- class Settings < Hanami::Settings
72
- setting :some_flag
73
- end
74
- end
75
- RUBY
76
-
77
- require "hanami/prepare"
78
-
79
- expect(Main::Slice.instance_variable_get(:@some_flag)).to eq "true"
80
- end
81
- end
82
- end
83
- end
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe "Settings / Access to constants", :app_integration do
4
- before do
5
- @env = ENV.to_h
6
- end
7
-
8
- after do
9
- ENV.replace(@env)
10
- end
11
-
12
- specify "Settings can not access autoloadable constants" do
13
- with_directory(make_tmp_directory) do
14
- write "config/app.rb", <<~'RUBY'
15
- require "hanami"
16
-
17
- module TestApp
18
- class App < Hanami::App
19
- end
20
- end
21
- RUBY
22
-
23
- write "config/settings.rb", <<~'RUBY'
24
- module TestApp
25
- class Settings < Hanami::Settings
26
- setting :some_flag, constructor: TestApp::Types::Params::Bool
27
- end
28
- end
29
- RUBY
30
-
31
- write "app/types.rb", <<~'RUBY'
32
- # auto_register: false
33
-
34
- require "dry/types"
35
-
36
- module TestApp
37
- Types = Dry.Types()
38
- end
39
- RUBY
40
-
41
- require "hanami/setup"
42
-
43
- expect { Hanami.app.settings }.to raise_error(NameError, /TestApp::Types/)
44
- end
45
- end
46
- end
@@ -1,188 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe "Settings / Access to constants", :app_integration do
4
- before do
5
- @env = ENV.to_h
6
- allow(Hanami::Env).to receive(:loaded?).and_return(false)
7
- end
8
-
9
- after do
10
- ENV.replace(@env)
11
- end
12
-
13
- specify "settings are loaded from ENV" do
14
- with_tmp_directory(Dir.mktmpdir) do
15
- write "config/app.rb", <<~'RUBY'
16
- require "hanami"
17
-
18
- module TestApp
19
- class App < Hanami::App
20
- end
21
- end
22
- RUBY
23
-
24
- write "config/settings.rb", <<~'RUBY'
25
- module TestApp
26
- class Settings < Hanami::Settings
27
- setting :database_url
28
- end
29
- end
30
- RUBY
31
-
32
- ENV["DATABASE_URL"] = "postgres://localhost/database"
33
-
34
- require "hanami/prepare"
35
-
36
- expect(Hanami.app["settings"].database_url).to eq "postgres://localhost/database"
37
- end
38
- end
39
-
40
- describe "settings are loaded from .env files" do
41
- context "hanami env is development" do
42
- it "loads settings from .env.development.local, .env.local, .env.development and .env (in this order)" do
43
- with_tmp_directory(Dir.mktmpdir) do
44
- write "config/app.rb", <<~'RUBY'
45
- require "hanami"
46
-
47
- module TestApp
48
- class App < Hanami::App
49
- end
50
- end
51
- RUBY
52
-
53
- write "config/settings.rb", <<~'RUBY'
54
- module TestApp
55
- class Settings < Hanami::Settings
56
- setting :from_specific_env_local
57
- setting :from_base_local
58
- setting :from_specific_env
59
- setting :from_base
60
- end
61
- end
62
- RUBY
63
-
64
- write ".env.development.local", <<~'TEXT'
65
- FROM_SPECIFIC_ENV_LOCAL="from .env.development.local"
66
- TEXT
67
-
68
- write ".env.local", <<~'TEXT'
69
- FROM_BASE_LOCAL="from .env.local"
70
-
71
- FROM_SPECIFIC_ENV_LOCAL=nope
72
- TEXT
73
-
74
- write ".env.development", <<~'TEXT'
75
- FROM_SPECIFIC_ENV="from .env.development"
76
-
77
- FROM_SPECIFIC_ENV_LOCAL=nope
78
- FROM_BASE_LOCAL=nope
79
- TEXT
80
-
81
- write ".env", <<~'TEXT'
82
- FROM_BASE="from .env"
83
-
84
- FROM_SPECIFIC_ENV_LOCAL=nope
85
- FROM_BASE_LOCAL=nope
86
- FROM_SPECIFIC_ENV=nope
87
- TEXT
88
-
89
- ENV["HANAMI_ENV"] = "development"
90
-
91
- require "hanami/prepare"
92
-
93
- expect(Hanami.app["settings"].from_specific_env_local).to eq "from .env.development.local"
94
- expect(Hanami.app["settings"].from_base_local).to eq "from .env.local"
95
- expect(Hanami.app["settings"].from_specific_env).to eq "from .env.development"
96
- expect(Hanami.app["settings"].from_base).to eq "from .env"
97
- end
98
- end
99
-
100
- context "hanami env is test" do
101
- it "loads settings from .env.development.local, .env.development and .env (in this order)" do
102
- with_tmp_directory(Dir.mktmpdir) do
103
- write "config/app.rb", <<~'RUBY'
104
- require "hanami"
105
-
106
- module TestApp
107
- class App < Hanami::App
108
- end
109
- end
110
- RUBY
111
-
112
- write "config/settings.rb", <<~'RUBY'
113
- module TestApp
114
- class Settings < Hanami::Settings
115
- setting :from_specific_env_local
116
- setting :from_base_local
117
- setting :from_specific_env
118
- setting :from_base
119
- end
120
- end
121
- RUBY
122
-
123
- write ".env.test.local", <<~'TEXT'
124
- FROM_SPECIFIC_ENV_LOCAL="from .env.test.local"
125
- TEXT
126
-
127
- write ".env.local", <<~'TEXT'
128
- FROM_BASE_LOCAL="from .env.local"
129
- TEXT
130
-
131
- write ".env.test", <<~'TEXT'
132
- FROM_SPECIFIC_ENV="from .env.test"
133
-
134
- FROM_SPECIFIC_ENV_LOCAL=nope
135
- TEXT
136
-
137
- write ".env", <<~'TEXT'
138
- FROM_BASE="from .env"
139
-
140
- FROM_SPECIFIC_ENV_LOCAL=nope
141
- FROM_SPECIFIC_ENV=nope
142
- TEXT
143
-
144
- ENV["HANAMI_ENV"] = "test"
145
-
146
- require "hanami/prepare"
147
-
148
- expect(Hanami.app["settings"].from_specific_env_local).to eq "from .env.test.local"
149
- expect(Hanami.app["settings"].from_base_local).to be nil
150
- expect(Hanami.app["settings"].from_specific_env).to eq "from .env.test"
151
- expect(Hanami.app["settings"].from_base).to eq "from .env"
152
- end
153
- end
154
- end
155
- end
156
- end
157
-
158
- it "prefers ENV values are preferred over .env files" do
159
- with_tmp_directory(Dir.mktmpdir) do
160
- write "config/app.rb", <<~'RUBY'
161
- require "hanami"
162
-
163
- module TestApp
164
- class App < Hanami::App
165
- end
166
- end
167
- RUBY
168
-
169
- write "config/settings.rb", <<~'RUBY'
170
- module TestApp
171
- class Settings < Hanami::Settings
172
- setting :database_url
173
- end
174
- end
175
- RUBY
176
-
177
- write ".env", <<~'TEXT'
178
- DATABASE_URL=nope
179
- TEXT
180
-
181
- ENV["DATABASE_URL"] = "postgres://localhost/database"
182
-
183
- require "hanami/prepare"
184
-
185
- expect(Hanami.app["settings"].database_url).to eq "postgres://localhost/database"
186
- end
187
- end
188
- end