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.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +19 -0
  3. data/hanami.gemspec +8 -7
  4. data/lib/hanami/app.rb +47 -36
  5. data/lib/hanami/assets/app_config.rb +7 -15
  6. data/lib/hanami/assets/config.rb +5 -6
  7. data/lib/hanami/config/actions/content_security_policy.rb +1 -1
  8. data/lib/hanami/config/actions/cookies.rb +27 -0
  9. data/lib/hanami/config/actions/sessions.rb +42 -5
  10. data/lib/hanami/config/actions.rb +81 -17
  11. data/lib/hanami/config/logger.rb +112 -23
  12. data/lib/hanami/config/router.rb +0 -1
  13. data/lib/hanami/config/views.rb +6 -10
  14. data/lib/hanami/config.rb +235 -73
  15. data/lib/hanami/constants.rb +4 -0
  16. data/lib/hanami/errors.rb +17 -0
  17. data/lib/hanami/extensions/action/slice_configured_action.rb +9 -5
  18. data/lib/hanami/extensions/action.rb +59 -7
  19. data/lib/hanami/extensions/view/context.rb +3 -4
  20. data/lib/hanami/extensions/view/slice_configured_view.rb +4 -4
  21. data/lib/hanami/extensions/view.rb +7 -5
  22. data/lib/hanami/providers/inflector.rb +6 -0
  23. data/lib/hanami/providers/logger.rb +8 -0
  24. data/lib/hanami/providers/rack.rb +12 -0
  25. data/lib/hanami/providers/routes.rb +14 -4
  26. data/lib/hanami/routes.rb +36 -1
  27. data/lib/hanami/settings/env_store.rb +1 -1
  28. data/lib/hanami/settings.rb +102 -36
  29. data/lib/hanami/slice/router.rb +38 -16
  30. data/lib/hanami/slice/routing/middleware/stack.rb +66 -42
  31. data/lib/hanami/slice/routing/resolver.rb +10 -17
  32. data/lib/hanami/slice/view_name_inferrer.rb +1 -1
  33. data/lib/hanami/slice.rb +553 -14
  34. data/lib/hanami/slice_registrar.rb +20 -15
  35. data/lib/hanami/version.rb +2 -3
  36. data/lib/hanami/web/rack_logger.rb +14 -4
  37. data/lib/hanami.rb +122 -23
  38. data/spec/integration/action/csrf_protection_spec.rb +1 -1
  39. data/spec/integration/container/application_routes_helper_spec.rb +3 -1
  40. data/spec/integration/container/provider_lifecycle_spec.rb +61 -0
  41. data/spec/integration/container/standard_providers/rack_provider_spec.rb +44 -0
  42. data/spec/integration/container/{standard_bootable_components_spec.rb → standard_providers_spec.rb} +3 -3
  43. data/spec/integration/rack_app/body_parser_spec.rb +3 -0
  44. data/spec/integration/rack_app/middleware_spec.rb +427 -3
  45. data/spec/integration/rack_app/non_booted_rack_app_spec.rb +2 -1
  46. data/spec/integration/rack_app/rack_app_spec.rb +39 -11
  47. data/spec/integration/setup_spec.rb +4 -4
  48. data/spec/integration/slices/external_slice_spec.rb +2 -1
  49. data/spec/integration/slices/slice_configuration_spec.rb +3 -1
  50. data/spec/integration/slices/slice_loading_spec.rb +4 -4
  51. data/spec/integration/slices/slice_routing_spec.rb +4 -3
  52. data/spec/integration/slices_spec.rb +100 -0
  53. data/spec/isolation/hanami/boot/success_spec.rb +1 -1
  54. data/spec/support/app_integration.rb +2 -10
  55. data/spec/unit/hanami/config/actions/content_security_policy_spec.rb +7 -7
  56. data/spec/unit/hanami/config/actions/default_values_spec.rb +1 -1
  57. data/spec/unit/hanami/config/actions/sessions_spec.rb +1 -3
  58. data/spec/unit/hanami/config/actions_spec.rb +1 -12
  59. data/spec/unit/hanami/config/logger_spec.rb +38 -55
  60. data/spec/unit/hanami/config/router_spec.rb +1 -1
  61. data/spec/unit/hanami/config/views_spec.rb +3 -13
  62. data/spec/unit/hanami/settings_spec.rb +1 -1
  63. data/spec/unit/hanami/slice_configurable_spec.rb +5 -5
  64. data/spec/unit/hanami/slice_spec.rb +32 -0
  65. data/spec/unit/hanami/version_spec.rb +1 -1
  66. data/spec/unit/hanami/web/rack_logger_spec.rb +13 -2
  67. metadata +54 -45
  68. data/lib/hanami/config/sessions.rb +0 -50
  69. 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 = File.new("/dev/null", "w")
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 = File.new("/dev/null", "w")
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 = File.new("/dev/null", "w")
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(Hanami::Logger)
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
- # Tear down Zeitwerk (from zeitwerk's own test/support/loader_test)
28
- Zeitwerk::Registry.loaders.reject! do |loader|
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.to_str).to eq(expected)
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.to_str).to match("'self' #{cdn_url}")
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.to_str).to match(cdn_url)
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.to_str).to match("plugin-types ;")
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.to_str).to_not match("object-src")
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.to_str).to match("a-custom-key foo")
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.to_str)
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.to_str
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.not_to be_an_instance_of(Hanami::Config::Actions)
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 { described_class.new(app_name: app_name, env: env) }
10
- let(:app_name) { Hanami::SliceName.new(double(name: "MyApp::app"), inflector: -> { Dry::Inflector.new }) }
11
- let(:env) { :development }
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
- expect { subject.logger_class = another_class }
22
- .to change { subject.logger_class }
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 IO object or a path to a file" do
67
- expect { subject.stream = "/dev/null" }
59
+ it "accepts a path to a file" do
60
+ expect { subject.stream = File::NULL }
68
61
  .to change { subject.stream }
69
- .to("/dev/null")
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 nil" do
75
- expect(subject.formatter).to eq(nil)
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 "#colors" do
96
- it "defaults to nil" do
97
- expect(subject.colors).to eq(nil)
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 "#colors=" do
102
+ describe "#template=" do
118
103
  it "accepts a value" do
119
- expect { subject.colors = false }
120
- .to change { subject.colors }
121
- .to(false)
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 array" do
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
- let(:app_name) { Hanami::SliceName.new(double(name: "SOS::app"), inflector: -> { Dry::Inflector.new }) }
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 an Hanami::Logger instance, based on the default logger settings" do
191
- expect(config.logger_instance).to be_an_instance_of config.logger.logger_class
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.not_to be_an_instance_of(Hanami::Config::Router)
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::FrozenConfig)
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::FrozenConfig)
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.not_to be_an_instance_of(Hanami::Config::Views)
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::FrozenConfig)
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
- module Nested
112
- class MySubclass < TestApp::BaseClass
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 }
@@ -2,6 +2,6 @@
2
2
 
3
3
  RSpec.describe "Hanami::VERSION" do
4
4
  it "returns current version" do
5
- expect(Hanami::VERSION).to eq("2.0.0.beta4")
5
+ expect(Hanami::VERSION).to eq("2.0.0.rc1")
6
6
  end
7
7
  end
@@ -1,13 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "hanami/web/rack_logger"
4
- require "hanami/logger"
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
- let(:logger) { Hanami::Logger.new(app_name, stream: stream, level: Hanami::Logger::DEBUG, filter: filters) }
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" }