hanami 2.0.0.beta4 → 2.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +19 -0
- data/hanami.gemspec +8 -7
- data/lib/hanami/app.rb +47 -36
- data/lib/hanami/assets/app_config.rb +7 -15
- data/lib/hanami/assets/config.rb +5 -6
- data/lib/hanami/config/actions/content_security_policy.rb +1 -1
- data/lib/hanami/config/actions/cookies.rb +27 -0
- data/lib/hanami/config/actions/sessions.rb +42 -5
- data/lib/hanami/config/actions.rb +81 -17
- data/lib/hanami/config/logger.rb +112 -23
- data/lib/hanami/config/router.rb +0 -1
- data/lib/hanami/config/views.rb +6 -10
- data/lib/hanami/config.rb +235 -73
- data/lib/hanami/constants.rb +4 -0
- data/lib/hanami/errors.rb +17 -0
- data/lib/hanami/extensions/action/slice_configured_action.rb +9 -5
- data/lib/hanami/extensions/action.rb +59 -7
- data/lib/hanami/extensions/view/context.rb +3 -4
- data/lib/hanami/extensions/view/slice_configured_view.rb +4 -4
- data/lib/hanami/extensions/view.rb +7 -5
- data/lib/hanami/providers/inflector.rb +6 -0
- data/lib/hanami/providers/logger.rb +8 -0
- data/lib/hanami/providers/rack.rb +12 -0
- data/lib/hanami/providers/routes.rb +14 -4
- data/lib/hanami/routes.rb +36 -1
- data/lib/hanami/settings/env_store.rb +1 -1
- data/lib/hanami/settings.rb +102 -36
- data/lib/hanami/slice/router.rb +38 -16
- data/lib/hanami/slice/routing/middleware/stack.rb +66 -42
- data/lib/hanami/slice/routing/resolver.rb +10 -17
- data/lib/hanami/slice/view_name_inferrer.rb +1 -1
- data/lib/hanami/slice.rb +553 -14
- data/lib/hanami/slice_registrar.rb +20 -15
- data/lib/hanami/version.rb +2 -3
- data/lib/hanami/web/rack_logger.rb +14 -4
- data/lib/hanami.rb +122 -23
- data/spec/integration/action/csrf_protection_spec.rb +1 -1
- data/spec/integration/container/application_routes_helper_spec.rb +3 -1
- data/spec/integration/container/provider_lifecycle_spec.rb +61 -0
- data/spec/integration/container/standard_providers/rack_provider_spec.rb +44 -0
- data/spec/integration/container/{standard_bootable_components_spec.rb → standard_providers_spec.rb} +3 -3
- data/spec/integration/rack_app/body_parser_spec.rb +3 -0
- data/spec/integration/rack_app/middleware_spec.rb +427 -3
- data/spec/integration/rack_app/non_booted_rack_app_spec.rb +2 -1
- data/spec/integration/rack_app/rack_app_spec.rb +39 -11
- data/spec/integration/setup_spec.rb +4 -4
- data/spec/integration/slices/external_slice_spec.rb +2 -1
- data/spec/integration/slices/slice_configuration_spec.rb +3 -1
- data/spec/integration/slices/slice_loading_spec.rb +4 -4
- data/spec/integration/slices/slice_routing_spec.rb +4 -3
- data/spec/integration/slices_spec.rb +100 -0
- data/spec/isolation/hanami/boot/success_spec.rb +1 -1
- data/spec/support/app_integration.rb +2 -10
- data/spec/unit/hanami/config/actions/content_security_policy_spec.rb +7 -7
- data/spec/unit/hanami/config/actions/default_values_spec.rb +1 -1
- data/spec/unit/hanami/config/actions/sessions_spec.rb +1 -3
- data/spec/unit/hanami/config/actions_spec.rb +1 -12
- data/spec/unit/hanami/config/logger_spec.rb +38 -55
- data/spec/unit/hanami/config/router_spec.rb +1 -1
- data/spec/unit/hanami/config/views_spec.rb +3 -13
- data/spec/unit/hanami/settings_spec.rb +1 -1
- data/spec/unit/hanami/slice_configurable_spec.rb +5 -5
- data/spec/unit/hanami/slice_spec.rb +32 -0
- data/spec/unit/hanami/version_spec.rb +1 -1
- data/spec/unit/hanami/web/rack_logger_spec.rb +13 -2
- metadata +54 -45
- data/lib/hanami/config/sessions.rb +0 -50
- data/spec/unit/hanami/config_spec.rb +0 -43
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "constants"
|
4
|
-
require_relative "slice"
|
5
4
|
|
6
5
|
module Hanami
|
7
6
|
# @api private
|
8
7
|
class SliceRegistrar
|
8
|
+
VALID_SLICE_NAME_RE = /^[a-z][a-z0-9_]+$/
|
9
9
|
SLICE_DELIMITER = CONTAINER_KEY_DELIMITER
|
10
10
|
|
11
11
|
attr_reader :parent, :slices
|
@@ -17,14 +17,16 @@ module Hanami
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def register(name, slice_class = nil, &block)
|
20
|
+
unless name.to_s =~ VALID_SLICE_NAME_RE
|
21
|
+
raise ArgumentError, "slice name #{name.inspect} must be lowercase alphanumeric text and underscores only"
|
22
|
+
end
|
23
|
+
|
20
24
|
return unless filter_slice_names([name]).any?
|
21
25
|
|
22
26
|
if slices.key?(name.to_sym)
|
23
27
|
raise SliceLoadError, "Slice '#{name}' is already registered"
|
24
28
|
end
|
25
29
|
|
26
|
-
# TODO: raise error unless name meets format (i.e. single level depth only)
|
27
|
-
|
28
30
|
slice = slice_class || build_slice(name, &block)
|
29
31
|
|
30
32
|
configure_slice(name, slice)
|
@@ -44,8 +46,6 @@ module Hanami
|
|
44
46
|
end
|
45
47
|
|
46
48
|
def load_slices
|
47
|
-
return self unless root
|
48
|
-
|
49
49
|
slice_configs = Dir[root.join(CONFIG_DIR, SLICES_DIR, "*#{RB_EXT}")]
|
50
50
|
.map { |file| File.basename(file, RB_EXT) }
|
51
51
|
|
@@ -77,7 +77,9 @@ module Hanami
|
|
77
77
|
|
78
78
|
def with_nested
|
79
79
|
to_a.flat_map { |slice|
|
80
|
-
|
80
|
+
# Return nested slices first so that their more specific namespaces may be picked up first
|
81
|
+
# by SliceConfigurable#slice_for
|
82
|
+
slice.slices.with_nested + [slice]
|
81
83
|
}
|
82
84
|
end
|
83
85
|
|
@@ -91,36 +93,39 @@ module Hanami
|
|
91
93
|
parent.inflector
|
92
94
|
end
|
93
95
|
|
94
|
-
|
95
|
-
|
96
|
-
|
96
|
+
def parent_slice_namespace
|
97
|
+
parent.eql?(parent.app) ? Object : parent.namespace
|
98
|
+
end
|
99
|
+
|
100
|
+
# Runs when a slice file has been found at `config/slices/[slice_name].rb`, or a slice directory
|
101
|
+
# at `slices/[slice_name]`. Attempts to require the slice class, if defined, before registering
|
102
|
+
# the slice. If a slice class is not found, registering the slice will generate the slice class.
|
97
103
|
def load_slice(slice_name)
|
98
|
-
slice_const_name = inflector.camelize(slice_name)
|
99
104
|
slice_require_path = root.join(CONFIG_DIR, SLICES_DIR, slice_name).to_s
|
100
|
-
|
101
105
|
begin
|
102
106
|
require(slice_require_path)
|
103
107
|
rescue LoadError => e
|
104
108
|
raise e unless e.path == slice_require_path
|
105
109
|
end
|
106
110
|
|
111
|
+
slice_module_name = inflector.camelize("#{parent_slice_namespace.name}#{PATH_DELIMITER}#{slice_name}")
|
107
112
|
slice_class =
|
108
113
|
begin
|
109
|
-
inflector.constantize("#{
|
114
|
+
inflector.constantize("#{slice_module_name}#{MODULE_DELIMITER}Slice")
|
110
115
|
rescue NameError => e
|
111
|
-
raise e unless e.name.to_s ==
|
116
|
+
raise e unless e.name.to_s == inflector.camelize(slice_name) || e.name.to_s == :Slice
|
112
117
|
end
|
113
118
|
|
114
119
|
register(slice_name, slice_class)
|
115
120
|
end
|
116
121
|
|
117
122
|
def build_slice(slice_name, &block)
|
123
|
+
slice_module_name = inflector.camelize("#{parent_slice_namespace.name}#{PATH_DELIMITER}#{slice_name}")
|
118
124
|
slice_module =
|
119
125
|
begin
|
120
|
-
slice_module_name = inflector.camelize(slice_name.to_s)
|
121
126
|
inflector.constantize(slice_module_name)
|
122
127
|
rescue NameError
|
123
|
-
|
128
|
+
parent_slice_namespace.const_set(inflector.camelize(slice_name), Module.new)
|
124
129
|
end
|
125
130
|
|
126
131
|
slice_module.const_set(:Slice, Class.new(Hanami::Slice, &block))
|
data/lib/hanami/version.rb
CHANGED
@@ -1,8 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Hanami
|
4
|
+
# @api private
|
4
5
|
module Web
|
5
6
|
# Rack logger for Hanami apps
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
# @since 2.0.0
|
6
10
|
class RackLogger
|
7
11
|
REQUEST_METHOD = "REQUEST_METHOD"
|
8
12
|
private_constant :REQUEST_METHOD
|
@@ -25,10 +29,14 @@ module Hanami
|
|
25
29
|
CONTENT_LENGTH = "Content-Length"
|
26
30
|
private_constant :CONTENT_LENGTH
|
27
31
|
|
32
|
+
# @api private
|
33
|
+
# @since 2.0.0
|
28
34
|
def initialize(logger)
|
29
35
|
@logger = logger
|
30
36
|
end
|
31
37
|
|
38
|
+
# @api private
|
39
|
+
# @since 2.0.0
|
32
40
|
def attach(rack_monitor)
|
33
41
|
rack_monitor.on :stop do |event|
|
34
42
|
log_request event[:env], event[:status], event[:time]
|
@@ -39,6 +47,8 @@ module Hanami
|
|
39
47
|
end
|
40
48
|
end
|
41
49
|
|
50
|
+
# @api private
|
51
|
+
# @since 2.0.0
|
42
52
|
def log_request(env, status, elapsed)
|
43
53
|
data = {
|
44
54
|
verb: env[REQUEST_METHOD],
|
@@ -47,16 +57,16 @@ module Hanami
|
|
47
57
|
ip: env[HTTP_X_FORWARDED_FOR] || env[REMOTE_ADDR],
|
48
58
|
path: env[SCRIPT_NAME] + env[PATH_INFO].to_s,
|
49
59
|
length: extract_content_length(env),
|
50
|
-
params: env[ROUTER_PARAMS]
|
51
|
-
time: Time.now,
|
60
|
+
params: env[ROUTER_PARAMS]
|
52
61
|
}
|
53
62
|
|
54
63
|
logger.info(data)
|
55
64
|
end
|
56
65
|
|
66
|
+
# @api private
|
67
|
+
# @since 2.0.0
|
57
68
|
def log_exception(exception)
|
58
|
-
logger.error
|
59
|
-
logger.error exception.backtrace.join("\n")
|
69
|
+
logger.error(exception)
|
60
70
|
end
|
61
71
|
|
62
72
|
private
|
data/lib/hanami.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "zeitwerk"
|
4
|
+
require_relative "hanami/constants"
|
5
|
+
|
3
6
|
# A complete web framework for Ruby
|
4
7
|
#
|
5
8
|
# @since 0.1.0
|
@@ -9,11 +12,21 @@ module Hanami
|
|
9
12
|
@_mutex = Mutex.new
|
10
13
|
@_bundled = {}
|
11
14
|
|
15
|
+
# @api private
|
16
|
+
# @since 2.0.0
|
17
|
+
def self.loader
|
18
|
+
@loader ||= Zeitwerk::Loader.for_gem.tap do |loader|
|
19
|
+
loader.ignore(
|
20
|
+
"#{loader.dirs.first}/hanami/{constants,boot,errors,prepare,rake_tasks,setup}.rb"
|
21
|
+
)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
12
25
|
# Finds and loads the Hanami app file (`config/app.rb`).
|
13
26
|
#
|
14
27
|
# Raises an exception if the app file cannot be found.
|
15
28
|
#
|
16
|
-
# @return [
|
29
|
+
# @return [app] the loaded app class
|
17
30
|
#
|
18
31
|
# @api public
|
19
32
|
# @since 2.0.0
|
@@ -34,32 +47,18 @@ module Hanami
|
|
34
47
|
end
|
35
48
|
end
|
36
49
|
|
37
|
-
#
|
50
|
+
# Returns the Hamami app class.
|
38
51
|
#
|
39
|
-
#
|
40
|
-
# app file can be found.
|
52
|
+
# To ensure your Hanami app is loaded, run {.setup} (or `require "hanami/setup"`) first.
|
41
53
|
#
|
42
|
-
# @
|
43
|
-
# directory.
|
54
|
+
# @return [Hanami::App] the app class
|
44
55
|
#
|
45
|
-
# @
|
56
|
+
# @raise [AppLoadError] if the app has not been loaded
|
57
|
+
#
|
58
|
+
# @see .setup
|
46
59
|
#
|
47
60
|
# @api public
|
48
61
|
# @since 2.0.0
|
49
|
-
def self.app_path(dir = Dir.pwd)
|
50
|
-
dir = Pathname(dir).expand_path
|
51
|
-
path = dir.join(APP_PATH)
|
52
|
-
|
53
|
-
if path.file?
|
54
|
-
path.to_s
|
55
|
-
elsif !dir.root?
|
56
|
-
app_path(dir.parent)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
APP_PATH = "config/app.rb"
|
61
|
-
private_constant :APP_PATH
|
62
|
-
|
63
62
|
def self.app
|
64
63
|
@_mutex.synchronize do
|
65
64
|
unless defined?(@_app)
|
@@ -72,10 +71,18 @@ module Hanami
|
|
72
71
|
end
|
73
72
|
end
|
74
73
|
|
74
|
+
# Returns true if the Hanami app class has been loaded.
|
75
|
+
#
|
76
|
+
# @return [Boolean]
|
77
|
+
#
|
78
|
+
# @api public
|
79
|
+
# @since 2.0.0
|
75
80
|
def self.app?
|
76
81
|
instance_variable_defined?(:@_app)
|
77
82
|
end
|
78
83
|
|
84
|
+
# @api private
|
85
|
+
# @since 2.0.0
|
79
86
|
def self.app=(klass)
|
80
87
|
@_mutex.synchronize do
|
81
88
|
if instance_variable_defined?(:@_app)
|
@@ -86,30 +93,117 @@ module Hanami
|
|
86
93
|
end
|
87
94
|
end
|
88
95
|
|
96
|
+
# Finds and returns the absolute path for the Hanami app file (`config/app.rb`).
|
97
|
+
#
|
98
|
+
# Searches within the given directory, then searches upwards through parent directories until the
|
99
|
+
# app file can be found.
|
100
|
+
#
|
101
|
+
# @param dir [String] The directory from which to start searching. Defaults to the current
|
102
|
+
# directory.
|
103
|
+
#
|
104
|
+
# @return [String, nil] the app file path, or nil if not found.
|
105
|
+
#
|
106
|
+
# @api public
|
107
|
+
# @since 2.0.0
|
108
|
+
def self.app_path(dir = Dir.pwd)
|
109
|
+
dir = Pathname(dir).expand_path
|
110
|
+
path = dir.join(APP_PATH)
|
111
|
+
|
112
|
+
if path.file?
|
113
|
+
path.to_s
|
114
|
+
elsif !dir.root?
|
115
|
+
app_path(dir.parent)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# Returns the Hanami app environment as loaded from the `HANAMI_ENV` environment variable.
|
120
|
+
#
|
121
|
+
# @example
|
122
|
+
# Hanami.env # => :development
|
123
|
+
#
|
124
|
+
# @return [Symbol] the environment name
|
125
|
+
#
|
126
|
+
# @api public
|
127
|
+
# @since 2.0.0
|
89
128
|
def self.env
|
90
129
|
ENV.fetch("HANAMI_ENV") { ENV.fetch("RACK_ENV", "development") }.to_sym
|
91
130
|
end
|
92
131
|
|
132
|
+
# Returns true if {.env} matches any of the given names
|
133
|
+
#
|
134
|
+
# @example
|
135
|
+
# Hanami.env # => :development
|
136
|
+
# Hanami.env?(:development, :test) # => true
|
137
|
+
#
|
138
|
+
# @param names [Array<Symbol>] the environment names to check
|
139
|
+
#
|
140
|
+
# @return [Boolean]
|
141
|
+
#
|
142
|
+
# @api public
|
143
|
+
# @since 2.0.0
|
93
144
|
def self.env?(*names)
|
94
145
|
names.map(&:to_sym).include?(env)
|
95
146
|
end
|
96
147
|
|
148
|
+
# Returns the app's logger.
|
149
|
+
#
|
150
|
+
# Direct global access to the logger via this method is not recommended. Instead, consider
|
151
|
+
# accessing the logger via the app or slice container, in most cases as an dependency using the
|
152
|
+
# `Deps` mixin.
|
153
|
+
#
|
154
|
+
# @example
|
155
|
+
# # app/my_component.rb
|
156
|
+
#
|
157
|
+
# module MyApp
|
158
|
+
# class MyComponent
|
159
|
+
# include Deps["logger"]
|
160
|
+
#
|
161
|
+
# def some_method
|
162
|
+
# logger.info("hello")
|
163
|
+
# end
|
164
|
+
# end
|
165
|
+
# end
|
166
|
+
#
|
167
|
+
# @return [Dry::Logger::Dispatcher]
|
168
|
+
#
|
169
|
+
# @api public
|
170
|
+
# @since 1.0.0
|
97
171
|
def self.logger
|
98
172
|
app[:logger]
|
99
173
|
end
|
100
174
|
|
175
|
+
# Prepares the Hanami app.
|
176
|
+
#
|
177
|
+
# @see App::ClassMethods#prepare
|
178
|
+
#
|
179
|
+
# @api public
|
180
|
+
# @since 2.0.0
|
101
181
|
def self.prepare
|
102
182
|
app.prepare
|
103
183
|
end
|
104
184
|
|
185
|
+
# Boots the Hanami app.
|
186
|
+
#
|
187
|
+
# @see App::ClassMethods#boot
|
188
|
+
#
|
189
|
+
# @api public
|
190
|
+
# @since 2.0.0
|
105
191
|
def self.boot
|
106
192
|
app.boot
|
107
193
|
end
|
108
194
|
|
195
|
+
# Shuts down the Hanami app.
|
196
|
+
#
|
197
|
+
# @see App::ClassMethods#shutdown
|
198
|
+
#
|
199
|
+
# @api public
|
200
|
+
# @since 2.0.0
|
109
201
|
def self.shutdown
|
110
202
|
app.shutdown
|
111
203
|
end
|
112
204
|
|
205
|
+
# @api private
|
206
|
+
# @since 2.0.0
|
113
207
|
def self.bundled?(gem_name)
|
114
208
|
@_mutex.synchronize do
|
115
209
|
@_bundled[gem_name] ||= begin
|
@@ -120,12 +214,17 @@ module Hanami
|
|
120
214
|
end
|
121
215
|
end
|
122
216
|
|
217
|
+
# Returns an array of bundler group names to be eagerly loaded by hanami-cli and other CLI
|
218
|
+
# extensions.
|
219
|
+
#
|
220
|
+
# @api private
|
221
|
+
# @since 2.0.0
|
123
222
|
def self.bundler_groups
|
124
223
|
[:plugins]
|
125
224
|
end
|
126
225
|
|
127
|
-
|
226
|
+
loader.setup
|
227
|
+
|
128
228
|
require_relative "hanami/errors"
|
129
229
|
require_relative "hanami/extensions"
|
130
|
-
require_relative "hanami/app"
|
131
230
|
end
|
@@ -35,7 +35,7 @@ RSpec.describe "App action / CSRF protection", :app_integration do
|
|
35
35
|
context "CSRF protection explicitly disabled" do
|
36
36
|
let(:app_hook) {
|
37
37
|
proc do
|
38
|
-
config.sessions = :cookie, {secret: "abc123"}
|
38
|
+
config.actions.sessions = :cookie, {secret: "abc123"}
|
39
39
|
config.actions.csrf_protection = false
|
40
40
|
end
|
41
41
|
}
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "stringio"
|
4
|
+
|
3
5
|
RSpec.describe "App routes helper", :app_integration do
|
4
6
|
specify "Routing to actions based on their container identifiers" do
|
5
7
|
with_tmp_directory(Dir.mktmpdir) do
|
@@ -8,7 +10,7 @@ RSpec.describe "App routes helper", :app_integration do
|
|
8
10
|
|
9
11
|
module TestApp
|
10
12
|
class App < Hanami::App
|
11
|
-
config.logger.stream =
|
13
|
+
config.logger.stream = StringIO.new
|
12
14
|
end
|
13
15
|
end
|
14
16
|
RUBY
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe "Container / Provider lifecycle", :app_integration do
|
4
|
+
let!(:slice) {
|
5
|
+
module TestApp
|
6
|
+
class App < Hanami::App
|
7
|
+
register_provider :connection do
|
8
|
+
prepare do
|
9
|
+
module ::TestApp
|
10
|
+
class Connection
|
11
|
+
def initialize
|
12
|
+
@connected = true
|
13
|
+
end
|
14
|
+
|
15
|
+
def disconnect
|
16
|
+
@connected = false
|
17
|
+
end
|
18
|
+
|
19
|
+
def connected?
|
20
|
+
@connected
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
start do
|
27
|
+
register("connection", TestApp::Connection.new)
|
28
|
+
end
|
29
|
+
|
30
|
+
stop do
|
31
|
+
container["connection"].disconnect
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
TestApp::App
|
38
|
+
}
|
39
|
+
|
40
|
+
before do
|
41
|
+
require "hanami/setup"
|
42
|
+
end
|
43
|
+
|
44
|
+
specify "individual providers can be prepared, started and stopped" do
|
45
|
+
expect { TestApp::Connection }.to raise_error NameError
|
46
|
+
|
47
|
+
slice.prepare :connection
|
48
|
+
|
49
|
+
expect(TestApp::Connection).to be
|
50
|
+
expect(slice.container.registered?("connection")).to be false
|
51
|
+
|
52
|
+
slice.start :connection
|
53
|
+
|
54
|
+
expect(slice.container.registered?("connection")).to be true
|
55
|
+
expect(slice["connection"]).to be_connected
|
56
|
+
|
57
|
+
slice.stop :connection
|
58
|
+
|
59
|
+
expect(slice["connection"]).not_to be_connected
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
RSpec.describe "Container / Standard providers / Rack", :app_integration do
|
2
|
+
specify "Rack provider is loaded when rack is bundled" 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
|
+
end
|
10
|
+
end
|
11
|
+
RUBY
|
12
|
+
|
13
|
+
write "slices/main/.keep", ""
|
14
|
+
|
15
|
+
require "hanami/prepare"
|
16
|
+
|
17
|
+
expect(Hanami.app["rack.monitor"]).to be_a_kind_of(Dry::Monitor::Rack::Middleware)
|
18
|
+
expect(Main::Slice["rack.monitor"]).to be_a_kind_of(Dry::Monitor::Rack::Middleware)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
specify "Rack provider is not loaded when rack is not bundled" do
|
23
|
+
allow(Hanami).to receive(:bundled?).and_call_original
|
24
|
+
allow(Hanami).to receive(:bundled?).with("rack").and_return false
|
25
|
+
|
26
|
+
with_tmp_directory(Dir.mktmpdir) do
|
27
|
+
write "config/app.rb", <<~RUBY
|
28
|
+
require "hanami"
|
29
|
+
|
30
|
+
module TestApp
|
31
|
+
class App < Hanami::App
|
32
|
+
end
|
33
|
+
end
|
34
|
+
RUBY
|
35
|
+
|
36
|
+
write "slices/main/.keep", ""
|
37
|
+
|
38
|
+
require "hanami/prepare"
|
39
|
+
|
40
|
+
expect(Hanami.app.key?("rack.monitor")).to be false
|
41
|
+
expect(Main::Slice.key?("rack.monitor")).to be false
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/spec/integration/container/{standard_bootable_components_spec.rb → standard_providers_spec.rb}
RENAMED
@@ -1,4 +1,4 @@
|
|
1
|
-
RSpec.describe "Container / Standard
|
1
|
+
RSpec.describe "Container / Standard providers", :app_integration do
|
2
2
|
specify "Standard components are available on booted container" do
|
3
3
|
with_tmp_directory(Dir.mktmpdir) do
|
4
4
|
write "config/app.rb", <<~RUBY
|
@@ -15,7 +15,7 @@ RSpec.describe "Container / Standard bootable components", :app_integration do
|
|
15
15
|
|
16
16
|
expect(Hanami.app.key?(:settings)).to be false
|
17
17
|
expect(Hanami.app["inflector"]).to eql Hanami.app.inflector
|
18
|
-
expect(Hanami.app["logger"]).to be_a_kind_of(
|
18
|
+
expect(Hanami.app["logger"]).to be_a_kind_of(Dry::Logger::Dispatcher)
|
19
19
|
expect(Hanami.app["rack.monitor"]).to be_a_kind_of(Dry::Monitor::Rack::Middleware)
|
20
20
|
end
|
21
21
|
end
|
@@ -36,7 +36,7 @@ RSpec.describe "Container / Standard bootable components", :app_integration do
|
|
36
36
|
|
37
37
|
expect(Hanami.app.key?(:settings)).to be false
|
38
38
|
expect(Hanami.app["inflector"]).to eql Hanami.app.inflector
|
39
|
-
expect(Hanami.app["logger"]).to be_a_kind_of(
|
39
|
+
expect(Hanami.app["logger"]).to be_a_kind_of(Dry::Logger::Dispatcher)
|
40
40
|
expect(Hanami.app["rack.monitor"]).to be_a_kind_of(Dry::Monitor::Rack::Middleware)
|
41
41
|
end
|
42
42
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "rack/test"
|
4
|
+
require "stringio"
|
4
5
|
|
5
6
|
RSpec.describe "Hanami web app", :app_integration do
|
6
7
|
include Rack::Test::Methods
|
@@ -18,6 +19,7 @@ RSpec.describe "Hanami web app", :app_integration do
|
|
18
19
|
module TestApp
|
19
20
|
class App < Hanami::App
|
20
21
|
config.middleware.use :body_parser, :json
|
22
|
+
config.logger.stream = StringIO.new
|
21
23
|
end
|
22
24
|
end
|
23
25
|
RUBY
|
@@ -66,6 +68,7 @@ RSpec.describe "Hanami web app", :app_integration do
|
|
66
68
|
class App < Hanami::App
|
67
69
|
config.actions.formats["application/json+scim"] = :json
|
68
70
|
config.middleware.use :body_parser, [json: "application/json+scim"]
|
71
|
+
config.logger.stream = StringIO.new
|
69
72
|
end
|
70
73
|
end
|
71
74
|
RUBY
|