hanami 2.0.0.beta4 → 2.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.
- 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,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 "Slices / Slice routing", :app_integration do
|
6
7
|
include Rack::Test::Methods
|
@@ -34,7 +35,7 @@ RSpec.describe "Slices / Slice routing", :app_integration do
|
|
34
35
|
|
35
36
|
module TestApp
|
36
37
|
class App < Hanami::App
|
37
|
-
config.logger.stream =
|
38
|
+
config.logger.stream = StringIO.new
|
38
39
|
end
|
39
40
|
end
|
40
41
|
RUBY
|
@@ -67,7 +68,7 @@ RSpec.describe "Slices / Slice routing", :app_integration do
|
|
67
68
|
|
68
69
|
module TestApp
|
69
70
|
class App < Hanami::App
|
70
|
-
config.logger.stream =
|
71
|
+
config.logger.stream = StringIO.new
|
71
72
|
end
|
72
73
|
end
|
73
74
|
RUBY
|
@@ -118,7 +119,7 @@ RSpec.describe "Slices / Slice routing", :app_integration do
|
|
118
119
|
|
119
120
|
module TestApp
|
120
121
|
class App < Hanami::App
|
121
|
-
config.logger.stream =
|
122
|
+
config.logger.stream = StringIO.new
|
122
123
|
end
|
123
124
|
end
|
124
125
|
RUBY
|
@@ -55,6 +55,32 @@ RSpec.describe "Slices", :app_integration do
|
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
|
+
specify "Loading a nested slice with a defined slice class" do
|
59
|
+
with_tmp_directory(Dir.mktmpdir) do
|
60
|
+
write "config/app.rb", <<~RUBY
|
61
|
+
require "hanami"
|
62
|
+
|
63
|
+
module TestApp
|
64
|
+
class App < Hanami::App
|
65
|
+
end
|
66
|
+
end
|
67
|
+
RUBY
|
68
|
+
|
69
|
+
write "slices/main/config/slices/nested.rb", <<~RUBY
|
70
|
+
module Main
|
71
|
+
module Nested
|
72
|
+
class Slice < Hanami::Slice
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
RUBY
|
77
|
+
|
78
|
+
require "hanami/prepare"
|
79
|
+
|
80
|
+
expect(Hanami.app.slices[:main].slices[:nested]).to be Main::Nested::Slice
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
58
84
|
it "Loading a slice generates a slice class if none is defined" do
|
59
85
|
with_tmp_directory(Dir.mktmpdir) do
|
60
86
|
write "config/app.rb", <<~RUBY
|
@@ -78,6 +104,80 @@ RSpec.describe "Slices", :app_integration do
|
|
78
104
|
end
|
79
105
|
end
|
80
106
|
|
107
|
+
specify "Registering a slice on the app creates a slice class with a top-level namespace" do
|
108
|
+
with_tmp_directory(Dir.mktmpdir) do
|
109
|
+
write "config/app.rb", <<~RUBY
|
110
|
+
require "hanami"
|
111
|
+
|
112
|
+
module TestApp
|
113
|
+
class App < Hanami::App
|
114
|
+
register_slice :main
|
115
|
+
end
|
116
|
+
end
|
117
|
+
RUBY
|
118
|
+
|
119
|
+
require "hanami/prepare"
|
120
|
+
|
121
|
+
expect(Hanami.app.slices[:main]).to be Main::Slice
|
122
|
+
expect(Main::Slice.ancestors).to include(Hanami::Slice)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
specify "Registering a nested slice creates a slice class within the parent's namespace" do
|
127
|
+
with_tmp_directory(Dir.mktmpdir) do
|
128
|
+
write "config/app.rb", <<~RUBY
|
129
|
+
require "hanami"
|
130
|
+
|
131
|
+
module TestApp
|
132
|
+
class App < Hanami::App
|
133
|
+
end
|
134
|
+
end
|
135
|
+
RUBY
|
136
|
+
|
137
|
+
write "config/slices/main.rb", <<~RUBY
|
138
|
+
module Main
|
139
|
+
class Slice < Hanami::Slice
|
140
|
+
register_slice :nested
|
141
|
+
end
|
142
|
+
end
|
143
|
+
RUBY
|
144
|
+
|
145
|
+
require "hanami/prepare"
|
146
|
+
|
147
|
+
expect(Hanami.app.slices[:main].slices[:nested]).to be Main::Nested::Slice
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
specify "Registering a nested slice with an existing class uses that class' own namespace" do
|
152
|
+
with_tmp_directory(Dir.mktmpdir) do
|
153
|
+
write "config/app.rb", <<~RUBY
|
154
|
+
require "hanami"
|
155
|
+
|
156
|
+
module TestApp
|
157
|
+
class App < Hanami::App
|
158
|
+
end
|
159
|
+
end
|
160
|
+
RUBY
|
161
|
+
|
162
|
+
write "config/slices/main.rb", <<~RUBY
|
163
|
+
module Admin
|
164
|
+
class Slice < Hanami::Slice
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
module Main
|
169
|
+
class Slice < Hanami::Slice
|
170
|
+
register_slice :nested, Admin::Slice
|
171
|
+
end
|
172
|
+
end
|
173
|
+
RUBY
|
174
|
+
|
175
|
+
require "hanami/prepare"
|
176
|
+
|
177
|
+
expect(Hanami.app.slices[:main].slices[:nested]).to be Admin::Slice
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
81
181
|
it "Registering a slice with a block creates a slice class and evals the block" do
|
82
182
|
with_tmp_directory(Dir.mktmpdir) do
|
83
183
|
write "config/app.rb", <<~RUBY
|
@@ -44,7 +44,7 @@ RSpec.describe Hanami do
|
|
44
44
|
Hanami.boot
|
45
45
|
expect(Hanami.app.ancestors).to include(Hanami::Application)
|
46
46
|
expect(Hanami.app.root).to eq(Dir.pwd)
|
47
|
-
expect(Hanami.logger).to be_kind_of(
|
47
|
+
expect(Hanami.logger).to be_kind_of(Dry::Logger::Dispatcher)
|
48
48
|
end
|
49
49
|
end
|
50
50
|
end
|
@@ -24,19 +24,11 @@ RSpec.shared_context "Application integration" do
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def autoloaders_teardown!
|
27
|
-
|
28
|
-
|
29
|
-
test_loader = loader.dirs.any? { |dir|
|
27
|
+
ObjectSpace.each_object(Zeitwerk::Loader) do |loader|
|
28
|
+
loader.unregister if loader.dirs.any? { |dir|
|
30
29
|
dir.include?("/spec/") || dir.include?(Dir.tmpdir) ||
|
31
30
|
dir.include?("/slices/") || dir.include?("/app")
|
32
31
|
}
|
33
|
-
|
34
|
-
if test_loader
|
35
|
-
loader.unregister
|
36
|
-
true
|
37
|
-
else
|
38
|
-
false
|
39
|
-
end
|
40
32
|
end
|
41
33
|
end
|
42
34
|
|
@@ -29,7 +29,7 @@ RSpec.describe Hanami::Config::Actions, "#content_security_policy" do
|
|
29
29
|
%(style-src 'self' 'unsafe-inline' https:)
|
30
30
|
].join("\n")
|
31
31
|
|
32
|
-
expect(content_security_policy.
|
32
|
+
expect(content_security_policy.to_s).to eq(expected)
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
@@ -51,35 +51,35 @@ RSpec.describe Hanami::Config::Actions, "#content_security_policy" do
|
|
51
51
|
content_security_policy[:script_src] += " #{cdn_url}"
|
52
52
|
|
53
53
|
expect(content_security_policy[:script_src]).to eq("'self' #{cdn_url}")
|
54
|
-
expect(content_security_policy.
|
54
|
+
expect(content_security_policy.to_s).to match("'self' #{cdn_url}")
|
55
55
|
end
|
56
56
|
|
57
57
|
it "overrides default values" do
|
58
58
|
content_security_policy[:style_src] = cdn_url
|
59
59
|
|
60
60
|
expect(content_security_policy[:style_src]).to eq(cdn_url)
|
61
|
-
expect(content_security_policy.
|
61
|
+
expect(content_security_policy.to_s).to match(cdn_url)
|
62
62
|
end
|
63
63
|
|
64
64
|
it "nullifies value" do
|
65
65
|
content_security_policy[:plugin_types] = nil
|
66
66
|
|
67
67
|
expect(content_security_policy[:plugin_types]).to be(nil)
|
68
|
-
expect(content_security_policy.
|
68
|
+
expect(content_security_policy.to_s).to match("plugin-types ;")
|
69
69
|
end
|
70
70
|
|
71
71
|
it "deletes key" do
|
72
72
|
content_security_policy.delete(:object_src)
|
73
73
|
|
74
74
|
expect(content_security_policy[:object_src]).to be(nil)
|
75
|
-
expect(content_security_policy.
|
75
|
+
expect(content_security_policy.to_s).to_not match("object-src")
|
76
76
|
end
|
77
77
|
|
78
78
|
it "adds a custom key" do
|
79
79
|
content_security_policy[:a_custom_key] = "foo"
|
80
80
|
|
81
81
|
expect(content_security_policy[:a_custom_key]).to eq("foo")
|
82
|
-
expect(content_security_policy.
|
82
|
+
expect(content_security_policy.to_s).to match("a-custom-key foo")
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
@@ -87,7 +87,7 @@ RSpec.describe Hanami::Config::Actions, "#content_security_policy" do
|
|
87
87
|
it "sets default header" do
|
88
88
|
config.finalize!
|
89
89
|
|
90
|
-
expect(config.default_headers.fetch("Content-Security-Policy")).to eq(content_security_policy.
|
90
|
+
expect(config.default_headers.fetch("Content-Security-Policy")).to eq(content_security_policy.to_s)
|
91
91
|
end
|
92
92
|
end
|
93
93
|
|
@@ -46,7 +46,7 @@ RSpec.describe Hanami::Config::Actions, "default values" do
|
|
46
46
|
"X-Frame-Options" => "DENY",
|
47
47
|
"X-Content-Type-Options" => "nosniff",
|
48
48
|
"X-XSS-Protection" => "1; mode=block",
|
49
|
-
"Content-Security-Policy" => config.content_security_policy.
|
49
|
+
"Content-Security-Policy" => config.content_security_policy.to_s
|
50
50
|
)
|
51
51
|
}
|
52
52
|
end
|
@@ -42,9 +42,7 @@ RSpec.describe Hanami::Config::Actions, "#sessions" do
|
|
42
42
|
end
|
43
43
|
|
44
44
|
it "returns an array of middleware classes and options" do
|
45
|
-
expect(sessions.middleware).to eq [
|
46
|
-
[Rack::Session::Cookie, [secret: "abc"]]
|
47
|
-
]
|
45
|
+
expect(sessions.middleware).to eq [Rack::Session::Cookie, {secret: "abc"}]
|
48
46
|
end
|
49
47
|
end
|
50
48
|
end
|
@@ -34,17 +34,6 @@ RSpec.describe Hanami::Config, "#actions" do
|
|
34
34
|
it "can be finalized" do
|
35
35
|
is_expected.to respond_to(:finalize!)
|
36
36
|
end
|
37
|
-
|
38
|
-
describe "#settings" do
|
39
|
-
it "returns a set of available settings" do
|
40
|
-
expect(actions.settings).to be_a(Set)
|
41
|
-
expect(actions.settings).to include(:view_context_identifier, :handled_exceptions)
|
42
|
-
end
|
43
|
-
|
44
|
-
it "includes all base action settings" do
|
45
|
-
expect(actions.settings).to include(Hanami::Action.settings)
|
46
|
-
end
|
47
|
-
end
|
48
37
|
end
|
49
38
|
|
50
39
|
context "hanami-controller is not bundled" do
|
@@ -54,7 +43,7 @@ RSpec.describe Hanami::Config, "#actions" do
|
|
54
43
|
end
|
55
44
|
|
56
45
|
it "does not expose any settings" do
|
57
|
-
is_expected.
|
46
|
+
is_expected.to be_an_instance_of(Hanami::Config::NullConfig)
|
58
47
|
is_expected.not_to respond_to(:default_response_format)
|
59
48
|
is_expected.not_to respond_to(:default_response_format=)
|
60
49
|
end
|
@@ -4,26 +4,19 @@ require "hanami/config/logger"
|
|
4
4
|
require "hanami/slice_name"
|
5
5
|
require "dry/inflector"
|
6
6
|
require "logger"
|
7
|
+
require "stringio"
|
7
8
|
|
8
9
|
RSpec.describe Hanami::Config::Logger do
|
9
|
-
subject
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
describe "#logger_class" do
|
14
|
-
it "defaults to Hanami::Logger" do
|
15
|
-
expect(subject.logger_class).to eql Hanami::Logger
|
16
|
-
end
|
17
|
-
|
18
|
-
it "can be changed to another class" do
|
19
|
-
another_class = Class.new
|
10
|
+
subject do
|
11
|
+
described_class.new(app_name: app_name, env: env)
|
12
|
+
end
|
20
13
|
|
21
|
-
|
22
|
-
|
23
|
-
.to(another_class)
|
24
|
-
end
|
14
|
+
let(:app_name) do
|
15
|
+
Hanami::SliceName.new(double(name: "MyApp::app"), inflector: -> { Dry::Inflector.new })
|
25
16
|
end
|
26
17
|
|
18
|
+
let(:env) { :development }
|
19
|
+
|
27
20
|
describe "#level" do
|
28
21
|
it "defaults to :debug" do
|
29
22
|
expect(subject.level).to eq(:debug)
|
@@ -63,16 +56,24 @@ RSpec.describe Hanami::Config::Logger do
|
|
63
56
|
end
|
64
57
|
|
65
58
|
describe "#stream=" do
|
66
|
-
it "accepts a
|
67
|
-
expect { subject.stream =
|
59
|
+
it "accepts a path to a file" do
|
60
|
+
expect { subject.stream = File::NULL }
|
68
61
|
.to change { subject.stream }
|
69
|
-
.to(
|
62
|
+
.to(File::NULL)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "accepts a IO object" do
|
66
|
+
stream = StringIO.new
|
67
|
+
|
68
|
+
expect { subject.stream = stream }
|
69
|
+
.to change { subject.stream }
|
70
|
+
.to(stream)
|
70
71
|
end
|
71
72
|
end
|
72
73
|
|
73
74
|
describe "#formatter" do
|
74
|
-
it "defaults to
|
75
|
-
expect(subject.formatter).to eq(
|
75
|
+
it "defaults to :rack" do
|
76
|
+
expect(subject.formatter).to eq(:rack)
|
76
77
|
end
|
77
78
|
|
78
79
|
context "when :production environment" do
|
@@ -92,33 +93,17 @@ RSpec.describe Hanami::Config::Logger do
|
|
92
93
|
end
|
93
94
|
end
|
94
95
|
|
95
|
-
describe "#
|
96
|
-
it "defaults to
|
97
|
-
expect(subject.
|
98
|
-
end
|
99
|
-
|
100
|
-
context "when :test environment" do
|
101
|
-
let(:env) { :test }
|
102
|
-
|
103
|
-
it "returns false" do
|
104
|
-
expect(subject.colors).to eq(false)
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
context "when :production environment" do
|
109
|
-
let(:env) { :production }
|
110
|
-
|
111
|
-
it "returns false" do
|
112
|
-
expect(subject.colors).to eq(false)
|
113
|
-
end
|
96
|
+
describe "#template" do
|
97
|
+
it "defaults to false" do
|
98
|
+
expect(subject.template).to eq("[%<progname>s] [%<severity>s] [%<time>s] %<message>s")
|
114
99
|
end
|
115
100
|
end
|
116
101
|
|
117
|
-
describe "#
|
102
|
+
describe "#template=" do
|
118
103
|
it "accepts a value" do
|
119
|
-
expect { subject.
|
120
|
-
.to change { subject.
|
121
|
-
.to(
|
104
|
+
expect { subject.template = "%<message>s" }
|
105
|
+
.to change { subject.template }
|
106
|
+
.to("%<message>s")
|
122
107
|
end
|
123
108
|
end
|
124
109
|
|
@@ -145,20 +130,14 @@ RSpec.describe Hanami::Config::Logger do
|
|
145
130
|
end
|
146
131
|
|
147
132
|
describe "#options" do
|
148
|
-
it "defaults to empty
|
149
|
-
expect(subject.options).to eq(
|
133
|
+
it "defaults to empty hash" do
|
134
|
+
expect(subject.options).to eq({})
|
150
135
|
end
|
151
136
|
end
|
152
137
|
|
153
138
|
describe "#options=" do
|
154
139
|
it "accepts value" do
|
155
|
-
subject.options = expected = "daily"
|
156
|
-
|
157
|
-
expect(subject.options).to eq([expected])
|
158
|
-
end
|
159
|
-
|
160
|
-
it "accepts values" do
|
161
|
-
subject.options = expected = [0, 1048576]
|
140
|
+
subject.options = expected = {rotate: "daily"}
|
162
141
|
|
163
142
|
expect(subject.options).to eq(expected)
|
164
143
|
end
|
@@ -167,7 +146,11 @@ end
|
|
167
146
|
|
168
147
|
RSpec.describe Hanami::Config do
|
169
148
|
subject(:config) { described_class.new(app_name: app_name, env: env) }
|
170
|
-
|
149
|
+
|
150
|
+
let(:app_name) do
|
151
|
+
Hanami::SliceName.new(double(name: "SOS::app"), inflector: -> { Dry::Inflector.new })
|
152
|
+
end
|
153
|
+
|
171
154
|
let(:env) { :development }
|
172
155
|
|
173
156
|
describe "#logger" do
|
@@ -187,8 +170,8 @@ RSpec.describe Hanami::Config do
|
|
187
170
|
end
|
188
171
|
|
189
172
|
describe "#logger_instance" do
|
190
|
-
it "defaults to
|
191
|
-
expect(config.logger_instance).to
|
173
|
+
it "defaults to using Dry::Logger, based on the default logger settings" do
|
174
|
+
expect(config.logger_instance).to be_a(Dry::Logger::Dispatcher)
|
192
175
|
expect(config.logger_instance.level).to eq Logger::DEBUG
|
193
176
|
end
|
194
177
|
|
@@ -33,7 +33,7 @@ RSpec.describe Hanami::Config, "#router" do
|
|
33
33
|
end
|
34
34
|
|
35
35
|
it "does not expose any settings" do
|
36
|
-
is_expected.
|
36
|
+
is_expected.to be_an_instance_of(Hanami::Config::NullConfig)
|
37
37
|
is_expected.not_to respond_to(:resolver)
|
38
38
|
end
|
39
39
|
|
@@ -28,16 +28,6 @@ RSpec.describe Hanami::Config, "#views" do
|
|
28
28
|
expect(views).not_to respond_to(:inflector=)
|
29
29
|
end
|
30
30
|
|
31
|
-
describe "#settings" do
|
32
|
-
it "includes locally defined settings" do
|
33
|
-
expect(views.settings).to include :parts_path
|
34
|
-
end
|
35
|
-
|
36
|
-
it "includes all view settings apart from inflector" do
|
37
|
-
expect(views.settings).to include (Hanami::View.settings - [:inflector])
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
31
|
it "preserves default values from the base view config" do
|
42
32
|
expect(views.layouts_dir).to eq Hanami::View.config.layouts_dir
|
43
33
|
end
|
@@ -80,11 +70,11 @@ RSpec.describe Hanami::Config, "#views" do
|
|
80
70
|
end
|
81
71
|
|
82
72
|
it "does not allow changes to locally defined settings" do
|
83
|
-
expect { views.parts_path = "parts" }.to raise_error(Dry::Configurable::
|
73
|
+
expect { views.parts_path = "parts" }.to raise_error(Dry::Configurable::FrozenConfigError)
|
84
74
|
end
|
85
75
|
|
86
76
|
it "does not allow changes to base view settings" do
|
87
|
-
expect { views.paths = [] }.to raise_error(Dry::Configurable::
|
77
|
+
expect { views.paths = [] }.to raise_error(Dry::Configurable::FrozenConfigError)
|
88
78
|
end
|
89
79
|
end
|
90
80
|
end
|
@@ -96,7 +86,7 @@ RSpec.describe Hanami::Config, "#views" do
|
|
96
86
|
end
|
97
87
|
|
98
88
|
it "does not expose any settings" do
|
99
|
-
is_expected.
|
89
|
+
is_expected.to be_an_instance_of(Hanami::Config::NullConfig)
|
100
90
|
is_expected.not_to respond_to(:layouts_dir)
|
101
91
|
is_expected.not_to respond_to(:layouts_dir=)
|
102
92
|
end
|
@@ -68,7 +68,7 @@ RSpec.describe Hanami::Settings do
|
|
68
68
|
settings = settings_class.new(store)
|
69
69
|
|
70
70
|
expect(settings.config).to be_frozen
|
71
|
-
expect { settings.database_url = "new" }.to raise_error(Dry::Configurable::
|
71
|
+
expect { settings.database_url = "new" }.to raise_error(Dry::Configurable::FrozenConfigError)
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
@@ -106,18 +106,18 @@ RSpec.describe Hanami::SliceConfigurable, :app_integration do
|
|
106
106
|
class Slice
|
107
107
|
register_slice :nested
|
108
108
|
end
|
109
|
-
end
|
110
109
|
|
111
|
-
|
112
|
-
|
110
|
+
module Nested
|
111
|
+
class MySubclass < TestApp::BaseClass
|
112
|
+
end
|
113
113
|
end
|
114
114
|
end
|
115
115
|
end
|
116
116
|
|
117
|
-
subject(:subclass) { Nested::MySubclass }
|
117
|
+
subject(:subclass) { Main::Nested::MySubclass }
|
118
118
|
|
119
119
|
it "calls `configure_for_slice` with the nested slice" do
|
120
|
-
expect(subclass.traces).to eq [Nested::Slice]
|
120
|
+
expect(subclass.traces).to eq [Main::Nested::Slice]
|
121
121
|
end
|
122
122
|
end
|
123
123
|
end
|
@@ -8,6 +8,38 @@ RSpec.describe Hanami::Slice, :app_integration do
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
+
describe ".environemnt" do
|
12
|
+
subject(:slice) { Hanami.app.register_slice(:main) }
|
13
|
+
|
14
|
+
before do
|
15
|
+
allow(slice.config).to receive(:env) { :development }
|
16
|
+
end
|
17
|
+
|
18
|
+
it "evaluates the block with the env matches the Hanami.env" do
|
19
|
+
expect {
|
20
|
+
slice.environment(:development) do
|
21
|
+
config.logger.level = :info
|
22
|
+
end
|
23
|
+
}
|
24
|
+
.to change { slice.config.logger.level }
|
25
|
+
.to :info
|
26
|
+
end
|
27
|
+
|
28
|
+
it "yields the slice to the block" do
|
29
|
+
captured_slice = nil
|
30
|
+
slice.environment(:development) { |slice| captured_slice = slice }
|
31
|
+
expect(captured_slice).to be slice
|
32
|
+
end
|
33
|
+
|
34
|
+
it "does not evaluate the block with the env does not match the Hanami.env" do
|
35
|
+
expect {
|
36
|
+
slice.environment(:test) do
|
37
|
+
config.logger.level = :info
|
38
|
+
end
|
39
|
+
}.not_to(change { slice.config.logger.level })
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
11
43
|
describe ".prepare" do
|
12
44
|
it "raises an error if the slice class is anonymous" do
|
13
45
|
expect { Class.new(described_class).prepare }
|
@@ -1,13 +1,24 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "hanami/web/rack_logger"
|
4
|
-
require "
|
4
|
+
require "dry/logger"
|
5
5
|
require "stringio"
|
6
6
|
require "rack/mock"
|
7
7
|
|
8
8
|
RSpec.describe Hanami::Web::RackLogger do
|
9
9
|
subject { described_class.new(logger) }
|
10
|
-
|
10
|
+
|
11
|
+
let(:logger) do
|
12
|
+
Dry.Logger(
|
13
|
+
app_name,
|
14
|
+
stream: stream,
|
15
|
+
level: :debug,
|
16
|
+
filters: filters,
|
17
|
+
formatter: :rack,
|
18
|
+
template: "[%<progname>s] [%<severity>s] [%<time>s] %<message>s"
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
11
22
|
let(:stream) { StringIO.new }
|
12
23
|
let(:filters) { ["user.password"] }
|
13
24
|
let(:app_name) { "my_app" }
|