hanami 2.0.0.rc1 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +24 -0
  3. data/FEATURES.md +15 -21
  4. data/README.md +7 -37
  5. data/hanami.gemspec +5 -5
  6. data/lib/hanami/app.rb +2 -33
  7. data/lib/hanami/config/actions/content_security_policy.rb +1 -1
  8. data/lib/hanami/config/actions.rb +0 -3
  9. data/lib/hanami/config/logger.rb +52 -29
  10. data/lib/hanami/config.rb +22 -1
  11. data/lib/hanami/env.rb +52 -0
  12. data/lib/hanami/extensions/action/slice_configured_action.rb +5 -2
  13. data/lib/hanami/extensions/view/slice_configured_view.rb +4 -1
  14. data/lib/hanami/port.rb +45 -0
  15. data/lib/hanami/providers/rack.rb +15 -7
  16. data/lib/hanami/rake_tasks.rb +4 -5
  17. data/lib/hanami/slice.rb +3 -1
  18. data/lib/hanami/version.rb +1 -1
  19. data/lib/hanami/web/rack_logger.rb +64 -15
  20. data/lib/hanami.rb +24 -5
  21. data/spec/integration/action/format_config_spec.rb +194 -0
  22. data/spec/integration/action/slice_configuration_spec.rb +39 -42
  23. data/spec/integration/code_loading/loading_from_lib_spec.rb +34 -0
  24. data/spec/integration/dotenv_loading_spec.rb +1 -0
  25. data/spec/integration/rack_app/body_parser_spec.rb +2 -5
  26. data/spec/integration/rack_app/rack_app_spec.rb +132 -5
  27. data/spec/integration/settings/access_in_slice_class_body_spec.rb +1 -0
  28. data/spec/integration/settings/loading_from_env_spec.rb +1 -0
  29. data/spec/integration/setup_spec.rb +2 -2
  30. data/spec/spec_helper.rb +12 -0
  31. data/spec/unit/hanami/config/actions/content_security_policy_spec.rb +14 -14
  32. data/spec/unit/hanami/config/actions/default_values_spec.rb +0 -8
  33. data/spec/unit/hanami/config/actions_spec.rb +7 -10
  34. data/spec/unit/hanami/config/logger_spec.rb +4 -4
  35. data/spec/unit/hanami/port_spec.rb +117 -0
  36. data/spec/unit/hanami/version_spec.rb +1 -1
  37. data/spec/unit/hanami/web/rack_logger_spec.rb +4 -1
  38. metadata +36 -12
@@ -42,6 +42,8 @@ RSpec.describe "Hanami web app", :app_integration do
42
42
 
43
43
  module TestApp
44
44
  class App < Hanami::App
45
+ config.actions.format :json
46
+ config.logger.options = {colorize: true}
45
47
  config.logger.stream = config.root.join("test.log")
46
48
  end
47
49
  end
@@ -61,16 +63,31 @@ RSpec.describe "Hanami web app", :app_integration do
61
63
  end
62
64
  RUBY
63
65
 
66
+ write "app/actions/users/create.rb", <<~RUBY
67
+ module TestApp
68
+ module Actions
69
+ module Users
70
+ class Create < Hanami::Action
71
+ def handle(req, resp)
72
+ resp.body = req.params.to_h.keys
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ RUBY
79
+
64
80
  write "config/routes.rb", <<~RUBY
65
81
  module TestApp
66
82
  class Routes < Hanami::Routes
67
83
  root to: ->(env) { [200, {}, ["OK"]] }
68
84
  get "/users", to: "users.index"
85
+ post "/users", to: "users.create"
69
86
  end
70
87
  end
71
88
  RUBY
72
89
 
73
- require "hanami/boot"
90
+ require "hanami/prepare"
74
91
 
75
92
  expect(Hanami.app["rack.monitor"]).to be_instance_of(Dry::Monitor::Rack::Middleware)
76
93
 
@@ -78,7 +95,11 @@ RSpec.describe "Hanami web app", :app_integration do
78
95
 
79
96
  logs = -> { Pathname(dir).join("test.log").realpath.read }
80
97
 
81
- expect(logs.()).to match %r{GET 200 \d+ms 127.0.0.1 /}
98
+ expect(logs.()).to match %r{GET 200 \d+(µs|ms) 127.0.0.1 /}
99
+
100
+ post "/users", JSON.generate(name: "jane", password: "secret"), {"CONTENT_TYPE" => "application/json"}
101
+
102
+ expect(logs.()).to match %r{POST 200 \d+(µs|ms) 127.0.0.1 /}
82
103
 
