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,398 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe "DB / Slices", :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 "slices using the same database_url and extensions share a gateway/connection" do
14
- with_tmp_directory(@dir = Dir.mktmpdir) do
15
- write "config/app.rb", <<~RUBY
16
- require "hanami"
17
-
18
- module TestApp
19
- class App < Hanami::App
20
- config.logger.stream = File::NULL
21
- end
22
- end
23
- RUBY
24
-
25
- write "slices/admin/relations/.keep", ""
26
- write "slices/main/relations/.keep", ""
27
-
28
- ENV["DATABASE_URL"] = "sqlite::memory"
29
-
30
- require "hanami/prepare"
31
-
32
- expect(Admin::Slice["db.rom"].gateways[:default]).to be Main::Slice["db.rom"].gateways[:default]
33
- end
34
- end
35
-
36
- specify "slices using a parent gateway with connection options share a gateway/connection" do
37
- with_tmp_directory(@dir = Dir.mktmpdir) do
38
- write "config/app.rb", <<~RUBY
39
- require "hanami"
40
-
41
- module TestApp
42
- class App < Hanami::App
43
- config.logger.stream = File::NULL
44
- end
45
- end
46
- RUBY
47
-
48
- write "config/providers/db.rb", <<~RUBY
49
- Hanami.app.configure_provider :db do
50
- config.gateway :default do |gw|
51
- gw.connection_options timeout: 10_000
52
- end
53
-
54
- config.gateway :extra do |gw|
55
- gw.connection_options timeout: 20_000
56
- end
57
- end
58
- RUBY
59
-
60
- write "slices/main/config/providers/db.rb", <<~RUBY
61
- Main::Slice.configure_provider :db do
62
- config.gateway :bonus do |gw|
63
- gw.connection_options timeout: 5_000
64
- end
65
- end
66
- RUBY
67
-
68
- write "db/.keep", ""
69
- write "slices/admin/relations/.keep", ""
70
- write "slices/main/relations/.keep", ""
71
-
72
- ENV["DATABASE_URL"] = "sqlite://" + Pathname(@dir).realpath.join("app.sqlite").to_s
73
- ENV["DATABASE_URL__EXTRA"] = "sqlite://" + Pathname(@dir).realpath.join("extra.sqlite").to_s
74
- ENV["DATABASE_URL__BONUS"] = "sqlite://" + Pathname(@dir).realpath.join("bonus.sqlite").to_s
75
-
76
- # "extra" gateway in admin slice, same URL as app
77
- ENV["ADMIN__DATABASE_URL__EXTRA"] = ENV["DATABASE_URL__EXTRA"]
78
- # "extra" gatway in main slice, different URL
79
- ENV["MAIN__DATABASE_URL__EXTRA"] = "sqlite://" + Pathname(@dir).realpath.join("extra-main.sqlite").to_s
80
- # "bonus" gateway in admin slice, same URL as app
81
- ENV["ADMIN__DATABASE_URL__BONUS"] = ENV["DATABASE_URL__BONUS"]
82
- # "bonus" gateway in main slice, same URL as app; different connection options in provider
83
- ENV["MAIN__DATABASE_URL__BONUS"] = ENV["DATABASE_URL__BONUS"]
84
-
85
- require "hanami/prepare"
86
-
87
- expect(Admin::Slice["db.gateway"]).to be Hanami.app["db.gateway"]
88
-
89
- expect(Admin::Slice["db.gateways.extra"]).to be Hanami.app["db.gateways.extra"]
90
- expect(Main::Slice["db.gateways.extra"]).not_to be Hanami.app["db.gateways.extra"]
91
-
92
- expect(Admin::Slice["db.gateways.bonus"]).to be Hanami.app["db.gateways.bonus"]
93
- expect(Main::Slice["db.gateways.bonus"]).not_to be Hanami.app["db.gateways.bonus"]
94
- end
95
- end
96
-
97
- specify "slices using the same database_url but different extensions have distinct gateways/connections" do
98
- with_tmp_directory(@dir = Dir.mktmpdir) do
99
- write "config/app.rb", <<~RUBY
100
- require "hanami"
101
-
102
- module TestApp
103
- class App < Hanami::App
104
- config.logger.stream = File::NULL
105
- end
106
- end
107
- RUBY
108
-
109
- write "slices/admin/config/providers/db.rb", <<~RUBY
110
- Admin::Slice.configure_provider :db do
111
- config.adapter :sql do |a|
112
- a.extensions.clear
113
- end
114
- end
115
- RUBY
116
-
117
- write "slices/main/config/providers/db.rb", <<~RUBY
118
- Main::Slice.configure_provider :db do
119
- config.adapter :sql do |a|
120
- a.extensions.clear
121
- a.extension :error_sql
122
- end
123
- end
124
- RUBY
125
-
126
- ENV["DATABASE_URL"] = "sqlite::memory"
127
-
128
- require "hanami/prepare"
129
-
130
- # Different gateways, due to the distinct extensions
131
- expect(Admin::Slice["db.rom"].gateways[:default]).not_to be Main::Slice["db.rom"].gateways[:default]
132
-
133
- # Even though their URIs are the same
134
- expect(Admin::Slice["db.rom"].gateways[:default].connection.opts[:uri])
135
- .to eq Main::Slice["db.rom"].gateways[:default].connection.opts[:uri]
136
- end
137
- end
138
-
139
- specify "using separate relations per slice, while sharing config from the app" do
140
- with_tmp_directory(@dir = Dir.mktmpdir) do
141
- write "config/app.rb", <<~RUBY
142
- require "hanami"
143
-
144
- module TestApp
145
- class App < Hanami::App
146
- config.logger.stream = File::NULL
147
- end
148
- end
149
- RUBY
150
-
151
- write "config/providers/db.rb", <<~RUBY
152
- Hanami.app.configure_provider :db do
153
- config.adapter :sql do |a|
154
- a.extension :exclude_or_null
155
- end
156
- end
157
- RUBY
158
-
159
- write "slices/admin/relations/posts.rb", <<~RUBY
160
- module Admin
161
- module Relations
162
- class Posts < Hanami::DB::Relation
163
- schema :posts, infer: true
164
- end
165
- end
166
- end
167
- RUBY
168
-
169
- write "slices/admin/relations/authors.rb", <<~RUBY
170
- module Admin
171
- module Relations
172
- class Authors < Hanami::DB::Relation
173
- schema :authors, infer: true
174
- end
175
- end
176
- end
177
- RUBY
178
-
179
- write "slices/main/config/providers/db.rb", <<~RUBY
180
- Main::Slice.configure_provider :db do
181
- config.adapter :sql do |a|
182
- a.skip_defaults :extensions
183
- a.extensions.clear
184
- end
185
- end
186
- RUBY
187
-
188
- write "slices/main/relations/posts.rb", <<~RUBY
189
- module Main
190
- module Relations
191
- class Posts < Hanami::DB::Relation
192
- schema :posts, infer: true
193
- end
194
- end
195
- end
196
- RUBY
197
-
198
- ENV["DATABASE_URL"] = "sqlite://" + Pathname(@dir).realpath.join("database.db").to_s
199
-
200
- # Extra gateway for app only. Unlike other config, not copied to child slices.
201
- ENV["DATABASE_URL__EXTRA"] = "sqlite://" + Pathname(@dir).realpath.join("extra.db").to_s
202
-
203
- require "hanami/prepare"
204
-
205
- Main::Slice.prepare :db
206
-
207
- expect(Main::Slice["db.config"]).to be_an_instance_of ROM::Configuration
208
- expect(Main::Slice["db.gateway"]).to be_an_instance_of ROM::SQL::Gateway
209
-
210
- expect(Admin::Slice.registered?("db.config")).to be false
211
-
212
- Admin::Slice.prepare :db
213
-
214
- expect(Admin::Slice["db.config"]).to be_an_instance_of ROM::Configuration
215
- expect(Admin::Slice["db.gateway"]).to be_an_instance_of ROM::SQL::Gateway
216
-
217
- # Manually run a migration and add a test record
218
- gateway = Admin::Slice["db.gateway"]
219
- migration = gateway.migration do
220
- change do
221
- create_table :posts do
222
- primary_key :id
223
- column :title, :text, null: false
224
- end
225
-
226
- create_table :authors do
227
- primary_key :id
228
- end
229
- end
230
- end
231
- migration.apply(gateway, :up)
232
- gateway.connection.execute("INSERT INTO posts (title) VALUES ('Together breakfast')")
233
-
234
- # Gateways on app are not passed down to child slices
235
- expect(Hanami.app["db.rom"].gateways.keys).to eq [:default, :extra]
236
- expect(Main::Slice["db.rom"].gateways.keys).to eq [:default]
237
- expect(Admin::Slice["db.rom"].gateways.keys).to eq [:default]
238
-
239
- # Admin slice has appropriate relations registered, and can access data
240
- expect(Admin::Slice["db.rom"].relations[:posts].to_a).to eq [{id: 1, title: "Together breakfast"}]
241
- expect(Admin::Slice["relations.posts"]).to be Admin::Slice["db.rom"].relations[:posts]
242
- expect(Admin::Slice["relations.authors"]).to be Admin::Slice["db.rom"].relations[:authors]
243
-
244
- # Main slice can access data, and only has its own relations (no crossover from admin slice)
245
- expect(Main::Slice["db.rom"].relations[:posts].to_a).to eq [{id: 1, title: "Together breakfast"}]
246
- expect(Main::Slice["relations.posts"]).to be Main::Slice["db.rom"].relations[:posts]
247
- expect(Main::Slice["db.rom"].relations.elements.keys).not_to include :authors
248
- expect(Main::Slice["relations.posts"]).not_to be Admin::Slice["relations.posts"]
249
-
250
- # Config in the app's db provider is copied to child slice providers
251
- expect(Admin::Slice["db.gateway"].options[:extensions]).to eq [
252
- :exclude_or_null,
253
- :caller_logging,
254
- :error_sql,
255
- :sql_comments,
256
- ]
257
- # Except when it has been explicitly configured in a child slice provider
258
- expect(Main::Slice["db.gateway"].options[:extensions]).to eq []
259
-
260
- # Plugins configured in the app's db provider are copied to child slice providers
261
- expect(Admin::Slice["db.config"].setup.plugins.length).to eq 2
262
- expect(Admin::Slice["db.config"].setup.plugins).to include an_object_satisfying { |plugin|
263
- plugin.type == :relation && plugin.name == :auto_restrictions
264
- }
265
- expect(Admin::Slice["db.config"].setup.plugins).to include an_object_satisfying { |plugin|
266
- plugin.type == :relation && plugin.name == :instrumentation
267
- }
268
-
269
- expect(Main::Slice["db.config"].setup.plugins).to eq Admin::Slice["db.config"].setup.plugins
270
- end
271
- end
272
-
273
- specify "disabling sharing of config from the app" do
274
- with_tmp_directory(@dir = Dir.mktmpdir) do
275
- write "config/app.rb", <<~RUBY
276
- require "hanami"
277
-
278
- module TestApp
279
- class App < Hanami::App
280
- config.logger.stream = File::NULL
281
- end
282
- end
283
- RUBY
284
-
285
- write "config/providers/db.rb", <<~RUBY
286
- Hanami.app.configure_provider :db do
287
- config.adapter :sql do |a|
288
- a.extension :exclude_or_null
289
- end
290
- end
291
- RUBY
292
-
293
- write "config/slices/admin.rb", <<~RUBY
294
- module Admin
295
- class Slice < Hanami::Slice
296
- config.db.configure_from_parent = false
297
- end
298
- end
299
- RUBY
300
-
301
- write "slices/admin/config/providers/db.rb", <<~RUBY
302
- Admin::Slice.configure_provider :db do
303
- end
304
- RUBY
305
-
306
- ENV["DATABASE_URL"] = "sqlite://" + Pathname(@dir).realpath.join("database.db").to_s
307
-
308
- require "hanami/prepare"
309
-
310
- expect(Admin::Slice["db.gateway"].options[:extensions]).not_to include :exclude_or_null
311
- end
312
- end
313
-
314
- specify "slices using separate databases" do
315
- with_tmp_directory(@dir = Dir.mktmpdir) do
316
- write "config/app.rb", <<~RUBY
317
- require "hanami"
318
-
319
- module TestApp
320
- class App < Hanami::App
321
- config.logger.stream = File::NULL
322
- end
323
- end
324
- RUBY
325
-
326
- write "slices/admin/relations/posts.rb", <<~RUBY
327
- module Admin
328
- module Relations
329
- class Posts < Hanami::DB::Relation
330
- schema :posts, infer: true
331
- end
332
- end
333
- end
334
- RUBY
335
-
336
- write "slices/admin/slices/super/relations/posts.rb", <<~RUBY
337
- module Admin
338
- module Super
339
- module Relations
340
- class Posts < Hanami::DB::Relation
341
- schema :posts, infer: true
342
- end
343
- end
344
- end
345
- end
346
- RUBY
347
-
348
- write "slices/main/relations/posts.rb", <<~RUBY
349
- module Main
350
- module Relations
351
- class Posts < Hanami::DB::Relation
352
- schema :posts, infer: true
353
- end
354
- end
355
- end
356
- RUBY
357
-
358
- ENV["ADMIN__DATABASE_URL"] = "sqlite://" + Pathname(@dir).realpath.join("admin.db").to_s
359
- ENV["ADMIN__SUPER__DATABASE_URL"] = "sqlite://" + Pathname(@dir).realpath.join("admin_super.db").to_s
360
- ENV["MAIN__DATABASE_URL"] = "sqlite://" + Pathname(@dir).realpath.join("main.db").to_s
361
-
362
- require "hanami/prepare"
363
-
364
- Admin::Slice.prepare :db
365
- Admin::Super::Slice.prepare :db
366
- Main::Slice.prepare :db
367
-
368
- # Manually run a migration and add a test record in each slice's database
369
- gateways = [
370
- Admin::Slice["db.gateway"],
371
- Admin::Super::Slice["db.gateway"],
372
- Main::Slice["db.gateway"]
373
- ]
374
- gateways.each do |gateway|
375
- migration = gateway.migration do
376
- change do
377
- create_table :posts do
378
- primary_key :id
379
- column :title, :text, null: false
380
- end
381
-
382
- create_table :authors do
383
- primary_key :id
384
- end
385
- end
386
- end
387
- migration.apply(gateway, :up)
388
- end
389
- gateways[0].connection.execute("INSERT INTO posts (title) VALUES ('Gem glow')")
390
- gateways[1].connection.execute("INSERT INTO posts (title) VALUES ('Cheeseburger backpack')")
391
- gateways[2].connection.execute("INSERT INTO posts (title) VALUES ('Together breakfast')")
392
-
393
- expect(Admin::Slice["relations.posts"].to_a).to eq [{id: 1, title: "Gem glow"}]
394
- expect(Admin::Super::Slice["relations.posts"].to_a).to eq [{id: 1, title: "Cheeseburger backpack"}]
395
- expect(Main::Slice["relations.posts"].to_a).to eq [{id: 1, title: "Together breakfast"}]
396
- end
397
- end
398
- end
@@ -1,245 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe "DB", :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
- it "sets up ROM and registers relations" 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 "app/relations/posts.rb", <<~RUBY
25
- module TestApp
26
- module Relations
27
- class Posts < Hanami::DB::Relation
28
- schema :posts, infer: true
29
- end
30
- end
31
- end
32
- RUBY
33
-
34
- ENV["DATABASE_URL"] = "sqlite::memory"
35
-
36
- require "hanami/prepare"
37
-
38
- Hanami.app.prepare :db
39
-
40
- expect(Hanami.app["db.config"]).to be_an_instance_of ROM::Configuration
41
- expect(Hanami.app["db.gateway"]).to be_an_instance_of ROM::SQL::Gateway
42
- expect(Hanami.app["db.gateways.default"]).to be Hanami.app["db.gateway"]
43
-
44
- # Manually run a migration and add a test record
45
- gateway = Hanami.app["db.gateway"]
46
- migration = gateway.migration do
47
- change do
48
- # drop_table? :posts
49
- create_table :posts do
50
- primary_key :id
51
- column :title, :text, null: false
52
- end
53
- end
54
- end
55
- migration.apply(gateway, :up)
56
- gateway.connection.execute("INSERT INTO posts (title) VALUES ('Together breakfast')")
57
-
58
- Hanami.app.boot
59
-
60
- expect(Hanami.app["db.rom"].relations[:posts].to_a).to eq [{id: 1, title: "Together breakfast"}]
61
- expect(Hanami.app["relations.posts"]).to be Hanami.app["db.rom"].relations[:posts]
62
- end
63
- end
64
-
65
- it "provides access in a non-booted app" do
66
- with_tmp_directory(Dir.mktmpdir) do
67
- write "config/app.rb", <<~RUBY
68
- require "hanami"
69
-
70
- module TestApp
71
- class App < Hanami::App
72
- end
73
- end
74
- RUBY
75
-
76
- write "app/relations/posts.rb", <<~RUBY
77
- module TestApp
78
- module Relations
79
- class Posts < Hanami::DB::Relation
80
- schema :posts, infer: true
81
- end
82
- end
83
- end
84
- RUBY
85
-
86
- ENV["DATABASE_URL"] = "sqlite::memory"
87
-
88
- require "hanami/prepare"
89
-
90
- Hanami.app.prepare :db
91
-
92
- expect(Hanami.app["db.config"]).to be_an_instance_of ROM::Configuration
93
- expect(Hanami.app["db.gateway"]).to be_an_instance_of ROM::SQL::Gateway
94
- expect(Hanami.app["db.gateways.default"]).to be Hanami.app["db.gateway"]
95
-
96
- # Manually run a migration and add a test record
97
- gateway = Hanami.app["db.gateway"]
98
- migration = gateway.migration do
99
- change do
100
- # drop_table? :posts
101
- create_table :posts do
102
- primary_key :id
103
- column :title, :text, null: false
104
- end
105
- end
106
- end
107
- migration.apply(gateway, :up)
108
- gateway.connection.execute("INSERT INTO posts (title) VALUES ('Together breakfast')")
109
-
110
- expect(Hanami.app["db.rom"].relations[:posts].to_a).to eq [{id: 1, title: "Together breakfast"}]
111
- expect(Hanami.app["relations.posts"]).to be Hanami.app["db.rom"].relations[:posts]
112
- end
113
- end
114
-
115
- it "raises an error when no database URL is provided" do
116
- with_tmp_directory(Dir.mktmpdir) do
117
- write "config/app.rb", <<~RUBY
118
- require "hanami"
119
-
120
- module TestApp
121
- class App < Hanami::App
122
- end
123
- end
124
- RUBY
125
-
126
- write "app/relations/.keep", ""
127
-
128
- require "hanami/prepare"
129
-
130
- expect { Hanami.app.prepare :db }.to raise_error(Hanami::ComponentLoadError, /database_url/)
131
- end
132
- end
133
-
134
- it "raises an error when the database driver gem is missing" do
135
- allow(Hanami).to receive(:bundled?).and_call_original
136
- expect(Hanami).to receive(:bundled?).with("pg").and_return false
137
-
138
- with_tmp_directory(Dir.mktmpdir) do
139
- write "config/app.rb", <<~RUBY
140
- require "hanami"
141
-
142
- module TestApp
143
- class App < Hanami::App
144
- end
145
- end
146
- RUBY
147
-
148
- write "app/relations/.keep", ""
149
-
150
- ENV["DATABASE_URL"] = "postgres://127.0.0.0"
151
-
152
- require "hanami/prepare"
153
-
154
- expect { Hanami.app.prepare :db }.to raise_error(Hanami::ComponentLoadError) { |error|
155
- expect(error.message).to include %(The "pg" gem is required)
156
- }
157
- end
158
- end
159
-
160
- it "allows the user to configure the provider" do
161
- with_tmp_directory(Dir.mktmpdir) do
162
- write "config/app.rb", <<~RUBY
163
- require "hanami"
164
-
165
- module TestApp
166
- class App < Hanami::App
167
- end
168
- end
169
- RUBY
170
-
171
- write "app/relations/posts.rb", <<~RUBY
172
- module TestApp
173
- module Relations
174
- class Posts < Hanami::DB::Relation
175
- schema :posts, infer: true
176
- end
177
- end
178
- end
179
- RUBY
180
-
181
- write "config/providers/db.rb", <<~RUBY
182
- Hanami.app.configure_provider :db do
183
- # In this test, we're not setting an ENV["DATABASE_URL"], and instead configuring
184
- # it via the provider source config, to prove that this works
185
- config.gateway :default do |gw|
186
- gw.database_url = "sqlite::memory"
187
- end
188
- end
189
- RUBY
190
-
191
- require "hanami/prepare"
192
-
193
- Hanami.app.prepare :db
194
- gateway = Hanami.app["db.gateway"]
195
- migration = gateway.migration do
196
- change do
197
- # drop_table? :posts
198
- create_table :posts do
199
- primary_key :id
200
- column :title, :text, null: false
201
- end
202
- end
203
- end
204
- migration.apply(gateway, :up)
205
- gateway.connection.execute("INSERT INTO posts (title) VALUES ('Together breakfast')")
206
-
207
- Hanami.app.boot
208
-
209
- expect(Hanami.app["db.rom"].relations[:posts].to_a).to eq [{id: 1, title: "Together breakfast"}]
210
- expect(Hanami.app["relations.posts"]).to be Hanami.app["db.rom"].relations[:posts]
211
- end
212
- end
213
-
214
- it "transforms the database URL in test mode" do
215
- with_tmp_directory(Dir.mktmpdir) do
216
- write "config/app.rb", <<~RUBY
217
- require "hanami"
218
-
219
- module TestApp
220
- class App < Hanami::App
221
- end
222
- end
223
- RUBY
224
-
225
- write "app/relations/posts.rb", <<~RUBY
226
- module TestApp
227
- module Relations
228
- class Posts < Hanami::DB::Relation
229
- schema :posts, infer: true
230
- end
231
- end
232
- end
233
- RUBY
234
-
235
- ENV["HANAMI_ENV"] = "test"
236
- ENV["DATABASE_URL"] = "sqlite://./development.db"
237
-
238
- require "hanami/prepare"
239
-
240
- Hanami.app.prepare :db
241
-
242
- expect(Hanami.app["db.gateway"].connection.url).to eq "sqlite://./test.db"
243
- end
244
- end
245
- end