require 'contest'
require 'tilt'
require 'tempfile'
class TiltTemplateTest < Test::Unit::TestCase
class MockTemplate < Tilt::Template
def prepare
end
end
test "needs a file or block" do
assert_raise(ArgumentError) { Tilt::Template.new }
end
test "initializing with a file" do
inst = MockTemplate.new('foo.erb') {}
assert_equal 'foo.erb', inst.file
end
test "initializing with a file and line" do
inst = MockTemplate.new('foo.erb', 55) {}
assert_equal 'foo.erb', inst.file
assert_equal 55, inst.line
end
test "initializing with a tempfile" do
tempfile = Tempfile.new('tilt_template_test')
inst = MockTemplate.new(tempfile)
assert_equal File.basename(tempfile.path), inst.basename
end
test "uses correct eval_file" do
inst = MockTemplate.new('foo.erb', 55) {}
assert_equal 'foo.erb', inst.eval_file
end
test "uses a default filename for #eval_file when no file provided" do
inst = MockTemplate.new { 'Hi' }
assert_not_nil inst.eval_file
assert !inst.eval_file.include?("\n")
end
test "calculating template's #basename" do
inst = MockTemplate.new('/tmp/templates/foo.html.erb') {}
assert_equal 'foo.html.erb', inst.basename
end
test "calculating the template's #name" do
inst = MockTemplate.new('/tmp/templates/foo.html.erb') {}
assert_equal 'foo', inst.name
end
test "initializing with a data loading block" do
MockTemplate.new { |template| "Hello World!" }
end
class InitializingMockTemplate < Tilt::Template
@@initialized_count = 0
def self.initialized_count
@@initialized_count
end
def initialize_engine
@@initialized_count += 1
end
def prepare
end
end
test "one-time template engine initialization" do
assert_nil InitializingMockTemplate.engine_initialized
assert_equal 0, InitializingMockTemplate.initialized_count
InitializingMockTemplate.new { "Hello World!" }
assert InitializingMockTemplate.engine_initialized
assert_equal 1, InitializingMockTemplate.initialized_count
InitializingMockTemplate.new { "Hello World!" }
assert_equal 1, InitializingMockTemplate.initialized_count
end
class PreparingMockTemplate < Tilt::Template
include Test::Unit::Assertions
def prepare
assert !data.nil?
@prepared = true
end
def prepared? ; @prepared ; end
end
test "raises NotImplementedError when #prepare not defined" do
assert_raise(NotImplementedError) { Tilt::Template.new { |template| "Hello World!" } }
end
test "raises NotImplementedError when #evaluate or #template_source not defined" do
inst = PreparingMockTemplate.new { |t| "Hello World!" }
assert_raise(NotImplementedError) { inst.render }
assert inst.prepared?
end
class SimpleMockTemplate < PreparingMockTemplate
include Test::Unit::Assertions
def evaluate(scope, locals, &block)
assert prepared?
assert !scope.nil?
assert !locals.nil?
"#{@data}"
end
end
test "prepares and evaluates the template on #render" do
inst = SimpleMockTemplate.new { |t| "Hello World!" }
assert_equal "Hello World!", inst.render
assert inst.prepared?
end
class SourceGeneratingMockTemplate < PreparingMockTemplate
def precompiled_template(locals)
"foo = [] ; foo << %Q{#{data}} ; foo.join"
end
end
test "template_source with locals" do
inst = SourceGeneratingMockTemplate.new { |t| 'Hey #{name}!' }
assert_equal "Hey Joe!", inst.render(Object.new, :name => 'Joe')
assert inst.prepared?
end
test "template_source with locals of strings" do
inst = SourceGeneratingMockTemplate.new { |t| 'Hey #{name}!' }
assert_equal "Hey Joe!", inst.render(Object.new, 'name' => 'Joe')
assert inst.prepared?
end
test "template_source with locals having non-variable keys raises error" do
inst = SourceGeneratingMockTemplate.new { |t| '1 + 2 = #{_answer}' }
err = assert_raise(RuntimeError) { inst.render(Object.new, 'ANSWER' => 3) }
assert_equal "invalid locals key: \"ANSWER\" (keys must be variable names)", err.message
assert_equal "1 + 2 = 3", inst.render(Object.new, '_answer' => 3)
end
class Person
CONSTANT = "Bob"
attr_accessor :name
def initialize(name)
@name = name
end
end
test "template_source with an object scope" do
inst = SourceGeneratingMockTemplate.new { |t| 'Hey #{@name}!' }
scope = Person.new('Joe')
assert_equal "Hey Joe!", inst.render(scope)
end
test "template_source with a block for yield" do
inst = SourceGeneratingMockTemplate.new { |t| 'Hey #{yield}!' }
assert_equal "Hey Joe!", inst.render(Object.new){ 'Joe' }
end
test "template which accesses a constant" do
inst = SourceGeneratingMockTemplate.new { |t| 'Hey #{CONSTANT}!' }
assert_equal "Hey Bob!", inst.render(Person.new("Joe"))
end
end