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