sinatra/test/routing_test.rb

306 lines
6.1 KiB
Ruby

require 'test/spec'
require 'sinatra/base'
require 'sinatra/test'
describe "Routing" do
include Sinatra::Test
%w[get put post delete head].each do |verb|
it "defines #{verb.upcase} request handlers with #{verb}" do
mock_app {
send verb, '/hello' do
'Hello World'
end
}
request = Rack::MockRequest.new(@app)
response = request.request(verb.upcase, '/hello', {})
response.should.be.ok
response.body.should.equal 'Hello World'
end
end
it "404s when no route satisfies the request" do
mock_app {
get('/foo') { }
}
get '/bar'
status.should.equal 404
end
it "exposes params with indifferent hash" do
mock_app {
get '/:foo' do
params['foo'].should.equal 'bar'
params[:foo].should.equal 'bar'
'well, alright'
end
}
get '/bar'
body.should.equal 'well, alright'
end
it "merges named params and query string params in params" do
mock_app {
get '/:foo' do
params['foo'].should.equal 'bar'
params['baz'].should.equal 'biz'
end
}
get '/bar?baz=biz'
should.be.ok
end
it "supports named params like /hello/:person" do
mock_app {
get '/hello/:person' do
"Hello #{params['person']}"
end
}
get '/hello/Frank'
body.should.equal 'Hello Frank'
end
it "supports optional named params like /?:foo?/?:bar?" do
mock_app {
get '/?:foo?/?:bar?' do
"foo=#{params[:foo]};bar=#{params[:bar]}"
end
}
get '/hello/world'
should.be.ok
body.should.equal "foo=hello;bar=world"
get '/hello'
should.be.ok
body.should.equal "foo=hello;bar="
get '/'
should.be.ok
body.should.equal "foo=;bar="
end
it "supports single splat params like /*" do
mock_app {
get '/*' do
params['splat'].should.be.kind_of Array
params['splat'].join "\n"
end
}
get '/foo'
body.should.equal "foo"
get '/foo/bar/baz'
body.should.equal "foo/bar/baz"
end
it "supports mixing multiple splat params like /*/foo/*/*" do
mock_app {
get '/*/foo/*/*' do
params['splat'].should.be.kind_of Array
params['splat'].join "\n"
end
}
get '/bar/foo/bling/baz/boom'
body.should.equal "bar\nbling\nbaz/boom"
get '/bar/foo/baz'
should.be.not_found
end
it "supports mixing named and splat params like /:foo/*" do
mock_app {
get '/:foo/*' do
params['foo'].should.equal 'foo'
params['splat'].should.equal ['bar/baz']
end
}
get '/foo/bar/baz'
should.be.ok
end
it "supports paths that include spaces" do
mock_app {
get '/path with spaces' do
'looks good'
end
}
get '/path%20with%20spaces'
should.be.ok
body.should.equal 'looks good'
end
it "URL decodes named parameters and splats" do
mock_app {
get '/:foo/*' do
params['foo'].should.equal 'hello world'
params['splat'].should.equal ['how are you']
nil
end
}
get '/hello%20world/how%20are%20you'
should.be.ok
end
it 'supports regular expressions' do
mock_app {
get(/^\/foo...\/bar$/) do
'Hello World'
end
}
get '/foooom/bar'
should.be.ok
body.should.equal 'Hello World'
end
it 'makes regular expression captures available in params[:captures]' do
mock_app {
get(/^\/fo(.*)\/ba(.*)/) do
params[:captures].should.equal ['orooomma', 'f']
'right on'
end
}
get '/foorooomma/baf'
should.be.ok
body.should.equal 'right on'
end
it "returns response immediately on halt" do
mock_app {
get '/' do
halt 'Hello World'
'Boo-hoo World'
end
}
get '/'
should.be.ok
body.should.equal 'Hello World'
end
it "transitions to the next matching route on pass" do
mock_app {
get '/:foo' do
pass
'Hello Foo'
end
get '/*' do
params.should.not.include 'foo'
'Hello World'
end
}
get '/bar'
should.be.ok
body.should.equal 'Hello World'
end
it "transitions to 404 when passed and no subsequent route matches" do
mock_app {
get '/:foo' do
pass
'Hello Foo'
end
}
get '/bar'
should.be.not_found
end
it "passes when matching condition returns false" do
mock_app {
condition { params[:foo] == 'bar' }
get '/:foo' do
'Hello World'
end
}
get '/bar'
should.be.ok
body.should.equal 'Hello World'
get '/foo'
should.be.not_found
end
it "does not pass when matching condition returns nil" do
mock_app {
condition { nil }
get '/:foo' do
'Hello World'
end
}
get '/bar'
should.be.ok
body.should.equal 'Hello World'
end
it "passes to next route when condition calls pass explicitly" do
mock_app {
condition { pass unless params[:foo] == 'bar' }
get '/:foo' do
'Hello World'
end
}
get '/bar'
should.be.ok
body.should.equal 'Hello World'
get '/foo'
should.be.not_found
end
it "passes to the next route when host_name does not match" do
mock_app {
host_name 'example.com'
get '/foo' do
'Hello World'
end
}
get '/foo'
should.be.not_found
get '/foo', :env => { 'HTTP_HOST' => 'example.com' }
status.should.equal 200
body.should.equal 'Hello World'
end
it "passes to the next route when user_agent does not match" do
mock_app {
user_agent /Foo/
get '/foo' do
'Hello World'
end
}
get '/foo'
should.be.not_found
get '/foo', :env => { 'HTTP_USER_AGENT' => 'Foo Bar' }
status.should.equal 200
body.should.equal 'Hello World'
end
it "makes captures in user agent pattern available in params[:agent]" do
mock_app {
user_agent /Foo (.*)/
get '/foo' do
'Hello ' + params[:agent].first
end
}
get '/foo', :env => { 'HTTP_USER_AGENT' => 'Foo Bar' }
status.should.equal 200
body.should.equal 'Hello Bar'
end
end