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,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" }
|