83
104
  begin
84
105
  get "/users"
@@ -86,13 +107,115 @@ RSpec.describe "Hanami web app", :app_integration do
86
107
  raise unless e.to_s == "OH NOEZ"
87
108
  end
88
109
 
89
- expect(logs.()).to match %r{OH NOEZ}
110
+ err_log = logs.()
111
+
112
+ expect(err_log).to include("OH NOEZ")
113
+ expect(err_log).to include("app/actions/users/index.rb:6:in `handle'")
90
114
  end
91
115
  end
92
116
 
93
- describe "Request logging when using a slice" do
117
+ specify "Logging via the rack monitor even when notifications bus has already been used" do
118
+ dir = Dir.mktmpdir
119
+
120
+ with_tmp_directory(dir) do
121
+ write "config/app.rb", <<~RUBY
122
+ require "hanami"
123
+
124
+ module TestApp
125
+ class App < Hanami::App
126
+ config.actions.format :json
127
+ config.logger.options = {colorize: true}
128
+ config.logger.stream = config.root.join("test.log")
129
+ end
130
+ end
131
+ RUBY
132
+
133
+ write "config/routes.rb", <<~RUBY
134
+ module TestApp
135
+ class Routes < Hanami::Routes
136
+ post "/users", to: "users.create"
137
+ end
138
+ end
139
+ RUBY
140
+
141
+ write "app/actions/users/create.rb", <<~RUBY
142
+ module TestApp
143
+ module Actions
144
+ module Users
145
+ class Create < Hanami::Action
146
+ def handle(req, resp)
147
+ resp.body = req.params.to_h.keys
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end
153
+ RUBY
154
+
155
+ require "hanami/prepare"
156
+
157
+ # Simulate any component interacting with the notifications bus such that it creates its
158
+ # internal bus with a duplicate copy of all currently registered events. This means that the
159
+ # class-level Dry::Monitor::Notification events implicitly registered by the
160
+ # Dry::Monitor::Rack::Middleware activated via the rack provider are ignored, unless our
161
+ # provider explicitly re-registers them on _instance_ of the notifications bus.
162
+ #
163
+ # See Hanami::Providers::Rack for more detail.
164
+ Hanami.app["notifications"].instrument(:sql)
165
+
166
+ logs = -> { Pathname(dir).join("test.log").realpath.read }
167
+
168
+ post "/users", JSON.generate(name: "jane", password: "secret"), {"CONTENT_TYPE" => "application/json"}
169
+ expect(logs.()).to match %r{POST 200 \d+(µs|ms) 127.0.0.1 /}
170
+ end
171
+ end
172
+
173
+ describe "Request logging when using slice router" do
174
+ let(:app) { Main::Slice.rack_app }
175
+
176
+ specify "Has rack monitor preconfigured with default request logging (when used via a slice)" do
177
+ dir = Dir.mktmpdir
178
+
179
+ with_tmp_directory(dir) do
180
+ write "config/app.rb", <<~RUBY
181
+ require "hanami"
182
+
183
+ module TestApp
184
+ class App < Hanami::App
185
+ config.logger.stream = config.root.join("test.log")
186
+ end
187
+ end
188
+ RUBY
189
+
190
+ write "slices/main/config/routes.rb", <<~RUBY
191
+ module Main
192
+ class Routes < Hanami::Routes
193
+ root to: ->(env) { [200, {}, ["OK"]] }
194
+ end
195
+ end
196
+ RUBY
197
+
198
+ require "hanami/prepare"
199
+
200
+ get "/"
201
+
202
+ logs = -> { Pathname(dir).join("test.log").realpath.read }
203
+
204
+ expect(logs.()).to match %r{GET 200 \d+(µs|ms) 127.0.0.1 /}
205
+ end
206
+ end
207
+ end
208
+
209
+ describe "Request logging on production" do
94
210
  let(:app) { Main::Slice.rack_app }
95
211
 
212
+ around do |example|
213
+ ENV["HANAMI_ENV"] = "production"
214
+ example.run
215
+ ensure
216
+ ENV["HANAMI_ENV"] = "test"
217
+ end
218
+
96
219
  specify "Has rack monitor preconfigured with default request logging (when used via a slice)" do
97
220
  dir = Dir.mktmpdir
98
221
 
@@ -121,7 +244,11 @@ RSpec.describe "Hanami web app", :app_integration do
121
244
 
