sinatra/test/base_test.rb

186 lines
5.3 KiB
Ruby

require_relative 'test_helper'
class BaseTest < Minitest::Test
describe 'Sinatra::Base subclasses' do
class TestApp < Sinatra::Base
get('/') { 'Hello World' }
end
class TestKeywordArgumentInitializerApp < Sinatra::Base
def initialize(argument:)
@argument = argument
end
get('/') { "Hello World with Keyword Arguments: #{@argument}" }
end
it 'include Rack::Utils' do
assert TestApp.included_modules.include?(Rack::Utils)
end
it 'processes requests with #call' do
assert TestApp.respond_to?(:call)
request = Rack::MockRequest.new(TestApp)
response = request.get('/')
assert response.ok?
assert_equal 'Hello World', response.body
end
class TestApp < Sinatra::Base
get '/state' do
@foo ||= "new"
body = "Foo: #{@foo}"
@foo = 'discard'
body
end
end
it 'does not maintain state between requests' do
request = Rack::MockRequest.new(TestApp)
2.times do
response = request.get('/state')
assert response.ok?
assert_equal 'Foo: new', response.body
end
end
it "passes the subclass to configure blocks" do
ref = nil
TestApp.configure { |app| ref = app }
assert_equal TestApp, ref
end
it "allows the configure block arg to be omitted and does not change context" do
context = nil
TestApp.configure { context = self }
assert_equal self, context
end
it "allows constructor to receive keyword arguments" do
app = TestKeywordArgumentInitializerApp.new(argument: "some argument")
request = Rack::MockRequest.new(app)
response = request.get('/')
assert response.ok?
assert_equal 'Hello World with Keyword Arguments: some argument', response.body
end
end
describe "Sinatra::Base#new" do
it 'returns a wrapper' do
assert_equal Sinatra::Wrapper, Sinatra::Base.new.class
end
it 'implements a nice inspect' do
assert_equal '#<Sinatra::Base app_file=nil>', Sinatra::Base.new.inspect
end
it 'exposes settings' do
assert_equal Sinatra::Base.settings, Sinatra::Base.new.settings
end
it 'exposes helpers' do
assert_equal 'image/jpeg', Sinatra::Base.new.helpers.mime_type(:jpg)
end
end
describe "Sinatra::Base as Rack middleware" do
app = lambda { |env|
headers = {'X-Downstream' => 'true'}
headers['X-Route-Missing'] = env['sinatra.route-missing'] || ''
[210, headers, ['Hello from downstream']] }
class TestMiddleware < Sinatra::Base
end
it 'creates a middleware that responds to #call with .new' do
middleware = TestMiddleware.new(app)
assert middleware.respond_to?(:call)
end
it 'exposes the downstream app' do
middleware = TestMiddleware.new!(app)
assert_same app, middleware.app
end
class TestMiddleware < Sinatra::Base
def route_missing
env['sinatra.route-missing'] = '1'
super
end
get('/') { 'Hello from middleware' }
end
middleware = TestMiddleware.new(app)
request = Rack::MockRequest.new(middleware)
it 'intercepts requests' do
response = request.get('/')
assert response.ok?
assert_equal 'Hello from middleware', response.body
end
it 'automatically forwards requests downstream when no matching route found' do
response = request.get('/missing')
assert_equal 210, response.status
assert_equal 'Hello from downstream', response.body
end
it 'calls #route_missing before forwarding downstream' do
response = request.get('/missing')
assert_equal '1', response['X-Route-Missing']
end
class TestMiddleware < Sinatra::Base
get('/low-level-forward') { app.call(env) }
end
it 'can call the downstream app directly and return result' do
response = request.get('/low-level-forward')
assert_equal 210, response.status
assert_equal 'true', response['X-Downstream']
assert_equal 'Hello from downstream', response.body
end
class TestMiddleware < Sinatra::Base
get '/explicit-forward' do
response['X-Middleware'] = 'true'
res = forward
assert_nil res
assert_equal 210, response.status
assert_equal 'true', response['X-Downstream']
assert_equal ['Hello from downstream'], response.body
'Hello after explicit forward'
end
end
it 'forwards the request downstream and integrates the response into the current context' do
response = request.get('/explicit-forward')
assert_equal 210, response.status
assert_equal 'true', response['X-Downstream']
assert_equal 'Hello after explicit forward', response.body
assert_equal '28', response['Content-Length']
end
app_content_length = lambda {|env|
[200, {'Content-Length' => '16'}, 'From downstream!']}
class TestMiddlewareContentLength < Sinatra::Base
get '/forward' do
'From after explicit forward!'
end
end
middleware_content_length = TestMiddlewareContentLength.new(app_content_length)
request_content_length = Rack::MockRequest.new(middleware_content_length)
it "sets content length for last response" do
response = request_content_length.get('/forward')
assert_equal '28', response['Content-Length']
end
end
end