hanami 2.0.0.alpha8 → 2.0.0.beta1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +442 -241
- data/FEATURES.md +30 -9
- data/README.md +1 -3
- data/hanami.gemspec +21 -11
- data/lib/hanami/app.rb +141 -0
- data/lib/hanami/assets/application_configuration.rb +10 -4
- data/lib/hanami/configuration/actions/content_security_policy.rb +5 -5
- data/lib/hanami/configuration/actions/cookies.rb +2 -2
- data/lib/hanami/configuration/actions.rb +10 -4
- data/lib/hanami/configuration/logger.rb +4 -4
- data/lib/hanami/configuration/router.rb +2 -6
- data/lib/hanami/configuration/sessions.rb +1 -1
- data/lib/hanami/configuration/views.rb +9 -4
- data/lib/hanami/configuration.rb +118 -46
- data/lib/hanami/constants.rb +24 -2
- data/lib/hanami/errors.rb +1 -1
- data/lib/hanami/{application → extensions}/action/slice_configured_action.rb +9 -9
- data/lib/hanami/extensions/action.rb +79 -0
- data/lib/hanami/extensions/view/context.rb +106 -0
- data/lib/hanami/{application → extensions}/view/slice_configured_context.rb +10 -10
- data/lib/hanami/{application → extensions}/view/slice_configured_view.rb +12 -6
- data/lib/hanami/extensions/view.rb +33 -0
- data/lib/hanami/extensions.rb +10 -0
- data/lib/hanami/providers/inflector.rb +13 -0
- data/lib/hanami/providers/logger.rb +13 -0
- data/lib/hanami/providers/rack.rb +27 -0
- data/lib/hanami/providers/routes.rb +33 -0
- data/lib/hanami/providers/settings.rb +23 -0
- data/lib/hanami/rake_tasks.rb +61 -0
- data/lib/hanami/routes.rb +51 -0
- data/lib/hanami/server.rb +1 -1
- data/lib/hanami/settings/dotenv_store.rb +58 -0
- data/lib/hanami/settings.rb +90 -0
- data/lib/hanami/setup.rb +4 -2
- data/lib/hanami/{application → slice}/router.rb +18 -13
- data/lib/hanami/slice/routes_helper.rb +37 -0
- data/lib/hanami/{application → slice}/routing/middleware/stack.rb +43 -5
- data/lib/hanami/slice/routing/resolver.rb +97 -0
- data/lib/hanami/{application → slice}/view_name_inferrer.rb +3 -3
- data/lib/hanami/slice.rb +246 -73
- data/lib/hanami/slice_configurable.rb +4 -17
- data/lib/hanami/slice_name.rb +6 -6
- data/lib/hanami/slice_registrar.rb +119 -0
- data/lib/hanami/version.rb +1 -1
- data/lib/hanami/web/rack_logger.rb +1 -1
- data/lib/hanami.rb +34 -26
- data/spec/integration/application_middleware_stack_spec.rb +84 -0
- data/spec/integration/assets/cdn_spec.rb +48 -0
- data/spec/integration/assets/fingerprint_spec.rb +42 -0
- data/spec/integration/assets/helpers_spec.rb +50 -0
- data/spec/integration/assets/serve_spec.rb +70 -0
- data/spec/integration/assets/subresource_integrity_spec.rb +54 -0
- data/spec/integration/body_parsers_spec.rb +50 -0
- data/spec/integration/cli/assets/precompile_spec.rb +147 -0
- data/spec/integration/cli/assets_spec.rb +14 -0
- data/spec/integration/cli/console_spec.rb +105 -0
- data/spec/integration/cli/db/apply_spec.rb +74 -0
- data/spec/integration/cli/db/console_spec.rb +40 -0
- data/spec/integration/cli/db/create_spec.rb +50 -0
- data/spec/integration/cli/db/drop_spec.rb +54 -0
- data/spec/integration/cli/db/migrate_spec.rb +108 -0
- data/spec/integration/cli/db/prepare_spec.rb +36 -0
- data/spec/integration/cli/db/rollback_spec.rb +96 -0
- data/spec/integration/cli/db/version_spec.rb +38 -0
- data/spec/integration/cli/db_spec.rb +21 -0
- data/spec/integration/cli/destroy/action_spec.rb +143 -0
- data/spec/integration/cli/destroy/app_spec.rb +118 -0
- data/spec/integration/cli/destroy/mailer_spec.rb +74 -0
- data/spec/integration/cli/destroy/migration_spec.rb +70 -0
- data/spec/integration/cli/destroy/model_spec.rb +113 -0
- data/spec/integration/cli/destroy_spec.rb +18 -0
- data/spec/integration/cli/generate/action_spec.rb +469 -0
- data/spec/integration/cli/generate/app_spec.rb +215 -0
- data/spec/integration/cli/generate/mailer_spec.rb +189 -0
- data/spec/integration/cli/generate/migration_spec.rb +72 -0
- data/spec/integration/cli/generate/model_spec.rb +290 -0
- data/spec/integration/cli/generate/secret_spec.rb +56 -0
- data/spec/integration/cli/generate_spec.rb +19 -0
- data/spec/integration/cli/new/database_spec.rb +235 -0
- data/spec/integration/cli/new/hanami_head_spec.rb +27 -0
- data/spec/integration/cli/new/template_spec.rb +118 -0
- data/spec/integration/cli/new/test_spec.rb +274 -0
- data/spec/integration/cli/new_spec.rb +970 -0
- data/spec/integration/cli/plugins_spec.rb +39 -0
- data/spec/integration/cli/routes_spec.rb +49 -0
- data/spec/integration/cli/server_spec.rb +626 -0
- data/spec/integration/cli/version_spec.rb +85 -0
- data/spec/integration/early_hints_spec.rb +35 -0
- data/spec/integration/handle_exceptions_spec.rb +244 -0
- data/spec/integration/head_spec.rb +89 -0
- data/spec/integration/http_headers_spec.rb +29 -0
- data/spec/integration/mailer_spec.rb +32 -0
- data/spec/integration/middleware_spec.rb +81 -0
- data/spec/integration/mount_applications_spec.rb +88 -0
- data/spec/integration/project_initializers_spec.rb +40 -0
- data/spec/integration/rackup_spec.rb +35 -0
- data/spec/integration/rake/with_minitest_spec.rb +67 -0
- data/spec/integration/rake/with_rspec_spec.rb +69 -0
- data/spec/integration/routing_helpers_spec.rb +61 -0
- data/spec/integration/security/content_security_policy_spec.rb +46 -0
- data/spec/integration/security/csrf_protection_spec.rb +42 -0
- data/spec/integration/security/force_ssl_spec.rb +29 -0
- data/spec/integration/security/x_content_type_options_spec.rb +46 -0
- data/spec/integration/security/x_frame_options_spec.rb +46 -0
- data/spec/integration/security/x_xss_protection_spec.rb +46 -0
- data/spec/integration/send_file_spec.rb +51 -0
- data/spec/integration/sessions_spec.rb +247 -0
- data/spec/integration/static_middleware_spec.rb +21 -0
- data/spec/integration/streaming_spec.rb +41 -0
- data/spec/integration/unsafe_send_file_spec.rb +52 -0
- data/spec/isolation/hanami/application/already_configured_spec.rb +19 -0
- data/spec/isolation/hanami/application/inherit_anonymous_class_spec.rb +10 -0
- data/spec/isolation/hanami/application/inherit_concrete_class_spec.rb +14 -0
- data/spec/isolation/hanami/application/not_configured_spec.rb +9 -0
- data/spec/isolation/hanami/application/routes/configured_spec.rb +44 -0
- data/spec/isolation/hanami/application/routes/not_configured_spec.rb +16 -0
- data/spec/isolation/hanami/boot/success_spec.rb +50 -0
- data/spec/new_integration/action/configuration_spec.rb +26 -0
- data/spec/new_integration/action/cookies_spec.rb +58 -0
- data/spec/new_integration/action/csrf_protection_spec.rb +54 -0
- data/spec/new_integration/action/routes_spec.rb +73 -0
- data/spec/new_integration/action/sessions_spec.rb +50 -0
- data/spec/new_integration/action/view_integration_spec.rb +165 -0
- data/spec/new_integration/action/view_rendering/automatic_rendering_spec.rb +247 -0
- data/spec/new_integration/action/view_rendering/paired_view_inference_spec.rb +115 -0
- data/spec/new_integration/action/view_rendering_spec.rb +107 -0
- data/spec/new_integration/code_loading/loading_from_app_spec.rb +152 -0
- data/spec/new_integration/code_loading/loading_from_slice_spec.rb +165 -0
- data/spec/new_integration/container/application_routes_helper_spec.rb +48 -0
- data/spec/new_integration/container/auto_injection_spec.rb +53 -0
- data/spec/new_integration/container/auto_registration_spec.rb +86 -0
- data/spec/new_integration/container/autoloader_spec.rb +80 -0
- data/spec/new_integration/container/imports_spec.rb +253 -0
- data/spec/new_integration/container/prepare_container_spec.rb +123 -0
- data/spec/new_integration/container/shutdown_spec.rb +91 -0
- data/spec/new_integration/container/standard_bootable_components_spec.rb +124 -0
- data/spec/new_integration/rack_app/middleware_spec.rb +215 -0
- data/spec/new_integration/rack_app/non_booted_rack_app_spec.rb +105 -0
- data/spec/new_integration/rack_app/rack_app_spec.rb +524 -0
- data/spec/new_integration/settings_spec.rb +115 -0
- data/spec/new_integration/slices/external_slice_spec.rb +92 -0
- data/spec/new_integration/slices/slice_configuration_spec.rb +40 -0
- data/spec/new_integration/slices/slice_routing_spec.rb +226 -0
- data/spec/new_integration/slices/slice_settings_spec.rb +141 -0
- data/spec/new_integration/slices_spec.rb +101 -0
- data/spec/new_integration/view/configuration_spec.rb +49 -0
- data/spec/new_integration/view/context/assets_spec.rb +67 -0
- data/spec/new_integration/view/context/inflector_spec.rb +48 -0
- data/spec/new_integration/view/context/request_spec.rb +61 -0
- data/spec/new_integration/view/context/routes_spec.rb +86 -0
- data/spec/new_integration/view/context/settings_spec.rb +50 -0
- data/spec/new_integration/view/inflector_spec.rb +57 -0
- data/spec/new_integration/view/part_namespace_spec.rb +96 -0
- data/spec/new_integration/view/path_spec.rb +56 -0
- data/spec/new_integration/view/template_spec.rb +68 -0
- data/spec/new_integration/view/views_spec.rb +103 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/support/app_integration.rb +91 -0
- data/spec/support/coverage.rb +1 -0
- data/spec/support/fixtures/hanami-plugin/Gemfile +8 -0
- data/spec/support/fixtures/hanami-plugin/README.md +35 -0
- data/spec/support/fixtures/hanami-plugin/Rakefile +4 -0
- data/spec/support/fixtures/hanami-plugin/bin/console +15 -0
- data/spec/support/fixtures/hanami-plugin/bin/setup +8 -0
- data/spec/support/fixtures/hanami-plugin/hanami-plugin.gemspec +28 -0
- data/spec/support/fixtures/hanami-plugin/lib/hanami/plugin/cli.rb +19 -0
- data/spec/support/fixtures/hanami-plugin/lib/hanami/plugin/version.rb +7 -0
- data/spec/support/fixtures/hanami-plugin/lib/hanami/plugin.rb +8 -0
- data/spec/support/rspec.rb +27 -0
- data/spec/support/shared_examples/cli/generate/app.rb +494 -0
- data/spec/support/shared_examples/cli/generate/migration.rb +32 -0
- data/spec/support/shared_examples/cli/generate/model.rb +81 -0
- data/spec/support/shared_examples/cli/new.rb +97 -0
- data/spec/unit/hanami/configuration/actions/content_security_policy_spec.rb +102 -0
- data/spec/unit/hanami/configuration/actions/cookies_spec.rb +46 -0
- data/spec/unit/hanami/configuration/actions/csrf_protection_spec.rb +57 -0
- data/spec/unit/hanami/configuration/actions/default_values_spec.rb +52 -0
- data/spec/unit/hanami/configuration/actions/sessions_spec.rb +50 -0
- data/spec/unit/hanami/configuration/actions_spec.rb +78 -0
- data/spec/unit/hanami/configuration/base_url_spec.rb +25 -0
- data/spec/unit/hanami/configuration/inflector_spec.rb +35 -0
- data/spec/unit/hanami/configuration/logger_spec.rb +203 -0
- data/spec/unit/hanami/configuration/views_spec.rb +120 -0
- data/spec/unit/hanami/configuration_spec.rb +43 -0
- data/spec/unit/hanami/env_spec.rb +54 -0
- data/spec/unit/hanami/routes_spec.rb +25 -0
- data/spec/unit/hanami/settings/dotenv_store_spec.rb +119 -0
- data/spec/unit/hanami/settings_spec.rb +56 -0
- data/spec/unit/hanami/slice_configurable_spec.rb +104 -0
- data/spec/unit/hanami/slice_name_spec.rb +47 -0
- data/spec/unit/hanami/slice_spec.rb +17 -0
- data/spec/unit/hanami/version_spec.rb +7 -0
- data/spec/unit/hanami/web/rack_logger_spec.rb +78 -0
- metadata +353 -57
- data/lib/hanami/application/action.rb +0 -72
- data/lib/hanami/application/container/providers/inflector.rb +0 -7
- data/lib/hanami/application/container/providers/logger.rb +0 -7
- data/lib/hanami/application/container/providers/rack_logger.rb +0 -15
- data/lib/hanami/application/container/providers/rack_monitor.rb +0 -12
- data/lib/hanami/application/container/providers/routes_helper.rb +0 -9
- data/lib/hanami/application/container/providers/settings.rb +0 -7
- data/lib/hanami/application/routes.rb +0 -55
- data/lib/hanami/application/routes_helper.rb +0 -34
- data/lib/hanami/application/routing/resolver/node.rb +0 -50
- data/lib/hanami/application/routing/resolver/trie.rb +0 -59
- data/lib/hanami/application/routing/resolver.rb +0 -87
- data/lib/hanami/application/routing/router.rb +0 -36
- data/lib/hanami/application/settings/dotenv_store.rb +0 -60
- data/lib/hanami/application/settings.rb +0 -93
- data/lib/hanami/application/slice_registrar.rb +0 -106
- data/lib/hanami/application/view/context.rb +0 -95
- data/lib/hanami/application/view.rb +0 -24
- data/lib/hanami/application.rb +0 -273
- data/lib/hanami/cli/application/cli.rb +0 -40
- data/lib/hanami/cli/application/command.rb +0 -47
- data/lib/hanami/cli/application/commands/console.rb +0 -81
- data/lib/hanami/cli/application/commands.rb +0 -16
- data/lib/hanami/cli/base_command.rb +0 -48
- data/lib/hanami/cli/commands/command.rb +0 -171
- data/lib/hanami/cli/commands/server.rb +0 -88
- data/lib/hanami/cli/commands.rb +0 -65
- data/lib/hanami/configuration/middleware.rb +0 -20
- data/lib/hanami/configuration/source_dirs.rb +0 -42
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
RSpec.describe "App action / View rendering", :app_integration do
|
|
4
|
+
specify "Views render with a request-specific context object" do
|
|
5
|
+
with_tmp_directory(Dir.mktmpdir) do
|
|
6
|
+
write "config/app.rb", <<~RUBY
|
|
7
|
+
require "hanami"
|
|
8
|
+
|
|
9
|
+
module TestApp
|
|
10
|
+
class App < Hanami::App
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
RUBY
|
|
14
|
+
|
|
15
|
+
write "app/action.rb", <<~RUBY
|
|
16
|
+
# auto_register: false
|
|
17
|
+
|
|
18
|
+
module TestApp
|
|
19
|
+
class Action < Hanami::Action
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
RUBY
|
|
23
|
+
|
|
24
|
+
write "app/view.rb", <<~RUBY
|
|
25
|
+
# auto_register: false
|
|
26
|
+
|
|
27
|
+
require "hanami/view"
|
|
28
|
+
|
|
29
|
+
module TestApp
|
|
30
|
+
class View < Hanami::View
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
RUBY
|
|
34
|
+
|
|
35
|
+
write "app/views/context.rb", <<~RUBY
|
|
36
|
+
require "hanami/view/context"
|
|
37
|
+
|
|
38
|
+
module TestApp
|
|
39
|
+
module Views
|
|
40
|
+
class Context < Hanami::View::Context
|
|
41
|
+
def request
|
|
42
|
+
_options.fetch(:request)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def response
|
|
46
|
+
_options.fetch(:response)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
RUBY
|
|
52
|
+
|
|
53
|
+
write "app/actions/users/show.rb", <<~RUBY
|
|
54
|
+
module TestApp
|
|
55
|
+
module Actions
|
|
56
|
+
module Users
|
|
57
|
+
class Show < TestApp::Action
|
|
58
|
+
include Deps[view: "views.users.show"]
|
|
59
|
+
|
|
60
|
+
def handle(req, res)
|
|
61
|
+
res[:job] = "Singer"
|
|
62
|
+
res[:age] = 0
|
|
63
|
+
|
|
64
|
+
res.render view, name: req.params[:name], age: 51
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
RUBY
|
|
71
|
+
|
|
72
|
+
write "app/views/users/show.rb", <<~RUBY
|
|
73
|
+
module TestApp
|
|
74
|
+
module Views
|
|
75
|
+
module Users
|
|
76
|
+
class Show < TestApp::View
|
|
77
|
+
expose :name, :job, :age
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
RUBY
|
|
83
|
+
|
|
84
|
+
write "app/templates/layouts/app.html.slim", <<~SLIM
|
|
85
|
+
html
|
|
86
|
+
body
|
|
87
|
+
== yield
|
|
88
|
+
SLIM
|
|
89
|
+
|
|
90
|
+
write "app/templates/users/show.html.slim", <<~'SLIM'
|
|
91
|
+
h1 Hello, #{name}
|
|
92
|
+
- request.params.to_h.values.sort.each do |value|
|
|
93
|
+
p = value
|
|
94
|
+
p = job
|
|
95
|
+
p = age
|
|
96
|
+
SLIM
|
|
97
|
+
|
|
98
|
+
require "hanami/prepare"
|
|
99
|
+
|
|
100
|
+
action = TestApp::App["actions.users.show"]
|
|
101
|
+
response = action.(name: "Jennifer", last_name: "Lopez")
|
|
102
|
+
rendered = response.body[0]
|
|
103
|
+
|
|
104
|
+
expect(rendered).to eq "<html><body><h1>Hello, Jennifer</h1><p>Jennifer</p><p>Lopez</p><p>Singer</p><p>51</p></body></html>"
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
RSpec.describe "Code loading / Loading from app directory", :app_integration do
|
|
4
|
+
before :context do
|
|
5
|
+
with_directory(@dir = make_tmp_directory) do
|
|
6
|
+
write "config/app.rb", <<~'RUBY'
|
|
7
|
+
require "hanami"
|
|
8
|
+
|
|
9
|
+
module TestApp
|
|
10
|
+
class App < Hanami::App
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
RUBY
|
|
14
|
+
|
|
15
|
+
write "app/test_class.rb", <<~'RUBY'
|
|
16
|
+
module TestApp
|
|
17
|
+
class TestClass
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
RUBY
|
|
21
|
+
|
|
22
|
+
write "app/action.rb", <<~'RUBY'
|
|
23
|
+
# auto_register: false
|
|
24
|
+
|
|
25
|
+
module TestApp
|
|
26
|
+
class Action < Hanami::Action
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
RUBY
|
|
30
|
+
|
|
31
|
+
write "app/actions/home/show.rb", <<~'RUBY'
|
|
32
|
+
module TestApp
|
|
33
|
+
module Actions
|
|
34
|
+
module Home
|
|
35
|
+
class Show < TestApp::Action
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
RUBY
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
before do
|
|
45
|
+
with_directory(@dir) do
|
|
46
|
+
require "hanami/prepare"
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
specify "Classes in app/ directory are autoloaded with the app namespace" do
|
|
51
|
+
expect(TestApp::TestClass).to be
|
|
52
|
+
expect(TestApp::Action).to be
|
|
53
|
+
expect(TestApp::Actions::Home::Show).to be
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
specify "Classes in app directory are auto-registered" do
|
|
57
|
+
expect(TestApp::App["test_class"]).to be_an_instance_of TestApp::TestClass
|
|
58
|
+
expect(TestApp::App["actions.home.show"]).to be_an_instance_of TestApp::Actions::Home::Show
|
|
59
|
+
|
|
60
|
+
# Files with "auto_register: false" magic comments are not auto-registered
|
|
61
|
+
expect(TestApp::App.key?("action")).to be false
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
describe "app/lib/ directory" do
|
|
65
|
+
before :context do
|
|
66
|
+
with_directory(@dir = make_tmp_directory) 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/lib/test_class.rb", <<~'RUBY'
|
|
77
|
+
module TestApp
|
|
78
|
+
class TestClass
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
RUBY
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
specify "Classes in app/lib/ directory are autoloaded with the app namespace" do
|
|
86
|
+
expect(TestApp::TestClass).to be
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
specify "Classes in app/lib/ directory are auto-registered" do
|
|
90
|
+
expect(TestApp::App["test_class"]).to be_an_instance_of TestApp::TestClass
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
specify "Classes in app/lib/ directory are not redundantly auto-registered under 'lib' key namespace" do
|
|
94
|
+
expect(TestApp::App.key?("lib.test_class")).to be false
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# rubocop:disable Style/GlobalVars
|
|
99
|
+
describe "same-named class defined in both app/ and app/lib/ directories" do
|
|
100
|
+
before :context do
|
|
101
|
+
with_directory(@dir = make_tmp_directory) do
|
|
102
|
+
write "config/app.rb", <<~'RUBY'
|
|
103
|
+
require "hanami"
|
|
104
|
+
|
|
105
|
+
module TestApp
|
|
106
|
+
class App < Hanami::App
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
RUBY
|
|
110
|
+
|
|
111
|
+
write "app/test_class.rb", <<~'RUBY'
|
|
112
|
+
$app_class_loaded = true
|
|
113
|
+
|
|
114
|
+
module TestApp
|
|
115
|
+
class TestClass
|
|
116
|
+
(@loaded_from ||= []) << "app"
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
RUBY
|
|
120
|
+
|
|
121
|
+
write "app/lib/test_class.rb", <<~'RUBY'
|
|
122
|
+
$app_lib_class_loaded = true
|
|
123
|
+
|
|
124
|
+
module TestApp
|
|
125
|
+
class TestClass
|
|
126
|
+
(@loaded_from ||= []) << "app/lib"
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
RUBY
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
after do
|
|
134
|
+
$app_class_loaded = $app_lib_class_loaded = nil
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
specify "Classes in app/lib/ directory are preferred for autoloading" do
|
|
138
|
+
expect(TestApp::TestClass).to be
|
|
139
|
+
expect(TestApp::TestClass.instance_variable_get(:@loaded_from)).to eq ["app/lib"]
|
|
140
|
+
expect($app_lib_class_loaded).to be true
|
|
141
|
+
expect($app_class_loaded).to be nil
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
specify "Classes in app/lib/ directory are preferred for auto-registration" do
|
|
145
|
+
expect(TestApp::App["test_class"]).to be
|
|
146
|
+
expect(TestApp::TestClass.instance_variable_get(:@loaded_from)).to eq ["app/lib"]
|
|
147
|
+
expect($app_lib_class_loaded).to be true
|
|
148
|
+
expect($app_class_loaded).to be nil
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
# rubocop:enable Style/GlobalVars
|
|
152
|
+
end
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
RSpec.describe "Code loading / Loading from slice directory", :app_integration do
|
|
4
|
+
before :context do
|
|
5
|
+
with_directory(@dir = make_tmp_directory) do
|
|
6
|
+
write "config/app.rb", <<~'RUBY'
|
|
7
|
+
require "hanami"
|
|
8
|
+
|
|
9
|
+
module TestApp
|
|
10
|
+
class App < Hanami::App
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
RUBY
|
|
14
|
+
|
|
15
|
+
write "slices/main/config/not_loadable.rb", <<~'RUBY'
|
|
16
|
+
raise "This file should never be loaded"
|
|
17
|
+
RUBY
|
|
18
|
+
|
|
19
|
+
write "slices/main/test_class.rb", <<~'RUBY'
|
|
20
|
+
module Main
|
|
21
|
+
class TestClass
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
RUBY
|
|
25
|
+
|
|
26
|
+
write "slices/main/action.rb", <<~'RUBY'
|
|
27
|
+
# auto_register: false
|
|
28
|
+
|
|
29
|
+
module Main
|
|
30
|
+
class Action < Hanami::Action
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
RUBY
|
|
34
|
+
|
|
35
|
+
write "slices/main/actions/home/show.rb", <<~'RUBY'
|
|
36
|
+
module Main
|
|
37
|
+
module Actions
|
|
38
|
+
module Home
|
|
39
|
+
class Show < Main::Action
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
RUBY
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
before do
|
|
49
|
+
with_directory(@dir) do
|
|
50
|
+
require "hanami/prepare"
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
specify "Classes in slice directory are autoloaded with the slice namespace" do
|
|
55
|
+
expect(Main::TestClass).to be
|
|
56
|
+
expect(Main::Action).to be
|
|
57
|
+
expect(Main::Actions::Home::Show).to be
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
specify "Files in slice config/ directory are not autoloaded" do
|
|
61
|
+
expect { Main::NotLoadable }.to raise_error NameError
|
|
62
|
+
expect { Main::Config::NotLoadable }.to raise_error NameError
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
specify "Classes in slice directory are auto-registered" do
|
|
66
|
+
expect(Main::Slice["test_class"]).to be_an_instance_of Main::TestClass
|
|
67
|
+
expect(Main::Slice["actions.home.show"]).to be_an_instance_of Main::Actions::Home::Show
|
|
68
|
+
|
|
69
|
+
# Files with "auto_register: false" magic comments are not auto-registered
|
|
70
|
+
expect(Main::Slice.key?("action")).to be false
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
specify "Files in slice config/ directory are not auto-registered" do
|
|
74
|
+
expect(Main::Slice.key?("config.settings")).to be false
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
describe "slice lib/ directory" do
|
|
78
|
+
before :context do
|
|
79
|
+
with_directory(@dir = make_tmp_directory) do
|
|
80
|
+
write "config/app.rb", <<~'RUBY'
|
|
81
|
+
require "hanami"
|
|
82
|
+
|
|
83
|
+
module TestApp
|
|
84
|
+
class App < Hanami::App
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
RUBY
|
|
88
|
+
|
|
89
|
+
write "slices/main/lib/test_class.rb", <<~'RUBY'
|
|
90
|
+
module Main
|
|
91
|
+
class TestClass
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
RUBY
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
specify "Classes in slice lib/ directory are autoloaded with the slice namespace" do
|
|
99
|
+
expect(Main::TestClass).to be
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
specify "Classes in slice lib/ directory are auto-registered" do
|
|
103
|
+
expect(Main::Slice["test_class"]).to be_an_instance_of Main::TestClass
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
specify "Classes in slice lib/ directory are not redundantly auto-registered under 'lib' key namespace" do
|
|
107
|
+
expect(Main::Slice.key?("lib.test_class")).to be false
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# rubocop:disable Style/GlobalVars
|
|
112
|
+
describe "same-named class defined in both slice and lib/ directories" do
|
|
113
|
+
before :context do
|
|
114
|
+
with_directory(@dir = make_tmp_directory) do
|
|
115
|
+
write "config/app.rb", <<~'RUBY'
|
|
116
|
+
require "hanami"
|
|
117
|
+
|
|
118
|
+
module TestApp
|
|
119
|
+
class App < Hanami::App
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
RUBY
|
|
123
|
+
|
|
124
|
+
write "slices/main/test_class.rb", <<~'RUBY'
|
|
125
|
+
$slice_class_loaded = true
|
|
126
|
+
|
|
127
|
+
module Main
|
|
128
|
+
class TestClass
|
|
129
|
+
(@loaded_from ||= []) << "slice"
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
RUBY
|
|
133
|
+
|
|
134
|
+
write "slices/main/lib/test_class.rb", <<~'RUBY'
|
|
135
|
+
$slice_lib_class_loaded = true
|
|
136
|
+
|
|
137
|
+
module Main
|
|
138
|
+
class TestClass
|
|
139
|
+
(@loaded_from ||= []) << "slice/lib"
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
RUBY
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
after do
|
|
147
|
+
$slice_class_loaded = $slice_lib_class_loaded = nil
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
specify "Classes in slice lib/ directory are preferred for autoloading" do
|
|
151
|
+
expect(Main::TestClass).to be
|
|
152
|
+
expect(Main::TestClass.instance_variable_get(:@loaded_from)).to eq ["slice/lib"]
|
|
153
|
+
expect($slice_lib_class_loaded).to be true
|
|
154
|
+
expect($slice_class_loaded).to be nil
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
specify "Classes in slice lib/ directory are preferred for auto-registration" do
|
|
158
|
+
expect(Main::Slice["test_class"]).to be
|
|
159
|
+
expect(Main::TestClass.instance_variable_get(:@loaded_from)).to eq ["slice/lib"]
|
|
160
|
+
expect($slice_lib_class_loaded).to be true
|
|
161
|
+
expect($slice_class_loaded).to be nil
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
# rubocop:enable Style/GlobalVars
|
|
165
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
RSpec.describe "App routes helper", :app_integration do
|
|
4
|
+
specify "Routing to actions based on their container identifiers" do
|
|
5
|
+
with_tmp_directory(Dir.mktmpdir) do
|
|
6
|
+
write "config/app.rb", <<~RUBY
|
|
7
|
+
require "hanami"
|
|
8
|
+
|
|
9
|
+
module TestApp
|
|
10
|
+
class App < Hanami::App
|
|
11
|
+
config.logger.stream = File.new("/dev/null", "w")
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
RUBY
|
|
15
|
+
|
|
16
|
+
write "config/routes.rb", <<~RUBY
|
|
17
|
+
module TestApp
|
|
18
|
+
class Routes < Hanami::Routes
|
|
19
|
+
define do
|
|
20
|
+
root to: "home.index"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
RUBY
|
|
25
|
+
|
|
26
|
+
write "app/actions/home/index.rb", <<~RUBY
|
|
27
|
+
require "hanami/action"
|
|
28
|
+
|
|
29
|
+
module TestApp
|
|
30
|
+
module Actions
|
|
31
|
+
module Home
|
|
32
|
+
class Index < Hanami::Action
|
|
33
|
+
def handle(*, res)
|
|
34
|
+
res.body = "Hello world"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
RUBY
|
|
41
|
+
|
|
42
|
+
require "hanami/prepare"
|
|
43
|
+
|
|
44
|
+
expect(TestApp::App["routes"].path(:root)).to eq "/"
|
|
45
|
+
expect(TestApp::App["routes"].url(:root).to_s).to match /http:\/\/.*\//
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
RSpec.describe "Container auto-injection (aka \"Deps\") mixin", :app_integration do
|
|
4
|
+
# rubocop:disable Metrics/MethodLength
|
|
5
|
+
def with_app
|
|
6
|
+
with_tmp_directory(Dir.mktmpdir) do
|
|
7
|
+
write "config/app.rb", <<~RUBY
|
|
8
|
+
require "hanami"
|
|
9
|
+
|
|
10
|
+
module TestApp
|
|
11
|
+
class App < Hanami::App
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
RUBY
|
|
15
|
+
|
|
16
|
+
write "app/some_service.rb", <<~'RUBY'
|
|
17
|
+
module TestApp
|
|
18
|
+
class SomeService
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
RUBY
|
|
22
|
+
|
|
23
|
+
write "app/some_operation.rb", <<~'RUBY'
|
|
24
|
+
module TestApp
|
|
25
|
+
class SomeOperation
|
|
26
|
+
include Deps["some_service"]
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
RUBY
|
|
30
|
+
|
|
31
|
+
yield
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
# rubocop:enable Metrics/MethodLength
|
|
35
|
+
|
|
36
|
+
specify "Dependencies are auto-injected in a booted app" do
|
|
37
|
+
with_app do
|
|
38
|
+
require "hanami/boot"
|
|
39
|
+
|
|
40
|
+
op = TestApp::App["some_operation"]
|
|
41
|
+
expect(op.some_service).to be_a TestApp::SomeService
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
specify "Dependencies are lazily resolved and auto-injected in an unbooted app" do
|
|
46
|
+
with_app do
|
|
47
|
+
require "hanami/prepare"
|
|
48
|
+
|
|
49
|
+
op = TestApp::App["some_operation"]
|
|
50
|
+
expect(op.some_service).to be_a TestApp::SomeService
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
RSpec.describe "Container auto-registration", :app_integration do
|
|
4
|
+
specify "Auto-registering files in slice source directories" do
|
|
5
|
+
with_tmp_directory(Dir.mktmpdir) do
|
|
6
|
+
write "config/app.rb", <<~RUBY
|
|
7
|
+
require "hanami"
|
|
8
|
+
|
|
9
|
+
module TestApp
|
|
10
|
+
class App < Hanami::App
|
|
11
|
+
config.inflections do |inflections|
|
|
12
|
+
inflections.acronym "NBA"
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
RUBY
|
|
17
|
+
|
|
18
|
+
write "app/action.rb", <<~RUBY
|
|
19
|
+
# auto_register: false
|
|
20
|
+
require "hanami/action"
|
|
21
|
+
|
|
22
|
+
module TestApp
|
|
23
|
+
class Action < Hanami::Action
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
RUBY
|
|
27
|
+
|
|
28
|
+
write "app/actions/nba_rosters/index.rb", <<~RUBY
|
|
29
|
+
module TestApp
|
|
30
|
+
module Actions
|
|
31
|
+
module NBARosters
|
|
32
|
+
class Index < TestApp::Action
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
RUBY
|
|
38
|
+
|
|
39
|
+
write "slices/admin/lib/nba_jam/get_that_outta_here.rb", <<~RUBY
|
|
40
|
+
module Admin
|
|
41
|
+
module NBAJam
|
|
42
|
+
class GetThatOuttaHere
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
RUBY
|
|
47
|
+
|
|
48
|
+
require "hanami/setup"
|
|
49
|
+
Hanami.boot
|
|
50
|
+
|
|
51
|
+
expect(TestApp::App["actions.nba_rosters.index"]).to be_an TestApp::Actions::NBARosters::Index
|
|
52
|
+
expect(Admin::Slice["nba_jam.get_that_outta_here"]).to be_an Admin::NBAJam::GetThatOuttaHere
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "Unbooted app resolves components lazily from the lib/ directories" do
|
|
57
|
+
with_tmp_directory(Dir.mktmpdir) do
|
|
58
|
+
write "config/app.rb", <<~RUBY
|
|
59
|
+
require "hanami"
|
|
60
|
+
|
|
61
|
+
module TestApp
|
|
62
|
+
class App < Hanami::App
|
|
63
|
+
config.inflections do |inflections|
|
|
64
|
+
inflections.acronym "NBA"
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
RUBY
|
|
69
|
+
|
|
70
|
+
write "slices/admin/lib/nba_jam/get_that_outta_here.rb", <<~RUBY
|
|
71
|
+
module Admin
|
|
72
|
+
module NBAJam
|
|
73
|
+
class GetThatOuttaHere
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
RUBY
|
|
78
|
+
|
|
79
|
+
require "hanami/prepare"
|
|
80
|
+
|
|
81
|
+
expect(Admin::Slice.keys).not_to include("nba_jam.get_that_outta_here")
|
|
82
|
+
expect(Admin::Slice["nba_jam.get_that_outta_here"]).to be_an Admin::NBAJam::GetThatOuttaHere
|
|
83
|
+
expect(Admin::Slice.keys).to include("nba_jam.get_that_outta_here")
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
RSpec.describe "App autoloader", :app_integration do
|
|
2
|
+
specify "Classes are autoloaded through direct reference, including through components resolved from the container" do
|
|
3
|
+
with_tmp_directory(Dir.mktmpdir) do
|
|
4
|
+
write "config/app.rb", <<~RUBY
|
|
5
|
+
require "hanami"
|
|
6
|
+
|
|
7
|
+
module TestApp
|
|
8
|
+
class App < Hanami::App
|
|
9
|
+
# Use a custom inflection to ensure this is respected by the autoloader
|
|
10
|
+
config.inflections do |inflections|
|
|
11
|
+
inflections.acronym "NBA"
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
RUBY
|
|
16
|
+
|
|
17
|
+
write "lib/non_app/thing.rb", <<~RUBY
|
|
18
|
+
module NonApp
|
|
19
|
+
class Thing
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
RUBY
|
|
23
|
+
|
|
24
|
+
write "lib/test_app/nba_jam/get_that_outta_here.rb", <<~RUBY
|
|
25
|
+
module TestApp
|
|
26
|
+
module NBAJam
|
|
27
|
+
class GetThatOuttaHere
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
RUBY
|
|
32
|
+
|
|
33
|
+
write "slices/admin/lib/operations/create_game.rb", <<~RUBY
|
|
34
|
+
module Admin
|
|
35
|
+
module Operations
|
|
36
|
+
class CreateGame
|
|
37
|
+
def call
|
|
38
|
+
Entities::Game.new
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
RUBY
|
|
44
|
+
|
|
45
|
+
write "slices/admin/lib/entities/game.rb", <<~RUBY
|
|
46
|
+
# auto_register: false
|
|
47
|
+
|
|
48
|
+
module Admin
|
|
49
|
+
module Entities
|
|
50
|
+
class Game
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
RUBY
|
|
55
|
+
|
|
56
|
+
write "slices/admin/lib/entities/quarter.rb", <<~RUBY
|
|
57
|
+
# auto_register: false
|
|
58
|
+
|
|
59
|
+
module Admin
|
|
60
|
+
module Entities
|
|
61
|
+
class Quarter
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
RUBY
|
|
66
|
+
|
|
67
|
+
require "hanami/prepare"
|
|
68
|
+
|
|
69
|
+
expect(require("non_app/thing")).to be true
|
|
70
|
+
expect(NonApp::Thing).to be
|
|
71
|
+
|
|
72
|
+
expect(TestApp::NBAJam::GetThatOuttaHere).to be
|
|
73
|
+
|
|
74
|
+
expect(Admin::Slice["operations.create_game"]).to be_an_instance_of(Admin::Operations::CreateGame)
|
|
75
|
+
expect(Admin::Slice["operations.create_game"].call).to be_an_instance_of(Admin::Entities::Game)
|
|
76
|
+
|
|
77
|
+
expect(Admin::Entities::Quarter).to be
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|