122
245
  logs = -> { Pathname(dir).join("test.log").realpath.read }
123
246
 
124
- expect(logs.()).to match %r{GET 200 \d+ms 127.0.0.1 /}
247
+ log_content = logs.()
248
+
249
+ expect(log_content).to match(%r["verb":"GET"])
250
+ expect(log_content).to match(%r["path":"/"])
251
+ expect(log_content).to match(%r[elapsed":\d+,"elapsed_unit":"µs"])
125
252
  end
126
253
  end
127
254
  end
@@ -3,6 +3,7 @@
3
3
  RSpec.describe "Settings / Access within slice class bodies", :app_integration do
4
4
  before do
5
5
  @env = ENV.to_h
6
+ allow(Hanami::Env).to receive(:loaded?).and_return(false)
6
7
  end
7
8
 
8
9
  after do
@@ -3,6 +3,7 @@
3
3
  RSpec.describe "Settings / Access to constants", :app_integration do
4
4
  before do
5
5
  @env = ENV.to_h
6
+ allow(Hanami::Env).to receive(:loaded?).and_return(false)
6
7
  end
7
8
 
8
9
  after do
@@ -126,7 +126,7 @@ RSpec.describe "Hanami setup", :app_integration do
126
126
  with_tmp_directory(Dir.mktmpdir) do
127
127
  write "config/app.rb"
128
128
 
129
- expect(app_path).to match(%r{^/.*/config/app.rb$})
129
+ expect(app_path.to_s).to match(%r{^/.*/config/app.rb$})
130
130
  end
131
131
  end
132
132
  end
@@ -138,7 +138,7 @@ RSpec.describe "Hanami setup", :app_integration do
138
138
  write "lib/foo/bar/.keep"
139
139
 
140
140
  Dir.chdir("lib/foo/bar") do
141
- expect(app_path).to match(%r{^/.*/config/app.rb$})
141
+ expect(app_path.to_s).to match(%r{^/.*/config/app.rb$})
142
142
  end
143
143
  end
144
144
  end
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "pathname"
4
+
3
5
  SPEC_ROOT = File.expand_path(__dir__).freeze
6
+ LOG_DIR = Pathname(SPEC_ROOT).join("..").join("log")
4
7
 
5
8
  require_relative "support/coverage" if ENV["COVERAGE"].eql?("true")
6
9
 
@@ -14,3 +17,12 @@ Hanami::Utils::FileList["./spec/support/**/*.rb"].each do |file|
14
17
 
15
18
  require file
16
19
  end
20
+
21
+ RSpec.configure do |config|
22
+ config.after(:suite) do
23
+ # TODO: Find out what causes logger to create this dir when running specs.
24
+ # There's probably a test app class being created somewhere with root
25
+ # not pointing to a tmp dir.
26
+ FileUtils.rm_r(LOG_DIR) if LOG_DIR.exist?
27
+ end
28
+ end
@@ -13,21 +13,21 @@ RSpec.describe Hanami::Config::Actions, "#content_security_policy" do
13
13
  expect(content_security_policy[:base_uri]).to eq("'self'")
14
14
 
15
15
  expected = [
16
- %(base-uri 'self';),
17
- %(child-src 'self';),
18
- %(connect-src 'self';),
19
- %(default-src 'none';),
20
- %(font-src 'self';),
21
- %(form-action 'self';),
22
- %(frame-ancestors 'self';),
23
- %(frame-src 'self';),
24
- %(img-src 'self' https: data:;),
25
- %(media-src 'self';),
26
- %(object-src 'none';),
27
- %(plugin-types application/pdf;),
28
- %(script-src 'self';),
16
+ %(base-uri 'self'),
17
+ %(child-src 'self'),
18
+ %(connect-src 'self'),
19
+ %(default-src 'none'),
20
+ %(font-src 'self'),
21
+ %(form-action 'self'),
22
+ %(frame-ancestors 'self'),
23
+ %(frame-src 'self'),
24
+ %(img-src 'self' https: data:),
25
+ %(media-src 'self'),
26
+ %(object-src 'none'),
27
+ %(plugin-types application/pdf),
28
+ %(script-src 'self'),
29
29
  %(style-src 'self' 'unsafe-inline' https:)
30
- ].join("\n")
30
+ ].join(";")
31
31
 
32
32
  expect(content_security_policy.to_s).to eq(expected)
33
33
  end
@@ -26,14 +26,6 @@ RSpec.describe Hanami::Config::Actions, "default values" do
26
26
  end
27
27
 
28
28
  describe "new default values applied to base action settings" do
29
- describe "default_request_format" do
30
- specify { expect(config.default_request_format).to eq :html }
31
- end
32
-
33
- describe "default_response_format" do
34
- specify { expect(config.default_response_format).to eq :html }
35
- end
36
-
37
29
  describe "content_security_policy" do
38
30
  specify { expect(config.content_security_policy).to be_kind_of(Hanami::Config::Actions::ContentSecurityPolicy) }
39
31
  end
@@ -13,22 +13,19 @@ RSpec.describe Hanami::Config, "#actions" do
13
13
  it "is a full actions config" do
14
14
  is_expected.to be_an_instance_of(Hanami::Config::Actions)
15
15
 
16
- is_expected.to respond_to(:default_response_format)
17
- is_expected.to respond_to(:default_response_format=)
16
+ is_expected.to respond_to(:format)
18
17
  end
19
18
 
20
19
  it "configures base action settings" do
21
- expect { actions.default_request_format = :json }
22
- .to change { actions.default_request_format }
23
- .to :json
20
+ expect { actions.public_directory = "pub" }
21
+ .to change { actions.public_directory }
22
+ .to end_with("pub")
24
23
  end
25
24
 
26
25
  it "configures base actions settings using custom methods" do
27
- actions.formats = {}
28
-
29
- expect { actions.format json: "app/json" }
30
- .to change { actions.formats }
31
- .to("app/json" => :json)
26
+ expect { actions.formats.add(:json, "app/json") }
27
+ .to change { actions.formats.mapping }
28
+ .to include("app/json" => :json)
32
29
  end
33
30
 
34
31
  it "can be finalized" do
@@ -72,8 +72,8 @@ RSpec.describe Hanami::Config::Logger do
72
72
  end
73
73
 
74
74
  describe "#formatter" do
75
- it "defaults to :rack" do
76
- expect(subject.formatter).to eq(:rack)
75
+ it "defaults to :string" do
76
+ expect(subject.formatter).to eq(:string)
77
77
  end
78
78
 
79
79
  context "when :production environment" do
@@ -94,8 +94,8 @@ RSpec.describe Hanami::Config::Logger do
94
94
  end
95
95
 
96
96
  describe "#template" do
97
- it "defaults to false" do
98
- expect(subject.template).to eq("[%<progname>s] [%<severity>s] [%<time>s] %<message>s")
97
+ it "defaults to :details" do
98
+ expect(subject.template).to be(:details)
99
99
  end
100
100
  end
101
101
 
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "hanami/port"
4
+
5
+ RSpec.describe Hanami::Port do
6
+ context "Hanami::Port::DEFAULT" do
7
+ it "returns default value" do
8
+ expect(Hanami::Port::DEFAULT).to eq(2300)
9
+ end
10
+ end
11
+
12
+ context "Hanami::Port::ENV_VAR" do
13
+ it "returns default value" do
14
+ expect(Hanami::Port::ENV_VAR).to eq("HANAMI_PORT")
15
+ end
16
+ end
17
+
18
+ context ".call" do
19
+ let(:value) { nil }
20
+ let(:env) { nil }
21
+
22
+ it "is aliased as .[]" do
23
+ expect(described_class[value, env]).to be(2300)
24
+ end
25
+
26
+ context "when ENV var is nil" do
27
+ context "and value is nil" do
28
+ it "returns default value" do
29
+ expect(described_class.call(value, env)).to be(2300)
30
+ end
31
+ end
32
+
33
+ context "and value is not nil" do
34
+ let(:value) { 18_000 }
35
+
36
+ it "returns given value" do
37
+ expect(described_class.call(value, env)).to be(value)
38
+ end
39
+
40
+ context "and value is default" do
41
+ let(:value) { 2300 }
42
+
43
+ it "returns given value" do
44
+ expect(described_class.call(value, env)).to be(value)
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ context "when ENV var not nil" do
51
+ let(:env) { 9000 }
52
+
53
+ context "and value is nil" do
54
+ it "returns env value" do
55
+ expect(described_class.call(value, env)).to be(env)
56
+ end
57
+ end
58
+
59
+ context "and value is not nil" do
60
+ let(:value) { 18_000 }
61
+
62
+ it "returns given value" do
63
+ expect(described_class.call(value, env)).to be(value)
64
+ end
65
+
66
+ context "and value is default" do
67
+ let(:value) { 2300 }
68
+
69
+ it "returns env value" do
70
+ expect(described_class.call(value, env)).to be(env)
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+
77
+ context ".call!" do
78
+ before { ENV.delete("HANAMI_PORT") }
79
+ let(:value) { 2300 }
80
+
81
+ context "when given value is default" do
82
+ it "doesn't set env var" do
83
+ described_class.call!(value)
84
+
85
+ expect(ENV.key?("HANAMI_PORT")).to be(false)
86
+ end
87
+ end
88
+
89
+ context "when given value isn't default" do
90
+ let(:value) { 9000 }
91
+
92
+ it "set env var" do
93
+ described_class.call!(value)
94
+
95
+ expect(ENV.fetch("HANAMI_PORT")).to eq(value.to_s)
96
+ end
97
+ end
98
+ end
99
+
100
+ context ".default?" do
101
+ context "when given value is default" do
102
+ let(:value) { 2300 }
103
+
104
+ it "returns true" do
105
+ expect(described_class.default?(value)).to be(true)
106
+ end
107
+ end
108
+
109
+ context "when given value isn't default" do
110
+ let(:value) { 9000 }
111
+
112
+ it "returns false" do
113
+ expect(described_class.default?(value)).to be(false)
114
+ end
115
+ end
116
+ end
117
+ end
@@ -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.rc1")
5
+ expect(Hanami::VERSION).to eq("2.0.1")
6
6
  end
7
7
  end
@@ -53,7 +53,10 @@ RSpec.describe Hanami::Web::RackLogger do
53
53
  stream.rewind
54
54
  actual = stream.read
55
55
 
56
- expect(actual).to include(%([#{app_name}] [INFO] [#{time}] #{verb} #{status} #{elapsed}ms #{ip} #{path} #{content_length} {"user"=>{"password"=>"[FILTERED]"}}))
56
+ expect(actual).to eql(<<~LOG)
57
+ [#{app_name}] [INFO] [#{time}] #{verb} #{status} #{elapsed}µs #{ip} #{path} #{content_length}
58
+ {"user"=>{"password"=>"[FILTERED]"}}
59
+ LOG
57
60
  end
58
61
 
59
62
  context "ip" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hanami
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.rc1
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luca Guidi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-11-08 00:00:00.000000000 Z
11
+ date: 2022-12-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -97,6 +97,9 @@ dependencies:
97
97
  - - "~>"
98
98
  - !ruby/object:Gem::Version
99
99
  version: '1.0'
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: 1.0.1
100
103
  - - "<"
101
104
  - !ruby/object:Gem::Version
102
105
  version: '2'
@@ -107,6 +110,9 @@ dependencies:
107
110
  - - "~>"
108
111
  - !ruby/object:Gem::Version
109
112
  version: '1.0'
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: 1.0.1
110
116
  - - "<"
111
117
  - !ruby/object:Gem::Version
112
118
  version: '2'
@@ -116,56 +122,68 @@ dependencies:
116
122
  requirements:
117
123
  - - "~>"
118
124
  - !ruby/object:Gem::Version
119
- version: 1.0.rc
125
+ version: '1.0'
126
+ - - "<"
127
+ - !ruby/object:Gem::Version
128
+ version: '2'
120
129
  type: :runtime
121
130
  prerelease: false
122
131
  version_requirements: !ruby/object:Gem::Requirement
123
132
  requirements:
124
133
  - - "~>"
125
134
  - !ruby/object:Gem::Version
126
- version: 1.0.rc
135
+ version: '1.0'
136
+ - - "<"
137
+ - !ruby/object:Gem::Version
138
+ version: '2'
127
139
  - !ruby/object:Gem::Dependency
128
140
  name: dry-logger
129
141
  requirement: !ruby/object:Gem::Requirement
130
142
  requirements:
131
143
  - - "~>"
132
144
  - !ruby/object:Gem::Version
133
- version: 1.0.rc
145
+ version: '1.0'
146
+ - - "<"
147
+ - !ruby/object:Gem::Version
148
+ version: '2'
134
149
  type: :runtime
135
150
  prerelease: false
136
151
  version_requirements: !ruby/object:Gem::Requirement
137
152
  requirements:
138
153
  - - "~>"
139
154
  - !ruby/object:Gem::Version
140
- version: 1.0.rc
155
+ version: '1.0'
156
+ - - "<"
157
+ - !ruby/object:Gem::Version
158
+ version: '2'
141
159
  - !ruby/object:Gem::Dependency
142
160
  name: hanami-cli
143
161
  requirement: !ruby/object:Gem::Requirement
144
162
  requirements:
145
163
  - - "~>"
146
164
  - !ruby/object:Gem::Version
147
- version: 2.0.rc
165
+ version: '2.0'
148
166
  type: :runtime
149
167
  prerelease: false
150
168
  version_requirements: !ruby/object:Gem::Requirement
151
169
  requirements:
152
170
  - - "~>"
153
171
  - !ruby/object:Gem::Version
154
- version: 2.0.rc
172
+ version: '2.0'
155
173
  - !ruby/object:Gem::Dependency
156
174
  name: hanami-utils
157
175
  requirement: !ruby/object:Gem::Requirement
158
176
  requirements:
159
177
  - - "~>"
160
178
  - !ruby/object:Gem::Version
161
- version: 2.0.rc
179
+ version: '2.0'
162
180
  type: :runtime
163
181
  prerelease: false
164
182
  version_requirements: !ruby/object:Gem::Requirement
165
183
  requirements:
166
184
  - - "~>"
167
185
  - !ruby/object:Gem::Version
168
- version: 2.0.rc
186
+ version: '2.0'
169
187
  - !ruby/object:Gem::Dependency
170
188
  name: zeitwerk
171
189
  requirement: !ruby/object:Gem::Requirement
@@ -250,6 +268,7 @@ files:
250
268
  - lib/hanami/config/router.rb
251
269
  - lib/hanami/config/views.rb
252
270
  - lib/hanami/constants.rb
271
+ - lib/hanami/env.rb
253
272
  - lib/hanami/errors.rb
254
273
  - lib/hanami/extensions.rb
255
274
  - lib/hanami/extensions/action.rb
@@ -258,6 +277,7 @@ files:
258
277
  - lib/hanami/extensions/view/context.rb
259
278
  - lib/hanami/extensions/view/slice_configured_context.rb
260
279
  - lib/hanami/extensions/view/slice_configured_view.rb
280
+ - lib/hanami/port.rb
261
281
  - lib/hanami/prepare.rb
262
282
  - lib/hanami/providers/inflector.rb
263
283
  - lib/hanami/providers/logger.rb
@@ -281,6 +301,7 @@ files:
281
301
  - lib/hanami/web/rack_logger.rb
282
302
  - spec/integration/action/cookies_spec.rb
283
303
  - spec/integration/action/csrf_protection_spec.rb
304
+ - spec/integration/action/format_config_spec.rb
284
305
  - spec/integration/action/routes_spec.rb
285
306
  - spec/integration/action/sessions_spec.rb
286
307
  - spec/integration/action/slice_configuration_spec.rb
@@ -357,6 +378,7 @@ files:
357
378
  - spec/unit/hanami/config/slices_spec.rb
358
379
  - spec/unit/hanami/config/views_spec.rb
359
380
  - spec/unit/hanami/env_spec.rb
381
+ - spec/unit/hanami/port_spec.rb
360
382
  - spec/unit/hanami/settings/env_store_spec.rb
361
383
  - spec/unit/hanami/settings_spec.rb
362
384
  - spec/unit/hanami/slice_configurable_spec.rb
@@ -381,9 +403,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
381
403
  version: '3.0'
382
404
  required_rubygems_version: !ruby/object:Gem::Requirement
383
405
  requirements:
384
- - - ">"
406
+ - - ">="
385
407
  - !ruby/object:Gem::Version
386
- version: 1.3.1
408
+ version: '0'
387
409
  requirements: []
388
410
  rubygems_version: 3.3.3
389
411
  signing_key:
@@ -392,6 +414,7 @@ summary: The web, with simplicity
392
414
  test_files:
393
415
  - spec/integration/action/cookies_spec.rb
394
416
  - spec/integration/action/csrf_protection_spec.rb
417
+ - spec/integration/action/format_config_spec.rb
395
418
  - spec/integration/action/routes_spec.rb
396
419
  - spec/integration/action/sessions_spec.rb
397
420
  - spec/integration/action/slice_configuration_spec.rb
@@ -468,6 +491,7 @@ test_files:
468
491
  - spec/unit/hanami/config/slices_spec.rb
469
492
  - spec/unit/hanami/config/views_spec.rb
470
493
  - spec/unit/hanami/env_spec.rb
494
+ - spec/unit/hanami/port_spec.rb
471
495
  - spec/unit/hanami/settings/env_store_spec.rb
472
496
  - spec/unit/hanami/settings_spec.rb
473
497
  - spec/unit/hanami/slice_configurable_spec.rb