hanami 2.3.0.beta2 → 2.3.0
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 +64 -1
- data/README.md +1 -3
- data/hanami.gemspec +3 -3
- data/lib/hanami/config/actions/content_security_policy.rb +2 -2
- data/lib/hanami/config/actions.rb +3 -2
- data/lib/hanami/config/router.rb +1 -0
- data/lib/hanami/config.rb +8 -16
- data/lib/hanami/extensions/action.rb +1 -0
- data/lib/hanami/extensions/operation/slice_configured_db_operation.rb +88 -0
- data/lib/hanami/extensions/operation.rb +8 -23
- data/lib/hanami/extensions/view/context.rb +2 -1
- data/lib/hanami/extensions/view/part.rb +3 -0
- data/lib/hanami/extensions/view/scope.rb +3 -0
- data/lib/hanami/extensions/view.rb +1 -0
- data/lib/hanami/helpers/assets_helper.rb +2 -2
- data/lib/hanami/middleware/content_security_policy_nonce.rb +3 -3
- data/lib/hanami/routes.rb +1 -0
- data/lib/hanami/slice/router.rb +201 -12
- data/lib/hanami/slice.rb +1 -0
- data/lib/hanami/slice_configurable.rb +1 -3
- data/lib/hanami/version.rb +1 -1
- data/lib/hanami/web/rack_logger.rb +25 -8
- data/lib/hanami.rb +15 -1
- data/spec/integration/action/format_config_spec.rb +0 -68
- data/spec/integration/logging/request_logging_spec.rb +16 -0
- data/spec/integration/operations/extension_spec.rb +63 -0
- data/spec/integration/rack_app/body_parser_spec.rb +1 -2
- data/spec/integration/router/resource_routes_spec.rb +281 -0
- metadata +14 -11
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "dry/inflector"
|
|
4
|
+
require "hanami/slice/router"
|
|
5
|
+
require "json"
|
|
6
|
+
|
|
7
|
+
RSpec.describe "Router / Resource routes" do
|
|
8
|
+
let(:router) { Hanami::Slice::Router.new(routes:, resolver:, inflector: Dry::Inflector.new) { } }
|
|
9
|
+
|
|
10
|
+
let(:resolver) { Hanami::Slice::Routing::Resolver.new(slice:) }
|
|
11
|
+
let(:slice) {
|
|
12
|
+
Class.new(Hanami::Slice).tap { |slice|
|
|
13
|
+
allow(slice).to receive(:container) { actions_container }
|
|
14
|
+
allow(slice).to receive(:slices) { {reviews: child_slice} }
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
let(:child_slice) {
|
|
18
|
+
Class.new(Hanami::Slice).tap { |slice|
|
|
19
|
+
allow(slice).to receive(:container) { actions_container("[reviews]") }
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
def actions_container(prefix = nil)
|
|
23
|
+
Hash.new { |_hsh, key|
|
|
24
|
+
Class.new { |klass|
|
|
25
|
+
klass.define_method(:call) do |env|
|
|
26
|
+
body = key
|
|
27
|
+
body = "#{body} #{JSON.generate(env["router.params"])}" if env["router.params"].any?
|
|
28
|
+
body = "#{prefix}#{body}" if prefix
|
|
29
|
+
[200, {}, body]
|
|
30
|
+
end
|
|
31
|
+
}.new
|
|
32
|
+
}.tap { |container|
|
|
33
|
+
def container.resolve(key) = self[key]
|
|
34
|
+
}
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
let(:app) { Rack::MockRequest.new(router) }
|
|
38
|
+
def routed(method, url)
|
|
39
|
+
app.request(method, url).body
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
describe "resources" do
|
|
43
|
+
let(:routes) { proc { resources :posts } }
|
|
44
|
+
|
|
45
|
+
it "routes all RESTful actions to the resource" do
|
|
46
|
+
expect(routed("GET", "/posts")).to eq %(actions.posts.index)
|
|
47
|
+
expect(routed("GET", "/posts/new")).to eq %(actions.posts.new)
|
|
48
|
+
expect(routed("POST", "/posts")).to eq %(actions.posts.create)
|
|
49
|
+
expect(routed("GET", "/posts/1")).to eq %(actions.posts.show {"id":"1"})
|
|
50
|
+
expect(routed("GET", "/posts/1/edit")).to eq %(actions.posts.edit {"id":"1"})
|
|
51
|
+
expect(routed("PATCH", "/posts/1")).to eq %(actions.posts.update {"id":"1"})
|
|
52
|
+
expect(routed("DELETE", "/posts/1")).to eq %(actions.posts.destroy {"id":"1"})
|
|
53
|
+
|
|
54
|
+
expect(router.path("posts")).to eq "/posts"
|
|
55
|
+
expect(router.path("new_post")).to eq "/posts/new"
|
|
56
|
+
expect(router.path("edit_post", id: 1)).to eq "/posts/1/edit"
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
describe "with :only" do
|
|
60
|
+
let(:routes) { proc { resources :posts, only: %i(index show) } }
|
|
61
|
+
|
|
62
|
+
it "routes only the given actions to the resource" do
|
|
63
|
+
expect(routed("GET", "/posts")).to eq %(actions.posts.index)
|
|
64
|
+
expect(routed("GET", "/posts/1")).to eq %(actions.posts.show {"id":"1"})
|
|
65
|
+
|
|
66
|
+
expect(routed("GET", "/posts/new")).not_to eq %(actions.posts.new)
|
|
67
|
+
expect(routed("POST", "/posts")).to eq "Method Not Allowed"
|
|
68
|
+
expect(routed("GET", "/posts/1/edit")).to eq "Not Found"
|
|
69
|
+
expect(routed("PATCH", "/posts/1")).to eq "Method Not Allowed"
|
|
70
|
+
expect(routed("DELETE", "/posts/1")).to eq "Method Not Allowed"
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
describe "with :except" do
|
|
75
|
+
let(:routes) { proc { resources :posts, except: %i(edit update destroy) } }
|
|
76
|
+
|
|
77
|
+
it "routes all except the given actions to the resource" do
|
|
78
|
+
expect(routed("GET", "/posts")).to eq %(actions.posts.index)
|
|
79
|
+
expect(routed("GET", "/posts/new")).to eq %(actions.posts.new)
|
|
80
|
+
expect(routed("POST", "/posts")).to eq %(actions.posts.create)
|
|
81
|
+
expect(routed("GET", "/posts/1")).to eq %(actions.posts.show {"id":"1"})
|
|
82
|
+
|
|
83
|
+
expect(routed("GET", "/posts/1/edit")).to eq "Not Found"
|
|
84
|
+
expect(routed("PATCH", "/posts/1")).to eq "Method Not Allowed"
|
|
85
|
+
expect(routed("DELETE", "/posts/1")).to eq "Method Not Allowed"
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
describe "with :to" do
|
|
90
|
+
let(:routes) { proc { resources :posts, to: "articles" } }
|
|
91
|
+
|
|
92
|
+
it "uses actions from the given container key namespace" do
|
|
93
|
+
expect(routed("GET", "/posts")).to eq %(actions.articles.index)
|
|
94
|
+
expect(routed("GET", "/posts/new")).to eq %(actions.articles.new)
|
|
95
|
+
expect(routed("POST", "/posts")).to eq %(actions.articles.create)
|
|
96
|
+
expect(routed("GET", "/posts/1")).to eq %(actions.articles.show {"id":"1"})
|
|
97
|
+
expect(routed("GET", "/posts/1/edit")).to eq %(actions.articles.edit {"id":"1"})
|
|
98
|
+
expect(routed("PATCH", "/posts/1")).to eq %(actions.articles.update {"id":"1"})
|
|
99
|
+
expect(routed("DELETE", "/posts/1")).to eq %(actions.articles.destroy {"id":"1"})
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
describe "witih :path" do
|
|
104
|
+
let(:routes) { proc { resources :posts, path: "articles" } }
|
|
105
|
+
|
|
106
|
+
it "uses the given path for the routes" do
|
|
107
|
+
expect(routed("GET", "/articles")).to eq %(actions.posts.index)
|
|
108
|
+
expect(routed("GET", "/articles/new")).to eq %(actions.posts.new)
|
|
109
|
+
expect(routed("POST", "/articles")).to eq %(actions.posts.create)
|
|
110
|
+
expect(routed("GET", "/articles/1")).to eq %(actions.posts.show {"id":"1"})
|
|
111
|
+
expect(routed("GET", "/articles/1/edit")).to eq %(actions.posts.edit {"id":"1"})
|
|
112
|
+
expect(routed("PATCH", "/articles/1")).to eq %(actions.posts.update {"id":"1"})
|
|
113
|
+
expect(routed("DELETE", "/articles/1")).to eq %(actions.posts.destroy {"id":"1"})
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
describe "resource" do
|
|
119
|
+
let(:routes) { proc { resource :profile } }
|
|
120
|
+
|
|
121
|
+
it "routes all RESTful actions (except index) to the resource" do
|
|
122
|
+
expect(routed("GET", "/profile/new")).to eq %(actions.profile.new)
|
|
123
|
+
expect(routed("POST", "/profile")).to eq %(actions.profile.create)
|
|
124
|
+
expect(routed("GET", "/profile")).to eq %(actions.profile.show)
|
|
125
|
+
expect(routed("GET", "/profile/edit")).to eq %(actions.profile.edit)
|
|
126
|
+
expect(routed("PATCH", "/profile")).to eq %(actions.profile.update)
|
|
127
|
+
expect(routed("DELETE", "/profile")).to eq %(actions.profile.destroy)
|
|
128
|
+
|
|
129
|
+
expect(routed("GET", "/profiles")).to eq "Not Found"
|
|
130
|
+
expect(routed("GET", "/profiles/1")).to eq "Not Found"
|
|
131
|
+
expect(routed("GET", "/profile/1")).to eq "Not Found"
|
|
132
|
+
|
|
133
|
+
expect(router.path("profile")).to eq "/profile"
|
|
134
|
+
expect(router.path("new_profile")).to eq "/profile/new"
|
|
135
|
+
expect(router.path("edit_profile")).to eq "/profile/edit"
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
describe "with :only" do
|
|
139
|
+
let(:routes) { proc { resource :profile, only: %i(show edit update) } }
|
|
140
|
+
|
|
141
|
+
it "routes only the given actions to the resource" do
|
|
142
|
+
expect(routed("GET", "/profile")).to eq %(actions.profile.show)
|
|
143
|
+
expect(routed("GET", "/profile/edit")).to eq %(actions.profile.edit)
|
|
144
|
+
expect(routed("PATCH", "/profile")).to eq %(actions.profile.update)
|
|
145
|
+
|
|
146
|
+
expect(routed("GET", "/profile/new")).to eq "Not Found"
|
|
147
|
+
expect(routed("POST", "/profile")).to eq "Method Not Allowed"
|
|
148
|
+
expect(routed("DELETE", "/profile")).to eq "Method Not Allowed"
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
describe "with :except" do
|
|
153
|
+
let(:routes) { proc { resource :profile, except: %i(edit update destroy) } }
|
|
154
|
+
|
|
155
|
+
it "routes all except the given actions to the resource" do
|
|
156
|
+
expect(routed("GET", "/profile/new")).to eq %(actions.profile.new)
|
|
157
|
+
expect(routed("POST", "/profile")).to eq %(actions.profile.create)
|
|
158
|
+
expect(routed("GET", "/profile")).to eq %(actions.profile.show)
|
|
159
|
+
|
|
160
|
+
expect(routed("GET", "/profile/edit")).to eq "Not Found"
|
|
161
|
+
expect(routed("PATCH", "/profile")).to eq "Method Not Allowed"
|
|
162
|
+
expect(routed("DELETE", "/profile")).to eq "Method Not Allowed"
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
describe "with :to" do
|
|
167
|
+
let(:routes) { proc { resource :profile, to: "user" } }
|
|
168
|
+
|
|
169
|
+
it "uses actions from the given container key namespace" do
|
|
170
|
+
expect(routed("GET", "/profile/new")).to eq %(actions.user.new)
|
|
171
|
+
expect(routed("POST", "/profile")).to eq %(actions.user.create)
|
|
172
|
+
expect(routed("GET", "/profile")).to eq %(actions.user.show)
|
|
173
|
+
expect(routed("GET", "/profile/edit")).to eq %(actions.user.edit)
|
|
174
|
+
expect(routed("PATCH", "/profile")).to eq %(actions.user.update)
|
|
175
|
+
expect(routed("DELETE", "/profile")).to eq %(actions.user.destroy)
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
describe "with :path" do
|
|
180
|
+
let(:routes) { proc { resource :profile, path: "user"} }
|
|
181
|
+
|
|
182
|
+
it "uses the given path for the routes" do
|
|
183
|
+
expect(routed("GET", "/user/new")).to eq %(actions.profile.new)
|
|
184
|
+
expect(routed("POST", "/user")).to eq %(actions.profile.create)
|
|
185
|
+
expect(routed("GET", "/user")).to eq %(actions.profile.show)
|
|
186
|
+
expect(routed("GET", "/user/edit")).to eq %(actions.profile.edit)
|
|
187
|
+
expect(routed("PATCH", "/user")).to eq %(actions.profile.update)
|
|
188
|
+
expect(routed("DELETE", "/user")).to eq %(actions.profile.destroy)
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
describe "nested resources" do
|
|
194
|
+
let(:routes) {
|
|
195
|
+
proc {
|
|
196
|
+
resources :cafes, only: :show do
|
|
197
|
+
resources :reviews, only: :index do
|
|
198
|
+
resources :comments, only: [:index, :new, :create]
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
resource :profile, only: :show do
|
|
203
|
+
resource :avatar, only: :show do
|
|
204
|
+
resources :comments, only: :index
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
it "routes to the nested resources" do
|
|
211
|
+
expect(routed("GET", "/cafes/1")).to eq %(actions.cafes.show {"id":"1"})
|
|
212
|
+
expect(routed("GET", "/cafes/1/reviews")).to eq %(actions.cafes.reviews.index {"cafe_id":"1"})
|
|
213
|
+
expect(routed("GET", "/cafes/1/reviews/2/comments")).to eq %(actions.cafes.reviews.comments.index {"cafe_id":"1","review_id":"2"})
|
|
214
|
+
|
|
215
|
+
expect(router.path("cafe", id: 1)).to eq "/cafes/1"
|
|
216
|
+
expect(router.path("cafe_reviews", cafe_id: 1)).to eq "/cafes/1/reviews"
|
|
217
|
+
expect(router.path("cafe_review_comments", cafe_id: 1, review_id: 1)).to eq "/cafes/1/reviews/1/comments"
|
|
218
|
+
expect(router.path("new_cafe_review_comment", cafe_id: 1, review_id: 1)).to eq "/cafes/1/reviews/1/comments/new"
|
|
219
|
+
|
|
220
|
+
expect(routed("GET", "/profile")).to eq %(actions.profile.show)
|
|
221
|
+
expect(routed("GET", "/profile/avatar")).to eq %(actions.profile.avatar.show)
|
|
222
|
+
expect(routed("GET", "/profile/avatar/comments")).to eq %(actions.profile.avatar.comments.index)
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
describe "standalone routes nested under resources" do
|
|
227
|
+
let(:routes) {
|
|
228
|
+
proc {
|
|
229
|
+
resources :cafes, only: :show do
|
|
230
|
+
get "/top-reviews", to: "cafes.top_reviews.index", as: :top_reviews
|
|
231
|
+
end
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
it "nests the standalone route under the resource" do
|
|
236
|
+
expect(routed("GET", "/cafes/1")).to eq %(actions.cafes.show {"id":"1"})
|
|
237
|
+
expect(routed("GET", "/cafes/1/top-reviews")).to eq %(actions.cafes.top_reviews.index {"cafe_id":"1"})
|
|
238
|
+
|
|
239
|
+
expect(router.path("cafe_top_reviews", cafe_id: 1)).to eq "/cafes/1/top-reviews"
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
describe "resources nested under scopes" do
|
|
244
|
+
let(:routes) {
|
|
245
|
+
proc {
|
|
246
|
+
scope "coffee-lovers" do
|
|
247
|
+
resources :cafes, only: :show do
|
|
248
|
+
get "/top-reviews", to: "cafes.top_reviews.index", as: :top_reviews
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
it "routes to the resources under the scope" do
|
|
255
|
+
expect(routed("GET", "/coffee-lovers/cafes/1")).to eq %(actions.cafes.show {"id":"1"})
|
|
256
|
+
expect(routed("GET", "/coffee-lovers/cafes/1/top-reviews")).to eq %(actions.cafes.top_reviews.index {"cafe_id":"1"})
|
|
257
|
+
|
|
258
|
+
expect(router.path("coffee_lovers_cafe", id: 1)).to eq "/coffee-lovers/cafes/1"
|
|
259
|
+
expect(router.path("coffee_lovers_cafe_top_reviews", cafe_id: 1)).to eq "/coffee-lovers/cafes/1/top-reviews"
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
describe "slices nested under resources" do
|
|
264
|
+
let(:routes) {
|
|
265
|
+
proc {
|
|
266
|
+
resources :cafes, only: :show do
|
|
267
|
+
slice :reviews, at: "" do
|
|
268
|
+
resources :reviews, only: :index
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
it "routes to actions within the nested slice" do
|
|
275
|
+
expect(routed("GET", "/cafes/1")).to eq %(actions.cafes.show {"id":"1"})
|
|
276
|
+
expect(routed("GET", "/cafes/1/reviews")).to eq %([reviews]actions.cafes.reviews.index {"cafe_id":"1"})
|
|
277
|
+
|
|
278
|
+
expect(router.path("cafe_reviews", cafe_id: 1)).to eq "/cafes/1/reviews"
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hanami
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.3.0
|
|
4
|
+
version: 2.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Hanakai team
|
|
@@ -147,7 +147,7 @@ dependencies:
|
|
|
147
147
|
requirements:
|
|
148
148
|
- - "~>"
|
|
149
149
|
- !ruby/object:Gem::Version
|
|
150
|
-
version: '1.
|
|
150
|
+
version: '1.2'
|
|
151
151
|
- - "<"
|
|
152
152
|
- !ruby/object:Gem::Version
|
|
153
153
|
version: '2'
|
|
@@ -157,7 +157,7 @@ dependencies:
|
|
|
157
157
|
requirements:
|
|
158
158
|
- - "~>"
|
|
159
159
|
- !ruby/object:Gem::Version
|
|
160
|
-
version: '1.
|
|
160
|
+
version: '1.2'
|
|
161
161
|
- - "<"
|
|
162
162
|
- !ruby/object:Gem::Version
|
|
163
163
|
version: '2'
|
|
@@ -165,30 +165,30 @@ dependencies:
|
|
|
165
165
|
name: hanami-cli
|
|
166
166
|
requirement: !ruby/object:Gem::Requirement
|
|
167
167
|
requirements:
|
|
168
|
-
- - "
|
|
168
|
+
- - ">="
|
|
169
169
|
- !ruby/object:Gem::Version
|
|
170
|
-
version: 2.3.0
|
|
170
|
+
version: 2.3.0
|
|
171
171
|
type: :runtime
|
|
172
172
|
prerelease: false
|
|
173
173
|
version_requirements: !ruby/object:Gem::Requirement
|
|
174
174
|
requirements:
|
|
175
|
-
- - "
|
|
175
|
+
- - ">="
|
|
176
176
|
- !ruby/object:Gem::Version
|
|
177
|
-
version: 2.3.0
|
|
177
|
+
version: 2.3.0
|
|
178
178
|
- !ruby/object:Gem::Dependency
|
|
179
179
|
name: hanami-utils
|
|
180
180
|
requirement: !ruby/object:Gem::Requirement
|
|
181
181
|
requirements:
|
|
182
|
-
- - "
|
|
182
|
+
- - ">="
|
|
183
183
|
- !ruby/object:Gem::Version
|
|
184
|
-
version: 2.3.0
|
|
184
|
+
version: 2.3.0
|
|
185
185
|
type: :runtime
|
|
186
186
|
prerelease: false
|
|
187
187
|
version_requirements: !ruby/object:Gem::Requirement
|
|
188
188
|
requirements:
|
|
189
|
-
- - "
|
|
189
|
+
- - ">="
|
|
190
190
|
- !ruby/object:Gem::Version
|
|
191
|
-
version: 2.3.0
|
|
191
|
+
version: 2.3.0
|
|
192
192
|
- !ruby/object:Gem::Dependency
|
|
193
193
|
name: json
|
|
194
194
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -309,6 +309,7 @@ files:
|
|
|
309
309
|
- lib/hanami/extensions/action/slice_configured_action.rb
|
|
310
310
|
- lib/hanami/extensions/db/repo.rb
|
|
311
311
|
- lib/hanami/extensions/operation.rb
|
|
312
|
+
- lib/hanami/extensions/operation/slice_configured_db_operation.rb
|
|
312
313
|
- lib/hanami/extensions/router/errors.rb
|
|
313
314
|
- lib/hanami/extensions/view.rb
|
|
314
315
|
- lib/hanami/extensions/view/context.rb
|
|
@@ -413,6 +414,7 @@ files:
|
|
|
413
414
|
- spec/integration/rack_app/non_booted_rack_app_spec.rb
|
|
414
415
|
- spec/integration/rack_app/rack_app_spec.rb
|
|
415
416
|
- spec/integration/rake_tasks_spec.rb
|
|
417
|
+
- spec/integration/router/resource_routes_spec.rb
|
|
416
418
|
- spec/integration/settings/access_in_slice_class_body_spec.rb
|
|
417
419
|
- spec/integration/settings/access_to_constants_spec.rb
|
|
418
420
|
- spec/integration/settings/loading_from_env_spec.rb
|
|
@@ -568,6 +570,7 @@ test_files:
|
|
|
568
570
|
- spec/integration/rack_app/non_booted_rack_app_spec.rb
|
|
569
571
|
- spec/integration/rack_app/rack_app_spec.rb
|
|
570
572
|
- spec/integration/rake_tasks_spec.rb
|
|
573
|
+
- spec/integration/router/resource_routes_spec.rb
|
|
571
574
|
- spec/integration/settings/access_in_slice_class_body_spec.rb
|
|
572
575
|
- spec/integration/settings/access_to_constants_spec.rb
|
|
573
576
|
- spec/integration/settings/loading_from_env_spec.rb
|