tennpipes-base 3.6.6
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 +7 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +294 -0
- data/Rakefile +1 -0
- data/bin/tennpipes +8 -0
- data/lib/tennpipes-base.rb +196 -0
- data/lib/tennpipes-base/application.rb +175 -0
- data/lib/tennpipes-base/application/application_setup.rb +202 -0
- data/lib/tennpipes-base/application/authenticity_token.rb +25 -0
- data/lib/tennpipes-base/application/flash.rb +229 -0
- data/lib/tennpipes-base/application/params_protection.rb +129 -0
- data/lib/tennpipes-base/application/routing.rb +1002 -0
- data/lib/tennpipes-base/application/show_exceptions.rb +50 -0
- data/lib/tennpipes-base/caller.rb +53 -0
- data/lib/tennpipes-base/cli/adapter.rb +33 -0
- data/lib/tennpipes-base/cli/base.rb +105 -0
- data/lib/tennpipes-base/cli/console.rb +20 -0
- data/lib/tennpipes-base/cli/launcher.rb +103 -0
- data/lib/tennpipes-base/cli/rake.rb +50 -0
- data/lib/tennpipes-base/cli/rake_tasks.rb +72 -0
- data/lib/tennpipes-base/command.rb +38 -0
- data/lib/tennpipes-base/ext/sinatra.rb +29 -0
- data/lib/tennpipes-base/filter.rb +52 -0
- data/lib/tennpipes-base/images/404.png +0 -0
- data/lib/tennpipes-base/images/500.png +0 -0
- data/lib/tennpipes-base/loader.rb +202 -0
- data/lib/tennpipes-base/logger.rb +492 -0
- data/lib/tennpipes-base/module.rb +58 -0
- data/lib/tennpipes-base/mounter.rb +308 -0
- data/lib/tennpipes-base/path_router.rb +119 -0
- data/lib/tennpipes-base/path_router/compiler.rb +110 -0
- data/lib/tennpipes-base/path_router/error_handler.rb +8 -0
- data/lib/tennpipes-base/path_router/matcher.rb +123 -0
- data/lib/tennpipes-base/path_router/route.rb +169 -0
- data/lib/tennpipes-base/reloader.rb +309 -0
- data/lib/tennpipes-base/reloader/rack.rb +26 -0
- data/lib/tennpipes-base/reloader/storage.rb +55 -0
- data/lib/tennpipes-base/router.rb +98 -0
- data/lib/tennpipes-base/server.rb +119 -0
- data/lib/tennpipes-base/tasks.rb +21 -0
- data/lib/tennpipes-base/version.rb +20 -0
- data/lib/tennpipes-base/version.rb~ +20 -0
- data/test/fixtures/app_gem/Gemfile +4 -0
- data/test/fixtures/app_gem/app/app.rb +3 -0
- data/test/fixtures/app_gem/app_gem.gemspec +17 -0
- data/test/fixtures/app_gem/lib/app_gem.rb +7 -0
- data/test/fixtures/app_gem/lib/app_gem/version.rb +3 -0
- data/test/fixtures/apps/complex.rb +32 -0
- data/test/fixtures/apps/demo_app.rb +7 -0
- data/test/fixtures/apps/demo_demo.rb +7 -0
- data/test/fixtures/apps/demo_project/api/app.rb +7 -0
- data/test/fixtures/apps/demo_project/api/lib/api_lib.rb +3 -0
- data/test/fixtures/apps/demo_project/app.rb +7 -0
- data/test/fixtures/apps/external_apps/fake_lib.rb +1 -0
- data/test/fixtures/apps/external_apps/fake_root.rb +2 -0
- data/test/fixtures/apps/helpers/class_methods_helpers.rb +4 -0
- data/test/fixtures/apps/helpers/instance_methods_helpers.rb +4 -0
- data/test/fixtures/apps/helpers/support.rb +1 -0
- data/test/fixtures/apps/helpers/system_helpers.rb +8 -0
- data/test/fixtures/apps/kiq.rb +3 -0
- data/test/fixtures/apps/lib/myklass.rb +2 -0
- data/test/fixtures/apps/lib/myklass/mysubklass.rb +4 -0
- data/test/fixtures/apps/models/child.rb +2 -0
- data/test/fixtures/apps/models/parent.rb +5 -0
- data/test/fixtures/apps/mountable_apps/rack_apps.rb +15 -0
- data/test/fixtures/apps/mountable_apps/static.html +1 -0
- data/test/fixtures/apps/precompiled_app.rb +19 -0
- data/test/fixtures/apps/simple.rb +32 -0
- data/test/fixtures/apps/static.rb +10 -0
- data/test/fixtures/apps/system.rb +13 -0
- data/test/fixtures/apps/system_class_methods_demo.rb +7 -0
- data/test/fixtures/apps/system_instance_methods_demo.rb +7 -0
- data/test/fixtures/dependencies/a.rb +9 -0
- data/test/fixtures/dependencies/b.rb +4 -0
- data/test/fixtures/dependencies/c.rb +1 -0
- data/test/fixtures/dependencies/circular/e.rb +13 -0
- data/test/fixtures/dependencies/circular/f.rb +2 -0
- data/test/fixtures/dependencies/circular/g.rb +2 -0
- data/test/fixtures/dependencies/d.rb +4 -0
- data/test/fixtures/reloadable_apps/external/app/app.rb +6 -0
- data/test/fixtures/reloadable_apps/external/app/controllers/base.rb +6 -0
- data/test/fixtures/reloadable_apps/main/app.rb +10 -0
- data/test/helper.rb +30 -0
- data/test/test_application.rb +185 -0
- data/test/test_core.rb +93 -0
- data/test/test_csrf_protection.rb +208 -0
- data/test/test_dependencies.rb +57 -0
- data/test/test_filters.rb +389 -0
- data/test/test_flash.rb +168 -0
- data/test/test_locale.rb +21 -0
- data/test/test_logger.rb +295 -0
- data/test/test_mounter.rb +302 -0
- data/test/test_params_protection.rb +195 -0
- data/test/test_reloader_complex.rb +74 -0
- data/test/test_reloader_external.rb +21 -0
- data/test/test_reloader_simple.rb +101 -0
- data/test/test_reloader_system.rb +113 -0
- data/test/test_restful_routing.rb +33 -0
- data/test/test_router.rb +281 -0
- data/test/test_routing.rb +2328 -0
- metadata +301 -0
|
@@ -0,0 +1,2328 @@
|
|
|
1
|
+
#encoding: utf-8
|
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/helper')
|
|
3
|
+
|
|
4
|
+
class FooError < RuntimeError; end
|
|
5
|
+
|
|
6
|
+
class RegexpLookAlike
|
|
7
|
+
# RegexpLookAlike#to_s, RegexpLookAlike#names and MatchData#names must be defined.
|
|
8
|
+
class MatchData
|
|
9
|
+
def captures
|
|
10
|
+
["this", "is", "a", "test"]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def names
|
|
14
|
+
["one", "two", "three", "four"]
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def names
|
|
19
|
+
["one", "two", "three", "four"]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def to_s
|
|
23
|
+
"/this/is/a/test/"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def match(string)
|
|
27
|
+
::RegexpLookAlike::MatchData.new if string == "/this/is/a/test/"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
describe "Routing" do
|
|
32
|
+
before do
|
|
33
|
+
Tennpipes.clear!
|
|
34
|
+
ENV['RACK_BASE_URI'] = nil
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'should serve static files with simple cache control' do
|
|
38
|
+
mock_app do
|
|
39
|
+
set :static_cache_control, :public
|
|
40
|
+
set :public_folder, File.dirname(__FILE__)
|
|
41
|
+
end
|
|
42
|
+
get "/#{File.basename(__FILE__)}"
|
|
43
|
+
assert headers.has_key?('Cache-Control')
|
|
44
|
+
assert_equal headers['Cache-Control'], 'public'
|
|
45
|
+
end # static simple
|
|
46
|
+
|
|
47
|
+
it 'should serve static files with cache control and max_age' do
|
|
48
|
+
mock_app do
|
|
49
|
+
set :static_cache_control, [:public, :must_revalidate, {:max_age => 300}]
|
|
50
|
+
set :public_folder, File.dirname(__FILE__)
|
|
51
|
+
end
|
|
52
|
+
get "/#{File.basename(__FILE__)}"
|
|
53
|
+
assert headers.has_key?('Cache-Control')
|
|
54
|
+
assert_equal headers['Cache-Control'], 'public, must-revalidate, max-age=300'
|
|
55
|
+
end # static max_age
|
|
56
|
+
|
|
57
|
+
it 'should render static files with custom status via options' do
|
|
58
|
+
mock_app do
|
|
59
|
+
set :static, true
|
|
60
|
+
set :public_folder, File.dirname(__FILE__)
|
|
61
|
+
|
|
62
|
+
post '/*' do
|
|
63
|
+
static!(:status => params[:status])
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
post "/#{File.basename(__FILE__)}?status=422"
|
|
68
|
+
assert_equal response.status, 422
|
|
69
|
+
assert_equal File.size(__FILE__).to_s, response['Content-Length']
|
|
70
|
+
assert response.headers.include?('Last-Modified')
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it 'should ignore trailing delimiters for basic route' do
|
|
74
|
+
mock_app do
|
|
75
|
+
get("/foo"){ "okey" }
|
|
76
|
+
get(:test) { "tester" }
|
|
77
|
+
end
|
|
78
|
+
get "/foo"
|
|
79
|
+
assert_equal "okey", body
|
|
80
|
+
get "/foo/"
|
|
81
|
+
assert_equal "okey", body
|
|
82
|
+
get "/test"
|
|
83
|
+
assert_equal "tester", body
|
|
84
|
+
get "/test/"
|
|
85
|
+
assert_equal "tester", body
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it 'should fail with unrecognized route exception when not found' do
|
|
89
|
+
mock_app do
|
|
90
|
+
get(:index){ "okey" }
|
|
91
|
+
end
|
|
92
|
+
get @app.url_for(:index)
|
|
93
|
+
assert_equal "okey", body
|
|
94
|
+
assert_raises(Tennpipes::Routing::UnrecognizedException) {
|
|
95
|
+
get @app.url_for(:fake)
|
|
96
|
+
}
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it 'should fail with unrecognized route exception when namespace is invalid' do
|
|
100
|
+
mock_app do
|
|
101
|
+
controller :foo_bar do
|
|
102
|
+
get(:index){ "okey" }
|
|
103
|
+
get(:test_baz){ "okey" }
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
assert_equal "/foo_bar", @app.url_for(:foo_bar, :index)
|
|
107
|
+
assert_raises(Tennpipes::Routing::UnrecognizedException) {
|
|
108
|
+
get @app.url_for(:foo, :bar, :index)
|
|
109
|
+
}
|
|
110
|
+
assert_raises(Tennpipes::Routing::UnrecognizedException) {
|
|
111
|
+
get @app.url_for(:foo, :bar_index)
|
|
112
|
+
}
|
|
113
|
+
assert_equal "/foo_bar/test_baz", @app.url_for(:foo_bar, :test_baz)
|
|
114
|
+
assert_raises(Tennpipes::Routing::UnrecognizedException) {
|
|
115
|
+
get @app.url_for(:foo_bar, :test, :baz)
|
|
116
|
+
}
|
|
117
|
+
assert_raises(Tennpipes::Routing::UnrecognizedException) {
|
|
118
|
+
get @app.url_for(:foo, :bar_test, :baz)
|
|
119
|
+
}
|
|
120
|
+
assert_raises(Tennpipes::Routing::UnrecognizedException) {
|
|
121
|
+
get @app.url_for(:foo, :bar_test_baz)
|
|
122
|
+
}
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
it 'should accept regexp routes' do
|
|
126
|
+
mock_app do
|
|
127
|
+
get(%r./fob|/baz.) { "regexp" }
|
|
128
|
+
get("/foo") { "str" }
|
|
129
|
+
get %r./([0-9]+)/. do |num|
|
|
130
|
+
"Your lucky number: #{num} #{params[:captures].first}"
|
|
131
|
+
end
|
|
132
|
+
get %r./page/([0-9]+)|/. do |num|
|
|
133
|
+
"My lucky number: #{num} #{params[:captures].first}"
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
get "/foo"
|
|
137
|
+
assert_equal "str", body
|
|
138
|
+
get "/fob"
|
|
139
|
+
assert_equal "regexp", body
|
|
140
|
+
get "/baz"
|
|
141
|
+
assert_equal "regexp", body
|
|
142
|
+
get "/321/"
|
|
143
|
+
assert_equal "Your lucky number: 321 321", body
|
|
144
|
+
get "/page/99"
|
|
145
|
+
assert_equal "My lucky number: 99 99", body
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
it 'should accept regexp routes with generate with :generate_with' do
|
|
149
|
+
mock_app do
|
|
150
|
+
get(%r{/fob|/baz}, :name => :foo, :generate_with => '/fob') { "regexp" }
|
|
151
|
+
end
|
|
152
|
+
assert_equal "/fob", @app.url(:foo)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
it 'should parse routes with question marks' do
|
|
156
|
+
mock_app do
|
|
157
|
+
get("/foo/?"){ "okey" }
|
|
158
|
+
post('/unauthenticated/?') { "no access" }
|
|
159
|
+
end
|
|
160
|
+
get "/foo"
|
|
161
|
+
assert_equal "okey", body
|
|
162
|
+
get "/foo/"
|
|
163
|
+
assert_equal "okey", body
|
|
164
|
+
post "/unauthenticated"
|
|
165
|
+
assert_equal "no access", body
|
|
166
|
+
post "/unauthenticated/"
|
|
167
|
+
assert_equal "no access", body
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
it 'should parse routes that are encoded' do
|
|
171
|
+
mock_app do
|
|
172
|
+
get('/щч') { 'success!' }
|
|
173
|
+
end
|
|
174
|
+
get(URI.escape('/щч'))
|
|
175
|
+
assert_equal 'success!', body
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
it 'should parse routes that include encoded slash' do
|
|
179
|
+
mock_app do
|
|
180
|
+
get('/:drive_alias/:path', :path => /.*/){
|
|
181
|
+
"Show #{params[:drive_alias]} and #{params[:path]}"
|
|
182
|
+
}
|
|
183
|
+
end
|
|
184
|
+
get("/drive%2Ffoo/some/path")
|
|
185
|
+
assert_equal "Show drive/foo and some/path", body
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
it 'should encode params using UTF-8' do
|
|
189
|
+
mock_app do
|
|
190
|
+
get('/:foo') { params[:foo].encoding.name }
|
|
191
|
+
end
|
|
192
|
+
get '/bar'
|
|
193
|
+
assert_equal 'UTF-8', body
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
it 'should match correctly similar paths' do
|
|
197
|
+
mock_app do
|
|
198
|
+
get("/my/:foo_id"){ params[:foo_id] }
|
|
199
|
+
get("/my/:bar_id/bar"){ params[:bar_id] }
|
|
200
|
+
end
|
|
201
|
+
get "/my/1"
|
|
202
|
+
assert_equal "1", body
|
|
203
|
+
get "/my/2/bar"
|
|
204
|
+
assert_equal "2", body
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
it 'should match user agents' do
|
|
208
|
+
app = mock_app do
|
|
209
|
+
get("/main", :agent => /IE/){ "hello IE" }
|
|
210
|
+
get("/main"){ "hello" }
|
|
211
|
+
end
|
|
212
|
+
get "/main"
|
|
213
|
+
assert_equal "hello", body
|
|
214
|
+
get "/main", {}, {'HTTP_USER_AGENT' => 'This is IE'}
|
|
215
|
+
assert_equal "hello IE", body
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
it 'should use regex for parts of a route' do
|
|
219
|
+
app = mock_app do
|
|
220
|
+
get("/main/:id", :id => /\d+/){ "hello #{params[:id]}" }
|
|
221
|
+
end
|
|
222
|
+
get "/main/123"
|
|
223
|
+
assert_equal "hello 123", body
|
|
224
|
+
get "/main/asd"
|
|
225
|
+
assert_equal 404, status
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
it 'should parse params when use regex for parts of a route' do
|
|
229
|
+
mock_app do
|
|
230
|
+
post :index, :with => [:foo, :bar], :bar => /.+/ do
|
|
231
|
+
"show #{params[:foo]}"
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
get :index, :map => '/mystuff/:a_id/boing/:boing_id' do
|
|
235
|
+
"show #{params[:a_id]} and #{params[:boing_id]}"
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
get "/mystuff/5/boing/2"
|
|
239
|
+
assert_equal "show 5 and 2", body
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
it 'should not generate overlapping head urls' do
|
|
243
|
+
app = mock_app do
|
|
244
|
+
get("/main"){ "hello" }
|
|
245
|
+
post("/main"){ "hello" }
|
|
246
|
+
end
|
|
247
|
+
assert_equal 3, app.routes.size, "should generate GET, HEAD and PUT"
|
|
248
|
+
assert_equal "GET", app.routes[0].request_methods.first
|
|
249
|
+
assert_equal "HEAD", app.routes[1].request_methods.first
|
|
250
|
+
assert_equal "POST", app.routes[2].request_methods.first
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
it 'should generate basic urls' do
|
|
254
|
+
mock_app do
|
|
255
|
+
get(:foo){ "/foo" }
|
|
256
|
+
get(:foo, :with => :id){ |id| "/foo/#{id}" }
|
|
257
|
+
get([:foo, :id]){ |id| "/foo/#{id}" }
|
|
258
|
+
get(:hash, :with => :id){ url(:hash, :id => 1) }
|
|
259
|
+
get(:anchor) { url(:anchor, :anchor => 'comments') }
|
|
260
|
+
get(:fragment) { url(:anchor, :fragment => 'comments') }
|
|
261
|
+
get(:fragment2) { url(:anchor, :fragment => :comments) }
|
|
262
|
+
get([:hash, :id]){ url(:hash, :id => 1) }
|
|
263
|
+
get(:array, :with => :id){ url(:array, 23) }
|
|
264
|
+
get([:array, :id]){ url(:array, 23) }
|
|
265
|
+
get(:hash_with_extra, :with => :id){ url(:hash_with_extra, :id => 1, :query => 'string') }
|
|
266
|
+
get([:hash_with_extra, :id]){ url(:hash_with_extra, :id => 1, :query => 'string') }
|
|
267
|
+
get(:array_with_extra, :with => :id){ url(:array_with_extra, 23, :query => 'string') }
|
|
268
|
+
get([:array_with_extra, :id]){ url(:array_with_extra, 23, :query => 'string') }
|
|
269
|
+
get("/old-bar/:id"){ params[:id] }
|
|
270
|
+
post(:mix, :map => "/mix-bar/:id"){ params[:id] }
|
|
271
|
+
get(:mix, :map => "/mix-bar/:id"){ params[:id] }
|
|
272
|
+
get(:foo, '', :with => :id){ |id| "/#{id}" }
|
|
273
|
+
post(:foo, '', :with => :id){ |id| "/#{id}" }
|
|
274
|
+
delete(:drugs, :with => [:id, 'destroy']){ |id| "/drugs/#{id}/destroy" }
|
|
275
|
+
delete(:drugs, '', :with => [:id, 'destroy']){ |id| "/#{id}/destroy" }
|
|
276
|
+
get(:splatter, "/splatter/*/*"){ |a, b| url(:splatter, :splat => ["123", "456"]) }
|
|
277
|
+
end
|
|
278
|
+
get "/foo"
|
|
279
|
+
assert_equal "/foo", body
|
|
280
|
+
get "/foo/123"
|
|
281
|
+
assert_equal "/foo/123", body
|
|
282
|
+
get "/hash/2"
|
|
283
|
+
assert_equal "/hash/1", body
|
|
284
|
+
get "/anchor"
|
|
285
|
+
assert_equal "/anchor#comments", body
|
|
286
|
+
get "/fragment"
|
|
287
|
+
assert_equal "/anchor#comments", body
|
|
288
|
+
get "/fragment2"
|
|
289
|
+
assert_equal "/anchor#comments", body
|
|
290
|
+
get "/array/23"
|
|
291
|
+
assert_equal "/array/23", body
|
|
292
|
+
get "/hash_with_extra/1"
|
|
293
|
+
assert_equal "/hash_with_extra/1?query=string", body
|
|
294
|
+
get "/array_with_extra/23"
|
|
295
|
+
assert_equal "/array_with_extra/23?query=string", body
|
|
296
|
+
get "/old-bar/3"
|
|
297
|
+
assert_equal "3", body
|
|
298
|
+
post "/mix-bar/4"
|
|
299
|
+
assert_equal "4", body
|
|
300
|
+
get "/mix-bar/4"
|
|
301
|
+
assert_equal "4", body
|
|
302
|
+
get "/123"
|
|
303
|
+
assert_equal "/123", body
|
|
304
|
+
post "/123"
|
|
305
|
+
assert_equal "/123", body
|
|
306
|
+
delete "/drugs/123/destroy"
|
|
307
|
+
assert_equal "/drugs/123/destroy", body
|
|
308
|
+
delete "/123/destroy"
|
|
309
|
+
assert_equal "/123/destroy", body
|
|
310
|
+
get "/splatter/123/456"
|
|
311
|
+
assert_equal "/splatter/123/456", body
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
it 'should generate url with format' do
|
|
315
|
+
mock_app do
|
|
316
|
+
get(:a, :provides => :any){ url(:a, :format => :json) }
|
|
317
|
+
get(:b, :provides => :js){ url(:b, :format => :js) }
|
|
318
|
+
get(:c, :provides => [:js, :json]){ url(:c, :format => :json) }
|
|
319
|
+
get(:d, :provides => [:html, :js]){ url(:d, :format => :js, :foo => :bar) }
|
|
320
|
+
end
|
|
321
|
+
get "/a.js"
|
|
322
|
+
assert_equal "/a.json", body
|
|
323
|
+
get "/b.js"
|
|
324
|
+
assert_equal "/b.js", body
|
|
325
|
+
get "/b.ru"
|
|
326
|
+
assert_equal 404, status
|
|
327
|
+
get "/c.js"
|
|
328
|
+
assert_equal "/c.json", body
|
|
329
|
+
get "/c.json"
|
|
330
|
+
assert_equal "/c.json", body
|
|
331
|
+
get "/c.ru"
|
|
332
|
+
assert_equal 404, status
|
|
333
|
+
get "/d"
|
|
334
|
+
assert_equal "/d.js?foo=bar", body
|
|
335
|
+
get "/d.js"
|
|
336
|
+
assert_equal "/d.js?foo=bar", body
|
|
337
|
+
get "/e.xml"
|
|
338
|
+
assert_equal 404, status
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
it 'should generate absolute urls' do
|
|
342
|
+
mock_app do
|
|
343
|
+
get(:hash, :with => :id){ absolute_url(:hash, :id => 1) }
|
|
344
|
+
end
|
|
345
|
+
get "/hash/2"
|
|
346
|
+
assert_equal "http://example.org/hash/1", body
|
|
347
|
+
get "https://example.org/hash/2"
|
|
348
|
+
assert_equal "https://example.org/hash/1", body
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
it 'should generate absolute urls from stringified keys' do
|
|
352
|
+
mock_app do
|
|
353
|
+
get(:hash, with: :id) { absolute_url(:hash, "id" => 1) }
|
|
354
|
+
end
|
|
355
|
+
get "/hash/2"
|
|
356
|
+
assert_equal "http://example.org/hash/1", body
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
it 'should generate proper absolute urls for mounted apps' do
|
|
360
|
+
class Test < Tennpipes::Application
|
|
361
|
+
get :foo do
|
|
362
|
+
absolute_url(:foo, :id => 1)
|
|
363
|
+
end
|
|
364
|
+
end
|
|
365
|
+
Tennpipes.mount("Test").to("/test")
|
|
366
|
+
@app = Tennpipes.application
|
|
367
|
+
get('/test/foo')
|
|
368
|
+
assert_equal 'http://example.org/test/foo?id=1', body
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
it 'should rebase simple string urls to app uri_root' do
|
|
372
|
+
mock_app do
|
|
373
|
+
set :uri_root, '/app'
|
|
374
|
+
get(:a){ url('/foo') }
|
|
375
|
+
get(:b){ url('bar') }
|
|
376
|
+
get(:c){ absolute_url('/foo') }
|
|
377
|
+
get(:d, :map => '/d/e/f'){ absolute_url('bar') }
|
|
378
|
+
end
|
|
379
|
+
get "/a"
|
|
380
|
+
assert_equal "/app/foo", body
|
|
381
|
+
get "/b"
|
|
382
|
+
assert_equal "bar", body
|
|
383
|
+
get "/c"
|
|
384
|
+
assert_equal "http://example.org/app/foo", body
|
|
385
|
+
get "/d/e/f"
|
|
386
|
+
assert_equal "http://example.org/app/d/e/bar", body
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
it 'should allow regex url with format' do
|
|
390
|
+
mock_app do
|
|
391
|
+
get(/.*/, :provides => :any) { "regexp" }
|
|
392
|
+
end
|
|
393
|
+
get "/anything"
|
|
394
|
+
assert_equal "regexp", body
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
it 'should use tennpipes url method' do
|
|
398
|
+
mock_app do
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
assert_equal @app.method(:url).owner, Tennpipes::Routing::ClassMethods
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
it 'should work correctly with sinatra redirects' do
|
|
405
|
+
mock_app do
|
|
406
|
+
get(:index) { redirect url(:index) }
|
|
407
|
+
get(:google) { redirect "http://google.com" }
|
|
408
|
+
get("/foo") { redirect "/bar" }
|
|
409
|
+
get("/bar") { "Bar" }
|
|
410
|
+
end
|
|
411
|
+
|
|
412
|
+
get "/"
|
|
413
|
+
assert_equal "http://example.org/", headers['Location']
|
|
414
|
+
get "/google"
|
|
415
|
+
assert_equal "http://google.com", headers['Location']
|
|
416
|
+
get "/foo"
|
|
417
|
+
assert_equal "http://example.org/bar", headers['Location']
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
it 'should return 406 on Accept-Headers it does not provide' do
|
|
421
|
+
mock_app do
|
|
422
|
+
get(:a, :provides => [:html, :js]){ content_type }
|
|
423
|
+
end
|
|
424
|
+
|
|
425
|
+
get "/a", {}, {"HTTP_ACCEPT" => "application/yaml"}
|
|
426
|
+
assert_equal 406, status
|
|
427
|
+
end
|
|
428
|
+
|
|
429
|
+
it 'should return 406 on file extensions it does not provide and flag is set' do
|
|
430
|
+
mock_app do
|
|
431
|
+
enable :treat_format_as_accept
|
|
432
|
+
get(:a, :provides => [:html, :js]){ content_type }
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
get "/a.xml", {}, {}
|
|
436
|
+
assert_equal 406, status
|
|
437
|
+
end
|
|
438
|
+
|
|
439
|
+
it 'should return 404 on file extensions it does not provide and flag is not set' do
|
|
440
|
+
mock_app do
|
|
441
|
+
get(:a, :provides => [:html, :js]){ content_type }
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
get "/a.xml", {}, {}
|
|
445
|
+
assert_equal 404, status
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
it 'should not set content_type to :html if Accept */* and html not in provides' do
|
|
449
|
+
mock_app do
|
|
450
|
+
get("/foo", :provides => [:json, :xml]) { content_type.to_s }
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
get '/foo', {}, { 'HTTP_ACCEPT' => '*/*;q=0.5' }
|
|
454
|
+
assert_equal 'json', body
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
it 'should set content_type to :json if Accept contains */*' do
|
|
458
|
+
mock_app do
|
|
459
|
+
get("/foo", :provides => [:json]) { content_type.to_s }
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
get '/foo', {}, { 'HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' }
|
|
463
|
+
assert_equal 'json', body
|
|
464
|
+
end
|
|
465
|
+
|
|
466
|
+
it 'should set and get content_type' do
|
|
467
|
+
mock_app do
|
|
468
|
+
get("/foo"){ content_type(:json); content_type.to_s }
|
|
469
|
+
end
|
|
470
|
+
get "/foo"
|
|
471
|
+
assert_equal 'application/json', content_type
|
|
472
|
+
assert_equal 'json', body
|
|
473
|
+
end
|
|
474
|
+
|
|
475
|
+
it 'should send the appropriate number of params' do
|
|
476
|
+
mock_app do
|
|
477
|
+
get('/id/:user_id', :provides => [:json]) { |user_id, format| user_id}
|
|
478
|
+
end
|
|
479
|
+
get '/id/5.json'
|
|
480
|
+
assert_equal '5', body
|
|
481
|
+
end
|
|
482
|
+
|
|
483
|
+
it 'should allow "." in param values' do
|
|
484
|
+
mock_app do
|
|
485
|
+
get('/id/:email', :provides => [:json]) { |email, format| [email, format] * '/' }
|
|
486
|
+
end
|
|
487
|
+
get '/id/foo@bar.com.json'
|
|
488
|
+
assert_equal 'foo@bar.com/json', body
|
|
489
|
+
end
|
|
490
|
+
|
|
491
|
+
it 'should set correct content_type for Accept not equal to */* even if */* also provided' do
|
|
492
|
+
mock_app do
|
|
493
|
+
get("/foo", :provides => [:html, :js, :xml]) { content_type.to_s }
|
|
494
|
+
end
|
|
495
|
+
|
|
496
|
+
get '/foo', {}, { 'HTTP_ACCEPT' => 'application/javascript, */*;q=0.5' }
|
|
497
|
+
assert_equal 'js', body
|
|
498
|
+
end
|
|
499
|
+
|
|
500
|
+
it 'should return the first content type in provides if accept header is empty' do
|
|
501
|
+
mock_app do
|
|
502
|
+
get(:a, :provides => [:js]){ content_type.to_s }
|
|
503
|
+
end
|
|
504
|
+
|
|
505
|
+
get "/a", {}, {}
|
|
506
|
+
assert_equal "js", body
|
|
507
|
+
end
|
|
508
|
+
|
|
509
|
+
it 'should not default to HTML if HTML is not provided and no type is given' do
|
|
510
|
+
mock_app do
|
|
511
|
+
get(:a, :provides => [:js]){ content_type }
|
|
512
|
+
end
|
|
513
|
+
|
|
514
|
+
get "/a", {}, {}
|
|
515
|
+
assert_equal "application/javascript;charset=utf-8", content_type
|
|
516
|
+
end
|
|
517
|
+
|
|
518
|
+
it 'should not match routes if url_format and http_accept is provided but not included' do
|
|
519
|
+
mock_app do
|
|
520
|
+
get(:a, :provides => [:js, :html]){ content_type }
|
|
521
|
+
end
|
|
522
|
+
|
|
523
|
+
get "/a.xml", {}, {"HTTP_ACCEPT" => "text/html"}
|
|
524
|
+
assert_equal 404, status
|
|
525
|
+
end
|
|
526
|
+
|
|
527
|
+
it 'should generate routes for format simple' do
|
|
528
|
+
mock_app do
|
|
529
|
+
get(:foo, :provides => [:html, :rss]) { render :haml, "Test" }
|
|
530
|
+
end
|
|
531
|
+
get "/foo"
|
|
532
|
+
assert_equal "Test\n", body
|
|
533
|
+
get "/foo.rss"
|
|
534
|
+
assert_equal "Test\n", body
|
|
535
|
+
end
|
|
536
|
+
|
|
537
|
+
it 'should inject the controller name into the request' do
|
|
538
|
+
mock_app do
|
|
539
|
+
controller :posts do
|
|
540
|
+
get(:index) { request.controller }
|
|
541
|
+
controller :mini do
|
|
542
|
+
get(:index) { request.controller }
|
|
543
|
+
end
|
|
544
|
+
end
|
|
545
|
+
end
|
|
546
|
+
get "/posts"
|
|
547
|
+
assert_equal "posts", body
|
|
548
|
+
get "/mini"
|
|
549
|
+
assert_equal "mini", body
|
|
550
|
+
end
|
|
551
|
+
|
|
552
|
+
it 'should inject the action name into the request' do
|
|
553
|
+
mock_app do
|
|
554
|
+
controller :posts do
|
|
555
|
+
get('/omnomnom(/:id)?') { request.action.inspect }
|
|
556
|
+
controller :mini do
|
|
557
|
+
get([:a, :b, :c]) { request.action.inspect }
|
|
558
|
+
end
|
|
559
|
+
end
|
|
560
|
+
end
|
|
561
|
+
get "/posts/omnomnom"
|
|
562
|
+
assert_equal "\"/omnomnom(/:id)?\"", body
|
|
563
|
+
get "/mini/a/b/c"
|
|
564
|
+
assert_equal ":a", body
|
|
565
|
+
end
|
|
566
|
+
|
|
567
|
+
it 'should support not_found' do
|
|
568
|
+
mock_app do
|
|
569
|
+
not_found { 'whatever' }
|
|
570
|
+
|
|
571
|
+
get :index, :map => "/" do
|
|
572
|
+
'index'
|
|
573
|
+
end
|
|
574
|
+
end
|
|
575
|
+
get '/wrong'
|
|
576
|
+
assert_equal 404, status
|
|
577
|
+
assert_equal 'whatever', body
|
|
578
|
+
get '/'
|
|
579
|
+
assert_equal 'index', body
|
|
580
|
+
assert_equal 200, status
|
|
581
|
+
end
|
|
582
|
+
|
|
583
|
+
it 'should inject the route into the request' do
|
|
584
|
+
mock_app do
|
|
585
|
+
controller :posts do
|
|
586
|
+
get(:index) { request.route_obj.name.to_s }
|
|
587
|
+
end
|
|
588
|
+
end
|
|
589
|
+
get "/posts"
|
|
590
|
+
assert_equal "posts index", body
|
|
591
|
+
end
|
|
592
|
+
|
|
593
|
+
it 'should preserve the format if you set it manually' do
|
|
594
|
+
mock_app do
|
|
595
|
+
before do
|
|
596
|
+
params[:format] = "json"
|
|
597
|
+
end
|
|
598
|
+
|
|
599
|
+
get "test", :provides => [:html, :json] do
|
|
600
|
+
content_type.inspect
|
|
601
|
+
end
|
|
602
|
+
end
|
|
603
|
+
get "/test"
|
|
604
|
+
assert_equal ":json", body
|
|
605
|
+
get "/test.html"
|
|
606
|
+
assert_equal ":json", body
|
|
607
|
+
get "/test.php"
|
|
608
|
+
assert_equal ":json", body
|
|
609
|
+
end
|
|
610
|
+
|
|
611
|
+
it 'should correctly accept "." in the route' do
|
|
612
|
+
mock_app do
|
|
613
|
+
get "test.php", :provides => [:html, :json] do
|
|
614
|
+
content_type.inspect
|
|
615
|
+
end
|
|
616
|
+
end
|
|
617
|
+
get "/test.php"
|
|
618
|
+
assert_equal ":html", body
|
|
619
|
+
get "/test.php.json"
|
|
620
|
+
assert_equal ":json", body
|
|
621
|
+
end
|
|
622
|
+
|
|
623
|
+
it 'should correctly accept priority of format' do
|
|
624
|
+
mock_app do
|
|
625
|
+
get "test.php", :provides => [:html, :json, :xml] do
|
|
626
|
+
content_type.inspect
|
|
627
|
+
end
|
|
628
|
+
end
|
|
629
|
+
|
|
630
|
+
get "/test.php"
|
|
631
|
+
assert_equal ":html", body
|
|
632
|
+
get "/test.php", {}, { 'HTTP_ACCEPT' => 'application/xml' }
|
|
633
|
+
assert_equal ":xml", body
|
|
634
|
+
get "/test.php?format=json", { 'HTTP_ACCEPT' => 'application/xml' }
|
|
635
|
+
assert_equal ":json", body
|
|
636
|
+
get "/test.php.json?format=html", { 'HTTP_ACCEPT' => 'application/xml' }
|
|
637
|
+
assert_equal ":json", body
|
|
638
|
+
end
|
|
639
|
+
|
|
640
|
+
it 'should generate routes for format with controller' do
|
|
641
|
+
mock_app do
|
|
642
|
+
controller :posts do
|
|
643
|
+
get(:index, :provides => [:html, :rss, :atom, :js]) { render :haml, "Index.#{content_type}" }
|
|
644
|
+
get(:show, :with => :id, :provides => [:html, :rss, :atom]) { render :haml, "Show.#{content_type}" }
|
|
645
|
+
end
|
|
646
|
+
end
|
|
647
|
+
get "/posts"
|
|
648
|
+
assert_equal "Index.html\n", body
|
|
649
|
+
get "/posts.rss"
|
|
650
|
+
assert_equal "Index.rss\n", body
|
|
651
|
+
get "/posts.atom"
|
|
652
|
+
assert_equal "Index.atom\n", body
|
|
653
|
+
get "/posts.js"
|
|
654
|
+
assert_equal "Index.js\n", body
|
|
655
|
+
get "/posts/show/5"
|
|
656
|
+
assert_equal "Show.html\n", body
|
|
657
|
+
get "/posts/show/5.rss"
|
|
658
|
+
assert_equal "Show.rss\n", body
|
|
659
|
+
get "/posts/show/10.atom"
|
|
660
|
+
assert_equal "Show.atom\n", body
|
|
661
|
+
end
|
|
662
|
+
|
|
663
|
+
it 'should map routes' do
|
|
664
|
+
mock_app do
|
|
665
|
+
get(:bar){ "bar" }
|
|
666
|
+
end
|
|
667
|
+
get "/bar"
|
|
668
|
+
assert_equal "bar", body
|
|
669
|
+
assert_equal "/bar", @app.url(:bar)
|
|
670
|
+
end
|
|
671
|
+
|
|
672
|
+
it 'should remove index from path' do
|
|
673
|
+
mock_app do
|
|
674
|
+
get(:index){ "index" }
|
|
675
|
+
get("/accounts/index"){ "accounts" }
|
|
676
|
+
end
|
|
677
|
+
get "/"
|
|
678
|
+
assert_equal "index", body
|
|
679
|
+
assert_equal "/", @app.url(:index)
|
|
680
|
+
get "/accounts/index"
|
|
681
|
+
assert_equal "accounts", body
|
|
682
|
+
end
|
|
683
|
+
|
|
684
|
+
it 'should remove index from path with params' do
|
|
685
|
+
mock_app do
|
|
686
|
+
get(:index, :with => :name){ "index with #{params[:name]}" }
|
|
687
|
+
end
|
|
688
|
+
get "/bobby"
|
|
689
|
+
assert_equal "index with bobby", body
|
|
690
|
+
assert_equal "/john", @app.url(:index, :name => "john")
|
|
691
|
+
end
|
|
692
|
+
|
|
693
|
+
it 'should parse named params' do
|
|
694
|
+
mock_app do
|
|
695
|
+
get(:print, :with => :id){ "Im #{params[:id]}" }
|
|
696
|
+
end
|
|
697
|
+
get "/print/9"
|
|
698
|
+
assert_equal "Im 9", body
|
|
699
|
+
assert_equal "/print/9", @app.url(:print, :id => 9)
|
|
700
|
+
end
|
|
701
|
+
|
|
702
|
+
it 'should 405 on wrong request_method' do
|
|
703
|
+
mock_app do
|
|
704
|
+
post('/bar'){ "bar" }
|
|
705
|
+
end
|
|
706
|
+
get "/bar"
|
|
707
|
+
assert_equal 405, status
|
|
708
|
+
end
|
|
709
|
+
|
|
710
|
+
it 'should respond to' do
|
|
711
|
+
mock_app do
|
|
712
|
+
get(:a, :provides => :js){ "js" }
|
|
713
|
+
get(:b, :provides => :any){ "any" }
|
|
714
|
+
get(:c, :provides => [:js, :json]){ "js,json" }
|
|
715
|
+
get(:d, :provides => [:html, :js]){ "html,js"}
|
|
716
|
+
end
|
|
717
|
+
get "/a"
|
|
718
|
+
assert_equal 200, status
|
|
719
|
+
assert_equal "js", body
|
|
720
|
+
get "/a.js"
|
|
721
|
+
assert_equal "js", body
|
|
722
|
+
get "/b"
|
|
723
|
+
assert_equal "any", body
|
|
724
|
+
# TODO randomly fails in minitest :(
|
|
725
|
+
# assert_raises(RuntimeError) { get "/b.foo" }
|
|
726
|
+
get "/c"
|
|
727
|
+
assert_equal 200, status
|
|
728
|
+
assert_equal "js,json", body
|
|
729
|
+
get "/c.js"
|
|
730
|
+
assert_equal "js,json", body
|
|
731
|
+
get "/c.json"
|
|
732
|
+
assert_equal "js,json", body
|
|
733
|
+
get "/d"
|
|
734
|
+
assert_equal "html,js", body
|
|
735
|
+
get "/d.js"
|
|
736
|
+
assert_equal "html,js", body
|
|
737
|
+
end
|
|
738
|
+
|
|
739
|
+
it 'should respond_to and set content_type' do
|
|
740
|
+
Rack::Mime::MIME_TYPES['.foo'] = 'application/foo'
|
|
741
|
+
mock_app do
|
|
742
|
+
get :a, :provides => :any do
|
|
743
|
+
case content_type
|
|
744
|
+
when :js then "js"
|
|
745
|
+
when :json then "json"
|
|
746
|
+
when :foo then "foo"
|
|
747
|
+
when :html then "html"
|
|
748
|
+
end
|
|
749
|
+
end
|
|
750
|
+
end
|
|
751
|
+
get "/a.js"
|
|
752
|
+
assert_equal "js", body
|
|
753
|
+
assert_equal 'application/javascript;charset=utf-8', response["Content-Type"]
|
|
754
|
+
get "/a.json"
|
|
755
|
+
assert_equal "json", body
|
|
756
|
+
assert_equal 'application/json', response["Content-Type"]
|
|
757
|
+
get "/a.foo"
|
|
758
|
+
assert_equal "foo", body
|
|
759
|
+
assert_equal 'application/foo;charset=utf-8', response["Content-Type"]
|
|
760
|
+
get "/a"
|
|
761
|
+
assert_equal "html", body
|
|
762
|
+
assert_equal 'text/html;charset=utf-8', response["Content-Type"]
|
|
763
|
+
end
|
|
764
|
+
|
|
765
|
+
it 'should use controllers' do
|
|
766
|
+
mock_app do
|
|
767
|
+
controller "/admin" do
|
|
768
|
+
get("/"){ "index" }
|
|
769
|
+
get("/show/:id"){ "show #{params[:id]}" }
|
|
770
|
+
end
|
|
771
|
+
end
|
|
772
|
+
get "/admin"
|
|
773
|
+
assert_equal "index", body
|
|
774
|
+
get "/admin/show/1"
|
|
775
|
+
assert_equal "show 1", body
|
|
776
|
+
end
|
|
777
|
+
|
|
778
|
+
it 'should use named controllers' do
|
|
779
|
+
mock_app do
|
|
780
|
+
controller :admin do
|
|
781
|
+
get(:index, :with => :id){ params[:id] }
|
|
782
|
+
get(:show, :with => :id){ "show #{params[:id]}" }
|
|
783
|
+
end
|
|
784
|
+
controllers :foo, :bar do
|
|
785
|
+
get(:index){ "foo_bar_index" }
|
|
786
|
+
end
|
|
787
|
+
end
|
|
788
|
+
get "/admin/1"
|
|
789
|
+
assert_equal "1", body
|
|
790
|
+
get "/admin/show/1"
|
|
791
|
+
assert_equal "show 1", body
|
|
792
|
+
assert_equal "/admin/1", @app.url(:admin, :index, :id => 1)
|
|
793
|
+
assert_equal "/admin/show/1", @app.url(:admin, :show, :id => 1)
|
|
794
|
+
get "/foo/bar"
|
|
795
|
+
assert_equal "foo_bar_index", body
|
|
796
|
+
end
|
|
797
|
+
|
|
798
|
+
it 'should use map and with' do
|
|
799
|
+
mock_app do
|
|
800
|
+
get :index, :map => '/bugs', :with => :id do
|
|
801
|
+
params[:id]
|
|
802
|
+
end
|
|
803
|
+
end
|
|
804
|
+
get '/bugs/4'
|
|
805
|
+
assert_equal '4', body
|
|
806
|
+
assert_equal "/bugs/4", @app.url(:index, :id => 4)
|
|
807
|
+
end
|
|
808
|
+
|
|
809
|
+
it 'should ignore trailing delimiters within a named controller' do
|
|
810
|
+
mock_app do
|
|
811
|
+
controller :posts do
|
|
812
|
+
get(:index, :provides => [:html, :js]){ "index" }
|
|
813
|
+
get(:new) { "new" }
|
|
814
|
+
get(:show, :with => :id){ "show #{params[:id]}" }
|
|
815
|
+
end
|
|
816
|
+
end
|
|
817
|
+
get "/posts"
|
|
818
|
+
assert_equal "index", body
|
|
819
|
+
get "/posts/"
|
|
820
|
+
assert_equal "index", body
|
|
821
|
+
get "/posts.js"
|
|
822
|
+
assert_equal "index", body
|
|
823
|
+
get "/posts.js/"
|
|
824
|
+
assert_equal "index", body
|
|
825
|
+
get "/posts/new"
|
|
826
|
+
assert_equal "new", body
|
|
827
|
+
get "/posts/new/"
|
|
828
|
+
assert_equal "new", body
|
|
829
|
+
end
|
|
830
|
+
|
|
831
|
+
it 'should ignore trailing delimiters within a named controller for unnamed actions' do
|
|
832
|
+
mock_app do
|
|
833
|
+
controller :accounts do
|
|
834
|
+
get("/") { "account_index" }
|
|
835
|
+
get("/new") { "new" }
|
|
836
|
+
end
|
|
837
|
+
controller :votes do
|
|
838
|
+
get("/") { "vote_index" }
|
|
839
|
+
end
|
|
840
|
+
end
|
|
841
|
+
get "/accounts"
|
|
842
|
+
assert_equal "account_index", body
|
|
843
|
+
get "/accounts/"
|
|
844
|
+
assert_equal "account_index", body
|
|
845
|
+
get "/accounts/new"
|
|
846
|
+
assert_equal "new", body
|
|
847
|
+
get "/accounts/new/"
|
|
848
|
+
assert_equal "new", body
|
|
849
|
+
get "/votes"
|
|
850
|
+
assert_equal "vote_index", body
|
|
851
|
+
get "/votes/"
|
|
852
|
+
assert_equal "vote_index", body
|
|
853
|
+
end
|
|
854
|
+
|
|
855
|
+
it 'should use named controllers with array routes' do
|
|
856
|
+
mock_app do
|
|
857
|
+
controller :admin do
|
|
858
|
+
get(:index){ "index" }
|
|
859
|
+
get(:show, :with => :id){ "show #{params[:id]}" }
|
|
860
|
+
end
|
|
861
|
+
controllers :foo, :bar do
|
|
862
|
+
get(:index){ "foo_bar_index" }
|
|
863
|
+
end
|
|
864
|
+
end
|
|
865
|
+
get "/admin"
|
|
866
|
+
assert_equal "index", body
|
|
867
|
+
get "/admin/show/1"
|
|
868
|
+
assert_equal "show 1", body
|
|
869
|
+
assert_equal "/admin", @app.url(:admin, :index)
|
|
870
|
+
assert_equal "/admin/show/1", @app.url(:admin, :show, :id => 1)
|
|
871
|
+
get "/foo/bar"
|
|
872
|
+
assert_equal "foo_bar_index", body
|
|
873
|
+
end
|
|
874
|
+
|
|
875
|
+
it 'should support a reindex action and remove index inside controller' do
|
|
876
|
+
mock_app do
|
|
877
|
+
controller :posts do
|
|
878
|
+
get(:index){ "index" }
|
|
879
|
+
get(:reindex){ "reindex" }
|
|
880
|
+
end
|
|
881
|
+
end
|
|
882
|
+
get "/posts"
|
|
883
|
+
assert_equal "index", body
|
|
884
|
+
get "/posts/reindex"
|
|
885
|
+
assert_equal "/posts/reindex", @app.url(:posts, :reindex)
|
|
886
|
+
assert_equal "reindex", body
|
|
887
|
+
end
|
|
888
|
+
|
|
889
|
+
it 'should use uri_root' do
|
|
890
|
+
mock_app do
|
|
891
|
+
get(:foo){ "foo" }
|
|
892
|
+
end
|
|
893
|
+
@app.uri_root = '/'
|
|
894
|
+
assert_equal "/foo", @app.url(:foo)
|
|
895
|
+
@app.uri_root = '/testing'
|
|
896
|
+
assert_equal "/testing/foo", @app.url(:foo)
|
|
897
|
+
@app.uri_root = '/testing/'
|
|
898
|
+
assert_equal "/testing/foo", @app.url(:foo)
|
|
899
|
+
@app.uri_root = 'testing/bar///'
|
|
900
|
+
assert_equal "/testing/bar/foo", @app.url(:foo)
|
|
901
|
+
end
|
|
902
|
+
|
|
903
|
+
it 'should use uri_root with controllers' do
|
|
904
|
+
mock_app do
|
|
905
|
+
controller :foo do
|
|
906
|
+
get(:bar){ "bar" }
|
|
907
|
+
end
|
|
908
|
+
end
|
|
909
|
+
@app.uri_root = '/testing'
|
|
910
|
+
assert_equal "/testing/foo/bar", @app.url(:foo, :bar)
|
|
911
|
+
end
|
|
912
|
+
|
|
913
|
+
it 'should use RACK_BASE_URI' do
|
|
914
|
+
mock_app do
|
|
915
|
+
get(:foo){ "foo" }
|
|
916
|
+
end
|
|
917
|
+
# Wish there was a side-effect free way to test this...
|
|
918
|
+
ENV['RACK_BASE_URI'] = '/'
|
|
919
|
+
assert_equal "/foo", @app.url(:foo)
|
|
920
|
+
ENV['RACK_BASE_URI'] = '/testing'
|
|
921
|
+
assert_equal "/testing/foo", @app.url(:foo)
|
|
922
|
+
ENV['RACK_BASE_URI'] = nil
|
|
923
|
+
end
|
|
924
|
+
|
|
925
|
+
it 'should use uri_root and RACK_BASE_URI' do
|
|
926
|
+
mock_app do
|
|
927
|
+
controller :foo do
|
|
928
|
+
get(:bar){ "bar" }
|
|
929
|
+
end
|
|
930
|
+
end
|
|
931
|
+
ENV['RACK_BASE_URI'] = '/base'
|
|
932
|
+
@app.uri_root = 'testing'
|
|
933
|
+
assert_equal '/base/testing/foo/bar', @app.url(:foo, :bar)
|
|
934
|
+
ENV['RACK_BASE_URI'] = nil
|
|
935
|
+
end
|
|
936
|
+
|
|
937
|
+
it 'should reset routes' do
|
|
938
|
+
mock_app do
|
|
939
|
+
get("/"){ "foo" }
|
|
940
|
+
reset_router!
|
|
941
|
+
end
|
|
942
|
+
get "/"
|
|
943
|
+
assert_equal 404, status
|
|
944
|
+
end
|
|
945
|
+
|
|
946
|
+
it 'should match params and format' do
|
|
947
|
+
app = mock_app do
|
|
948
|
+
get '/:id', :provides => [:json, :html] do |id, _|
|
|
949
|
+
id
|
|
950
|
+
end
|
|
951
|
+
|
|
952
|
+
get 'format/:id', :provides => [:json, :html] do |id, format|
|
|
953
|
+
format
|
|
954
|
+
end
|
|
955
|
+
end
|
|
956
|
+
|
|
957
|
+
get '/123.html'
|
|
958
|
+
assert_equal '123', body
|
|
959
|
+
|
|
960
|
+
get 'format/123.html'
|
|
961
|
+
assert_equal 'html', body
|
|
962
|
+
end
|
|
963
|
+
|
|
964
|
+
|
|
965
|
+
it 'should respect priorities' do
|
|
966
|
+
route_order = []
|
|
967
|
+
mock_app do
|
|
968
|
+
get(:index, :priority => :normal) { route_order << :normal; pass }
|
|
969
|
+
get(:index, :priority => :low) { route_order << :low; "hello" }
|
|
970
|
+
get(:index, :priority => :high) { route_order << :high; pass }
|
|
971
|
+
end
|
|
972
|
+
get '/'
|
|
973
|
+
assert_equal [:high, :normal, :low], route_order
|
|
974
|
+
assert_equal "hello", body
|
|
975
|
+
end
|
|
976
|
+
|
|
977
|
+
it 'should set the params correctly even if using prioritized routes' do
|
|
978
|
+
mock_app do
|
|
979
|
+
get("*__sinatra__/:image.png"){}
|
|
980
|
+
get "/:primary/:secondary", :priority => :low do
|
|
981
|
+
"#{params[:primary]} #{params[:secondary]}"
|
|
982
|
+
end
|
|
983
|
+
end
|
|
984
|
+
get "/abc/def"
|
|
985
|
+
assert_equal "abc def", body
|
|
986
|
+
end
|
|
987
|
+
|
|
988
|
+
it 'should catch all after controllers' do
|
|
989
|
+
mock_app do
|
|
990
|
+
get(:index, :with => :slug, :priority => :low) { "catch all" }
|
|
991
|
+
controllers :contact do
|
|
992
|
+
get(:index) { "contact"}
|
|
993
|
+
end
|
|
994
|
+
end
|
|
995
|
+
get "/contact"
|
|
996
|
+
assert_equal "contact", body
|
|
997
|
+
get "/foo"
|
|
998
|
+
assert_equal "catch all", body
|
|
999
|
+
end
|
|
1000
|
+
|
|
1001
|
+
it 'should allow optionals' do
|
|
1002
|
+
mock_app do
|
|
1003
|
+
get(:show, :map => "/stories/:type(/:category)?") do
|
|
1004
|
+
"#{params[:type]}/#{params[:category]}"
|
|
1005
|
+
end
|
|
1006
|
+
end
|
|
1007
|
+
get "/stories/foo"
|
|
1008
|
+
assert_equal "foo/", body
|
|
1009
|
+
get "/stories/foo/bar"
|
|
1010
|
+
assert_equal "foo/bar", body
|
|
1011
|
+
end
|
|
1012
|
+
|
|
1013
|
+
it 'should apply maps' do
|
|
1014
|
+
mock_app do
|
|
1015
|
+
controllers :admin do
|
|
1016
|
+
get(:index, :map => "/"){ "index" }
|
|
1017
|
+
get(:show, :with => :id, :map => "/show"){ "show #{params[:id]}" }
|
|
1018
|
+
get(:edit, :map => "/edit/:id/product"){ "edit #{params[:id]}" }
|
|
1019
|
+
get(:wacky, :map => "/wacky-:id-:product_id"){ "wacky #{params[:id]}-#{params[:product_id]}" }
|
|
1020
|
+
end
|
|
1021
|
+
end
|
|
1022
|
+
get "/"
|
|
1023
|
+
assert_equal "index", body
|
|
1024
|
+
get @app.url(:admin, :index)
|
|
1025
|
+
assert_equal "index", body
|
|
1026
|
+
get "/show/1"
|
|
1027
|
+
assert_equal "show 1", body
|
|
1028
|
+
get "/edit/1/product"
|
|
1029
|
+
assert_equal "edit 1", body
|
|
1030
|
+
get "/wacky-1-2"
|
|
1031
|
+
assert_equal "wacky 1-2", body
|
|
1032
|
+
end
|
|
1033
|
+
|
|
1034
|
+
it 'should apply maps when given path is kind of hash' do
|
|
1035
|
+
mock_app do
|
|
1036
|
+
controllers :admin do
|
|
1037
|
+
get(:foobar, "/foo/bar"){ "foobar" }
|
|
1038
|
+
end
|
|
1039
|
+
end
|
|
1040
|
+
get "/foo/bar"
|
|
1041
|
+
assert_equal "foobar", body
|
|
1042
|
+
end
|
|
1043
|
+
|
|
1044
|
+
it 'should apply parent to route' do
|
|
1045
|
+
mock_app do
|
|
1046
|
+
controllers :project do
|
|
1047
|
+
get(:index, :parent => :user) { "index #{params[:user_id]}" }
|
|
1048
|
+
get(:index, :parent => [:user, :section]) { "index #{params[:user_id]} #{params[:section_id]}" }
|
|
1049
|
+
get(:edit, :with => :id, :parent => :user) { "edit #{params[:id]} #{params[:user_id]}"}
|
|
1050
|
+
get(:show, :with => :id, :parent => [:user, :product]) { "show #{params[:id]} #{params[:user_id]} #{params[:product_id]}"}
|
|
1051
|
+
end
|
|
1052
|
+
end
|
|
1053
|
+
get "/user/1/project"
|
|
1054
|
+
assert_equal "index 1", body
|
|
1055
|
+
get "/user/1/section/3/project"
|
|
1056
|
+
assert_equal "index 1 3", body
|
|
1057
|
+
get "/user/1/project/edit/2"
|
|
1058
|
+
assert_equal "edit 2 1", body
|
|
1059
|
+
get "/user/1/product/2/project/show/3"
|
|
1060
|
+
assert_equal "show 3 1 2", body
|
|
1061
|
+
end
|
|
1062
|
+
|
|
1063
|
+
it 'should respect parent precedence: controllers parents go before route parents' do
|
|
1064
|
+
mock_app do
|
|
1065
|
+
controllers :project do
|
|
1066
|
+
get(:index, :parent => :user) { "index #{params[:user_id]}" }
|
|
1067
|
+
end
|
|
1068
|
+
|
|
1069
|
+
controllers :bar, :parent => :foo do
|
|
1070
|
+
get(:index) { "index on foo #{params[:foo_id]} @ bar" }
|
|
1071
|
+
get(:index, :parent => :baz) { "index on foo #{params[:foo_id]} @ baz #{params[:baz_id]} @ bar" }
|
|
1072
|
+
end
|
|
1073
|
+
end
|
|
1074
|
+
|
|
1075
|
+
get "/user/1/project"
|
|
1076
|
+
assert_equal "index 1", body
|
|
1077
|
+
get "/foo/1/bar"
|
|
1078
|
+
assert_equal "index on foo 1 @ bar", body
|
|
1079
|
+
get "/foo/1/baz/2/bar"
|
|
1080
|
+
assert_equal "index on foo 1 @ baz 2 @ bar", body
|
|
1081
|
+
end
|
|
1082
|
+
|
|
1083
|
+
it 'should keep a reference to the parent on the route' do
|
|
1084
|
+
mock_app do
|
|
1085
|
+
controllers :project do
|
|
1086
|
+
get(:index, :parent => :user) { "index #{params[:user_id]}" }
|
|
1087
|
+
get(:index, :parent => [:user, :section]) { "index #{params[:user_id]} #{params[:section_id]}" }
|
|
1088
|
+
get(:edit, :with => :id, :parent => :user) { "edit #{params[:id]} #{params[:user_id]}"}
|
|
1089
|
+
get(:show, :with => :id, :parent => [:user, :product]) { "show #{params[:id]} #{params[:user_id]} #{params[:product_id]}"}
|
|
1090
|
+
end
|
|
1091
|
+
|
|
1092
|
+
controllers :bar, :parent => :foo do
|
|
1093
|
+
get(:index) { "index on foo/bar" }
|
|
1094
|
+
get(:index, :parent => :baz) { "index on foo/baz/bar" }
|
|
1095
|
+
end
|
|
1096
|
+
end
|
|
1097
|
+
|
|
1098
|
+
# get "/user/1/project"
|
|
1099
|
+
assert_equal :user, @app.routes[0].parent
|
|
1100
|
+
# get "/user/1/section/3/project"
|
|
1101
|
+
assert_equal [:user, :section], @app.routes[2].parent
|
|
1102
|
+
# get "/user/1/project/edit/2"
|
|
1103
|
+
assert_equal :user, @app.routes[4].parent
|
|
1104
|
+
# get "/user/1/product/2/project/show/3"
|
|
1105
|
+
assert_equal [:user, :product], @app.routes[6].parent
|
|
1106
|
+
# get "/foo/1/bar"
|
|
1107
|
+
assert_equal :foo, @app.routes[8].parent
|
|
1108
|
+
# get "/foo/1/baz/2/bar"
|
|
1109
|
+
assert_equal [:foo, :baz], @app.routes[10].parent
|
|
1110
|
+
end
|
|
1111
|
+
|
|
1112
|
+
it 'should apply parent to controller' do
|
|
1113
|
+
mock_app do
|
|
1114
|
+
controller :project, :parent => :user do
|
|
1115
|
+
get(:index) { "index #{params[:user_id]}"}
|
|
1116
|
+
get(:edit, :with => :id, :parent => :user) { "edit #{params[:id]} #{params[:user_id]}"}
|
|
1117
|
+
get(:show, :with => :id, :parent => :product) { "show #{params[:id]} #{params[:user_id]} #{params[:product_id]}"}
|
|
1118
|
+
end
|
|
1119
|
+
end
|
|
1120
|
+
|
|
1121
|
+
user_project_url = "/user/1/project"
|
|
1122
|
+
get user_project_url
|
|
1123
|
+
assert_equal "index 1", body
|
|
1124
|
+
assert_equal user_project_url, @app.url(:project, :index, :user_id => 1)
|
|
1125
|
+
|
|
1126
|
+
user_project_edit_url = "/user/1/project/edit/2"
|
|
1127
|
+
get user_project_edit_url
|
|
1128
|
+
assert_equal "edit 2 1", body
|
|
1129
|
+
assert_equal user_project_edit_url, @app.url(:project, :edit, :user_id => 1, :id => 2)
|
|
1130
|
+
|
|
1131
|
+
user_product_project_url = "/user/1/product/2/project/show/3"
|
|
1132
|
+
get user_product_project_url
|
|
1133
|
+
assert_equal "show 3 1 2", body
|
|
1134
|
+
assert_equal user_product_project_url, @app.url(:project, :show, :user_id => 1, :product_id => 2, :id => 3)
|
|
1135
|
+
end
|
|
1136
|
+
|
|
1137
|
+
it 'should apply parent with shallowing to controller' do
|
|
1138
|
+
mock_app do
|
|
1139
|
+
controller :project do
|
|
1140
|
+
parent :user
|
|
1141
|
+
parent :shop, :optional => true
|
|
1142
|
+
get(:index) { "index #{params[:user_id]} #{params[:shop_id]}" }
|
|
1143
|
+
get(:edit, :with => :id) { "edit #{params[:id]} #{params[:user_id]} #{params[:shop_id]}" }
|
|
1144
|
+
get(:show, :with => :id, :parent => :product) { "show #{params[:id]} #{params[:user_id]} #{params[:product_id]} #{params[:shop_id]}" }
|
|
1145
|
+
end
|
|
1146
|
+
end
|
|
1147
|
+
|
|
1148
|
+
assert_equal "/user/1/project", @app.url(:project, :index, :user_id => 1, :shop_id => nil)
|
|
1149
|
+
assert_equal "/user/1/shop/23/project", @app.url(:project, :index, :user_id => 1, :shop_id => 23)
|
|
1150
|
+
|
|
1151
|
+
user_project_url = "/user/1/project"
|
|
1152
|
+
get user_project_url
|
|
1153
|
+
assert_equal "index 1 ", body
|
|
1154
|
+
assert_equal user_project_url, @app.url(:project, :index, :user_id => 1)
|
|
1155
|
+
|
|
1156
|
+
user_project_edit_url = "/user/1/project/edit/2"
|
|
1157
|
+
get user_project_edit_url
|
|
1158
|
+
assert_equal "edit 2 1 ", body
|
|
1159
|
+
assert_equal user_project_edit_url, @app.url(:project, :edit, :user_id => 1, :id => 2)
|
|
1160
|
+
|
|
1161
|
+
user_product_project_url = "/user/1/product/2/project/show/3"
|
|
1162
|
+
get user_product_project_url
|
|
1163
|
+
assert_equal "show 3 1 2 ", body
|
|
1164
|
+
assert_equal user_product_project_url, @app.url(:project, :show, :user_id => 1, :product_id => 2, :id => 3)
|
|
1165
|
+
|
|
1166
|
+
user_project_url = "/user/1/shop/1/project"
|
|
1167
|
+
get user_project_url
|
|
1168
|
+
assert_equal "index 1 1", body
|
|
1169
|
+
assert_equal user_project_url, @app.url(:project, :index, :user_id => 1, :shop_id => 1)
|
|
1170
|
+
|
|
1171
|
+
user_project_edit_url = "/user/1/shop/1/project/edit/2"
|
|
1172
|
+
get user_project_edit_url
|
|
1173
|
+
assert_equal "edit 2 1 1", body
|
|
1174
|
+
assert_equal user_project_edit_url, @app.url(:project, :edit, :user_id => 1, :id => 2, :shop_id => 1)
|
|
1175
|
+
|
|
1176
|
+
user_product_project_url = "/user/1/shop/1/product/2/project/show/3"
|
|
1177
|
+
get user_product_project_url
|
|
1178
|
+
assert_equal "show 3 1 2 1", body
|
|
1179
|
+
assert_equal user_product_project_url, @app.url(:project, :show, :user_id => 1, :product_id => 2, :id => 3, :shop_id => 1)
|
|
1180
|
+
end
|
|
1181
|
+
|
|
1182
|
+
it 'should respect map in parents with shallowing' do
|
|
1183
|
+
mock_app do
|
|
1184
|
+
controller :project do
|
|
1185
|
+
parent :shop, :map => "/foo/bar"
|
|
1186
|
+
get(:index) { "index #{params[:shop_id]}" }
|
|
1187
|
+
end
|
|
1188
|
+
end
|
|
1189
|
+
|
|
1190
|
+
shop_project_url = "/foo/bar/1/project"
|
|
1191
|
+
get shop_project_url
|
|
1192
|
+
assert_equal "index 1", body
|
|
1193
|
+
assert_equal shop_project_url, @app.url(:project, :index, :shop_id => 1)
|
|
1194
|
+
end
|
|
1195
|
+
|
|
1196
|
+
it 'should use default values' do
|
|
1197
|
+
mock_app do
|
|
1198
|
+
controller :lang => :it do
|
|
1199
|
+
get(:index, :map => "/:lang") { "lang is #{params[:lang]}" }
|
|
1200
|
+
end
|
|
1201
|
+
# This is only for be sure that default values
|
|
1202
|
+
# work only for the given controller
|
|
1203
|
+
get(:foo, :map => "/foo") {}
|
|
1204
|
+
end
|
|
1205
|
+
assert_equal "/it", @app.url(:index)
|
|
1206
|
+
assert_equal "/foo", @app.url(:foo)
|
|
1207
|
+
get "/en"
|
|
1208
|
+
assert_equal "lang is en", body
|
|
1209
|
+
end
|
|
1210
|
+
|
|
1211
|
+
it 'should transitions to the next matching route on pass' do
|
|
1212
|
+
mock_app do
|
|
1213
|
+
get '/:foo' do
|
|
1214
|
+
pass
|
|
1215
|
+
'Hello Foo'
|
|
1216
|
+
end
|
|
1217
|
+
get '/:bar' do
|
|
1218
|
+
'Hello World'
|
|
1219
|
+
end
|
|
1220
|
+
end
|
|
1221
|
+
|
|
1222
|
+
get '/za'
|
|
1223
|
+
assert_equal 'Hello World', body
|
|
1224
|
+
end
|
|
1225
|
+
|
|
1226
|
+
it 'should filters by media type' do
|
|
1227
|
+
mock_app do
|
|
1228
|
+
get '/foo', :accepts => [:xml, :json] do
|
|
1229
|
+
request.env['CONTENT_TYPE']
|
|
1230
|
+
end
|
|
1231
|
+
end
|
|
1232
|
+
|
|
1233
|
+
get '/foo', {}, { 'CONTENT_TYPE' => 'application/xml' }
|
|
1234
|
+
assert ok?
|
|
1235
|
+
assert_equal 'application/xml', body
|
|
1236
|
+
assert_equal 'application/xml;charset=utf-8', response.headers['Content-Type']
|
|
1237
|
+
get '/foo'
|
|
1238
|
+
assert_equal 406, status
|
|
1239
|
+
get '/foo.xml'
|
|
1240
|
+
assert_equal 404, status
|
|
1241
|
+
|
|
1242
|
+
get '/foo', {}, { 'CONTENT_TYPE' => 'application/json' }
|
|
1243
|
+
assert ok?
|
|
1244
|
+
assert_equal 'application/json', body
|
|
1245
|
+
assert_equal 'application/json', response.headers['Content-Type']
|
|
1246
|
+
end
|
|
1247
|
+
|
|
1248
|
+
it 'should filters by media type when using :accepts as controller option' do
|
|
1249
|
+
mock_app do
|
|
1250
|
+
controller accepts: [:xml, :js] do
|
|
1251
|
+
get '/foo' do
|
|
1252
|
+
request.env['CONTENT_TYPE']
|
|
1253
|
+
end
|
|
1254
|
+
end
|
|
1255
|
+
end
|
|
1256
|
+
|
|
1257
|
+
get '/foo', {}, { 'CONTENT_TYPE' => 'application/javascript' }
|
|
1258
|
+
assert ok?
|
|
1259
|
+
assert_equal 'application/javascript', body
|
|
1260
|
+
end
|
|
1261
|
+
|
|
1262
|
+
it 'should filters by accept header' do
|
|
1263
|
+
mock_app do
|
|
1264
|
+
get '/foo', :provides => [:xml, :js] do
|
|
1265
|
+
request.env['HTTP_ACCEPT']
|
|
1266
|
+
end
|
|
1267
|
+
end
|
|
1268
|
+
|
|
1269
|
+
get '/foo', {}, { 'HTTP_ACCEPT' => 'application/xml' }
|
|
1270
|
+
assert ok?
|
|
1271
|
+
assert_equal 'application/xml', body
|
|
1272
|
+
assert_equal 'application/xml;charset=utf-8', response.headers['Content-Type']
|
|
1273
|
+
|
|
1274
|
+
get '/foo.xml'
|
|
1275
|
+
assert ok?
|
|
1276
|
+
assert_equal 'application/xml;charset=utf-8', response.headers['Content-Type']
|
|
1277
|
+
|
|
1278
|
+
get '/foo', {}, { 'HTTP_ACCEPT' => 'application/javascript' }
|
|
1279
|
+
assert ok?
|
|
1280
|
+
assert_equal 'application/javascript', body
|
|
1281
|
+
assert_equal 'application/javascript;charset=utf-8', response.headers['Content-Type']
|
|
1282
|
+
|
|
1283
|
+
get '/foo.js'
|
|
1284
|
+
assert ok?
|
|
1285
|
+
assert_equal 'application/javascript;charset=utf-8', response.headers['Content-Type']
|
|
1286
|
+
|
|
1287
|
+
get '/foo', {}, { "HTTP_ACCEPT" => 'text/html' }
|
|
1288
|
+
assert_equal 406, status
|
|
1289
|
+
end
|
|
1290
|
+
|
|
1291
|
+
it 'should does not allow global provides' do
|
|
1292
|
+
mock_app do
|
|
1293
|
+
provides :xml
|
|
1294
|
+
|
|
1295
|
+
get("/foo"){ "Foo in #{content_type.inspect}" }
|
|
1296
|
+
get("/bar"){ "Bar in #{content_type.inspect}" }
|
|
1297
|
+
end
|
|
1298
|
+
|
|
1299
|
+
get '/foo', {}, { 'HTTP_ACCEPT' => 'application/xml' }
|
|
1300
|
+
assert_equal 'Foo in :xml', body
|
|
1301
|
+
get '/foo'
|
|
1302
|
+
assert_equal 'Foo in :xml', body
|
|
1303
|
+
|
|
1304
|
+
get '/bar', {}, { 'HTTP_ACCEPT' => 'application/xml' }
|
|
1305
|
+
assert_equal 'Bar in nil', body
|
|
1306
|
+
end
|
|
1307
|
+
|
|
1308
|
+
it 'should does not allow global provides in controller' do
|
|
1309
|
+
mock_app do
|
|
1310
|
+
controller :base do
|
|
1311
|
+
provides :xml
|
|
1312
|
+
|
|
1313
|
+
get(:foo, "/foo"){ "Foo in #{content_type.inspect}" }
|
|
1314
|
+
get(:bar, "/bar"){ "Bar in #{content_type.inspect}" }
|
|
1315
|
+
end
|
|
1316
|
+
end
|
|
1317
|
+
|
|
1318
|
+
get '/foo', {}, { 'HTTP_ACCEPT' => 'application/xml' }
|
|
1319
|
+
assert_equal 'Foo in :xml', body
|
|
1320
|
+
get '/foo'
|
|
1321
|
+
assert_equal 'Foo in :xml', body
|
|
1322
|
+
|
|
1323
|
+
get '/bar', {}, { 'HTTP_ACCEPT' => 'application/xml' }
|
|
1324
|
+
assert_equal 'Bar in nil', body
|
|
1325
|
+
end
|
|
1326
|
+
|
|
1327
|
+
it 'should map non named routes in controllers' do
|
|
1328
|
+
mock_app do
|
|
1329
|
+
controller :base do
|
|
1330
|
+
get("/foo") { "ok" }
|
|
1331
|
+
get("/bar") { "ok" }
|
|
1332
|
+
end
|
|
1333
|
+
end
|
|
1334
|
+
|
|
1335
|
+
get "/base/foo"
|
|
1336
|
+
assert ok?
|
|
1337
|
+
get "/base/bar"
|
|
1338
|
+
assert ok?
|
|
1339
|
+
end
|
|
1340
|
+
|
|
1341
|
+
it 'should set content_type to :html for both empty Accept as well as Accept text/html' do
|
|
1342
|
+
mock_app do
|
|
1343
|
+
provides :html
|
|
1344
|
+
|
|
1345
|
+
get("/foo"){ content_type.to_s }
|
|
1346
|
+
end
|
|
1347
|
+
|
|
1348
|
+
get '/foo', {}, {}
|
|
1349
|
+
assert_equal 'html', body
|
|
1350
|
+
|
|
1351
|
+
get '/foo', {}, { 'HTTP_ACCEPT' => 'text/html' }
|
|
1352
|
+
assert_equal 'html', body
|
|
1353
|
+
end
|
|
1354
|
+
|
|
1355
|
+
it 'should set content_type to :html if Accept */*' do
|
|
1356
|
+
mock_app do
|
|
1357
|
+
get("/foo", :provides => [:html, :js]) { content_type.to_s }
|
|
1358
|
+
end
|
|
1359
|
+
get '/foo', {}, {}
|
|
1360
|
+
assert_equal 'html', body
|
|
1361
|
+
|
|
1362
|
+
get '/foo', {}, { 'HTTP_ACCEPT' => '*/*;q=0.5' }
|
|
1363
|
+
assert_equal 'html', body
|
|
1364
|
+
end
|
|
1365
|
+
|
|
1366
|
+
it 'should set content_type to :js if Accept includes both application/javascript and */*;q=0.5' do
|
|
1367
|
+
mock_app do
|
|
1368
|
+
get("/foo", :provides => [:html, :js]) { content_type.to_s }
|
|
1369
|
+
end
|
|
1370
|
+
get '/foo', {}, { 'HTTP_ACCEPT' => 'application/javascript, */*;q=0.5' }
|
|
1371
|
+
assert_equal 'js', body
|
|
1372
|
+
end
|
|
1373
|
+
|
|
1374
|
+
it 'should set content_type to :html if Accept */* and provides of :any' do
|
|
1375
|
+
mock_app do
|
|
1376
|
+
get("/foo", :provides => :any) { content_type.to_s }
|
|
1377
|
+
end
|
|
1378
|
+
|
|
1379
|
+
get '/foo', {}, { 'HTTP_ACCEPT' => '*/*' }
|
|
1380
|
+
assert_equal 'html', body
|
|
1381
|
+
end
|
|
1382
|
+
|
|
1383
|
+
it 'should set content_type to :js if Accept includes both application/javascript, */*;q=0.5 and provides of :any' do
|
|
1384
|
+
mock_app do
|
|
1385
|
+
get("/foo", :provides => :any) { content_type.to_s }
|
|
1386
|
+
end
|
|
1387
|
+
|
|
1388
|
+
get '/foo', {}, { 'HTTP_ACCEPT' => 'application/javascript, */*;q=0.5' }
|
|
1389
|
+
assert_equal 'js', body
|
|
1390
|
+
end
|
|
1391
|
+
|
|
1392
|
+
it 'should allows custom route-conditions to be set via route options and halt' do
|
|
1393
|
+
protector = Module.new do
|
|
1394
|
+
def protect(*args)
|
|
1395
|
+
condition {
|
|
1396
|
+
unless authorize(params["user"], params["password"])
|
|
1397
|
+
halt 403, "go away"
|
|
1398
|
+
end
|
|
1399
|
+
}
|
|
1400
|
+
end
|
|
1401
|
+
end
|
|
1402
|
+
|
|
1403
|
+
mock_app do
|
|
1404
|
+
register protector
|
|
1405
|
+
|
|
1406
|
+
helpers do
|
|
1407
|
+
def authorize(username, password)
|
|
1408
|
+
username == "foo" && password == "bar"
|
|
1409
|
+
end
|
|
1410
|
+
end
|
|
1411
|
+
|
|
1412
|
+
get "/", :protect => true do
|
|
1413
|
+
"hey"
|
|
1414
|
+
end
|
|
1415
|
+
end
|
|
1416
|
+
|
|
1417
|
+
get "/"
|
|
1418
|
+
assert forbidden?
|
|
1419
|
+
assert_equal "go away", body
|
|
1420
|
+
|
|
1421
|
+
get "/", :user => "foo", :password => "bar"
|
|
1422
|
+
assert ok?
|
|
1423
|
+
assert_equal "hey", body
|
|
1424
|
+
end
|
|
1425
|
+
|
|
1426
|
+
it 'should allows custom route-conditions to be set via route options using two routes' do
|
|
1427
|
+
protector = Module.new do
|
|
1428
|
+
def protect(*args)
|
|
1429
|
+
condition { authorize(params["user"], params["password"]) }
|
|
1430
|
+
end
|
|
1431
|
+
end
|
|
1432
|
+
|
|
1433
|
+
mock_app do
|
|
1434
|
+
register protector
|
|
1435
|
+
|
|
1436
|
+
helpers do
|
|
1437
|
+
def authorize(username, password)
|
|
1438
|
+
username == "foo" && password == "bar"
|
|
1439
|
+
end
|
|
1440
|
+
end
|
|
1441
|
+
|
|
1442
|
+
get "/", :protect => true do
|
|
1443
|
+
"hey"
|
|
1444
|
+
end
|
|
1445
|
+
|
|
1446
|
+
get "/" do
|
|
1447
|
+
"go away"
|
|
1448
|
+
end
|
|
1449
|
+
end
|
|
1450
|
+
|
|
1451
|
+
get "/"
|
|
1452
|
+
assert_equal "go away", body
|
|
1453
|
+
|
|
1454
|
+
get "/", :user => "foo", :password => "bar"
|
|
1455
|
+
assert ok?
|
|
1456
|
+
assert_equal "hey", body
|
|
1457
|
+
end
|
|
1458
|
+
|
|
1459
|
+
it 'should allow concise routing' do
|
|
1460
|
+
mock_app do
|
|
1461
|
+
get :index, ":id" do
|
|
1462
|
+
params[:id]
|
|
1463
|
+
end
|
|
1464
|
+
|
|
1465
|
+
get :map, "route/:id" do
|
|
1466
|
+
params[:id]
|
|
1467
|
+
end
|
|
1468
|
+
end
|
|
1469
|
+
|
|
1470
|
+
get "/123"
|
|
1471
|
+
assert_equal "123", body
|
|
1472
|
+
|
|
1473
|
+
get "/route/123"
|
|
1474
|
+
assert_equal "123", body
|
|
1475
|
+
end
|
|
1476
|
+
|
|
1477
|
+
it 'should support halting with 404 and message' do
|
|
1478
|
+
mock_app do
|
|
1479
|
+
controller do
|
|
1480
|
+
get :index do
|
|
1481
|
+
halt 404, "not found"
|
|
1482
|
+
end
|
|
1483
|
+
end
|
|
1484
|
+
end
|
|
1485
|
+
|
|
1486
|
+
get "/"
|
|
1487
|
+
assert_equal 404, status
|
|
1488
|
+
assert_equal "not found", body
|
|
1489
|
+
end
|
|
1490
|
+
|
|
1491
|
+
it 'should allow passing & halting in before filters' do
|
|
1492
|
+
mock_app do
|
|
1493
|
+
controller do
|
|
1494
|
+
before { env['QUERY_STRING'] == 'secret' or pass }
|
|
1495
|
+
get :index do
|
|
1496
|
+
"secret index"
|
|
1497
|
+
end
|
|
1498
|
+
end
|
|
1499
|
+
|
|
1500
|
+
controller do
|
|
1501
|
+
before { env['QUERY_STRING'] == 'halt' and halt 401, 'go away!' }
|
|
1502
|
+
get :index do
|
|
1503
|
+
"index"
|
|
1504
|
+
end
|
|
1505
|
+
end
|
|
1506
|
+
end
|
|
1507
|
+
|
|
1508
|
+
get "/?secret"
|
|
1509
|
+
assert_equal "secret index", body
|
|
1510
|
+
|
|
1511
|
+
get "/?halt"
|
|
1512
|
+
assert_equal "go away!", body
|
|
1513
|
+
assert_equal 401, status
|
|
1514
|
+
|
|
1515
|
+
get "/"
|
|
1516
|
+
assert_equal "index", body
|
|
1517
|
+
end
|
|
1518
|
+
|
|
1519
|
+
it 'should scope filters in the given controller' do
|
|
1520
|
+
mock_app do
|
|
1521
|
+
before { @global = 'global' }
|
|
1522
|
+
after { @global = nil }
|
|
1523
|
+
|
|
1524
|
+
controller :foo do
|
|
1525
|
+
before { @foo = :foo }
|
|
1526
|
+
after { @foo = nil }
|
|
1527
|
+
get("/") { [@foo, @bar, @global].compact.join(" ") }
|
|
1528
|
+
end
|
|
1529
|
+
|
|
1530
|
+
get("/") { [@foo, @bar, @global].compact.join(" ") }
|
|
1531
|
+
|
|
1532
|
+
controller :bar do
|
|
1533
|
+
before { @bar = :bar }
|
|
1534
|
+
after { @bar = nil }
|
|
1535
|
+
get("/") { [@foo, @bar, @global].compact.join(" ") }
|
|
1536
|
+
end
|
|
1537
|
+
end
|
|
1538
|
+
|
|
1539
|
+
get "/bar"
|
|
1540
|
+
assert_equal "bar global", body
|
|
1541
|
+
|
|
1542
|
+
get "/foo"
|
|
1543
|
+
assert_equal "foo global", body
|
|
1544
|
+
|
|
1545
|
+
get "/"
|
|
1546
|
+
assert_equal "global", body
|
|
1547
|
+
end
|
|
1548
|
+
|
|
1549
|
+
it 'should works with optionals params' do
|
|
1550
|
+
mock_app do
|
|
1551
|
+
get("/foo(/:bar)?") { params[:bar] }
|
|
1552
|
+
end
|
|
1553
|
+
|
|
1554
|
+
get "/foo/bar"
|
|
1555
|
+
assert_equal "bar", body
|
|
1556
|
+
|
|
1557
|
+
get "/foo"
|
|
1558
|
+
assert_equal "", body
|
|
1559
|
+
end
|
|
1560
|
+
|
|
1561
|
+
it 'should work with multiple dashed params' do
|
|
1562
|
+
mock_app do
|
|
1563
|
+
get "/route/:foo/:bar/:baz", :provides => :html do
|
|
1564
|
+
"#{params[:foo]};#{params[:bar]};#{params[:baz]}"
|
|
1565
|
+
end
|
|
1566
|
+
end
|
|
1567
|
+
|
|
1568
|
+
get "/route/foo/bar/baz"
|
|
1569
|
+
assert_equal 'foo;bar;baz', body
|
|
1570
|
+
|
|
1571
|
+
get "/route/foo/bar-whatever/baz"
|
|
1572
|
+
assert_equal 'foo;bar-whatever;baz', body
|
|
1573
|
+
end
|
|
1574
|
+
|
|
1575
|
+
it 'should work with arbitrary params' do
|
|
1576
|
+
mock_app do
|
|
1577
|
+
get(:testing) { params[:foo] }
|
|
1578
|
+
end
|
|
1579
|
+
|
|
1580
|
+
url = @app.url(:testing, :foo => 'bar')
|
|
1581
|
+
assert_equal "/testing?foo=bar", url
|
|
1582
|
+
get url
|
|
1583
|
+
assert_equal "bar", body
|
|
1584
|
+
end
|
|
1585
|
+
|
|
1586
|
+
it 'should ignore nil params' do
|
|
1587
|
+
mock_app do
|
|
1588
|
+
get(:testing, :provides => [:html, :json]) do
|
|
1589
|
+
end
|
|
1590
|
+
end
|
|
1591
|
+
assert_equal '/testing.html', @app.url(:testing, :format => :html)
|
|
1592
|
+
assert_equal '/testing', @app.url(:testing, :format => nil)
|
|
1593
|
+
end
|
|
1594
|
+
|
|
1595
|
+
it 'should be able to access params in a before filter' do
|
|
1596
|
+
username_from_before_filter = nil
|
|
1597
|
+
|
|
1598
|
+
mock_app do
|
|
1599
|
+
before do
|
|
1600
|
+
username_from_before_filter = params[:username]
|
|
1601
|
+
end
|
|
1602
|
+
|
|
1603
|
+
get :users, :with => :username do
|
|
1604
|
+
end
|
|
1605
|
+
end
|
|
1606
|
+
get '/users/josh'
|
|
1607
|
+
assert_equal 'josh', username_from_before_filter
|
|
1608
|
+
end
|
|
1609
|
+
|
|
1610
|
+
it 'should be able to access params normally when a before filter is specified' do
|
|
1611
|
+
mock_app do
|
|
1612
|
+
before { }
|
|
1613
|
+
get :index do
|
|
1614
|
+
params.inspect
|
|
1615
|
+
end
|
|
1616
|
+
end
|
|
1617
|
+
get '/?test=what'
|
|
1618
|
+
assert_equal '{"test"=>"what"}', body
|
|
1619
|
+
end
|
|
1620
|
+
|
|
1621
|
+
it 'should work only for the given controller and route when using before-filter with route name' do
|
|
1622
|
+
mock_app do
|
|
1623
|
+
controller :foo do
|
|
1624
|
+
before(:index) { @a = "only to :index" }
|
|
1625
|
+
get(:index) { @a }
|
|
1626
|
+
get(:main) { @a }
|
|
1627
|
+
end
|
|
1628
|
+
end
|
|
1629
|
+
get '/foo/'
|
|
1630
|
+
assert_equal 'only to :index', body
|
|
1631
|
+
get '/foo/main'
|
|
1632
|
+
assert_equal '', body
|
|
1633
|
+
end
|
|
1634
|
+
|
|
1635
|
+
it 'should work only for the given controller and route when using after-filter with route name' do
|
|
1636
|
+
mock_app do
|
|
1637
|
+
controller :after_controller do
|
|
1638
|
+
global = "global variable"
|
|
1639
|
+
get(:index) { global }
|
|
1640
|
+
get(:main) { global }
|
|
1641
|
+
after(:index) { global = nil }
|
|
1642
|
+
end
|
|
1643
|
+
end
|
|
1644
|
+
get '/after_controller'
|
|
1645
|
+
assert_equal 'global variable', body
|
|
1646
|
+
get '/after_controller'
|
|
1647
|
+
assert_equal '', body
|
|
1648
|
+
end
|
|
1649
|
+
|
|
1650
|
+
it 'should execute the before/after filters when they are inserted after the target route' do
|
|
1651
|
+
mock_app do
|
|
1652
|
+
controller :after_test do
|
|
1653
|
+
global = "global variable"
|
|
1654
|
+
get(:index) { global }
|
|
1655
|
+
get(:foo) { global }
|
|
1656
|
+
before(:index) { global.delete!(" ") }
|
|
1657
|
+
after(:index) { global = "after" }
|
|
1658
|
+
end
|
|
1659
|
+
end
|
|
1660
|
+
get '/after_test'
|
|
1661
|
+
assert_equal 'globalvariable', body
|
|
1662
|
+
get '/after_test/foo'
|
|
1663
|
+
assert_equal 'after', body
|
|
1664
|
+
end
|
|
1665
|
+
|
|
1666
|
+
it 'should work with controller and arbitrary params' do
|
|
1667
|
+
mock_app do
|
|
1668
|
+
get(:testing) { params[:foo] }
|
|
1669
|
+
controller :test1 do
|
|
1670
|
+
get(:url1) { params[:foo] }
|
|
1671
|
+
get(:url2, :provides => [:html, :json]) { params[:foo] }
|
|
1672
|
+
end
|
|
1673
|
+
end
|
|
1674
|
+
|
|
1675
|
+
url = @app.url(:test1, :url1, :foo => 'bar1')
|
|
1676
|
+
assert_equal "/test1/url1?foo=bar1", url
|
|
1677
|
+
get url
|
|
1678
|
+
assert_equal "bar1", body
|
|
1679
|
+
|
|
1680
|
+
url = @app.url(:test1, :url2, :foo => 'bar2')
|
|
1681
|
+
assert_equal "/test1/url2?foo=bar2", url
|
|
1682
|
+
get url
|
|
1683
|
+
assert_equal "bar2", body
|
|
1684
|
+
end
|
|
1685
|
+
|
|
1686
|
+
it 'should parse two routes with the same path but different http verbs' do
|
|
1687
|
+
mock_app do
|
|
1688
|
+
get(:index) { "This is the get index" }
|
|
1689
|
+
post(:index) { "This is the post index" }
|
|
1690
|
+
end
|
|
1691
|
+
get "/"
|
|
1692
|
+
assert_equal "This is the get index", body
|
|
1693
|
+
post "/"
|
|
1694
|
+
assert_equal "This is the post index", body
|
|
1695
|
+
end
|
|
1696
|
+
|
|
1697
|
+
it 'should use optionals params' do
|
|
1698
|
+
mock_app do
|
|
1699
|
+
get(:index, :map => "/:foo(/:bar)?") { "#{params[:foo]}-#{params[:bar]}" }
|
|
1700
|
+
end
|
|
1701
|
+
get "/foo"
|
|
1702
|
+
assert_equal "foo-", body
|
|
1703
|
+
get "/foo/bar"
|
|
1704
|
+
assert_equal "foo-bar", body
|
|
1705
|
+
end
|
|
1706
|
+
|
|
1707
|
+
it 'should parse two routes with the same path but different http verbs and provides' do
|
|
1708
|
+
mock_app do
|
|
1709
|
+
get(:index, :provides => [:html, :json]) { "This is the get index.#{content_type}" }
|
|
1710
|
+
post(:index, :provides => [:html, :json]) { "This is the post index.#{content_type}" }
|
|
1711
|
+
end
|
|
1712
|
+
get "/"
|
|
1713
|
+
assert_equal "This is the get index.html", body
|
|
1714
|
+
post "/"
|
|
1715
|
+
assert_equal "This is the post index.html", body
|
|
1716
|
+
get "/.json"
|
|
1717
|
+
assert_equal "This is the get index.json", body
|
|
1718
|
+
get "/.js"
|
|
1719
|
+
assert_equal 404, status
|
|
1720
|
+
post "/.json"
|
|
1721
|
+
assert_equal "This is the post index.json", body
|
|
1722
|
+
post "/.js"
|
|
1723
|
+
assert_equal 404, status
|
|
1724
|
+
end
|
|
1725
|
+
|
|
1726
|
+
it 'should allow controller level mapping' do
|
|
1727
|
+
mock_app do
|
|
1728
|
+
controller :map => "controller-:id" do
|
|
1729
|
+
get(:url3) { "#{params[:id]}" }
|
|
1730
|
+
get(:url4, :map => 'test-:id2') { "#{params[:id]}, #{params[:id2]}" }
|
|
1731
|
+
end
|
|
1732
|
+
end
|
|
1733
|
+
|
|
1734
|
+
url = @app.url(:url3, :id => 1)
|
|
1735
|
+
assert_equal "/controller-1/url3", url
|
|
1736
|
+
get url
|
|
1737
|
+
assert_equal "1", body
|
|
1738
|
+
|
|
1739
|
+
url = @app.url(:url4, 1, 2)
|
|
1740
|
+
assert_equal "/controller-1/test-2", url
|
|
1741
|
+
get url
|
|
1742
|
+
assert_equal "1, 2", body
|
|
1743
|
+
end
|
|
1744
|
+
|
|
1745
|
+
it 'should replace name of named controller with mapping path' do
|
|
1746
|
+
mock_app do
|
|
1747
|
+
controller :ugly, :map => "/pretty/:id" do
|
|
1748
|
+
get(:url3) { "#{params[:id]}" }
|
|
1749
|
+
get(:url4, :map => 'test-:id2') { "#{params[:id]}, #{params[:id2]}" }
|
|
1750
|
+
end
|
|
1751
|
+
controller :voldemort, :map => "" do
|
|
1752
|
+
get(:url5) { "okay" }
|
|
1753
|
+
end
|
|
1754
|
+
end
|
|
1755
|
+
|
|
1756
|
+
url = @app.url(:ugly, :url3, :id => 1)
|
|
1757
|
+
assert_equal "/pretty/1/url3", url
|
|
1758
|
+
get url
|
|
1759
|
+
assert_equal "1", body
|
|
1760
|
+
|
|
1761
|
+
url = @app.url(:ugly, :url4, 3, 5)
|
|
1762
|
+
assert_equal "/pretty/3/test-5", url
|
|
1763
|
+
get url
|
|
1764
|
+
assert_equal "3, 5", body
|
|
1765
|
+
|
|
1766
|
+
url = @app.url(:voldemort, :url5)
|
|
1767
|
+
assert_equal "/url5", url
|
|
1768
|
+
get url
|
|
1769
|
+
assert_equal 'okay', body
|
|
1770
|
+
end
|
|
1771
|
+
|
|
1772
|
+
it 'should use absolute and relative maps' do
|
|
1773
|
+
mock_app do
|
|
1774
|
+
controller :one do
|
|
1775
|
+
parent :three
|
|
1776
|
+
get :index, :map => 'one' do; end
|
|
1777
|
+
get :index2, :map => '/one' do; end
|
|
1778
|
+
end
|
|
1779
|
+
|
|
1780
|
+
controller :two, :map => 'two' do
|
|
1781
|
+
parent :three
|
|
1782
|
+
get :index, :map => 'two' do; end
|
|
1783
|
+
get :index2, :map => '/two', :with => :id do; end
|
|
1784
|
+
end
|
|
1785
|
+
end
|
|
1786
|
+
assert_equal "/three/three_id/one", @app.url(:one, :index, 'three_id')
|
|
1787
|
+
assert_equal "/one", @app.url(:one, :index2)
|
|
1788
|
+
assert_equal "/two/three/three_id/two", @app.url(:two, :index, 'three_id')
|
|
1789
|
+
assert_equal "/two/four_id", @app.url(:two, :index2, 'four_id')
|
|
1790
|
+
end
|
|
1791
|
+
|
|
1792
|
+
it 'should work with params and parent options' do
|
|
1793
|
+
mock_app do
|
|
1794
|
+
controller :test2, :parent => :parent1, :parent1_id => 1 do
|
|
1795
|
+
get(:url3) { params[:foo] }
|
|
1796
|
+
get(:url4, :with => :with1) { params[:foo] }
|
|
1797
|
+
get(:url5, :with => :with2, :provides => [:html]) { params[:foo] }
|
|
1798
|
+
end
|
|
1799
|
+
end
|
|
1800
|
+
|
|
1801
|
+
url = @app.url(:test2, :url3, :foo => 'bar3')
|
|
1802
|
+
assert_equal "/parent1/1/test2/url3?foo=bar3", url
|
|
1803
|
+
get url
|
|
1804
|
+
assert_equal "bar3", body
|
|
1805
|
+
|
|
1806
|
+
url = @app.url(:test2, :url4, :with1 => 'awith1', :foo => 'bar4')
|
|
1807
|
+
assert_equal "/parent1/1/test2/url4/awith1?foo=bar4", url
|
|
1808
|
+
get url
|
|
1809
|
+
assert_equal "bar4", body
|
|
1810
|
+
|
|
1811
|
+
url = @app.url(:test2, :url5, :with2 => 'awith1', :foo => 'bar5')
|
|
1812
|
+
assert_equal "/parent1/1/test2/url5/awith1?foo=bar5", url
|
|
1813
|
+
get url
|
|
1814
|
+
assert_equal "bar5", body
|
|
1815
|
+
end
|
|
1816
|
+
|
|
1817
|
+
it 'should parse params without explicit provides for every matching route' do
|
|
1818
|
+
mock_app do
|
|
1819
|
+
get(:index, :map => "/foos/:bar") { "get bar = #{params[:bar]}" }
|
|
1820
|
+
post :create, :map => "/foos/:bar", :provides => [:html, :js] do
|
|
1821
|
+
"post bar = #{params[:bar]}"
|
|
1822
|
+
end
|
|
1823
|
+
end
|
|
1824
|
+
|
|
1825
|
+
get "/foos/hello"
|
|
1826
|
+
assert_equal "get bar = hello", body
|
|
1827
|
+
post "/foos/hello"
|
|
1828
|
+
assert_equal "post bar = hello", body
|
|
1829
|
+
post "/foos/hello.js"
|
|
1830
|
+
assert_equal "post bar = hello", body
|
|
1831
|
+
end
|
|
1832
|
+
|
|
1833
|
+
it 'should properly route to first foo with two similar routes' do
|
|
1834
|
+
mock_app do
|
|
1835
|
+
controllers do
|
|
1836
|
+
get('/foo/') { "this is foo" }
|
|
1837
|
+
get(:show, :map => "/foo/:bar/:id") { "/foo/#{params[:bar]}/#{params[:id]}" }
|
|
1838
|
+
end
|
|
1839
|
+
end
|
|
1840
|
+
get "/foo"
|
|
1841
|
+
assert_equal "this is foo", body
|
|
1842
|
+
get "/foo/"
|
|
1843
|
+
assert_equal "this is foo", body
|
|
1844
|
+
get '/foo/5/10'
|
|
1845
|
+
assert_equal "/foo/5/10", body
|
|
1846
|
+
end
|
|
1847
|
+
|
|
1848
|
+
it 'should index routes should be optional when nested' do
|
|
1849
|
+
mock_app do
|
|
1850
|
+
controller '/users', :provides => [:json] do
|
|
1851
|
+
get '/' do
|
|
1852
|
+
"foo"
|
|
1853
|
+
end
|
|
1854
|
+
end
|
|
1855
|
+
end
|
|
1856
|
+
get "/users.json"
|
|
1857
|
+
assert_equal "foo", body
|
|
1858
|
+
end
|
|
1859
|
+
|
|
1860
|
+
it 'should use provides as conditional' do
|
|
1861
|
+
mock_app do
|
|
1862
|
+
provides :json
|
|
1863
|
+
get "/" do
|
|
1864
|
+
"foo"
|
|
1865
|
+
end
|
|
1866
|
+
end
|
|
1867
|
+
get "/.json"
|
|
1868
|
+
assert_equal "foo", body
|
|
1869
|
+
end
|
|
1870
|
+
|
|
1871
|
+
it 'should reset provides for routes that did not use it' do
|
|
1872
|
+
mock_app do
|
|
1873
|
+
get('/foo', :provides => :js){}
|
|
1874
|
+
get('/bar'){}
|
|
1875
|
+
end
|
|
1876
|
+
get '/foo'
|
|
1877
|
+
assert ok?
|
|
1878
|
+
get '/foo.js'
|
|
1879
|
+
assert ok?
|
|
1880
|
+
get '/bar'
|
|
1881
|
+
assert ok?
|
|
1882
|
+
get '/bar.js'
|
|
1883
|
+
assert_equal 404, status
|
|
1884
|
+
end
|
|
1885
|
+
|
|
1886
|
+
it 'should pass controller conditions to each route' do
|
|
1887
|
+
counter = 0
|
|
1888
|
+
|
|
1889
|
+
mock_app do
|
|
1890
|
+
self.class.send(:define_method, :increment!) do |*args|
|
|
1891
|
+
condition { counter += 1 }
|
|
1892
|
+
end
|
|
1893
|
+
|
|
1894
|
+
controller :posts, :conditions => {:increment! => true} do
|
|
1895
|
+
get("/foo") { "foo" }
|
|
1896
|
+
get("/bar") { "bar" }
|
|
1897
|
+
end
|
|
1898
|
+
|
|
1899
|
+
end
|
|
1900
|
+
|
|
1901
|
+
get "/posts/foo"
|
|
1902
|
+
get "/posts/bar"
|
|
1903
|
+
assert_equal 2, counter
|
|
1904
|
+
end
|
|
1905
|
+
|
|
1906
|
+
it 'should allow controller conditions to be overridden' do
|
|
1907
|
+
counter = 0
|
|
1908
|
+
|
|
1909
|
+
mock_app do
|
|
1910
|
+
self.class.send(:define_method, :increment!) do |increment|
|
|
1911
|
+
condition { counter += 1 } if increment
|
|
1912
|
+
end
|
|
1913
|
+
|
|
1914
|
+
controller :posts, :conditions => {:increment! => true} do
|
|
1915
|
+
get("/foo") { "foo" }
|
|
1916
|
+
get("/bar", :increment! => false) { "bar" }
|
|
1917
|
+
end
|
|
1918
|
+
|
|
1919
|
+
end
|
|
1920
|
+
|
|
1921
|
+
get "/posts/foo"
|
|
1922
|
+
get "/posts/bar"
|
|
1923
|
+
assert_equal 1, counter
|
|
1924
|
+
end
|
|
1925
|
+
|
|
1926
|
+
it 'should parse params with class level provides' do
|
|
1927
|
+
mock_app do
|
|
1928
|
+
controllers :posts, :provides => [:html, :js] do
|
|
1929
|
+
post(:create, :map => "/foo/:bar/:baz/:id") {
|
|
1930
|
+
"POST CREATE #{params[:bar]} - #{params[:baz]} - #{params[:id]}"
|
|
1931
|
+
}
|
|
1932
|
+
end
|
|
1933
|
+
controllers :topics, :provides => [:js, :html] do
|
|
1934
|
+
get(:show, :map => "/foo/:bar/:baz/:id") { render "topics/show" }
|
|
1935
|
+
post(:create, :map => "/foo/:bar/:baz") { "TOPICS CREATE #{params[:bar]} - #{params[:baz]}" }
|
|
1936
|
+
end
|
|
1937
|
+
end
|
|
1938
|
+
post "/foo/bar/baz.js"
|
|
1939
|
+
assert_equal "TOPICS CREATE bar - baz", body, "should parse params with explicit .js"
|
|
1940
|
+
post @app.url(:topics, :create, :format => :js, :bar => 'bar', :baz => 'baz')
|
|
1941
|
+
assert_equal "TOPICS CREATE bar - baz", body, "should parse params from generated url"
|
|
1942
|
+
post "/foo/bar/baz/5.js"
|
|
1943
|
+
assert_equal "POST CREATE bar - baz - 5", body
|
|
1944
|
+
post @app.url(:posts, :create, :format => :js, :bar => 'bar', :baz => 'baz', :id => 5)
|
|
1945
|
+
assert_equal "POST CREATE bar - baz - 5", body
|
|
1946
|
+
end
|
|
1947
|
+
|
|
1948
|
+
it 'should parse params properly with inline provides' do
|
|
1949
|
+
mock_app do
|
|
1950
|
+
controllers :posts do
|
|
1951
|
+
post(:create, :map => "/foo/:bar/:baz/:id", :provides => [:html, :js]) {
|
|
1952
|
+
"POST CREATE #{params[:bar]} - #{params[:baz]} - #{params[:id]}"
|
|
1953
|
+
}
|
|
1954
|
+
end
|
|
1955
|
+
controllers :topics do
|
|
1956
|
+
get(:show, :map => "/foo/:bar/:baz/:id", :provides => [:html, :js]) { render "topics/show" }
|
|
1957
|
+
post(:create, :map => "/foo/:bar/:baz", :provides => [:html, :js]) { "TOPICS CREATE #{params[:bar]} - #{params[:baz]}" }
|
|
1958
|
+
end
|
|
1959
|
+
end
|
|
1960
|
+
post @app.url(:topics, :create, :format => :js, :bar => 'bar', :baz => 'baz')
|
|
1961
|
+
assert_equal "TOPICS CREATE bar - baz", body, "should properly post to topics create action"
|
|
1962
|
+
post @app.url(:posts, :create, :format => :js, :bar => 'bar', :baz => 'baz', :id => 5)
|
|
1963
|
+
assert_equal "POST CREATE bar - baz - 5", body, "should properly post to create action"
|
|
1964
|
+
end
|
|
1965
|
+
|
|
1966
|
+
it 'should have overideable format' do
|
|
1967
|
+
::Rack::Mime::MIME_TYPES[".other"] = "text/html"
|
|
1968
|
+
mock_app do
|
|
1969
|
+
before do
|
|
1970
|
+
params[:format] ||= :other
|
|
1971
|
+
end
|
|
1972
|
+
get("/format_test", :provides => [:html, :other]){ content_type.to_s }
|
|
1973
|
+
end
|
|
1974
|
+
get "/format_test"
|
|
1975
|
+
assert_equal "other", body
|
|
1976
|
+
::Rack::Mime::MIME_TYPES.delete('.other')
|
|
1977
|
+
end
|
|
1978
|
+
|
|
1979
|
+
it 'should invokes handlers registered with ::error when raised' do
|
|
1980
|
+
mock_app do
|
|
1981
|
+
set :raise_errors, false
|
|
1982
|
+
error(FooError) { 'Foo!' }
|
|
1983
|
+
get '/' do
|
|
1984
|
+
raise FooError
|
|
1985
|
+
end
|
|
1986
|
+
end
|
|
1987
|
+
get '/'
|
|
1988
|
+
assert_equal 500, status
|
|
1989
|
+
assert_equal 'Foo!', body
|
|
1990
|
+
end
|
|
1991
|
+
|
|
1992
|
+
it 'should have MethodOverride middleware' do
|
|
1993
|
+
mock_app do
|
|
1994
|
+
put('/') { 'okay' }
|
|
1995
|
+
end
|
|
1996
|
+
assert @app.method_override?
|
|
1997
|
+
post '/', {'_method'=>'PUT'}, {}
|
|
1998
|
+
assert_equal 200, status
|
|
1999
|
+
assert_equal 'okay', body
|
|
2000
|
+
end
|
|
2001
|
+
|
|
2002
|
+
it 'should return value from params' do
|
|
2003
|
+
mock_app do
|
|
2004
|
+
get("/foo/:bar"){ raise "'bar' should be a string" unless params[:bar].kind_of? String}
|
|
2005
|
+
end
|
|
2006
|
+
get "/foo/50"
|
|
2007
|
+
assert ok?
|
|
2008
|
+
end
|
|
2009
|
+
|
|
2010
|
+
it 'should return params as a HashWithIndifferentAccess object via GET' do
|
|
2011
|
+
mock_app do
|
|
2012
|
+
get('/foo/:bar') { "#{params["bar"]} #{params[:bar]}" }
|
|
2013
|
+
get(:foo, :map => '/prefix/:var') { "#{params["var"]} #{params[:var]}" }
|
|
2014
|
+
end
|
|
2015
|
+
|
|
2016
|
+
get('/foo/some_text')
|
|
2017
|
+
assert_equal "some_text some_text", body
|
|
2018
|
+
|
|
2019
|
+
get('/prefix/var')
|
|
2020
|
+
assert_equal "var var", body
|
|
2021
|
+
end
|
|
2022
|
+
|
|
2023
|
+
it 'should return params as a HashWithIndifferentAccess object via POST' do
|
|
2024
|
+
mock_app do
|
|
2025
|
+
post('/user') do
|
|
2026
|
+
"#{params["user"]["full_name"]} #{params[:user][:full_name]}"
|
|
2027
|
+
end
|
|
2028
|
+
end
|
|
2029
|
+
|
|
2030
|
+
post '/user', {:user => {:full_name => 'example user'}}
|
|
2031
|
+
assert_equal "example user example user", body
|
|
2032
|
+
|
|
2033
|
+
post '/user', {"user" => {"full_name" => 'example user'}}
|
|
2034
|
+
assert_equal "example user example user", body
|
|
2035
|
+
end
|
|
2036
|
+
|
|
2037
|
+
it 'should have MethodOverride middleware with more options' do
|
|
2038
|
+
mock_app do
|
|
2039
|
+
put('/hi', :provides => [:json]) { 'hi' }
|
|
2040
|
+
end
|
|
2041
|
+
post '/hi', {'_method'=>'PUT'}
|
|
2042
|
+
assert_equal 200, status
|
|
2043
|
+
assert_equal 'hi', body
|
|
2044
|
+
post '/hi.json', {'_method'=>'PUT'}
|
|
2045
|
+
assert_equal 200, status
|
|
2046
|
+
assert_equal 'hi', body
|
|
2047
|
+
post '/hi.json'
|
|
2048
|
+
assert_equal 405, status
|
|
2049
|
+
end
|
|
2050
|
+
|
|
2051
|
+
it 'should parse nested params' do
|
|
2052
|
+
mock_app do
|
|
2053
|
+
get(:index) { "%s %s" % [params[:account][:name], params[:account][:surname]] }
|
|
2054
|
+
end
|
|
2055
|
+
get "/?" + { :account => { :name => 'foo', :surname => 'bar' } }.to_query
|
|
2056
|
+
assert_equal 'foo bar', body
|
|
2057
|
+
get @app.url(:index, "account[name]" => "foo", "account[surname]" => "bar")
|
|
2058
|
+
assert_equal 'foo bar', body
|
|
2059
|
+
end
|
|
2060
|
+
|
|
2061
|
+
it 'should render sinatra NotFound page' do
|
|
2062
|
+
mock_app { set :environment, :development }
|
|
2063
|
+
get "/"
|
|
2064
|
+
assert_equal 404, status
|
|
2065
|
+
assert_match %r{(Sinatra doesn’t know this ditty.|<h1>Not Found</h1>)}, body
|
|
2066
|
+
end
|
|
2067
|
+
|
|
2068
|
+
it 'should render a custom NotFound page' do
|
|
2069
|
+
mock_app do
|
|
2070
|
+
error(Sinatra::NotFound) { "not found" }
|
|
2071
|
+
end
|
|
2072
|
+
get "/"
|
|
2073
|
+
assert_equal 404, status
|
|
2074
|
+
assert_match /not found/, body
|
|
2075
|
+
end
|
|
2076
|
+
|
|
2077
|
+
it 'should render a custom 404 page using not_found' do
|
|
2078
|
+
mock_app do
|
|
2079
|
+
not_found { "custom 404 not found" }
|
|
2080
|
+
end
|
|
2081
|
+
get "/"
|
|
2082
|
+
assert_equal 404, status
|
|
2083
|
+
assert_equal "custom 404 not found", body
|
|
2084
|
+
end
|
|
2085
|
+
|
|
2086
|
+
it 'should render a custom error page using error method' do
|
|
2087
|
+
mock_app do
|
|
2088
|
+
error(404) { "custom 404 error" }
|
|
2089
|
+
end
|
|
2090
|
+
get "/"
|
|
2091
|
+
assert_equal 404, status
|
|
2092
|
+
assert_equal "custom 404 error", body
|
|
2093
|
+
end
|
|
2094
|
+
|
|
2095
|
+
it 'should render a custom 403 page' do
|
|
2096
|
+
mock_app do
|
|
2097
|
+
error(403) { "custom 403 not found" }
|
|
2098
|
+
get("/") { status 403 }
|
|
2099
|
+
end
|
|
2100
|
+
get "/"
|
|
2101
|
+
assert_equal 403, status
|
|
2102
|
+
assert_equal "custom 403 not found", body
|
|
2103
|
+
end
|
|
2104
|
+
|
|
2105
|
+
it 'should recognize paths' do
|
|
2106
|
+
mock_app do
|
|
2107
|
+
controller :foo do
|
|
2108
|
+
get(:bar, :map => "/my/:id/custom-route") { }
|
|
2109
|
+
end
|
|
2110
|
+
get(:simple, :map => "/simple/:id") { }
|
|
2111
|
+
get(:with_format, :with => :id, :provides => :js) { }
|
|
2112
|
+
end
|
|
2113
|
+
assert_equal [:"foo bar", { :id => "fantastic" }.with_indifferent_access], @app.recognize_path(@app.url(:foo, :bar, :id => :fantastic))
|
|
2114
|
+
assert_equal [:"foo bar", { :id => "18" }.with_indifferent_access], @app.recognize_path(@app.url(:foo, :bar, :id => 18))
|
|
2115
|
+
assert_equal [:simple, { :id => "bar" }.with_indifferent_access], @app.recognize_path(@app.url(:simple, :id => "bar"))
|
|
2116
|
+
assert_equal [:simple, { :id => "true" }.with_indifferent_access], @app.recognize_path(@app.url(:simple, :id => true))
|
|
2117
|
+
assert_equal [:simple, { :id => "9" }.with_indifferent_access], @app.recognize_path(@app.url(:simple, :id => 9))
|
|
2118
|
+
assert_equal [:with_format, { :id => "bar", :format => "js" }.with_indifferent_access], @app.recognize_path(@app.url(:with_format, :id => "bar", :format => :js))
|
|
2119
|
+
assert_equal [:with_format, { :id => "true", :format => "js" }.with_indifferent_access], @app.recognize_path(@app.url(:with_format, :id => true, :format => "js"))
|
|
2120
|
+
assert_equal [:with_format, { :id => "9", :format => "js" }.with_indifferent_access], @app.recognize_path(@app.url(:with_format, :id => 9, :format => :js))
|
|
2121
|
+
end
|
|
2122
|
+
|
|
2123
|
+
it 'should have current_path' do
|
|
2124
|
+
mock_app do
|
|
2125
|
+
controller :foo do
|
|
2126
|
+
get(:index) { current_path }
|
|
2127
|
+
get :bar, :map => "/paginate/:page" do
|
|
2128
|
+
current_path
|
|
2129
|
+
end
|
|
2130
|
+
get(:after) { current_path }
|
|
2131
|
+
end
|
|
2132
|
+
end
|
|
2133
|
+
get "/paginate/10"
|
|
2134
|
+
assert_equal "/paginate/10", body
|
|
2135
|
+
get "/foo/after"
|
|
2136
|
+
assert_equal "/foo/after", body
|
|
2137
|
+
get "/foo"
|
|
2138
|
+
assert_equal "/foo", body
|
|
2139
|
+
end
|
|
2140
|
+
|
|
2141
|
+
it 'should accept :map and :parent' do
|
|
2142
|
+
mock_app do
|
|
2143
|
+
controller :posts do
|
|
2144
|
+
get :show, :parent => :users, :map => "posts/:id" do
|
|
2145
|
+
"#{params[:user_id]}-#{params[:id]}"
|
|
2146
|
+
end
|
|
2147
|
+
end
|
|
2148
|
+
end
|
|
2149
|
+
get '/users/123/posts/321'
|
|
2150
|
+
assert_equal "123-321", body
|
|
2151
|
+
end
|
|
2152
|
+
|
|
2153
|
+
it 'should change params in current_path' do
|
|
2154
|
+
mock_app do
|
|
2155
|
+
get :index, :map => "/paginate/:page" do
|
|
2156
|
+
current_path(:page => 66)
|
|
2157
|
+
end
|
|
2158
|
+
end
|
|
2159
|
+
get @app.url(:index, :page => 10)
|
|
2160
|
+
assert_equal "/paginate/66", body
|
|
2161
|
+
end
|
|
2162
|
+
|
|
2163
|
+
it 'should not route get :users, :with => :id to /users//' do
|
|
2164
|
+
mock_app do
|
|
2165
|
+
get(:users, :with => :id) { 'boo' }
|
|
2166
|
+
end
|
|
2167
|
+
get '/users//'
|
|
2168
|
+
assert_equal 404, status
|
|
2169
|
+
end
|
|
2170
|
+
|
|
2171
|
+
it "should support splat params" do
|
|
2172
|
+
mock_app do
|
|
2173
|
+
get "/say/*/to/*" do
|
|
2174
|
+
params[:splat].inspect
|
|
2175
|
+
end
|
|
2176
|
+
end
|
|
2177
|
+
get "/say/hello/to/world"
|
|
2178
|
+
assert_equal %Q[["hello", "world"]], body
|
|
2179
|
+
end
|
|
2180
|
+
|
|
2181
|
+
it "should recognize the route containing splat params if path is ended with slash" do
|
|
2182
|
+
mock_app do
|
|
2183
|
+
get "/splat/*" do
|
|
2184
|
+
"slash!"
|
|
2185
|
+
end
|
|
2186
|
+
end
|
|
2187
|
+
get "/splat"
|
|
2188
|
+
assert_equal 404, status
|
|
2189
|
+
get "/splat/"
|
|
2190
|
+
assert_equal "slash!", body
|
|
2191
|
+
end
|
|
2192
|
+
|
|
2193
|
+
it "should match correctly paths even if the free regex route exists" do
|
|
2194
|
+
mock_app do
|
|
2195
|
+
get %r{/b/(?<aa>\w+)/(?<bb>\w+)} do
|
|
2196
|
+
"free regex"
|
|
2197
|
+
end
|
|
2198
|
+
|
|
2199
|
+
put '/b/:b/:c', :csrf_protection => false do
|
|
2200
|
+
params.inspect
|
|
2201
|
+
end
|
|
2202
|
+
end
|
|
2203
|
+
put "/b/x/y"
|
|
2204
|
+
assert_equal '{"b"=>"x", "c"=>"y"}', body
|
|
2205
|
+
end
|
|
2206
|
+
|
|
2207
|
+
it "should support named captures like %r{/hello/(?<person>[^/?#]+)} on Ruby >= 1.9" do
|
|
2208
|
+
next if RUBY_VERSION < '1.9'
|
|
2209
|
+
mock_app do
|
|
2210
|
+
get Regexp.new('/hello/(?<person>[^/?#]+)') do
|
|
2211
|
+
"Hello #{params['person']}"
|
|
2212
|
+
end
|
|
2213
|
+
end
|
|
2214
|
+
get '/hello/Frank'
|
|
2215
|
+
assert_equal 'Hello Frank', body
|
|
2216
|
+
end
|
|
2217
|
+
|
|
2218
|
+
it 'supports regular expression look-alike routes' do
|
|
2219
|
+
mock_app do
|
|
2220
|
+
get(RegexpLookAlike.new) do
|
|
2221
|
+
[params[:one], params[:two], params[:three], params[:four]].join(" ")
|
|
2222
|
+
end
|
|
2223
|
+
end
|
|
2224
|
+
|
|
2225
|
+
get '/this/is/a/test/'
|
|
2226
|
+
assert ok?
|
|
2227
|
+
assert_equal 'this is a test', body
|
|
2228
|
+
end
|
|
2229
|
+
|
|
2230
|
+
it "uses optional block passed to pass as route block if no other route is found" do
|
|
2231
|
+
mock_app do
|
|
2232
|
+
get "/" do
|
|
2233
|
+
pass do
|
|
2234
|
+
"this"
|
|
2235
|
+
end
|
|
2236
|
+
"not this"
|
|
2237
|
+
end
|
|
2238
|
+
end
|
|
2239
|
+
|
|
2240
|
+
get "/"
|
|
2241
|
+
assert ok?
|
|
2242
|
+
assert_equal "this", body
|
|
2243
|
+
end
|
|
2244
|
+
|
|
2245
|
+
it "supports mixing multiple splat params like /*/foo/*/* as block parameters" do
|
|
2246
|
+
mock_app do
|
|
2247
|
+
get '/*/foo/*/*' do |foo, bar, baz|
|
|
2248
|
+
"#{foo}, #{bar}, #{baz}"
|
|
2249
|
+
end
|
|
2250
|
+
end
|
|
2251
|
+
|
|
2252
|
+
get '/bar/foo/bling/baz/boom'
|
|
2253
|
+
assert ok?
|
|
2254
|
+
assert_equal 'bar, bling, baz/boom', body
|
|
2255
|
+
end
|
|
2256
|
+
|
|
2257
|
+
it "should be able to use PathRouter#recognize to recognize routes" do
|
|
2258
|
+
mock_app do
|
|
2259
|
+
get(:sample){}
|
|
2260
|
+
end
|
|
2261
|
+
env = Rack::MockRequest.env_for("/sample")
|
|
2262
|
+
request = Rack::Request.new(env)
|
|
2263
|
+
assert_equal :sample, @app.router.recognize(request).first.name
|
|
2264
|
+
end
|
|
2265
|
+
|
|
2266
|
+
it "should be able to use PathRouter#recognize to recognize routes by using Rack::MockRequest" do
|
|
2267
|
+
mock_app do
|
|
2268
|
+
get(:mock_sample){}
|
|
2269
|
+
end
|
|
2270
|
+
env = Rack::MockRequest.env_for("/mock_sample")
|
|
2271
|
+
assert_equal :mock_sample, @app.router.recognize(env).first.name
|
|
2272
|
+
env = Rack::MockRequest.env_for("/invalid")
|
|
2273
|
+
assert_equal [], @app.router.recognize(env)
|
|
2274
|
+
end
|
|
2275
|
+
|
|
2276
|
+
it "should be able to use params after sending request" do
|
|
2277
|
+
last_app = mock_app do
|
|
2278
|
+
get("/foo/:id"){ params.inspect }
|
|
2279
|
+
end
|
|
2280
|
+
get "/foo/123"
|
|
2281
|
+
assert_equal({"id"=>"123"}, Thread.current['tennpipes.instance'].instance_variable_get(:@params))
|
|
2282
|
+
end
|
|
2283
|
+
|
|
2284
|
+
it "should raise an exception if block arity is not same with captured params size" do
|
|
2285
|
+
assert_raises(Tennpipes::Routing::BlockArityError) do
|
|
2286
|
+
mock_app do
|
|
2287
|
+
get("/sample/:a/:b") { |a| }
|
|
2288
|
+
end
|
|
2289
|
+
end
|
|
2290
|
+
end
|
|
2291
|
+
|
|
2292
|
+
it "should pass format value as a block parameter" do
|
|
2293
|
+
mock_app do
|
|
2294
|
+
get "/sample/:a/:b", :provides => :xml do |a, b, format|
|
|
2295
|
+
"#{a}, #{b}, #{format}"
|
|
2296
|
+
end
|
|
2297
|
+
end
|
|
2298
|
+
get "/sample/foo/bar"
|
|
2299
|
+
assert_equal "foo, bar, ", body
|
|
2300
|
+
get "/sample/foo/bar.xml"
|
|
2301
|
+
assert_equal "foo, bar, xml", body
|
|
2302
|
+
end
|
|
2303
|
+
|
|
2304
|
+
it "should allow negative arity in route block" do
|
|
2305
|
+
mock_app do
|
|
2306
|
+
get("/:a/sample/*/*") { |*all| }
|
|
2307
|
+
end
|
|
2308
|
+
end
|
|
2309
|
+
|
|
2310
|
+
it "should be able to use splat and named captues" do
|
|
2311
|
+
mock_app do
|
|
2312
|
+
get("/:a/:b/*/*/*") { |a, b, *splats| "#{a}, #{b}, (#{splats * ","})" }
|
|
2313
|
+
end
|
|
2314
|
+
get "/123/456/a/b/c"
|
|
2315
|
+
assert_equal "123, 456, (a,b,c)", body
|
|
2316
|
+
end
|
|
2317
|
+
|
|
2318
|
+
it "can modify the request" do
|
|
2319
|
+
mock_app do
|
|
2320
|
+
get('/foo') { request.path_info = '/bar'; pass }
|
|
2321
|
+
get('/bar') { 'bar' }
|
|
2322
|
+
end
|
|
2323
|
+
|
|
2324
|
+
get '/foo'
|
|
2325
|
+
assert ok?
|
|
2326
|
+
assert_equal 'bar', body
|
|
2327
|
+
end
|
|
2328
|
+
end
|