1
0
Fork 0
mirror of https://github.com/sinatra/sinatra synced 2023-03-27 23:18:01 -04:00
sinatra/test/templates_test.rb
Konstantin Haase 1d676f41f8 Sets default content type according to template engine used instead of just text/html.
It does so by including a Mixin into the the returned string offering a content_type method. Therefore all of the following examples produce the expected results:

    # text/html
    get('/') do
      haml :index
    end

    # text/css
    get('/') do
      sass :index
    end

    # text/css
    get('/') do
      haml :index
      sass :index
    end

    # text/html
    get('/') do
      haml '= sass :index'
    end

It also allows setting the default content type for a template engine:

    set :builder, :content_type => :html

Tests and README adjustments (all languages) included.
2010-09-27 13:25:10 +02:00

213 lines
5.9 KiB
Ruby

require File.dirname(__FILE__) + '/helper'
File.delete(File.dirname(__FILE__) + '/views/layout.test') rescue nil
class TestTemplate < Tilt::Template
def prepare
end
alias compile! prepare # for tilt < 0.7
def evaluate(scope, locals={}, &block)
inner = block ? block.call : ''
data + inner
end
Tilt.register 'test', self
end
class TemplatesTest < Test::Unit::TestCase
def render_app(base=Sinatra::Base, options = {}, &block)
base, options = Sinatra::Base, base if base.is_a? Hash
mock_app(base) {
set :views, File.dirname(__FILE__) + '/views'
set options
get '/', &block
template(:layout3) { "Layout 3!\n" }
}
get '/'
end
def with_default_layout
layout = File.dirname(__FILE__) + '/views/layout.test'
File.open(layout, 'wb') { |io| io.write "Layout!\n" }
yield
ensure
File.unlink(layout) rescue nil
end
it 'renders String templates directly' do
render_app { render :test, 'Hello World' }
assert ok?
assert_equal 'Hello World', body
end
it 'renders Proc templates using the call result' do
render_app { render :test, Proc.new {'Hello World'} }
assert ok?
assert_equal 'Hello World', body
end
it 'looks up Symbol templates in views directory' do
render_app { render :test, :hello }
assert ok?
assert_equal "Hello World!\n", body
end
it 'uses the default layout template if not explicitly overridden' do
with_default_layout do
render_app { render :test, :hello }
assert ok?
assert_equal "Layout!\nHello World!\n", body
end
end
it 'uses the default layout template if not really overriden' do
with_default_layout do
render_app { render :test, :hello, :layout => true }
assert ok?
assert_equal "Layout!\nHello World!\n", body
end
end
it 'uses the layout template specified' do
render_app { render :test, :hello, :layout => :layout2 }
assert ok?
assert_equal "Layout 2!\nHello World!\n", body
end
it 'uses layout templates defined with the #template method' do
render_app { render :test, :hello, :layout => :layout3 }
assert ok?
assert_equal "Layout 3!\nHello World!\n", body
end
it 'avoids wrapping layouts around nested templates' do
render_app { render :str, :nested, :layout => :layout2 }
assert ok?
assert_equal "<h1>String Layout!</h1>\n<content><h1>Hello From String</h1></content>", body
end
it 'allows explicitly wrapping layouts around nested templates' do
render_app { render :str, :explicitly_nested, :layout => :layout2 }
assert ok?
assert_equal "<h1>String Layout!</h1>\n<content><h1>String Layout!</h1>\n<h1>Hello From String</h1></content>", body
end
it 'two independent render calls do not disable layouts' do
render_app do
render :str, :explicitly_nested, :layout => :layout2
render :str, :nested, :layout => :layout2
end
assert ok?
assert_equal "<h1>String Layout!</h1>\n<content><h1>Hello From String</h1></content>", body
end
it 'loads templates from source file' do
mock_app { enable :inline_templates }
assert_equal "this is foo\n\n", @app.templates[:foo][0]
assert_equal "X\n= yield\nX\n", @app.templates[:layout][0]
end
it 'ignores spaces after names of inline templates' do
mock_app { enable :inline_templates }
assert_equal "There's a space after 'bar'!\n\n", @app.templates[:bar][0]
assert_equal "this is not foo\n\n", @app.templates[:"foo bar"][0]
end
it 'loads templates from given source file' do
mock_app { set :inline_templates, __FILE__ }
assert_equal "this is foo\n\n", @app.templates[:foo][0]
end
test 'inline_templates ignores IO errors' do
assert_nothing_raised {
mock_app {
set :inline_templates, '/foo/bar'
}
}
assert @app.templates.empty?
end
it 'loads templates from specified views directory' do
render_app { render :test, :hello, :views => options.views + '/foo' }
assert_equal "from another views directory\n", body
end
it 'passes locals to the layout' do
mock_app {
template :my_layout do
'Hello <%= name %>!<%= yield %>'
end
get '/' do
erb '<p>content</p>', { :layout => :my_layout }, { :name => 'Mike'}
end
}
get '/'
assert ok?
assert_equal 'Hello Mike!<p>content</p>', body
end
it 'loads templates defined in subclasses' do
base = Class.new(Sinatra::Base)
base.template(:foo) { 'bar' }
render_app(base) { render :test, :foo }
assert ok?
assert_equal 'bar', body
end
it 'allows setting default content type per template engine' do
render_app(:str => { :content_type => :txt }) { render :str, 'foo' }
assert_equal 'text/plain;charset=utf-8', response['Content-Type']
end
it 'setting default content type does not affect other template engines' do
render_app(:str => { :content_type => :txt }) { render :test, 'foo' }
assert_equal 'text/html;charset=utf-8', response['Content-Type']
end
it 'setting default content type per template engine does not override content_type' do
render_app :str => { :content_type => :txt } do
content_type :html
render :str, 'foo'
end
assert_equal 'text/html;charset=utf-8', response['Content-Type']
end
it 'uses templates in superclasses before subclasses' do
base = Class.new(Sinatra::Base)
base.template(:foo) { 'template in superclass' }
assert_equal 'template in superclass', base.templates[:foo].first.call
mock_app(base) {
set :views, File.dirname(__FILE__) + '/views'
template(:foo) { 'template in subclass' }
get('/') { render :test, :foo }
}
assert_equal 'template in subclass', @app.templates[:foo].first.call
get '/'
assert ok?
assert_equal 'template in subclass', body
end
end
# __END__ : this is not the real end of the script.
__END__
@@ foo
this is foo
@@ bar
There's a space after 'bar'!
@@ foo bar
this is not foo
@@ layout
X
= yield
X