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,361 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe "DB / Gateways", :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 "configures gateways by detecting ENV vars" 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
- end
21
- end
22
- RUBY
23
-
24
- write "db/.keep", ""
25
- write "app/relations/.keep", ""
26
- write "slices/admin/relations/.keep", ""
27
-
28
- ENV["DATABASE_URL"] = "sqlite://db/default.sqlite3"
29
- ENV["DATABASE_URL__EXTRA"] = "sqlite://db/extra.sqlite3"
30
- ENV["ADMIN__DATABASE_URL__DEFAULT"] = "sqlite://db/admin.sqlite3"
31
- ENV["ADMIN__DATABASE_URL__SPECIAL"] = "sqlite://db/admin_special.sqlite3"
32
-
33
- require "hanami/prepare"
34
-
35
- expect(Hanami.app["db.rom"].gateways[:default]).to be
36
- expect(Hanami.app["db.rom"].gateways[:extra]).to be
37
- expect(Hanami.app["db.gateway"]).to be Hanami.app["db.rom"].gateways[:default]
38
- expect(Hanami.app["db.gateways.default"]).to be Hanami.app["db.rom"].gateways[:default]
39
- expect(Hanami.app["db.gateways.extra"]).to be Hanami.app["db.rom"].gateways[:extra]
40
-
41
- expect(Admin::Slice["db.rom"].gateways[:default]).to be
42
- expect(Admin::Slice["db.rom"].gateways[:special]).to be
43
- expect(Admin::Slice["db.gateway"]).to be Admin::Slice["db.rom"].gateways[:default]
44
- expect(Admin::Slice["db.gateways.default"]).to be Admin::Slice["db.rom"].gateways[:default]
45
- expect(Admin::Slice["db.gateways.special"]).to be Admin::Slice["db.rom"].gateways[:special]
46
- end
47
- end
48
-
49
- it "configures gateways from explicit config in the provider" do
50
- with_tmp_directory(@dir = Dir.mktmpdir) do
51
- write "config/app.rb", <<~RUBY
52
- require "hanami"
53
-
54
- module TestApp
55
- class App < Hanami::App
56
- end
57
- end
58
- RUBY
59
-
60
- write "db/.keep", ""
61
-
62
- write "config/providers/db.rb", <<~RUBY
63
- Hanami.app.configure_provider :db do
64
- config.gateway :default do |gw|
65
- gw.database_url = "sqlite://db/default.sqlite3"
66
- end
67
-
68
- config.gateway :extra do |gw|
69
- gw.database_url = "sqlite://db/extra.sqlite3"
70
- end
71
- end
72
- RUBY
73
-
74
- require "hanami/prepare"
75
-
76
- expect(Hanami.app["db.rom"].gateways[:default]).to be
77
- expect(Hanami.app["db.rom"].gateways[:extra]).to be
78
- expect(Hanami.app["db.gateway"]).to be Hanami.app["db.rom"].gateways[:default]
79
- expect(Hanami.app["db.gateways.default"]).to be Hanami.app["db.rom"].gateways[:default]
80
- expect(Hanami.app["db.gateways.extra"]).to be Hanami.app["db.rom"].gateways[:extra]
81
- end
82
- end
83
-
84
- it "configures connection options on their respective gateways" do
85
- with_tmp_directory(@dir = Dir.mktmpdir) do
86
- write "config/app.rb", <<~RUBY
87
- require "hanami"
88
-
89
- module TestApp
90
- class App < Hanami::App
91
- end
92
- end
93
- RUBY
94
-
95
- write "db/.keep", ""
96
-
97
- write "config/providers/db.rb", <<~RUBY
98
- Hanami.app.configure_provider :db do
99
- config.gateway :default do |gw|
100
- gw.connection_options timeout: 10_000
101
-
102
- gw.adapter :sql do |a|
103
- a.skip_defaults :extensions
104
- a.extension :error_sql
105
- end
106
- end
107
-
108
- config.gateway :extra do |gw|
109
- gw.connection_options readonly: true
110
- end
111
- end
112
- RUBY
113
-
114
- ENV["DATABASE_URL"] = "sqlite::memory"
115
- ENV["DATABASE_URL__EXTRA"] = "sqlite::memory"
116
-
117
- require "hanami/prepare"
118
-
119
- default = Hanami.app["db.gateways.default"]
120
- extra = Hanami.app["db.gateways.extra"]
121
-
122
- expect(default.options).to eq({timeout: 10_000, extensions: [:error_sql]})
123
- expect(extra.options).to eq({readonly: true, extensions: %i[caller_logging error_sql sql_comments]})
124
- end
125
- end
126
-
127
- it "exposes all database URLs as #database_urls on the provider source (for CLI commands)" do
128
- with_tmp_directory(@dir = Dir.mktmpdir) do
129
- write "config/app.rb", <<~RUBY
130
- require "hanami"
131
-
132
- module TestApp
133
- class App < Hanami::App
134
- end
135
- end
136
- RUBY
137
-
138
- write "config/providers/db.rb", <<~RUBY
139
- Hanami.app.configure_provider :db do
140
- config.gateway :special do |gw|
141
- gw.database_url = "sqlite://db/special.sqlite3"
142
- end
143
- end
144
- RUBY
145
-
146
- ENV["DATABASE_URL"] = "sqlite://db/default.sqlite3"
147
- ENV["DATABASE_URL__EXTRA"] = "sqlite://db/extra.sqlite3"
148
-
149
- require "hanami/prepare"
150
-
151
- database_urls = Hanami.app.container.providers[:db].source.finalize_config.database_urls
152
-
153
- expect(database_urls).to eq(
154
- default: "sqlite://db/default.sqlite3",
155
- extra: "sqlite://db/extra.sqlite3",
156
- special: "sqlite://db/special.sqlite3"
157
- )
158
- end
159
- end
160
-
161
- it "applies extensions from the default adapter to explicitly configured gateway adapters" do
162
- with_tmp_directory(@dir = Dir.mktmpdir) do
163
- write "config/app.rb", <<~RUBY
164
- require "hanami"
165
-
166
- module TestApp
167
- class App < Hanami::App
168
- end
169
- end
170
- RUBY
171
-
172
- write "config/providers/db.rb", <<~RUBY
173
- Hanami.app.configure_provider :db do
174
- config.adapter :sql do |a|
175
- a.extension :is_distinct_from
176
- end
177
-
178
- config.gateway :default do |gw|
179
- gw.adapter :sql do |a|
180
- a.extension :exclude_or_null
181
- end
182
- end
183
- end
184
- RUBY
185
-
186
- ENV["DATABASE_URL"] = "sqlite::memory"
187
- ENV["DATABASE_URL__SPECIAL"] = "sqlite::memory"
188
-
189
- require "hanami/prepare"
190
-
191
- expect(Hanami.app["db.gateways.default"].options[:extensions])
192
- .to eq [:exclude_or_null, :is_distinct_from, :caller_logging, :error_sql, :sql_comments]
193
-
194
- expect(Hanami.app["db.gateways.special"].options[:extensions])
195
- .to eq [:is_distinct_from, :caller_logging, :error_sql, :sql_comments]
196
- end
197
- end
198
-
199
- it "combines ROM plugins from both default adapter and gateway-configured adapters" do
200
- with_tmp_directory(@dir = Dir.mktmpdir) do
201
- write "config/app.rb", <<~RUBY
202
- require "hanami"
203
-
204
- module TestApp
205
- class App < Hanami::App
206
- end
207
- end
208
- RUBY
209
-
210
- write "config/providers/db.rb", <<~RUBY
211
- Hanami.app.configure_provider :db do
212
- config.adapter :sql do |a|
213
- a.plugin command: :associates
214
- end
215
-
216
- config.gateway :default do |gw|
217
- gw.database_url = "sqlite::memory"
218
- gw.adapter :sql do |a|
219
- a.plugin relation: :nullify
220
- end
221
- end
222
-
223
- config.gateway :special do |gw|
224
- gw.adapter :sql do |a|
225
- a.plugin relation: :pagination
226
- end
227
- end
228
- end
229
- RUBY
230
-
231
- ENV["DATABASE_URL"] = "sqlite::memory"
232
- ENV["DATABASE_URL__SPECIAL"] = "sqlite::memory"
233
-
234
- require "hanami/prepare"
235
-
236
- expect(Hanami.app["db.config"].setup.plugins.length).to eq 5
237
- expect(Hanami.app["db.config"].setup.plugins).to include(
238
- satisfying { |plugin| plugin.type == :command && plugin.name == :associates },
239
- satisfying { |plugin| plugin.type == :relation && plugin.name == :nullify },
240
- satisfying { |plugin| plugin.type == :relation && plugin.name == :pagination },
241
- satisfying { |plugin| plugin.type == :relation && plugin.name == :auto_restrictions },
242
- satisfying { |plugin| plugin.type == :relation && plugin.name == :instrumentation }
243
- )
244
- end
245
- end
246
-
247
- it "configures gateway adapters for their specific database types" do
248
- with_tmp_directory(@dir = Dir.mktmpdir) do
249
- write "config/app.rb", <<~RUBY
250
- require "hanami"
251
-
252
- module TestApp
253
- class App < Hanami::App
254
- end
255
- end
256
- RUBY
257
-
258
- write "config/providers/db.rb", <<~RUBY
259
- Hanami.app.configure_provider :db do
260
- config.gateway :default do |gw|
261
- gw.database_url = "sqlite::memory"
262
- end
263
- end
264
- RUBY
265
-
266
- ENV["DATABASE_URL"] = "sqlite::memory"
267
- ENV["DATABASE_URL__SPECIAL"] = "postgres://localhost/database"
268
-
269
- require "hanami/prepare"
270
-
271
- # Get the provider source and finalize config, because the tests here aren't set up to handle
272
- # connections to a running postgres database
273
- allow(Hanami).to receive(:bundled?).and_call_original
274
- allow(Hanami).to receive(:bundled?).with("pg").and_return true
275
- provider_source = Hanami.app.container.providers[:db].source
276
- provider_source.finalize_config
277
-
278
- expect(provider_source.config.gateways[:default].config.adapter.extensions)
279
- .to eq [:caller_logging, :error_sql, :sql_comments]
280
-
281
- expect(provider_source.config.gateways[:special].config.adapter.extensions)
282
- .to eq [
283
- :caller_logging, :error_sql, :sql_comments,
284
- :pg_array, :pg_enum, :pg_json, :pg_range
285
- ]
286
- end
287
- end
288
-
289
- it "makes the gateways available to relations" do
290
- with_tmp_directory(@dir = Dir.mktmpdir) do
291
- write "config/app.rb", <<~RUBY
292
- require "hanami"
293
-
294
- module TestApp
295
- class App < Hanami::App
296
- config.logger.stream = File::NULL
297
- end
298
- end
299
- RUBY
300
-
301
- write "app/relations/posts.rb", <<~RUBY
302
- module TestApp
303
- module Relations
304
- class Posts < Hanami::DB::Relation
305
- schema :posts, infer: true
306
- end
307
- end
308
- end
309
- RUBY
310
-
311
- write "app/relations/users.rb", <<~RUBY
312
- module TestApp
313
- module Relations
314
- class Users < Hanami::DB::Relation
315
- gateway :extra
316
- schema :users, infer: true
317
- end
318
- end
319
- end
320
- RUBY
321
-
322
- write "db/.keep", ""
323
- ENV["DATABASE_URL"] = "sqlite://db/default.sqlite3"
324
- ENV["DATABASE_URL__EXTRA"] = "sqlite://db/extra.sqlite3"
325
-
326
- require "hanami/prepare"
327
-
328
- Hanami.app.prepare :db
329
-
330
- # Manually run a migration and add a test record
331
- default_gateway = Hanami.app["db.gateways.default"]
332
- migration = default_gateway.migration do
333
- change do
334
- create_table :posts do
335
- primary_key :id
336
- column :title, :text, null: false
337
- end
338
- end
339
- end
340
- migration.apply(default_gateway, :up)
341
- default_gateway.connection.execute("INSERT INTO posts (title) VALUES ('Together breakfast')")
342
-
343
- extra_gateway = Hanami.app["db.gateways.extra"]
344
- migration = extra_gateway.migration do
345
- change do
346
- create_table :users do
347
- primary_key :id
348
- column :name, :text, null: false
349
- end
350
- end
351
- end
352
- migration.apply(extra_gateway, :up)
353
- extra_gateway.connection.execute("INSERT INTO users (name) VALUES ('Jane Doe')")
354
-
355
- Hanami.app.boot
356
-
357
- expect(Hanami.app["relations.posts"].to_a).to eq [{id: 1, title: "Together breakfast"}]
358
- expect(Hanami.app["relations.users"].to_a).to eq [{id: 1, name: "Jane Doe"}]
359
- end
360
- end
361
- end
@@ -1,301 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe "DB / Logging", :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 "logs SQL queries" 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/setup"
37
-
38
- logger_stream = StringIO.new
39
- Hanami.app.config.logger.stream = logger_stream
40
-
41
- require "hanami/prepare"
42
-
43
- Hanami.app.prepare :db
44
-
45
- # Manually run a migration and add a test record
46
- gateway = Hanami.app["db.gateway"]
47
- migration = gateway.migration do
48
- change do
49
- create_table :posts do
50
- primary_key :id
51
- column :title, :text, null: false
52
- end
53
-
54
- create_table :authors do
55
- primary_key :id
56
- end
57
- end
58
- end
59
- migration.apply(gateway, :up)
60
- gateway.connection.execute("INSERT INTO posts (title) VALUES ('Together breakfast')")
61
-
62
- relation = Hanami.app["relations.posts"]
63
- expect(relation.select(:title).to_a).to eq [{:title=>"Together breakfast"}]
64
-
65
- logger_stream.rewind
66
- log_lines = logger_stream.read.split("\n")
67
-
68
- expect(log_lines.length).to eq 1
69
- expect(log_lines.first).to match /Loaded :sqlite in \d+ms SELECT `posts`.`title` FROM `posts` ORDER BY `posts`.`id`/
70
- end
71
- end
72
-
73
- describe "slices sharing app db config" do
74
- it "logs SQL queries" do
75
- with_tmp_directory(Dir.mktmpdir) do
76
- write "config/app.rb", <<~RUBY
77
- require "hanami"
78
-
79
- module TestApp
80
- class App < Hanami::App
81
- end
82
- end
83
- RUBY
84
-
85
- write "config/providers/db.rb", <<~RUBY
86
- Hanami.app.configure_provider :db do
87
- end
88
- RUBY
89
-
90
- ENV["DATABASE_URL"] = "sqlite::memory"
91
-
92
- write "slices/admin/relations/posts.rb", <<~RUBY
93
- module Admin
94
- module Relations
95
- class Posts < Hanami::DB::Relation
96
- schema :posts, infer: true
97
- end
98
- end
99
- end
100
- RUBY
101
-
102
- write "slices/main/relations/posts.rb", <<~RUBY
103
- module Main
104
- module Relations
105
- class Posts < Hanami::DB::Relation
106
- schema :posts, infer: true
107
- end
108
- end
109
- end
110
- RUBY
111
-
112
- require "hanami/setup"
113
-
114
- logger_stream = StringIO.new
115
- Hanami.app.config.logger.stream = logger_stream
116
-
117
- require "hanami/prepare"
118
-
119
- Admin::Slice.prepare :db
120
-
121
- # Manually run a migration
122
- gateway = Admin::Slice["db.gateway"]
123
- migration = gateway.migration do
124
- change do
125
- create_table :posts do
126
- primary_key :id
127
- column :title, :text, null: false
128
- end
129
- end
130
- end
131
- migration.apply(gateway, :up)
132
- gateway.connection.execute("INSERT INTO posts (title) VALUES ('Together breakfast')")
133
-
134
- Hanami.app.boot
135
-
136
- # Booting the app will have the ROM schemas infer themself via some `PRAGMA` queries to the
137
- # database, which themselves will emit logs. Clear those logs, since we want to focus on
138
- # individual query logging in this test.
139
- logger_stream.truncate(0)
140
-
141
- relation = Admin::Slice["relations.posts"]
142
- relation.select(:title).to_a
143
-
144
- log_lines = logger_stream.string.split("\n")
145
- expect(log_lines.length).to eq 1
146
- expect(log_lines.last).to match /Loaded :sqlite in \d+ms SELECT `posts`.`title` FROM `posts` ORDER BY `posts`.`id`/
147
-
148
- relation = Main::Slice["relations.posts"]
149
- relation.select(:id).to_a
150
-
151
- log_lines = logger_stream.string.split("\n")
152
- expect(log_lines.length).to eq 2
153
- expect(log_lines.last).to match /Loaded :sqlite in \d+ms SELECT `posts`.`id` FROM `posts` ORDER BY `posts`.`id`/
154
- end
155
- end
156
- end
157
-
158
- describe "slices with independent db config" do
159
- # This is the same test as above, except without the config/providers/db.rb file.
160
- it "logs SQL queries" 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
- ENV["DATABASE_URL"] = "sqlite::memory"
172
-
173
- write "slices/admin/relations/posts.rb", <<~RUBY
174
- module Admin
175
- module Relations
176
- class Posts < Hanami::DB::Relation
177
- schema :posts, infer: true
178
- end
179
- end
180
- end
181
- RUBY
182
-
183
- write "slices/main/relations/posts.rb", <<~RUBY
184
- module Main
185
- module Relations
186
- class Posts < Hanami::DB::Relation
187
- schema :posts, infer: true
188
- end
189
- end
190
- end
191
- RUBY
192
-
193
- require "hanami/setup"
194
-
195
- logger_stream = StringIO.new
196
- Hanami.app.config.logger.stream = logger_stream
197
-
198
- require "hanami/prepare"
199
-
200
- Admin::Slice.prepare :db
201
-
202
- # Manually run a migration
203
- gateway = Admin::Slice["db.gateway"]
204
- migration = gateway.migration do
205
- change do
206
- create_table :posts do
207
- primary_key :id
208
- column :title, :text, null: false
209
- end
210
- end
211
- end
212
- migration.apply(gateway, :up)
213
- gateway.connection.execute("INSERT INTO posts (title) VALUES ('Together breakfast')")
214
-
215
- Hanami.app.boot
216
-
217
- # Booting the app will have the ROM schemas infer themself via some `PRAGMA` queries to the
218
- # database, which themselves will emit logs. Clear those logs, since we want to focus on
219
- # individual query logging in this test.
220
- logger_stream.truncate(0)
221
-
222
- relation = Admin::Slice["relations.posts"]
223
- relation.select(:title).to_a
224
-
225
- log_lines = logger_stream.string.split("\n")
226
- expect(log_lines.length).to eq 1
227
- expect(log_lines.last).to match /Loaded :sqlite in \d+ms SELECT `posts`.`title` FROM `posts` ORDER BY `posts`.`id`/
228
-
229
- relation = Main::Slice["relations.posts"]
230
- relation.select(:id).to_a
231
-
232
- log_lines = logger_stream.string.split("\n")
233
- expect(log_lines.length).to eq 2
234
- expect(log_lines.last).to match /Loaded :sqlite in \d+ms SELECT `posts`.`id` FROM `posts` ORDER BY `posts`.`id`/
235
- end
236
- end
237
- end
238
-
239
- describe "in production" do
240
- it "logs SQL queries" do
241
- with_tmp_directory(Dir.mktmpdir) do
242
- write "config/app.rb", <<~RUBY
243
- require "hanami"
244
-
245
- module TestApp
246
- class App < Hanami::App
247
- end
248
- end
249
- RUBY
250
-
251
- write "app/relations/posts.rb", <<~RUBY
252
- module TestApp
253
- module Relations
254
- class Posts < Hanami::DB::Relation
255
- schema :posts, infer: true
256
- end
257
- end
258
- end
259
- RUBY
260
-
261
- ENV["DATABASE_URL"] = "sqlite::memory"
262
- ENV["HANAMI_ENV"] = "production"
263
-
264
- require "hanami/setup"
265
-
266
- logger_stream = StringIO.new
267
- Hanami.app.config.logger.stream = logger_stream
268
-
269
- require "hanami/prepare"
270
-
271
- Hanami.app.prepare :db
272
-
273
- # Manually run a migration and add a test record
274
- gateway = Hanami.app["db.gateway"]
275
- migration = gateway.migration do
276
- change do
277
- create_table :posts do
278
- primary_key :id
279
- column :title, :text, null: false
280
- end
281
-
282
- create_table :authors do
283
- primary_key :id
284
- end
285
- end
286
- end
287
- migration.apply(gateway, :up)
288
- gateway.connection.execute("INSERT INTO posts (title) VALUES ('Together breakfast')")
289
-
290
- relation = Hanami.app["relations.posts"]
291
- expect(relation.select(:title).to_a).to eq [{:title=>"Together breakfast"}]
292
-
293
- logger_stream.rewind
294
- log_lines = logger_stream.read.split("\n")
295
-
296
- expect(log_lines.length).to eq 1
297
- expect(log_lines.first).to match /Loaded :sqlite in \d+ms SELECT `posts`.`title` FROM `posts` ORDER BY `posts`.`id`/
298
- end
299
- end
300
- end
301
- end