2009-07-01 03:19:46 -04:00
# -*- coding: utf-8 -*-
2012-04-26 15:43:39 -04:00
require File . dirname ( __FILE__ ) + '/test_helper'
2006-08-06 00:25:31 -04:00
2006-09-29 14:39:13 -04:00
class EngineTest < Test :: Unit :: TestCase
2008-08-29 20:40:59 -04:00
# A map of erroneous Haml documents to the error messages they should produce.
2008-04-24 16:47:59 -04:00
# The error messages may be arrays;
# if so, the second element should be the line number that should be reported for the error.
# If this isn't provided, the tests will assume the line number should be the last line of the document.
2008-04-18 14:08:49 -04:00
EXCEPTION_MAP = {
2008-04-18 14:43:29 -04:00
" !!! \n a " = > " Illegal nesting: nesting within a header command is illegal. " ,
" a \n b " = > " Illegal nesting: nesting within plain text is illegal. " ,
" / a \n b " = > " Illegal nesting: nesting within a tag that already has content is illegal. " ,
" % a " = > 'Invalid tag: "% a".' ,
" %p a \n b " = > " Illegal nesting: content can't be both given on the same line as %p and nested within it. " ,
2008-04-18 15:25:00 -04:00
" %p= " = > " There's no Ruby code for = to evaluate. " ,
" %p~ " = > " There's no Ruby code for ~ to evaluate. " ,
" ~ " = > " There's no Ruby code for ~ to evaluate. " ,
" = " = > " There's no Ruby code for = to evaluate. " ,
2008-04-18 15:54:15 -04:00
" %p/ \n a " = > " Illegal nesting: nesting within a self-closing tag is illegal. " ,
2008-04-24 16:47:59 -04:00
" :a \n b " = > [ 'Filter "a" is not defined.' , 1 ] ,
2008-04-18 14:43:29 -04:00
" :a= b " = > 'Invalid filter name ":a= b".' ,
2008-04-18 14:08:49 -04:00
" . " = > " Illegal element: classes and ids must have values. " ,
" . # " = > " Illegal element: classes and ids must have values. " ,
" .{} a " = > " Illegal element: classes and ids must have values. " ,
2009-05-19 17:28:34 -04:00
" .() a " = > " Illegal element: classes and ids must have values. " ,
2008-04-18 14:08:49 -04:00
" .= a " = > " Illegal element: classes and ids must have values. " ,
" %p..a " = > " Illegal element: classes and ids must have values. " ,
2008-04-18 15:54:15 -04:00
" %a/ b " = > " Self-closing tags can't have content. " ,
2008-05-29 16:47:40 -04:00
" %p{:a => 'b', \n :c => 'd'}/ e " = > [ " Self-closing tags can't have content. " , 2 ] ,
" %p{:a => 'b', \n :c => 'd'}= " = > [ " There's no Ruby code for = to evaluate. " , 2 ] ,
" %p.{:a => 'b', \n :c => 'd'} e " = > [ " Illegal element: classes and ids must have values. " , 1 ] ,
" %p{:a => 'b', \n :c => 'd', \n :e => 'f'} \n %p/ a " = > [ " Self-closing tags can't have content. " , 4 ] ,
" %p{:a => 'b', \n :c => 'd', \n :e => 'f'} \n - raise 'foo' " = > [ " foo " , 4 ] ,
" %p{:a => 'b', \n :c => raise('foo'), \n :e => 'f'} " = > [ " foo " , 2 ] ,
" %p{:a => 'b', \n :c => 'd', \n :e => raise('foo')} " = > [ " foo " , 3 ] ,
2008-05-29 22:07:12 -04:00
" %p foo " = > " Indenting at the beginning of the document is illegal. " ,
" %p foo " = > " Indenting at the beginning of the document is illegal. " ,
2010-03-06 17:54:52 -05:00
" - end " = > <<MESSAGE.rstrip,
You don ' t need to use " - end " in Haml . Un - indent to close a block :
- if foo?
% strong Foo !
- else
Not foo .
% p This line is un - indented , so it isn ' t part of the " if " block
MESSAGE
2008-06-01 00:35:07 -04:00
" \n \t \n %p foo " = > [ " Indenting at the beginning of the document is illegal. " , 3 ] ,
2008-05-29 22:07:12 -04:00
" \n \n %p foo " = > [ " Indenting at the beginning of the document is illegal. " , 3 ] ,
2008-05-31 23:33:05 -04:00
" %p \n foo \n foo " = > [ " Inconsistent indentation: 1 space was used for indentation, but the rest of the document was indented using 2 spaces. " , 3 ] ,
" %p \n foo \n %p \n foo " = > [ " Inconsistent indentation: 1 space was used for indentation, but the rest of the document was indented using 2 spaces. " , 4 ] ,
" %p \n \t \t foo \n \t foo " = > [ " Inconsistent indentation: 1 tab was used for indentation, but the rest of the document was indented using 2 tabs. " , 3 ] ,
" %p \n foo \n foo " = > [ " Inconsistent indentation: 3 spaces were used for indentation, but the rest of the document was indented using 2 spaces. " , 3 ] ,
" %p \n foo \n %p \n bar " = > [ " Inconsistent indentation: 3 spaces were used for indentation, but the rest of the document was indented using 2 spaces. " , 4 ] ,
" %p \n :plain \n bar \n \t baz " = > [ 'Inconsistent indentation: " \t " was used for indentation, but the rest of the document was indented using 2 spaces.' , 4 ] ,
" %p \n foo \n %p \n bar " = > [ " The line was indented 2 levels deeper than the previous line. " , 4 ] ,
" %p \n foo \n %p \n bar " = > [ " The line was indented 3 levels deeper than the previous line. " , 4 ] ,
2008-06-01 01:03:28 -04:00
" %p \n \t foo " = > [ " Indentation can't use both tabs and spaces. " , 2 ] ,
2009-05-19 17:28:34 -04:00
" %p( " = > " Invalid attribute list: \" ( \" . " ,
" %p(foo= \n bar) " = > [ " Invalid attribute list: \" (foo= \" . " , 1 ] ,
" %p(foo=) " = > " Invalid attribute list: \" (foo=) \" . " ,
" %p(foo 'bar') " = > " Invalid attribute list: \" (foo 'bar') \" . " ,
" %p(foo 'bar' \n baz='bang') " = > [ " Invalid attribute list: \" (foo 'bar' \" . " , 1 ] ,
" %p(foo='bar' \n baz 'bang' \n bip='bop') " = > [ " Invalid attribute list: \" (foo='bar' baz 'bang' \" . " , 2 ] ,
2009-09-27 20:37:22 -04:00
" %p{:foo => 'bar' :bar => 'baz'} " = > :compile ,
2009-09-27 20:38:15 -04:00
" %p{:foo => } " = > :compile ,
" %p{=> 'bar'} " = > :compile ,
" %p{:foo => 'bar} " = > :compile ,
" %p{'foo => 'bar'} " = > :compile ,
" %p{:foo => 'bar \" } " = > :compile ,
2008-04-29 00:28:01 -04:00
# Regression tests
" - raise 'foo' \n \n \n \n bar " = > [ " foo " , 1 ] ,
2008-05-02 03:48:39 -04:00
" = 'foo' \n -raise 'foo' " = > [ " foo " , 2 ] ,
" \n \n \n - raise 'foo' " = > [ " foo " , 4 ] ,
2008-05-29 03:13:34 -04:00
" %p foo | \n bar | \n baz | \n bop \n - raise 'foo' " = > [ " foo " , 5 ] ,
2008-05-29 04:30:29 -04:00
" foo \n \n \n bar " = > [ " Illegal nesting: nesting within plain text is illegal. " , 4 ] ,
" %p/ \n \n bar " = > [ " Illegal nesting: nesting within a self-closing tag is illegal. " , 3 ] ,
" %p foo \n \n bar " = > [ " Illegal nesting: content can't be both given on the same line as %p and nested within it. " , 3 ] ,
" / foo \n \n bar " = > [ " Illegal nesting: nesting within a tag that already has content is illegal. " , 3 ] ,
" !!! \n \n bar " = > [ " Illegal nesting: nesting within a header command is illegal. " , 3 ] ,
2008-07-15 23:35:08 -04:00
" foo \n :ruby \n 1 \n 2 \n 3 \n - raise 'foo' " = > [ " foo " , 6 ] ,
2010-01-29 15:13:57 -05:00
" foo \n :erb \n 1 \n 2 \n 3 \n - raise 'foo' " = > [ " foo " , 6 ] ,
2010-03-18 01:25:46 -04:00
" foo \n :plain \n 1 \n 2 \n 3 \n - raise 'foo' " = > [ " foo " , 6 ] ,
" foo \n :plain \n 1 \n 2 \n 3 \n 4 \n - raise 'foo' " = > [ " foo " , 7 ] ,
" foo \n :plain \n 1 \n 2 \n 3 \# {''} \n - raise 'foo' " = > [ " foo " , 6 ] ,
" foo \n :plain \n 1 \n 2 \n 3 \# {''} \n 4 \n - raise 'foo' " = > [ " foo " , 7 ] ,
" foo \n :plain \n 1 \n 2 \n \# {raise 'foo'} " = > [ " foo " , 5 ] ,
2009-11-03 23:18:13 -05:00
" = raise 'foo' \n foo \n bar \n baz \n bang " = > [ " foo " , 1 ] ,
2010-10-03 22:06:42 -04:00
" - case 1 \n \n - when 1 \n - raise 'foo' " = > [ " foo " , 4 ] ,
2008-04-18 14:08:49 -04:00
}
2006-08-05 23:18:54 -04:00
2008-04-28 00:14:12 -04:00
User = Struct . new ( 'User' , :id )
2009-07-03 00:32:31 -04:00
class CustomHamlClass < Struct . new ( :id )
def haml_object_ref
" my_thing "
end
end
2011-10-03 08:43:48 -04:00
CpkRecord = Struct . new ( 'CpkRecord' , :id ) do
def to_key
[ * self . id ] unless id . nil?
end
end
2008-04-28 00:14:12 -04:00
2007-11-23 07:14:02 -05:00
def render ( text , options = { } , & block )
2007-11-24 03:35:10 -05:00
scope = options . delete ( :scope ) || Object . new
locals = options . delete ( :locals ) || { }
2008-08-29 20:40:59 -04:00
engine ( text , options ) . to_html ( scope , locals , & block )
2006-08-05 23:18:54 -04:00
end
2012-04-29 10:36:19 -04:00
2008-08-29 20:40:59 -04:00
def engine ( text , options = { } )
unless options [ :filename ]
# use caller method name as fake filename. useful for debugging
i = - 1
caller [ i += 1 ] =~ / `(.+?)' / until $1 and $1 . index ( 'test_' ) == 0
options [ :filename ] = " ( #{ $1 } ) "
end
Haml :: Engine . new ( text , options )
end
2008-11-22 19:54:02 -05:00
2010-09-28 23:15:10 -04:00
def setup
2010-09-29 01:57:54 -04:00
return if Haml :: Util . ruby1_8?
2010-09-28 23:15:10 -04:00
@old_default_internal = Encoding . default_internal
Encoding . default_internal = nil
end
def teardown
2010-09-29 01:57:54 -04:00
return if Haml :: Util . ruby1_8?
2010-09-28 23:15:10 -04:00
Encoding . default_internal = @old_default_internal
end
2008-11-22 19:54:02 -05:00
def test_empty_render
assert_equal " " , render ( " " )
end
2008-05-31 23:33:05 -04:00
def test_flexible_tabulation
assert_equal ( " <p> \n foo \n </p> \n <q> \n bar \n <a> \n baz \n </a> \n </q> \n " ,
render ( " %p \n foo \n %q \n bar \n %a \n baz " ) )
assert_equal ( " <p> \n foo \n </p> \n <q> \n bar \n <a> \n baz \n </a> \n </q> \n " ,
render ( " %p \n \t foo \n %q \n \t bar \n \t %a \n \t \t baz " ) )
assert_equal ( " <p> \n \t \t bar \n baz \n </p> \n " ,
render ( " %p \n :plain \n \t \t bar \n baz " ) )
end
2006-09-29 14:39:13 -04:00
def test_empty_render_should_remain_empty
assert_equal ( '' , render ( '' ) )
2006-08-05 23:18:54 -04:00
end
2006-09-29 14:39:13 -04:00
def test_attributes_should_render_correctly
2008-05-09 19:00:08 -04:00
assert_equal ( " <div class='atlantis' style='ugly'></div> " , render ( " .atlantis{:style => 'ugly'} " ) . chomp )
2006-08-05 23:18:54 -04:00
end
2009-09-18 04:14:53 -04:00
def test_css_id_as_attribute_should_be_appended_with_underscore
assert_equal ( " <div id='my_id_1'></div> " , render ( " # my_id{:id => '1'} " ) . chomp )
assert_equal ( " <div id='my_id_1'></div> " , render ( " # my_id{:id => 1} " ) . chomp )
end
2006-09-29 14:39:13 -04:00
def test_ruby_code_should_work_inside_attributes
author = 'hcatlin'
assert_equal ( " <p class='3'>foo</p> " , render ( " %p{:class => 1+2} foo " ) . chomp )
2006-08-05 23:18:54 -04:00
end
2010-02-27 08:52:09 -05:00
def test_class_attr_with_array
assert_equal ( " <p class='a b'>foo</p> \n " , render ( " %p{:class => %w[a b]} foo " ) ) # basic
assert_equal ( " <p class='a b css'>foo</p> \n " , render ( " %p.css{:class => %w[a b]} foo " ) ) # merge with css
assert_equal ( " <p class='b css'>foo</p> \n " , render ( " %p.css{:class => %w[css b]} foo " ) ) # merge uniquely
assert_equal ( " <p class='a b c d'>foo</p> \n " , render ( " %p{:class => [%w[a b], %w[c d]]} foo " ) ) # flatten
assert_equal ( " <p class='a b'>foo</p> \n " , render ( " %p{:class => [:a, :b] } foo " ) ) # stringify
2010-08-22 19:21:56 -04:00
assert_equal ( " <p>foo</p> \n " , render ( " %p{:class => [nil, false] } foo " ) ) # strip falsey
2010-02-27 08:52:09 -05:00
assert_equal ( " <p class='a'>foo</p> \n " , render ( " %p{:class => :a} foo " ) ) # single stringify
assert_equal ( " <p>foo</p> \n " , render ( " %p{:class => false} foo " ) ) # single falsey
assert_equal ( " <p class='a b html'>foo</p> \n " , render ( " %p(class='html'){:class => %w[a b]} foo " ) ) # html attrs
end
def test_id_attr_with_array
assert_equal ( " <p id='a_b'>foo</p> \n " , render ( " %p{:id => %w[a b]} foo " ) ) # basic
assert_equal ( " <p id='css_a_b'>foo</p> \n " , render ( " %p # css{:id => %w[a b]} foo " ) ) # merge with css
assert_equal ( " <p id='a_b_c_d'>foo</p> \n " , render ( " %p{:id => [%w[a b], %w[c d]]} foo " ) ) # flatten
assert_equal ( " <p id='a_b'>foo</p> \n " , render ( " %p{:id => [:a, :b] } foo " ) ) # stringify
2010-08-22 19:21:56 -04:00
assert_equal ( " <p>foo</p> \n " , render ( " %p{:id => [nil, false] } foo " ) ) # strip falsey
2010-02-27 08:52:09 -05:00
assert_equal ( " <p id='a'>foo</p> \n " , render ( " %p{:id => :a} foo " ) ) # single stringify
assert_equal ( " <p>foo</p> \n " , render ( " %p{:id => false} foo " ) ) # single falsey
assert_equal ( " <p id='html_a_b'>foo</p> \n " , render ( " %p(id='html'){:id => %w[a b]} foo " ) ) # html attrs
end
2010-07-05 17:20:26 -04:00
def test_colon_in_class_attr
assert_equal ( " <p class='foo:bar' /> \n " , render ( " %p.foo:bar/ " ) )
end
def test_colon_in_id_attr
assert_equal ( " <p id='foo:bar' /> \n " , render ( " %p # foo:bar/ " ) )
end
2009-10-25 17:36:09 -04:00
def test_dynamic_attributes_with_no_content
assert_equal ( <<HTML, render(<<HAML))
< p >
< a href = 'http://haml-lang.com' > < / a>
< / p>
HTML
% p
% a { :href = > " http:// " + " haml-lang.com " }
HAML
end
2010-02-15 17:16:13 -05:00
def test_attributes_with_to_s
assert_equal ( <<HTML, render(<<HAML))
< p id = 'foo_2' > < / p>
< p class = '2 foo' > < / p>
< p blaz = '2' > < / p>
< p 2 = '2' > < / p>
HTML
% p #foo{:id => 1+1}
% p . foo { :class = > 1 + 1 }
% p { :blaz = > 1 + 1 }
% p { ( 1 + 1 ) = > 1 + 1 }
HAML
end
2006-09-29 14:39:13 -04:00
def test_nil_should_render_empty_tag
2008-05-09 19:00:08 -04:00
assert_equal ( " <div class='no_attributes'></div> " ,
2006-09-29 14:39:13 -04:00
render ( " .no_attributes{:nil => nil} " ) . chomp )
2006-08-05 23:18:54 -04:00
end
2006-09-29 14:39:13 -04:00
def test_strings_should_get_stripped_inside_tags
assert_equal ( " <div class='stripped'>This should have no spaces in front of it</div> " ,
render ( " .stripped This should have no spaces in front of it " ) . chomp )
2006-08-09 14:12:54 -04:00
end
2006-11-04 03:35:06 -05:00
2006-09-29 14:39:13 -04:00
def test_one_liner_should_be_one_line
assert_equal ( " <p>Hello</p> " , render ( '%p Hello' ) . chomp )
2006-08-13 18:02:04 -04:00
end
2006-08-13 18:10:05 -04:00
2008-04-24 22:14:52 -04:00
def test_one_liner_with_newline_shouldnt_be_one_line
assert_equal ( " <p> \n foo \n bar \n </p> " , render ( '%p= "foo\nbar"' ) . chomp )
2007-07-16 23:48:11 -04:00
end
2006-11-04 03:35:06 -05:00
2006-10-27 16:48:40 -04:00
def test_multi_render
2008-08-29 20:40:59 -04:00
engine = engine ( " %strong Hi there! " )
2006-10-27 16:48:40 -04:00
assert_equal ( " <strong>Hi there!</strong> \n " , engine . to_html )
assert_equal ( " <strong>Hi there!</strong> \n " , engine . to_html )
assert_equal ( " <strong>Hi there!</strong> \n " , engine . to_html )
end
2006-11-04 03:35:06 -05:00
2009-04-17 05:08:12 -04:00
def test_interpolation
assert_equal ( " <p>Hello World</p> \n " , render ( '%p Hello #{who}' , :locals = > { :who = > 'World' } ) )
assert_equal ( " <p> \n Hello World \n </p> \n " , render ( " %p \n Hello \# {who} " , :locals = > { :who = > 'World' } ) )
2007-05-07 14:16:24 -04:00
end
2009-04-17 05:08:12 -04:00
def test_interpolation_in_the_middle_of_a_string
2007-08-11 15:10:28 -04:00
assert_equal ( " \" title 'Title'. \" \n " ,
2009-04-17 05:08:12 -04:00
render ( " \" title ' \# { \" Title \" }'. \" " ) )
2007-08-11 15:10:28 -04:00
end
2009-04-17 05:14:38 -04:00
def test_interpolation_at_the_beginning_of_a_line
assert_equal ( " <p>2</p> \n " , render ( '%p #{1 + 1}' ) )
assert_equal ( " <p> \n 2 \n </p> \n " , render ( " %p \n \# {1 + 1} " ) )
end
2009-10-16 21:31:04 -04:00
def test_escaped_interpolation
assert_equal ( " <p>Foo & Bar & Baz</p> \n " , render ( '%p& Foo #{"&"} Bar & Baz' ) )
end
2007-08-16 17:49:53 -04:00
def test_nil_tag_value_should_render_as_empty
assert_equal ( " <p></p> \n " , render ( " %p= nil " ) )
end
def test_tag_with_failed_if_should_render_as_empty
assert_equal ( " <p></p> \n " , render ( " %p= 'Hello' if false " ) )
end
2007-11-22 00:29:26 -05:00
def test_static_attributes_with_empty_attr
assert_equal ( " <img alt='' src='/foo.png' /> \n " , render ( " %img{:src => '/foo.png', :alt => ''} " ) )
end
def test_dynamic_attributes_with_empty_attr
assert_equal ( " <img alt='' src='/foo.png' /> \n " , render ( " %img{:width => nil, :src => '/foo.png', :alt => String.new} " ) )
end
2008-05-29 16:47:40 -04:00
def test_attribute_hash_with_newlines
assert_equal ( " <p a='b' c='d'>foop</p> \n " , render ( " %p{:a => 'b', \n :c => 'd'} foop " ) )
assert_equal ( " <p a='b' c='d'> \n foop \n </p> \n " , render ( " %p{:a => 'b', \n :c => 'd'} \n foop " ) )
assert_equal ( " <p a='b' c='d' /> \n " , render ( " %p{:a => 'b', \n :c => 'd'}/ " ) )
assert_equal ( " <p a='b' c='d' e='f'></p> \n " , render ( " %p{:a => 'b', \n :c => 'd', \n :e => 'f'} " ) )
end
2008-10-03 01:38:40 -04:00
def test_attr_hashes_not_modified
hash = { :color = > 'red' }
assert_equal ( <<HTML, render(<<HAML, :locals => {:hash => hash}))
< div color = 'red' > < / div>
< div class = 'special' color = 'red' > < / div>
< div color = 'red' > < / div>
HTML
% div { hash }
. special { hash }
% div { hash }
HAML
assert_equal ( hash , { :color = > 'red' } )
end
2010-10-27 03:33:40 -04:00
def test_ugly_semi_prerendered_tags
assert_equal ( <<HTML, render(<<HAML, :ugly => true))
< p a = '2' > < / p>
< p a = '2' > foo < / p>
< p a = '2' / >
< p a = '2' > foo < / p>
< p a = '2' > foo
bar < / p>
< p a = '2' > foo
bar < / p>
< p a = '2' >
foo
< / p>
HTML
% p { :a = > 1 + 1 }
% p { :a = > 1 + 1 } foo
% p { :a = > 1 + 1 } /
% p { :a = > 1 + 1 } = " foo "
% p { :a = > 1 + 1 } = " foo \\ nbar "
% p { :a = > 1 + 1 } ~ " foo \\ nbar "
% p { :a = > 1 + 1 }
foo
HAML
end
2008-01-09 15:54:36 -05:00
def test_end_of_file_multiline
assert_equal ( " <p>0</p> \n <p>1</p> \n <p>2</p> \n " , render ( " - for i in (0...3) \n %p= | \n i | " ) )
end
2008-01-31 01:21:24 -05:00
def test_cr_newline
assert_equal ( " <p>foo</p> \n <p>bar</p> \n <p>baz</p> \n <p>boom</p> \n " , render ( " %p foo \r %p bar \r \n %p baz \n \r %p boom " ) )
end
2008-03-02 19:12:57 -05:00
def test_textareas
2008-04-24 15:59:03 -04:00
assert_equal ( " <textarea>Foo& # x000A; bar& # x000A; baz</textarea> \n " ,
2008-03-02 19:12:57 -05:00
render ( '%textarea= "Foo\n bar\n baz"' ) )
2008-04-24 15:59:03 -04:00
assert_equal ( " <pre>Foo& # x000A; bar& # x000A; baz</pre> \n " ,
2008-03-02 19:24:47 -05:00
render ( '%pre= "Foo\n bar\n baz"' ) )
2008-03-02 19:12:57 -05:00
assert_equal ( " <textarea> #{ 'a' * 100 } </textarea> \n " ,
render ( " %textarea #{ 'a' * 100 } " ) )
2008-05-11 04:39:02 -04:00
assert_equal ( " <p> \n <textarea>Foo \n Bar \n Baz</textarea> \n </p> \n " , render ( <<SOURCE))
% p
% textarea
Foo
Bar
Baz
SOURCE
2008-03-02 19:12:57 -05:00
end
2009-10-05 22:25:13 -04:00
def test_pre_code
assert_equal ( <<HTML, render(<<HAML))
< pre > < code > Foo & #x000A; bar
 baz</code></pre>
HTML
% pre
% code
:preserve
Foo
bar
baz
HAML
end
2008-03-02 20:20:43 -05:00
def test_boolean_attributes
2008-05-09 19:00:08 -04:00
assert_equal ( " <p bar baz='true' foo='bar'></p> \n " ,
2008-03-02 20:20:43 -05:00
render ( " %p{:foo => 'bar', :bar => true, :baz => 'true'} " , :format = > :html4 ) )
2008-05-09 19:00:08 -04:00
assert_equal ( " <p bar='bar' baz='true' foo='bar'></p> \n " ,
2008-03-02 20:20:43 -05:00
render ( " %p{:foo => 'bar', :bar => true, :baz => 'true'} " , :format = > :xhtml ) )
2008-05-09 19:00:08 -04:00
assert_equal ( " <p baz='false' foo='bar'></p> \n " ,
2008-03-02 20:20:43 -05:00
render ( " %p{:foo => 'bar', :bar => false, :baz => 'false'} " , :format = > :html4 ) )
2008-05-09 19:00:08 -04:00
assert_equal ( " <p baz='false' foo='bar'></p> \n " ,
2008-03-02 20:20:43 -05:00
render ( " %p{:foo => 'bar', :bar => false, :baz => 'false'} " , :format = > :xhtml ) )
end
2008-05-10 06:23:47 -04:00
def test_both_whitespace_nukes_work_together
assert_equal ( <<RESULT, render(<<SOURCE))
< p > < q > Foo
Bar < / q>< / p >
RESULT
% p
% q > < = " Foo \\ nBar "
SOURCE
end
2010-01-07 18:40:39 -05:00
def test_nil_option
assert_equal ( " <p foo='bar'></p> \n " , render ( '%p{:foo => "bar"}' , :attr_wrapper = > nil ) )
end
2011-05-10 18:27:13 -04:00
def test_comment_with_crazy_nesting
assert_equal ( <<HTML, render(<<HAML))
foo
bar
HTML
foo
- #
ul
% li {
foo
bar
HAML
end
2009-01-23 13:48:35 -05:00
# Regression tests
2011-11-23 20:05:39 -05:00
unless Haml :: Util . ruby1_8?
def test_indentation_after_dynamic_attr_hash
assert_equal ( <<HTML, render(<<HAML))
< html >
< body >
< img src = 'test' / >
foo
bar
< / body>
< / html>
HTML
% html
% body
% img { :src = > 'te' + 'st' }
= " foo \\ nbar "
HAML
end
end
2009-01-08 21:10:25 -05:00
def test_whitespace_nuke_with_both_newlines
assert_equal ( " <p>foo</p> \n " , render ( '%p<= "\nfoo\n"' ) )
assert_equal ( <<HTML, render(<<HAML))
< p >
< p > foo < / p>
< / p>
HTML
% p
% p < = " \\ nfoo \\ n "
HAML
end
2009-10-08 07:14:16 -04:00
def test_whitespace_nuke_with_tags_and_else
assert_equal ( <<HTML, render(<<HAML))
< a >
< b > foo < / b>
< / a>
HTML
% a
% b <
- if false
= " foo "
- else
foo
HAML
assert_equal ( <<HTML, render(<<HAML))
< a >
< b >
foo
< / b>
< / a>
HTML
% a
% b
- if false
= " foo "
- else
foo
HAML
end
2009-11-02 18:12:42 -05:00
def test_outer_whitespace_nuke_with_empty_script
assert_equal ( <<HTML, render(<<HAML))
< p >
foo < a > < / a>< / p >
HTML
% p
foo
= " "
% a >
HAML
end
2008-10-29 23:36:53 -04:00
def test_both_case_indentation_work_with_deeply_nested_code
result = <<RESULT
< h2 >
other
< / h2>
RESULT
assert_equal ( result , render ( <<HAML))
- case 'other'
- when 'test'
% h2
hi
- when 'other'
% h2
other
HAML
assert_equal ( result , render ( <<HAML))
- case 'other'
- when 'test'
% h2
hi
- when 'other'
% h2
other
HAML
end
2009-01-23 13:48:35 -05:00
def test_equals_block_with_ugly
2009-01-23 15:19:24 -05:00
assert_equal ( " foo \n " , render ( <<HAML, :ugly => true))
2009-01-23 13:48:35 -05:00
= capture_haml do
foo
HAML
end
2009-01-23 15:19:24 -05:00
def test_plain_equals_with_ugly
assert_equal ( " foo \n bar \n " , render ( <<HAML, :ugly => true))
= " foo "
bar
HAML
end
2009-02-26 15:59:28 -05:00
def test_inline_if
assert_equal ( <<HTML, render(<<HAML))
< p > One < / p>
< p > < / p>
< p > Three < / p>
HTML
- for name in [ " One " , " Two " , " Three " ]
% p = name unless name == " Two "
HAML
end
2009-03-15 22:06:43 -04:00
def test_end_with_method_call
assert_equal ( <<HTML, render(<<HAML))
2 | 3 | 4
b - a - r
HTML
= [ 1 , 2 , 3 ] . map do | i |
- i + 1
- end . join ( " | " )
= " bar " . gsub ( / . / ) do | s |
- s + " - "
- end . gsub ( / -$ / ) do | s |
- ''
HAML
end
2009-10-08 07:00:27 -04:00
def test_nested_end_with_method_call
assert_equal ( <<HTML, render(<<HAML))
< p >
2 | 3 | 4
b - a - r
< / p>
HTML
% p
= [ 1 , 2 , 3 ] . map do | i |
- i + 1
- end . join ( " | " )
= " bar " . gsub ( / . / ) do | s |
- s + " - "
- end . gsub ( / -$ / ) do | s |
- ''
HAML
end
2009-08-28 02:01:56 -04:00
def test_silent_end_with_stuff
assert_equal ( <<HTML, render(<<HAML))
e
d
c
b
a
HTML
- str = " abcde "
- if true
= str . slice! ( - 1 ) . chr
- end until str . empty?
HAML
assert_equal ( <<HTML, render(<<HAML))
< p > hi! < / p>
HTML
- if true
% p hi!
- end if " foo " . gsub ( / f / ) do
- " z "
- end + " bar "
HAML
end
2009-03-18 13:47:39 -04:00
def test_multiline_with_colon_after_filter
assert_equal ( <<HTML, render(<<HAML))
Foo
Bar
HTML
:plain
Foo
= { :a = > " Bar " , |
:b = > " Baz " } [ :a ] |
HAML
assert_equal ( <<HTML, render(<<HAML))
Bar
HTML
:plain
= { :a = > " Bar " , |
:b = > " Baz " } [ :a ] |
HAML
end
def test_multiline_in_filter
assert_equal ( <<HTML, render(<<HAML))
Foo |
Bar |
Baz
HTML
:plain
Foo |
Bar |
Baz
HAML
end
2009-03-28 03:19:13 -04:00
def test_curly_brace
assert_equal ( <<HTML, render(<<HAML))
Foo { Bar
HTML
== Foo { Bar
HAML
end
2010-10-12 00:05:53 -04:00
def test_escape_attrs_false
assert_equal ( <<HTML, render(<<HAML, :escape_attrs => false))
< div class = '<?php echo """ ?>' id = 'foo' >
bar
< / div>
HTML
#foo{:class => '<?php echo """ ?>'}
bar
HAML
end
def test_escape_attrs_always
assert_equal ( <<HTML, render(<<HAML, :escape_attrs => :always))
< div class = '"&lt;&gt;&amp;"' id = 'foo' >
bar
< / div>
HTML
#foo{:class => '"<>&"'}
bar
2009-03-28 03:19:13 -04:00
HAML
end
2009-07-10 15:35:42 -04:00
def test_escape_html
html = <<HTML
& amp ;
&
& amp ;
HTML
assert_equal ( html , render ( <<HAML, :escape_html => true))
& = " & "
!= " & "
= " & "
HAML
assert_equal ( html , render ( <<HAML, :escape_html => true))
& ~ " & "
!~ " & "
~ " & "
HAML
assert_equal ( html , render ( <<HAML, :escape_html => true))
& \ #{"&"}
! \ #{"&"}
\ #{"&"}
HAML
assert_equal ( html , render ( <<HAML, :escape_html => true))
& == \ #{"&"}
!= = \ #{"&"}
== \ #{"&"}
HAML
tag_html = <<HTML
< p > & amp ; < / p>
< p > & < / p>
< p > & amp ; < / p>
HTML
assert_equal ( tag_html , render ( <<HAML, :escape_html => true))
% p & = " & "
% p != " & "
% p = " & "
HAML
assert_equal ( tag_html , render ( <<HAML, :escape_html => true))
% p & ~ " & "
% p !~ " & "
% p ~ " & "
HAML
assert_equal ( tag_html , render ( <<HAML, :escape_html => true))
% p & \ #{"&"}
% p ! \ #{"&"}
% p \ #{"&"}
HAML
assert_equal ( tag_html , render ( <<HAML, :escape_html => true))
% p & == \ #{"&"}
% p != = \ #{"&"}
% p == \ #{"&"}
HAML
end
2009-07-12 10:36:47 -04:00
def test_new_attrs_with_hash
assert_equal ( " <a href=' # '></a> \n " , render ( '%a(href="#")' ) )
end
2009-07-19 19:26:43 -04:00
def test_javascript_filter_with_dynamic_interp_and_escape_html
assert_equal ( <<HTML, render(<<HAML, :escape_html => true))
< script type = 'text/javascript' >
/ / < ! [ CDATA [
& < > &
/ / ] ] >
< / script>
HTML
:javascript
& < > \ #{"&"}
HAML
end
2010-10-03 20:32:04 -04:00
def test_html5_javascript_filter
assert_equal ( <<HTML, render(<<HAML, :format => :html5))
< script >
/ / < ! [ CDATA [
foo bar
/ / ] ] >
< / script>
HTML
:javascript
foo bar
HAML
end
def test_html5_css_filter
assert_equal ( <<HTML, render(<<HAML, :format => :html5))
< style >
/ *<![CDATA[* /
foo bar
/ *]]>* /
< / style>
HTML
:css
foo bar
HAML
end
2010-01-29 15:13:57 -05:00
def test_erb_filter_with_multiline_expr
assert_equal ( <<HTML, render(<<HAML))
foobarbaz
HTML
:erb
< %= " foo " +
" bar " +
" baz " % >
HAML
end
2009-09-18 04:36:11 -04:00
def test_silent_script_with_hyphen_case
assert_equal ( " " , render ( " - 'foo-case-bar-case' " ) )
end
def test_silent_script_with_hyphen_end
assert_equal ( " " , render ( " - 'foo-end-bar-end' " ) )
end
def test_silent_script_with_hyphen_end_and_block
assert_equal ( <<HTML, render(<<HAML))
< p > foo - end < / p>
< p > bar - end < / p>
HTML
2010-03-16 19:58:10 -04:00
- ( " foo-end-bar-end " . gsub ( / \\ w+-end / ) do | s |
2009-09-18 04:36:11 -04:00
% p = s
2010-03-16 19:58:10 -04:00
- end ; nil )
2009-09-18 04:36:11 -04:00
HAML
end
2009-11-25 23:04:04 -05:00
def test_if_without_content_and_else
assert_equal ( <<HTML, render(<<HAML))
foo
HTML
- if false
- else
foo
HAML
2010-07-06 19:17:42 -04:00
assert_equal ( <<HTML, render(<<HAML))
foo
HTML
- if true
- if false
- else
foo
HAML
2009-11-25 23:04:04 -05:00
end
2010-01-30 18:58:50 -05:00
def test_html_attributes_with_hash
assert_equal ( " <a href=' # ' rel='top'>Foo</a> \n " ,
render ( '%a(href="#" rel="top") Foo' ) )
assert_equal ( " <a href=' # '>Foo</a> \n " ,
render ( '%a(href="#") #{"Foo"}' ) )
assert_equal ( " <a href=' # \" '></a> \n " , render ( '%a(href="#\\"")' ) )
end
2010-03-31 18:47:25 -04:00
def test_filter_with_newline_and_interp
assert_equal ( <<HTML, render(<<HAML))
\ \ n
HTML
:plain
\ \ n \ #{""}
HAML
end
2010-08-03 00:38:34 -04:00
def test_case_assigned_to_var
assert_equal ( <<HTML, render(<<HAML))
bar
HTML
- var = case 12
- when 1 ; " foo "
- when 12 ; " bar "
= var
HAML
assert_equal ( <<HTML, render(<<HAML))
bar
HTML
- var = case 12
- when 1
- " foo "
- when 12
- " bar "
= var
HAML
assert_equal ( <<HTML, render(<<HAML))
bar
HTML
- var = case 12
- when 1
- " foo "
- when 12
- " bar "
= var
HAML
end
2010-07-19 22:57:30 -04:00
def test_nested_case_assigned_to_var
assert_equal ( <<HTML, render(<<HAML))
bar
HTML
- if true
- var = case 12
- when 1 ; " foo "
- when 12 ; " bar "
= var
HAML
end
def test_case_assigned_to_multiple_vars
assert_equal ( <<HTML, render(<<HAML))
bar
bip
HTML
- var , vip = case 12
- when 1 ; [ " foo " , " baz " ]
- when 12 ; [ " bar " , " bip " ]
= var
= vip
HAML
end
2010-08-03 00:38:34 -04:00
def test_if_assigned_to_var
assert_equal ( <<HTML, render(<<HAML))
foo
HTML
- var = if false
- else
- " foo "
= var
HAML
assert_equal ( <<HTML, render(<<HAML))
foo
HTML
- var = if false
- elsif 12
- " foo "
- elsif 14 ; " bar "
- else
- " baz "
= var
HAML
assert_equal ( <<HTML, render(<<HAML))
foo
HTML
- var = if false
- " bar "
- else
- " foo "
= var
HAML
end
2010-10-03 22:06:42 -04:00
def test_case_with_newline_after_case
assert_equal ( <<HTML, render(<<HAML))
foo
HTML
- case 1
- when 1
foo
- when 2
bar
HAML
assert_equal ( <<HTML, render(<<HAML))
bar
HTML
- case 2
- when 1
foo
- when 2
bar
HAML
end
2010-09-29 02:36:10 -04:00
def test_escape_html_with_interpolated_if_statement
assert_equal ( <<HTML, render(<<HAML, :escape_html => true))
foo ,
HTML
foo \ #{"," if true}
HAML
end
2008-03-14 19:39:19 -04:00
# HTML escaping tests
2008-03-18 05:19:41 -04:00
def test_ampersand_equals_should_escape
2008-03-14 19:39:19 -04:00
assert_equal ( " <p> \n foo & bar \n </p> \n " , render ( " %p \n &= 'foo & bar' " , :escape_html = > false ) )
end
2008-03-18 05:19:41 -04:00
def test_ampersand_equals_inline_should_escape
2008-03-14 19:39:19 -04:00
assert_equal ( " <p>foo & bar</p> \n " , render ( " %p&= 'foo & bar' " , :escape_html = > false ) )
end
2008-08-04 01:04:50 -04:00
def test_ampersand_equals_should_escape_before_preserve
assert_equal ( " <textarea>foo& # x000A;bar</textarea> \n " , render ( '%textarea&= "foo\nbar"' , :escape_html = > false ) )
end
2008-03-18 05:19:41 -04:00
def test_bang_equals_should_not_escape
2008-03-14 19:39:19 -04:00
assert_equal ( " <p> \n foo & bar \n </p> \n " , render ( " %p \n != 'foo & bar' " , :escape_html = > true ) )
end
2008-03-18 05:19:41 -04:00
def test_bang_equals_inline_should_not_escape
2008-03-14 19:39:19 -04:00
assert_equal ( " <p>foo & bar</p> \n " , render ( " %p!= 'foo & bar' " , :escape_html = > true ) )
end
2012-04-29 10:36:19 -04:00
2008-03-18 05:19:41 -04:00
def test_static_attributes_should_be_escaped
assert_equal ( " <img class='atlantis' style='ugly&stupid' /> \n " ,
2008-07-27 20:44:02 -04:00
render ( " %img.atlantis{:style => 'ugly&stupid'} " ) )
2008-03-18 05:19:41 -04:00
assert_equal ( " <div class='atlantis' style='ugly&stupid'>foo</div> \n " ,
2008-07-27 20:44:02 -04:00
render ( " .atlantis{:style => 'ugly&stupid'} foo " ) )
2008-03-18 05:19:41 -04:00
assert_equal ( " <p class='atlantis' style='ugly&stupid'>foo</p> \n " ,
2008-07-27 20:44:02 -04:00
render ( " %p.atlantis{:style => 'ugly&stupid'}= 'foo' " ) )
2008-07-27 20:50:28 -04:00
assert_equal ( " <p class='atlantis' style='ugly& # x000A;stupid'></p> \n " ,
render ( " %p.atlantis{:style => \" ugly \\ nstupid \" } " ) )
2008-03-18 05:19:41 -04:00
end
def test_dynamic_attributes_should_be_escaped
2008-07-27 20:48:22 -04:00
assert_equal ( " <img alt='' src='&foo.png' /> \n " ,
render ( " %img{:width => nil, :src => '&foo.png', :alt => String.new} " ) )
assert_equal ( " <p alt='' src='&foo.png'>foo</p> \n " ,
render ( " %p{:width => nil, :src => '&foo.png', :alt => String.new} foo " ) )
assert_equal ( " <div alt='' src='&foo.png'>foo</div> \n " ,
render ( " %div{:width => nil, :src => '&foo.png', :alt => String.new}= 'foo' " ) )
2008-07-27 20:50:28 -04:00
assert_equal ( " <img alt='' src='foo& # x000A;.png' /> \n " ,
render ( " %img{:width => nil, :src => \" foo \\ n.png \" , :alt => String.new} " ) )
2008-03-18 05:19:41 -04:00
end
2008-12-11 16:46:14 -05:00
def test_string_double_equals_should_be_esaped
2009-10-16 21:31:04 -04:00
assert_equal ( " <p>4&<</p> \n " , render ( " %p== \# {2+2}& \# {'<'} " , :escape_html = > true ) )
assert_equal ( " <p>4&<</p> \n " , render ( " %p== \# {2+2}& \# {'<'} " , :escape_html = > false ) )
2008-03-18 05:19:41 -04:00
end
2008-12-11 16:46:14 -05:00
def test_escaped_inline_string_double_equals
2009-10-16 21:31:04 -04:00
assert_equal ( " <p>4&<</p> \n " , render ( " %p&== \# {2+2}& \# {'<'} " , :escape_html = > true ) )
assert_equal ( " <p>4&<</p> \n " , render ( " %p&== \# {2+2}& \# {'<'} " , :escape_html = > false ) )
2008-03-18 05:19:41 -04:00
end
2008-03-14 19:39:19 -04:00
2008-12-11 16:46:14 -05:00
def test_unescaped_inline_string_double_equals
2009-10-16 21:31:04 -04:00
assert_equal ( " <p>4&<</p> \n " , render ( " %p!== \# {2+2}& \# {'<'} " , :escape_html = > true ) )
assert_equal ( " <p>4&<</p> \n " , render ( " %p!== \# {2+2}& \# {'<'} " , :escape_html = > false ) )
2008-03-18 05:19:41 -04:00
end
2008-12-11 16:46:14 -05:00
def test_escaped_string_double_equals
2009-10-16 21:31:04 -04:00
assert_equal ( " <p> \n 4&< \n </p> \n " , render ( " %p \n &== \# {2+2}& \# {'<'} " , :escape_html = > true ) )
assert_equal ( " <p> \n 4&< \n </p> \n " , render ( " %p \n &== \# {2+2}& \# {'<'} " , :escape_html = > false ) )
2008-03-18 05:19:41 -04:00
end
2008-12-11 16:46:14 -05:00
def test_unescaped_string_double_equals
2009-10-16 21:31:04 -04:00
assert_equal ( " <p> \n 4&< \n </p> \n " , render ( " %p \n !== \# {2+2}& \# {'<'} " , :escape_html = > true ) )
assert_equal ( " <p> \n 4&< \n </p> \n " , render ( " %p \n !== \# {2+2}& \# {'<'} " , :escape_html = > false ) )
2008-03-18 05:19:41 -04:00
end
2008-12-11 16:46:14 -05:00
def test_string_interpolation_should_be_esaped
2009-10-16 21:31:04 -04:00
assert_equal ( " <p>4&<</p> \n " , render ( " %p \# {2+2}& \# {'<'} " , :escape_html = > true ) )
assert_equal ( " <p>4&<</p> \n " , render ( " %p \# {2+2}& \# {'<'} " , :escape_html = > false ) )
2008-12-11 16:46:14 -05:00
end
def test_escaped_inline_string_interpolation
2009-10-16 21:31:04 -04:00
assert_equal ( " <p>4&<</p> \n " , render ( " %p& \# {2+2}& \# {'<'} " , :escape_html = > true ) )
assert_equal ( " <p>4&<</p> \n " , render ( " %p& \# {2+2}& \# {'<'} " , :escape_html = > false ) )
2008-12-11 16:46:14 -05:00
end
def test_unescaped_inline_string_interpolation
2009-10-16 21:31:04 -04:00
assert_equal ( " <p>4&<</p> \n " , render ( " %p! \# {2+2}& \# {'<'} " , :escape_html = > true ) )
assert_equal ( " <p>4&<</p> \n " , render ( " %p! \# {2+2}& \# {'<'} " , :escape_html = > false ) )
2008-12-11 16:46:14 -05:00
end
def test_escaped_string_interpolation
2009-10-16 21:31:04 -04:00
assert_equal ( " <p> \n 4&< \n </p> \n " , render ( " %p \n & \# {2+2}& \# {'<'} " , :escape_html = > true ) )
assert_equal ( " <p> \n 4&< \n </p> \n " , render ( " %p \n & \# {2+2}& \# {'<'} " , :escape_html = > false ) )
2008-12-11 16:46:14 -05:00
end
def test_unescaped_string_interpolation
2009-10-16 21:31:04 -04:00
assert_equal ( " <p> \n 4&< \n </p> \n " , render ( " %p \n ! \# {2+2}& \# {'<'} " , :escape_html = > true ) )
assert_equal ( " <p> \n 4&< \n </p> \n " , render ( " %p \n ! \# {2+2}& \# {'<'} " , :escape_html = > false ) )
2008-12-11 16:46:14 -05:00
end
2008-03-18 05:19:41 -04:00
def test_scripts_should_respect_escape_html_option
2008-03-14 19:39:19 -04:00
assert_equal ( " <p> \n foo & bar \n </p> \n " , render ( " %p \n = 'foo & bar' " , :escape_html = > true ) )
assert_equal ( " <p> \n foo & bar \n </p> \n " , render ( " %p \n = 'foo & bar' " , :escape_html = > false ) )
end
2008-03-18 05:19:41 -04:00
def test_inline_scripts_should_respect_escape_html_option
2008-03-14 19:39:19 -04:00
assert_equal ( " <p>foo & bar</p> \n " , render ( " %p= 'foo & bar' " , :escape_html = > true ) )
assert_equal ( " <p>foo & bar</p> \n " , render ( " %p= 'foo & bar' " , :escape_html = > false ) )
end
2008-03-18 05:19:41 -04:00
def test_script_ending_in_comment_should_render_when_html_is_escaped
assert_equal ( " foo&bar \n " , render ( " = 'foo&bar' # comment " , :escape_html = > true ) )
end
2009-01-07 19:04:17 -05:00
def test_script_with_if_shouldnt_output
assert_equal ( <<HTML, render(<<HAML))
< p > foo < / p>
< p > < / p>
HTML
% p = " foo "
% p = " bar " if false
HAML
end
2006-11-04 03:35:06 -05:00
# Options tests
2008-05-02 02:54:10 -04:00
def test_filename_and_line
begin
render ( " \n \n = abc " , :filename = > 'test' , :line = > 2 )
rescue Exception = > e
assert_kind_of Haml :: SyntaxError , e
2008-08-29 20:40:59 -04:00
assert_match ( / test:4 / , e . backtrace . first )
2008-05-02 02:54:10 -04:00
end
begin
render ( " \n \n = 123 \n \n = nil[] " , :filename = > 'test' , :line = > 2 )
rescue Exception = > e
assert_kind_of NoMethodError , e
2008-08-29 20:40:59 -04:00
assert_match ( / test:6 / , e . backtrace . first )
2008-05-02 02:54:10 -04:00
end
end
2006-11-04 03:35:06 -05:00
def test_stop_eval
assert_equal ( " " , render ( " = 'Hello' " , :suppress_eval = > true ) )
2008-10-29 23:39:34 -04:00
assert_equal ( " " , render ( " - haml_concat 'foo' " , :suppress_eval = > true ) )
2007-06-02 06:45:24 -04:00
assert_equal ( " <div id='foo' yes='no' /> \n " , render ( " # foo{:yes => 'no'}/ " , :suppress_eval = > true ) )
assert_equal ( " <div id='foo' /> \n " , render ( " # foo{:yes => 'no', :call => a_function() }/ " , :suppress_eval = > true ) )
2007-04-09 13:03:12 -04:00
assert_equal ( " <div /> \n " , render ( " %div[1]/ " , :suppress_eval = > true ) )
2008-10-29 23:39:34 -04:00
assert_equal ( " " , render ( " :ruby \n Kernel.puts 'hello' " , :suppress_eval = > true ) )
2006-11-04 03:35:06 -05:00
end
2008-11-30 00:57:37 -05:00
def test_doctypes
assert_equal ( '<!DOCTYPE html>' ,
render ( '!!!' , :format = > :html5 ) . strip )
2009-11-20 06:07:21 -05:00
assert_equal ( '<!DOCTYPE html>' , render ( '!!! 5' ) . strip )
2008-11-30 00:57:37 -05:00
assert_equal ( '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">' ,
render ( '!!! strict' ) . strip )
assert_equal ( '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">' ,
render ( '!!! frameset' ) . strip )
assert_equal ( '<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">' ,
render ( '!!! mobile' ) . strip )
assert_equal ( '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">' ,
render ( '!!! basic' ) . strip )
assert_equal ( '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">' ,
render ( '!!! transitional' ) . strip )
assert_equal ( '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">' ,
render ( '!!!' ) . strip )
assert_equal ( '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">' ,
render ( '!!! strict' , :format = > :html4 ) . strip )
assert_equal ( '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">' ,
render ( '!!! frameset' , :format = > :html4 ) . strip )
assert_equal ( '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">' ,
render ( '!!! transitional' , :format = > :html4 ) . strip )
assert_equal ( '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">' ,
render ( '!!!' , :format = > :html4 ) . strip )
end
2006-11-04 03:35:06 -05:00
def test_attr_wrapper
2008-05-09 19:00:08 -04:00
assert_equal ( " <p strange=*attrs*></p> \n " , render ( " %p{ :strange => 'attrs'} " , :attr_wrapper = > '*' ) )
assert_equal ( " <p escaped='quo \" te'></p> \n " , render ( " %p{ :escaped => 'quo \" te'} " , :attr_wrapper = > '"' ) )
assert_equal ( " <p escaped= \" quo'te \" ></p> \n " , render ( " %p{ :escaped => 'quo \\ 'te'} " , :attr_wrapper = > '"' ) )
assert_equal ( " <p escaped= \" q'uo"te \" ></p> \n " , render ( " %p{ :escaped => 'q \\ 'uo \" te'} " , :attr_wrapper = > '"' ) )
2006-11-07 20:54:26 -05:00
assert_equal ( " <?xml version= \" 1.0 \" encoding= \" utf-8 \" ?> \n " , render ( " !!! XML " , :attr_wrapper = > '"' ) )
2006-11-04 03:35:06 -05:00
end
2009-11-14 15:44:40 -05:00
def test_autoclose_option
assert_equal ( " <flaz foo='bar' /> \n " , render ( " %flaz{:foo => 'bar'} " , :autoclose = > [ " flaz " ] ) )
assert_equal ( <<HTML, render(<<HAML, :autoclose => [/^flaz/]))
< flaz / >
< flaznicate / >
< flan > < / flan>
HTML
% flaz
% flaznicate
% flan
HAML
end
2007-06-02 06:45:24 -04:00
def test_attrs_parsed_correctly
2008-05-09 19:00:08 -04:00
assert_equal ( " <p boom=>biddly='bar => baz'></p> \n " , render ( " %p{'boom=>biddly' => 'bar => baz'} " ) )
assert_equal ( " <p foo,bar='baz, qux'></p> \n " , render ( " %p{'foo,bar' => 'baz, qux'} " ) )
2008-07-27 20:50:28 -04:00
assert_equal ( " <p escaped='quo& # x000A;te'></p> \n " , render ( " %p{ :escaped => \" quo \\ nte \" } " ) )
2008-05-09 19:00:08 -04:00
assert_equal ( " <p escaped='quo4te'></p> \n " , render ( " %p{ :escaped => \" quo \# {2 + 2}te \" } " ) )
2007-06-02 06:45:24 -04:00
end
2009-11-14 15:44:40 -05:00
2008-02-10 19:45:36 -05:00
def test_correct_parsing_with_brackets
assert_equal ( " <p class='foo'>{tada} foo</p> \n " , render ( " %p{:class => 'foo'} {tada} foo " ) )
assert_equal ( " <p class='foo'>deep {nested { things }}</p> \n " , render ( " %p{:class => 'foo'} deep {nested { things }} " ) )
assert_equal ( " <p class='bar foo'>{a { d</p> \n " , render ( " %p{{:class => 'foo'}, :class => 'bar'} {a { d " ) )
assert_equal ( " <p foo='bar'>a}</p> \n " , render ( " %p{:foo => 'bar'} a} " ) )
2012-04-29 10:36:19 -04:00
2008-02-10 19:45:36 -05:00
foo = [ ]
foo [ 0 ] = Struct . new ( 'Foo' , :id ) . new
assert_equal ( " <p class='struct_foo' id='struct_foo_new'>New User]</p> \n " ,
render ( " %p[foo[0]] New User] " , :locals = > { :foo = > foo } ) )
2008-04-10 06:37:22 -04:00
assert_equal ( " <p class='prefix_struct_foo' id='prefix_struct_foo_new'>New User]</p> \n " ,
render ( " %p[foo[0], :prefix] New User] " , :locals = > { :foo = > foo } ) )
foo [ 0 ] . id = 1
assert_equal ( " <p class='struct_foo' id='struct_foo_1'>New User]</p> \n " ,
render ( " %p[foo[0]] New User] " , :locals = > { :foo = > foo } ) )
assert_equal ( " <p class='prefix_struct_foo' id='prefix_struct_foo_1'>New User]</p> \n " ,
render ( " %p[foo[0], :prefix] New User] " , :locals = > { :foo = > foo } ) )
2008-02-10 19:45:36 -05:00
end
2012-04-29 10:36:19 -04:00
2007-07-24 22:46:43 -04:00
def test_empty_attrs
assert_equal ( " <p attr=''>empty</p> \n " , render ( " %p{ :attr => '' } empty " ) )
assert_equal ( " <p attr=''>empty</p> \n " , render ( " %p{ :attr => x } empty " , :locals = > { :x = > '' } ) )
end
2012-04-29 10:36:19 -04:00
2007-07-24 22:46:43 -04:00
def test_nil_attrs
assert_equal ( " <p>nil</p> \n " , render ( " %p{ :attr => nil } nil " ) )
assert_equal ( " <p>nil</p> \n " , render ( " %p{ :attr => x } nil " , :locals = > { :x = > nil } ) )
end
2007-06-02 06:45:24 -04:00
2008-01-10 03:40:00 -05:00
def test_nil_id_with_syntactic_id
assert_equal ( " <p id='foo'>nil</p> \n " , render ( " %p # foo{:id => nil} nil " ) )
assert_equal ( " <p id='foo_bar'>nil</p> \n " , render ( " %p # foo{{:id => 'bar'}, :id => nil} nil " ) )
assert_equal ( " <p id='foo_bar'>nil</p> \n " , render ( " %p # foo{{:id => nil}, :id => 'bar'} nil " ) )
end
def test_nil_class_with_syntactic_class
assert_equal ( " <p class='foo'>nil</p> \n " , render ( " %p.foo{:class => nil} nil " ) )
assert_equal ( " <p class='bar foo'>nil</p> \n " , render ( " %p.bar.foo{:class => nil} nil " ) )
assert_equal ( " <p class='bar foo'>nil</p> \n " , render ( " %p.foo{{:class => 'bar'}, :class => nil} nil " ) )
assert_equal ( " <p class='bar foo'>nil</p> \n " , render ( " %p.foo{{:class => nil}, :class => 'bar'} nil " ) )
end
2006-11-04 03:35:06 -05:00
def test_locals
assert_equal ( " <p>Paragraph!</p> \n " , render ( " %p= text " , :locals = > { :text = > " Paragraph! " } ) )
end
2007-05-10 04:12:20 -04:00
2007-08-26 13:12:22 -04:00
def test_dynamic_attrs_shouldnt_register_as_literal_values
2008-05-09 19:00:08 -04:00
assert_equal ( " <p a='b2c'></p> \n " , render ( '%p{:a => "b#{1 + 1}c"}' ) )
assert_equal ( " <p a='b2c'></p> \n " , render ( " %p{:a => 'b' + (1 + 1).to_s + 'c'} " ) )
2007-08-21 21:42:19 -04:00
end
2007-01-20 20:24:16 -05:00
2008-01-17 13:41:27 -05:00
def test_dynamic_attrs_with_self_closed_tag
assert_equal ( " <a b='2' /> \n c \n " , render ( " %a{'b' => 1 + 1}/ \n = 'c' \n " ) )
end
2009-09-27 21:20:50 -04:00
EXCEPTION_MAP . each do | key , value |
define_method ( " test_exception ( #{ key . inspect } ) " ) do
2007-01-27 05:29:14 -05:00
begin
2009-09-27 21:20:50 -04:00
render ( key , :filename = > __FILE__ )
2008-04-29 00:28:01 -04:00
rescue Exception = > err
2008-04-24 16:47:59 -04:00
value = [ value ] unless value . is_a? ( Array )
2008-08-29 20:40:59 -04:00
expected_message , line_no = value
line_no || = key . split ( " \n " ) . length
2008-04-24 16:47:59 -04:00
2009-09-27 20:37:22 -04:00
if expected_message == :compile
2009-11-08 18:56:42 -05:00
if Haml :: Util . ruby1_8?
assert_match ( / ^compile error \ n / , err . message , " Line: #{ key } " )
else
assert_match ( / ^ #{ Regexp . quote __FILE__ } : #{ line_no } : syntax error, / , err . message , " Line: #{ key } " )
end
2009-09-27 20:37:22 -04:00
else
assert_equal ( expected_message , err . message , " Line: #{ key } " )
end
2009-11-08 18:56:42 -05:00
if Haml :: Util . ruby1_8?
2010-07-19 22:57:30 -04:00
# Sometimes, the first backtrace entry is *only* in the message.
# No idea why.
bt =
if expected_message == :compile && err . message . include? ( " \n " )
err . message . split ( " \n " , 2 ) [ 1 ]
else
err . backtrace [ 0 ]
end
assert_match ( / ^ #{ Regexp . escape ( __FILE__ ) } : #{ line_no } / , bt , " Line: #{ key } " )
2009-11-08 18:56:42 -05:00
end
2007-01-27 05:29:14 -05:00
else
2008-04-29 00:28:01 -04:00
assert ( false , " Exception not raised for \n #{ key } " )
2007-01-27 05:29:14 -05:00
end
end
end
2008-04-18 14:08:49 -04:00
def test_exception_line
2007-11-24 03:35:10 -05:00
render ( " a \n b \n !!! \n c \n d " )
rescue Haml :: SyntaxError = > e
2008-08-29 20:40:59 -04:00
assert_equal ( " (test_exception_line):4 " , e . backtrace [ 0 ] )
2007-11-24 03:35:10 -05:00
else
assert ( false , '"a\nb\n!!!\n c\nd" doesn\'t produce an exception' )
end
2007-11-25 22:26:16 -05:00
def test_exception
render ( " %p \n hi \n %a= undefined \n = 12 " )
2007-11-24 03:35:10 -05:00
rescue Exception = > e
2008-08-29 20:40:59 -04:00
assert_match ( " (test_exception):3 " , e . backtrace [ 0 ] )
2007-11-24 03:35:10 -05:00
else
# Test failed... should have raised an exception
assert ( false )
2007-11-23 03:24:11 -05:00
end
2007-01-27 05:29:14 -05:00
def test_compile_error
2007-11-25 22:26:16 -05:00
render ( " a \n b \n - fee) \n c " )
2007-11-24 03:35:10 -05:00
rescue Exception = > e
2009-02-07 05:33:58 -05:00
assert_match ( / \ (test_compile_error \ ):3: syntax error /i , e . message )
2007-11-24 03:35:10 -05:00
else
assert ( false ,
2007-11-25 22:26:16 -05:00
'"a\nb\n- fee)\nc" doesn\'t produce an exception!' )
2007-01-27 05:29:14 -05:00
end
2007-01-31 01:38:23 -05:00
2007-11-25 20:36:57 -05:00
def test_unbalanced_brackets
2008-12-11 17:25:54 -05:00
render ( 'foo #{1 + 5} foo #{6 + 7 bar #{8 + 9}' )
2007-11-25 20:36:57 -05:00
rescue Haml :: SyntaxError = > e
assert_equal ( " Unbalanced brackets. " , e . message )
end
2008-04-28 23:59:43 -04:00
def test_balanced_conditional_comments
assert_equal ( " <!--[if !(IE 6)|(IE 7)]> Bracket: ] <![endif]--> \n " ,
render ( " /[if !(IE 6)|(IE 7)] Bracket: ] " ) )
end
2008-04-18 14:37:34 -04:00
def test_empty_filter
2012-04-29 10:36:19 -04:00
expectation = " <script type='text/javascript'> \n //<![CDATA[ \n \n //]]> \n </script> \n "
assert_equal ( expectation , render ( ':javascript' ) )
2008-04-18 14:37:34 -04:00
end
2008-07-10 23:38:39 -04:00
def test_ugly_filter
assert_equal ( <<END, render(":sass\n #foo\n bar: baz", :ugly => true))
#foo {
bar : baz ; }
END
end
2009-11-09 22:46:36 -05:00
def test_css_filter
2010-08-22 19:04:02 -04:00
assert_equal ( <<HTML, render(<<HAML))
2009-11-09 22:46:36 -05:00
< style type = 'text/css' >
/ *<![CDATA[* /
#foo {
bar : baz ; }
/ *]]>* /
< / style>
2010-08-22 19:04:02 -04:00
HTML
2009-11-09 22:46:36 -05:00
:css
#foo {
bar : baz ; }
2010-08-22 19:04:02 -04:00
HAML
2009-11-09 22:46:36 -05:00
end
2007-04-15 21:38:25 -04:00
def test_local_assigns_dont_modify_class
assert_equal ( " bar \n " , render ( " = foo " , :locals = > { :foo = > 'bar' } ) )
assert_equal ( nil , defined? ( foo ) )
end
2007-04-17 02:49:07 -04:00
def test_object_ref_with_nil_id
2008-04-28 00:14:12 -04:00
user = User . new
2007-04-17 02:49:07 -04:00
assert_equal ( " <p class='struct_user' id='struct_user_new'>New User</p> \n " ,
render ( " %p[user] New User " , :locals = > { :user = > user } ) )
end
2007-11-23 02:02:07 -05:00
2008-04-28 00:14:12 -04:00
def test_object_ref_before_attrs
user = User . new 42
assert_equal ( " <p class='struct_user' id='struct_user_42' style='width: 100px;'>New User</p> \n " ,
render ( " %p[user]{:style => 'width: 100px;'} New User " , :locals = > { :user = > user } ) )
end
2009-07-03 00:32:31 -04:00
def test_object_ref_with_custom_haml_class
custom = CustomHamlClass . new 42
assert_equal ( " <p class='my_thing' id='my_thing_42' style='width: 100px;'>My Thing</p> \n " ,
render ( " %p[custom]{:style => 'width: 100px;'} My Thing " , :locals = > { :custom = > custom } ) )
end
2012-04-29 10:36:19 -04:00
2011-10-03 08:43:48 -04:00
def test_object_ref_with_multiple_ids
cpk_record = CpkRecord . new ( [ 42 , 6 , 9 ] )
assert_equal ( " <p class='struct_cpk_record' id='struct_cpk_record_42_6_9' style='width: 100px;'>CPK Record</p> \n " ,
render ( " %p[cpk_record]{:style => 'width: 100px;'} CPK Record " , :locals = > { :cpk_record = > cpk_record } ) )
end
2009-07-03 00:32:31 -04:00
2007-12-19 04:41:33 -05:00
def test_non_literal_attributes
assert_equal ( " <p a1='foo' a2='bar' a3='baz' /> \n " ,
render ( " %p{a2, a1, :a3 => 'baz'}/ " ,
:locals = > { :a1 = > { :a1 = > 'foo' } , :a2 = > { :a2 = > 'bar' } } ) )
end
2007-11-23 02:02:07 -05:00
def test_render_should_accept_a_binding_as_scope
string = " This is a string! "
string . instance_variable_set ( " @var " , " Instance variable " )
2007-11-23 02:42:59 -05:00
b = string . instance_eval do
var = " Local variable "
binding
end
2007-11-23 02:02:07 -05:00
2007-11-23 02:42:59 -05:00
assert_equal ( " <p>THIS IS A STRING!</p> \n <p>Instance variable</p> \n <p>Local variable</p> \n " ,
render ( " %p= upcase \n %p= @var \n %p= var " , :scope = > b ) )
2007-11-23 02:02:07 -05:00
end
2007-11-23 07:14:02 -05:00
def test_yield_should_work_with_binding
assert_equal ( " 12 \n FOO \n " , render ( " = yield \n = upcase " , :scope = > " foo " . instance_eval { binding } ) { 12 } )
end
2007-11-23 21:32:18 -05:00
def test_yield_should_work_with_def_method
s = " foo "
2008-08-29 20:40:59 -04:00
engine ( " = yield \n = upcase " ) . def_method ( s , :render )
2007-11-23 21:32:18 -05:00
assert_equal ( " 12 \n FOO \n " , s . render { 12 } )
end
def test_def_method_with_module
2008-08-29 20:40:59 -04:00
engine ( " = yield \n = upcase " ) . def_method ( String , :render_haml )
2007-11-23 21:32:18 -05:00
assert_equal ( " 12 \n FOO \n " , " foo " . render_haml { 12 } )
end
2007-11-24 03:35:10 -05:00
def test_def_method_locals
obj = Object . new
2008-08-29 20:40:59 -04:00
engine ( " %p= foo \n .bar{:baz => baz}= boom " ) . def_method ( obj , :render , :foo , :baz , :boom )
2007-11-24 03:35:10 -05:00
assert_equal ( " <p>1</p> \n <div baz='2' class='bar'>3</div> \n " , obj . render ( :foo = > 1 , :baz = > 2 , :boom = > 3 ) )
end
def test_render_proc_locals
2008-08-29 20:40:59 -04:00
proc = engine ( " %p= foo \n .bar{:baz => baz}= boom " ) . render_proc ( Object . new , :foo , :baz , :boom )
2007-11-24 03:35:10 -05:00
assert_equal ( " <p>1</p> \n <div baz='2' class='bar'>3</div> \n " , proc [ :foo = > 1 , :baz = > 2 , :boom = > 3 ] )
end
def test_render_proc_with_binding
2008-08-29 20:40:59 -04:00
assert_equal ( " FOO \n " , engine ( " = upcase " ) . render_proc ( " foo " . instance_eval { binding } ) . call )
2007-11-24 03:35:10 -05:00
end
2008-02-13 04:30:21 -05:00
2009-11-03 23:08:43 -05:00
def test_haml_buffer_gets_reset_even_with_exception
scope = Object . new
render ( " - raise Haml::Error " , :scope = > scope )
assert ( false , " Expected exception " )
rescue Exception
assert_nil ( scope . send ( :haml_buffer ) )
end
def test_def_method_haml_buffer_gets_reset_even_with_exception
scope = Object . new
engine ( " - raise Haml::Error " ) . def_method ( scope , :render )
scope . render
assert ( false , " Expected exception " )
rescue Exception
assert_nil ( scope . send ( :haml_buffer ) )
end
def test_render_proc_haml_buffer_gets_reset_even_with_exception
scope = Object . new
proc = engine ( " - raise Haml::Error " ) . render_proc ( scope )
proc . call
assert ( false , " Expected exception " )
rescue Exception
assert_nil ( scope . send ( :haml_buffer ) )
end
2008-02-13 04:30:21 -05:00
def test_ugly_true
2008-02-13 23:13:12 -05:00
assert_equal ( " <div id='outer'> \n <div id='inner'> \n <p>hello world</p> \n </div> \n </div> \n " ,
render ( " # outer \n # inner \n %p hello world " , :ugly = > true ) )
assert_equal ( " <p> #{ 's' * 75 } </p> \n " ,
render ( " %p #{ 's' * 75 } " , :ugly = > true ) )
2008-02-13 04:30:21 -05:00
2008-02-13 23:13:12 -05:00
assert_equal ( " <p> #{ 's' * 75 } </p> \n " ,
render ( " %p= 's' * 75 " , :ugly = > true ) )
2008-02-13 04:30:21 -05:00
end
2008-02-24 17:10:30 -05:00
2008-05-27 15:16:24 -04:00
def test_auto_preserve_unless_ugly
assert_equal ( " <pre>foo& # x000A;bar</pre> \n " , render ( '%pre="foo\nbar"' ) )
assert_equal ( " <pre>foo \n bar</pre> \n " , render ( " %pre \n foo \n bar " ) )
assert_equal ( " <pre>foo \n bar</pre> \n " , render ( '%pre="foo\nbar"' , :ugly = > true ) )
assert_equal ( " <pre>foo \n bar</pre> \n " , render ( " %pre \n foo \n bar " , :ugly = > true ) )
end
2008-02-26 13:57:45 -05:00
def test_xhtml_output_option
2008-02-29 14:00:03 -05:00
assert_equal " <p> \n <br /> \n </p> \n " , render ( " %p \n %br " , :format = > :xhtml )
assert_equal " <a /> \n " , render ( " %a/ " , :format = > :xhtml )
2008-02-26 13:57:45 -05:00
end
def test_arbitrary_output_option
2010-08-08 19:05:01 -04:00
assert_raise_message ( Haml :: Error , " Invalid output format :html1 " ) do
engine ( " %br " , :format = > :html1 )
end
2008-02-26 13:57:45 -05:00
end
2009-06-03 18:01:40 -04:00
def test_static_hashes
assert_equal ( " <a b='a => b'></a> \n " , render ( " %a{:b => 'a => b'} " , :suppress_eval = > true ) )
assert_equal ( " <a b='a, b'></a> \n " , render ( " %a{:b => 'a, b'} " , :suppress_eval = > true ) )
assert_equal ( " <a b='a \t b'></a> \n " , render ( '%a{:b => "a\tb"}' , :suppress_eval = > true ) )
assert_equal ( " <a b='a \# {foo}b'></a> \n " , render ( '%a{:b => "a\\#{foo}b"}' , :suppress_eval = > true ) )
end
2009-06-03 18:05:14 -04:00
def test_dynamic_hashes_with_suppress_eval
assert_equal ( " <a></a> \n " , render ( '%a{:b => "a #{1 + 1} b", :c => "d"}' , :suppress_eval = > true ) )
end
2009-11-11 17:30:11 -05:00
def test_utf8_attrs
assert_equal ( " <a href='héllo'></a> \n " , render ( " %a{:href => 'héllo'} " ) )
assert_equal ( " <a href='héllo'></a> \n " , render ( " %a(href='héllo') " ) )
end
2008-02-26 13:43:37 -05:00
# HTML 4.0
def test_html_has_no_self_closing_tags
2008-02-29 14:00:03 -05:00
assert_equal " <p> \n <br> \n </p> \n " , render ( " %p \n %br " , :format = > :html4 )
assert_equal " <br> \n " , render ( " %br/ " , :format = > :html4 )
2008-02-26 13:43:37 -05:00
end
def test_html_renders_empty_node_with_closing_tag
2008-05-09 19:00:08 -04:00
assert_equal " <div class='foo'></div> \n " , render ( " .foo " , :format = > :html4 )
2008-02-26 13:43:37 -05:00
end
2008-10-06 12:46:09 -04:00
def test_html_doesnt_add_slash_to_self_closing_tags
assert_equal " <a> \n " , render ( " %a/ " , :format = > :html4 )
assert_equal " <a foo='2'> \n " , render ( " %a{:foo => 1 + 1}/ " , :format = > :html4 )
assert_equal " <meta> \n " , render ( " %meta " , :format = > :html4 )
assert_equal " <meta foo='2'> \n " , render ( " %meta{:foo => 1 + 1} " , :format = > :html4 )
2008-02-26 13:43:37 -05:00
end
def test_html_ignores_xml_prolog_declaration
2008-02-29 14:00:03 -05:00
assert_equal " " , render ( '!!! XML' , :format = > :html4 )
2008-02-26 13:43:37 -05:00
end
def test_html_has_different_doctype
assert_equal %{ <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> \n } ,
2008-02-29 14:00:03 -05:00
render ( '!!!' , :format = > :html4 )
2008-02-24 17:10:30 -05:00
end
2008-02-27 09:16:21 -05:00
# because anything before the doctype triggers quirks mode in IE
def test_xml_prolog_and_doctype_dont_result_in_a_leading_whitespace_in_html
2008-08-29 20:40:59 -04:00
assert_no_match ( / ^ \ s+ / , render ( " !!! xml \n !!! " , :format = > :html4 ) )
2008-02-27 09:16:21 -05:00
end
2008-02-27 09:20:44 -05:00
# HTML5
def test_html5_doctype
2008-02-29 14:00:03 -05:00
assert_equal %{ <!DOCTYPE html> \n } , render ( '!!!' , :format = > :html5 )
2008-02-27 09:20:44 -05:00
end
2009-05-19 17:28:34 -04:00
2010-03-14 19:13:53 -04:00
# HTML5 custom data attributes
2012-04-29 11:17:05 -04:00
def test_html5_data_attributes_without_hyphenation
2010-03-14 19:13:53 -04:00
assert_equal ( " <div data-author_id='123' data-biz='baz' data-foo='bar'></div> \n " ,
2012-04-29 11:17:05 -04:00
render ( " %div{:data => {:author_id => 123, :foo => 'bar', :biz => 'baz'}} " ,
:hyphenate_data_attrs = > false ) )
2010-03-14 19:13:53 -04:00
assert_equal ( " <div data-one_plus_one='2'></div> \n " ,
2012-04-29 11:17:05 -04:00
render ( " %div{:data => {:one_plus_one => 1+1}} " ,
:hyphenate_data_attrs = > false ) )
2010-03-14 19:13:53 -04:00
assert_equal ( " <div data-foo='Here's a \" quoteful \" string.'></div> \n " ,
2012-04-29 11:17:05 -04:00
render ( %{ %div { :data => { :foo => % { Here's a "quoteful" string. } } } } ,
:hyphenate_data_attrs = > false ) ) #'
2010-03-14 19:26:49 -04:00
end
2012-01-28 03:10:05 -05:00
def test_html5_data_attributes_with_hyphens
assert_equal ( " <div data-foo-bar='blip'></div> \n " ,
2012-04-29 11:17:05 -04:00
render ( " %div{:data => {:foo_bar => 'blip'}} " ) )
2012-01-28 03:10:05 -05:00
assert_equal ( " <div data-baz='bang' data-foo-bar='blip'></div> \n " ,
2012-04-29 11:17:05 -04:00
render ( " %div{:data => {:foo_bar => 'blip', :baz => 'bang'}} " ) )
2012-01-28 03:10:05 -05:00
end
2010-03-14 19:26:49 -04:00
def test_html5_data_attributes_with_multiple_defs
# Should always use the more-explicit attribute
assert_equal ( " <div data-foo='second'></div> \n " ,
render ( " %div{:data => {:foo => 'first'}, 'data-foo' => 'second'} " ) )
assert_equal ( " <div data-foo='first'></div> \n " ,
render ( " %div{'data-foo' => 'first', :data => {:foo => 'second'}} " ) )
2010-03-14 19:13:53 -04:00
end
2010-03-14 19:38:14 -04:00
def test_html5_data_attributes_with_attr_method
Haml :: Helpers . module_eval do
def data_hash
{ :data = > { :foo = > " bar " , :baz = > " bang " } }
end
def data_val
{ :data = > " dat " }
end
end
assert_equal ( " <div data-baz='bang' data-brat='wurst' data-foo='blip'></div> \n " ,
render ( " %div{data_hash, :data => {:foo => 'blip', :brat => 'wurst'}} " ) )
assert_equal ( " <div data-baz='bang' data-foo='blip'></div> \n " ,
render ( " %div{data_hash, 'data-foo' => 'blip'} " ) )
assert_equal ( " <div data-baz='bang' data-foo='bar' data='dat'></div> \n " ,
render ( " %div{data_hash, :data => 'dat'} " ) )
assert_equal ( " <div data-brat='wurst' data-foo='blip' data='dat'></div> \n " ,
render ( " %div{data_val, :data => {:foo => 'blip', :brat => 'wurst'}} " ) )
end
2011-09-09 00:22:09 -04:00
def test_xml_doc_using_html5_format_and_mime_type
assert_equal ( <<XML, render(<<HAML, { :format => :html5, :mime_type => 'text/xml' }))
< ? xml version = '1.0' encoding = 'utf-8' ?>
< root >
< element / >
< hr / >
< / root>
XML
! ! ! XML
% root
% element /
% hr
HAML
end
def test_xml_doc_using_html4_format_and_mime_type
assert_equal ( <<XML, render(<<HAML, { :format => :html4, :mime_type => 'text/xml' }))
< ? xml version = '1.0' encoding = 'utf-8' ?>
< root >
< element / >
< hr / >
< / root>
XML
! ! ! XML
% root
% element /
% hr
HAML
end
2009-05-19 17:28:34 -04:00
# New attributes
def test_basic_new_attributes
assert_equal ( " <a>bar</a> \n " , render ( " %a() bar " ) )
assert_equal ( " <a href='foo'>bar</a> \n " , render ( " %a(href='foo') bar " ) )
assert_equal ( " <a b='c' c='d' d='e'>baz</a> \n " , render ( %q{ %a(b="c" c='d' d="e") baz } ) )
end
def test_new_attribute_ids
assert_equal ( " <div id='foo_bar'></div> \n " , render ( " # foo(id='bar') " ) )
2010-10-27 05:42:33 -04:00
assert_equal ( " <div id='foo_baz_bar'></div> \n " , render ( " # foo{:id => 'bar'}(id='baz') " ) )
2009-05-19 17:28:34 -04:00
assert_equal ( " <div id='foo_baz_bar'></div> \n " , render ( " # foo(id='baz'){:id => 'bar'} " ) )
foo = User . new ( 42 )
assert_equal ( " <div class='struct_user' id='foo_baz_bar_struct_user_42'></div> \n " ,
render ( " # foo(id='baz'){:id => 'bar'}[foo] " , :locals = > { :foo = > foo } ) )
assert_equal ( " <div class='struct_user' id='foo_baz_bar_struct_user_42'></div> \n " ,
render ( " # foo(id='baz')[foo]{:id => 'bar'} " , :locals = > { :foo = > foo } ) )
assert_equal ( " <div class='struct_user' id='foo_baz_bar_struct_user_42'></div> \n " ,
render ( " # foo[foo](id='baz'){:id => 'bar'} " , :locals = > { :foo = > foo } ) )
2010-10-27 05:42:33 -04:00
assert_equal ( " <div class='struct_user' id='foo_baz_bar_struct_user_42'></div> \n " ,
2009-05-19 17:28:34 -04:00
render ( " # foo[foo]{:id => 'bar'}(id='baz') " , :locals = > { :foo = > foo } ) )
end
def test_new_attribute_classes
assert_equal ( " <div class='bar foo'></div> \n " , render ( " .foo(class='bar') " ) )
assert_equal ( " <div class='bar baz foo'></div> \n " , render ( " .foo{:class => 'bar'}(class='baz') " ) )
assert_equal ( " <div class='bar baz foo'></div> \n " , render ( " .foo(class='baz'){:class => 'bar'} " ) )
foo = User . new ( 42 )
assert_equal ( " <div class='bar baz foo struct_user' id='struct_user_42'></div> \n " ,
render ( " .foo(class='baz'){:class => 'bar'}[foo] " , :locals = > { :foo = > foo } ) )
assert_equal ( " <div class='bar baz foo struct_user' id='struct_user_42'></div> \n " ,
render ( " .foo[foo](class='baz'){:class => 'bar'} " , :locals = > { :foo = > foo } ) )
assert_equal ( " <div class='bar baz foo struct_user' id='struct_user_42'></div> \n " ,
render ( " .foo[foo]{:class => 'bar'}(class='baz') " , :locals = > { :foo = > foo } ) )
end
def test_dynamic_new_attributes
assert_equal ( " <a href='12'>bar</a> \n " , render ( " %a(href=foo) bar " , :locals = > { :foo = > 12 } ) )
assert_equal ( " <a b='12' c='13' d='14'>bar</a> \n " , render ( " %a(b=b c='13' d=d) bar " , :locals = > { :b = > 12 , :d = > 14 } ) )
end
def test_new_attribute_interpolation
assert_equal ( " <a href='12'>bar</a> \n " , render ( '%a(href="1#{1 + 1}") bar' ) )
assert_equal ( " <a href='2: 2, 3: 3'>bar</a> \n " , render ( %q{ %a(href='2: # { 1 + 1 } , 3: # { foo } ') bar } , :locals = > { :foo = > 3 } ) )
assert_equal ( %Q{ <a href='1 \# { 1 + 1 } '>bar</a> \n } , render ( '%a(href="1\#{1 + 1}") bar' ) )
end
def test_truthy_new_attributes
assert_equal ( " <a href='href'>bar</a> \n " , render ( " %a(href) bar " ) )
assert_equal ( " <a bar='baz' href>bar</a> \n " , render ( " %a(href bar='baz') bar " , :format = > :html5 ) )
assert_equal ( " <a href='href'>bar</a> \n " , render ( " %a(href=true) bar " ) )
assert_equal ( " <a>bar</a> \n " , render ( " %a(href=false) bar " ) )
end
def test_new_attribute_parsing
assert_equal ( " <a a2='b2'>bar</a> \n " , render ( " %a(a2=b2) bar " , :locals = > { :b2 = > 'b2' } ) )
assert_equal ( %Q{ <a a='foo"bar'>bar</a> \n } , render ( %q{ %a(a=" # { 'foo"bar' } ") bar } ) ) #'
assert_equal ( %Q{ <a a="foo'bar">bar</a> \n } , render ( %q{ %a(a=" # { "foo'bar" } ") bar } ) ) #'
assert_equal ( %Q{ <a a='foo"bar'>bar</a> \n } , render ( %q{ %a(a='foo"bar') bar } ) )
assert_equal ( %Q{ <a a="foo'bar">bar</a> \n } , render ( %q{ %a(a="foo'bar") bar } ) )
assert_equal ( " <a a:b='foo'>bar</a> \n " , render ( " %a(a:b='foo') bar " ) )
assert_equal ( " <a a='foo' b='bar'>bar</a> \n " , render ( " %a(a = 'foo' b = 'bar') bar " ) )
assert_equal ( " <a a='foo' b='bar'>bar</a> \n " , render ( " %a(a = foo b = bar) bar " , :locals = > { :foo = > 'foo' , :bar = > 'bar' } ) )
assert_equal ( " <a a='foo'>(b='bar')</a> \n " , render ( " %a(a='foo')(b='bar') " ) )
assert_equal ( " <a a='foo)bar'>baz</a> \n " , render ( " %a(a='foo)bar') baz " ) )
assert_equal ( " <a a='foo'>baz</a> \n " , render ( " %a( a = 'foo' ) baz " ) )
end
def test_new_attribute_escaping
assert_equal ( %Q{ <a a='foo " bar'>bar</a> \n } , render ( %q{ %a(a="foo \ " bar") bar } ) )
assert_equal ( %Q{ <a a='foo \\ " bar'>bar</a> \n } , render ( %q{ %a(a="foo \\ \\ \ " bar") bar } ) )
assert_equal ( %Q{ <a a="foo ' bar">bar</a> \n } , render ( %q{ %a(a='foo \ ' bar') bar } ) )
assert_equal ( %Q{ <a a="foo \\ ' bar">bar</a> \n } , render ( %q{ %a(a='foo \\ \\ \ ' bar') bar } ) )
assert_equal ( %Q{ <a a='foo \\ bar'>bar</a> \n } , render ( %q{ %a(a="foo \\ \\ bar") bar } ) )
assert_equal ( %Q{ <a a='foo \# { 1 + 1 } bar'>bar</a> \n } , render ( %q{ %a(a="foo \ # { 1 + 1 } bar") bar } ) )
end
def test_multiline_new_attribute
assert_equal ( " <a a='b' c='d'>bar</a> \n " , render ( " %a(a='b' \n c='d') bar " ) )
assert_equal ( " <a a='b' b='c' c='d' d='e' e='f' f='j'>bar</a> \n " ,
render ( " %a(a='b' b='c' \n c='d' d=e \n e='f' f='j') bar " , :locals = > { :e = > 'e' } ) )
end
def test_new_and_old_attributes
assert_equal ( " <a a='b' c='d'>bar</a> \n " , render ( " %a(a='b'){:c => 'd'} bar " ) )
assert_equal ( " <a a='b' c='d'>bar</a> \n " , render ( " %a{:c => 'd'}(a='b') bar " ) )
assert_equal ( " <a a='b' c='d'>bar</a> \n " , render ( " %a(c='d'){:a => 'b'} bar " ) )
assert_equal ( " <a a='b' c='d'>bar</a> \n " , render ( " %a{:a => 'b'}(c='d') bar " ) )
2010-10-27 05:42:33 -04:00
# Old-style always takes precedence over new-style,
# because theoretically old-style could have arbitrary end-of-method-call syntax.
assert_equal ( " <a a='b'>bar</a> \n " , render ( " %a{:a => 'b'}(a='d') bar " ) )
2009-05-19 17:28:34 -04:00
assert_equal ( " <a a='b'>bar</a> \n " , render ( " %a(a='d'){:a => 'b'} bar " ) )
assert_equal ( " <a a='b' b='c' c='d' d='e'>bar</a> \n " ,
render ( " %a{:a => 'b', \n :b => 'c'}(c='d' \n d='e') bar " ) )
2010-10-27 05:42:33 -04:00
locals = { :b = > 'b' , :d = > 'd' }
assert_equal ( " <p a='b' c='d'></p> \n " , render ( " %p{:a => b}(c=d) " , :locals = > locals ) )
assert_equal ( " <p a='b' c='d'></p> \n " , render ( " %p(a=b){:c => d} " , :locals = > locals ) )
2009-05-19 17:28:34 -04:00
end
2009-07-01 03:19:46 -04:00
2010-04-24 04:09:51 -04:00
# Ruby Multiline
def test_silent_ruby_multiline
assert_equal ( <<HTML, render(<<HAML))
bar , baz , bang
< p > foo < / p>
HTML
- foo = [ " bar " ,
" baz " ,
" bang " ]
= foo . join ( " , " )
% p foo
HAML
end
def test_loud_ruby_multiline
assert_equal ( <<HTML, render(<<HAML))
bar , baz , bang
< p > foo < / p>
< p > bar < / p>
HTML
= [ " bar " ,
" baz " ,
" bang " ] . join ( " , " )
% p foo
% p bar
HAML
end
2012-02-28 15:38:54 -05:00
def test_ruby_multiline_with_punctuated_methods_is_continuation
assert_equal ( <<HTML, render(<<HAML))
bar , , true , bang
< p > foo < / p>
< p > bar < / p>
HTML
= [ " bar " ,
" " . strip! ,
" " . empty? ,
" bang " ] . join ( " , " )
% p foo
% p bar
HAML
end
def test_ruby_character_literals_are_not_continuation
2012-04-18 20:40:11 -04:00
html = if RUBY_VERSION < " 1.9 "
" 44 \n 44 \n <p>foo</p> \n "
else
" , \n , \n <p>foo</p> \n "
end
assert_equal ( html , render ( <<HAML))
2012-02-28 15:38:54 -05:00
= ?,
= ?\ ,
% p foo
HAML
end
2010-04-24 04:09:51 -04:00
def test_escaped_loud_ruby_multiline
assert_equal ( <<HTML, render(<<HAML))
bar & lt ; , baz , bang
< p > foo < / p>
< p > bar < / p>
HTML
& = [ " bar< " ,
" baz " ,
" bang " ] . join ( " , " )
% p foo
% p bar
HAML
end
def test_unescaped_loud_ruby_multiline
assert_equal ( <<HTML, render(<<HAML, :escape_html => true))
bar < , baz , bang
< p > foo < / p>
< p > bar < / p>
HTML
!= [ " bar< " ,
" baz " ,
" bang " ] . join ( " , " )
% p foo
% p bar
HAML
end
def test_flattened_loud_ruby_multiline
assert_equal ( <<HTML, render(<<HAML))
< pre > bar & #x000A;baz
bang</pre>
< p > foo < / p>
< p > bar < / p>
HTML
~ " <pre> " + [ " bar " ,
" baz " ,
" bang " ] . join ( " \\ n " ) + " </pre> "
% p foo
% p bar
HAML
end
def test_loud_ruby_multiline_with_block
assert_equal ( <<HTML, render(<<HAML))
2010-09-28 23:05:19 -04:00
#{%w[far faz fang]}
2010-04-24 04:09:51 -04:00
< p > foo < / p>
< p > bar < / p>
HTML
= [ " bar " ,
" baz " ,
" bang " ] . map do | str |
- str . gsub ( " ba " ,
" fa " )
% p foo
% p bar
HAML
end
def test_silent_ruby_multiline_with_block
assert_equal ( <<HTML, render(<<HAML))
far
faz
fang
< p > foo < / p>
< p > bar < / p>
HTML
- [ " bar " ,
" baz " ,
" bang " ] . map do | str |
= str . gsub ( " ba " ,
" fa " )
% p foo
% p bar
HAML
end
def test_ruby_multiline_in_tag
assert_equal ( <<HTML, render(<<HAML))
< p > foo , bar , baz < / p>
< p > foo < / p>
< p > bar < / p>
HTML
% p = [ " foo " ,
" bar " ,
" baz " ] . join ( " , " )
% p foo
% p bar
HAML
end
def test_escaped_ruby_multiline_in_tag
assert_equal ( <<HTML, render(<<HAML))
< p > foo & lt ; , bar , baz < / p>
< p > foo < / p>
< p > bar < / p>
HTML
% p & = [ " foo< " ,
" bar " ,
" baz " ] . join ( " , " )
% p foo
% p bar
HAML
end
def test_unescaped_ruby_multiline_in_tag
assert_equal ( <<HTML, render(<<HAML, :escape_html => true))
< p > foo < , bar , baz < / p>
< p > foo < / p>
< p > bar < / p>
HTML
% p != [ " foo< " ,
" bar " ,
" baz " ] . join ( " , " )
% p foo
% p bar
HAML
end
def test_ruby_multiline_with_normal_multiline
assert_equal ( <<HTML, render(<<HAML))
foobarbar , baz , bang
< p > foo < / p>
< p > bar < / p>
HTML
= " foo " + |
" bar " + |
[ " bar " , |
" baz " ,
" bang " ] . join ( " , " )
% p foo
% p bar
HAML
end
def test_ruby_multiline_after_filter
assert_equal ( <<HTML, render(<<HAML))
foo
bar
bar , baz , bang
< p > foo < / p>
< p > bar < / p>
HTML
:plain
foo
bar
= [ " bar " ,
" baz " ,
" bang " ] . join ( " , " )
% p foo
% p bar
HAML
end
2009-07-01 03:19:46 -04:00
# Encodings
2010-02-14 18:25:36 -05:00
def test_utf_8_bom
2010-04-24 04:09:51 -04:00
assert_equal <<HTML, render(<<HAML)
2010-02-14 18:25:36 -05:00
< div class = 'foo' >
< p > baz < / p>
< / div>
2010-04-24 04:09:51 -04:00
HTML
2010-02-14 18:25:36 -05:00
\ xEF \ xBB \ xBF . foo
% p baz
2010-04-24 04:09:51 -04:00
HAML
2010-02-14 18:25:36 -05:00
end
2009-07-01 03:19:46 -04:00
unless Haml :: Util . ruby1_8?
def test_default_encoding
assert_equal ( Encoding . find ( " utf-8 " ) , render ( <<HAML.encode("us-ascii")).encoding)
% p bar
% p foo
HAML
end
[Haml] Add support for a workaround for fake ASCII input strings.
Closes gh-3
This is a complicated issue, but I'll do my best to explain it here.
By default, Haml encodes its templates as Encoding.default_internal,
which is usually UTF-8. This means that strings printed to the
template should be either UTF-8 or UTF-8-compatible ASCII. So far, all
well and good.
Now, it's possible to have strings that are marked as ASCII-8bit, but
which aren't UTF-8 compatible. This includes valid UTF-8 strings that
are forced into an ASCII-8bit encoding. If one of these strings is
concatenated to a UTF-8 string, Ruby says "I don't know what to do
with these non-ASCII characters!" and throws an encoding error. I call
this sort of string "fake ASCII."
This is what was happening in the referenced GitHub issue (or at least
in the sample app Adam Salter created at
http://github.com/adamsalter/test-project/tree/haml_utf8). The
template was UTF-8 encoded, and it was being passed a fake ASCII
string, marked as ASCII-8bit but with UTF-8 byte sequences in it, and
it was choking.
The issue now becomes: where is this fake ASCII string coming from?
From the database. The database drivers used by Rails aren't Ruby 1.9
compatible. Despite storing UTF-8 strings in the database, the drivers
return fake ASCII strings.
The best solution to this is clearly to fix the database drivers, but
that will probably take some time. One stop-gap would be to call
`force_encoding("utf-8")` on all the database values somewhere, which
is still a little annoying. Finally, the solution provided in this
commit is to set `:encoding => "ascii-8bit"` for Haml. This makes the
Haml template itself fake ASCII, which is wrong but will help prevent
encoding errors.
2009-11-08 18:59:52 -05:00
def test_fake_ascii_encoding
2010-09-29 01:16:38 -04:00
assert_encoded_equal ( <<HTML.force_encoding("ascii-8bit"), render(<<HAML, :encoding => "ascii-8bit"))
[Haml] Add support for a workaround for fake ASCII input strings.
Closes gh-3
This is a complicated issue, but I'll do my best to explain it here.
By default, Haml encodes its templates as Encoding.default_internal,
which is usually UTF-8. This means that strings printed to the
template should be either UTF-8 or UTF-8-compatible ASCII. So far, all
well and good.
Now, it's possible to have strings that are marked as ASCII-8bit, but
which aren't UTF-8 compatible. This includes valid UTF-8 strings that
are forced into an ASCII-8bit encoding. If one of these strings is
concatenated to a UTF-8 string, Ruby says "I don't know what to do
with these non-ASCII characters!" and throws an encoding error. I call
this sort of string "fake ASCII."
This is what was happening in the referenced GitHub issue (or at least
in the sample app Adam Salter created at
http://github.com/adamsalter/test-project/tree/haml_utf8). The
template was UTF-8 encoded, and it was being passed a fake ASCII
string, marked as ASCII-8bit but with UTF-8 byte sequences in it, and
it was choking.
The issue now becomes: where is this fake ASCII string coming from?
From the database. The database drivers used by Rails aren't Ruby 1.9
compatible. Despite storing UTF-8 strings in the database, the drivers
return fake ASCII strings.
The best solution to this is clearly to fix the database drivers, but
that will probably take some time. One stop-gap would be to call
`force_encoding("utf-8")` on all the database values somewhere, which
is still a little annoying. Finally, the solution provided in this
commit is to set `:encoding => "ascii-8bit"` for Haml. This makes the
Haml template itself fake ASCII, which is wrong but will help prevent
encoding errors.
2009-11-08 18:59:52 -05:00
< p > bâr < / p>
< p > föö < / p>
HTML
% p bâr
% p föö
HAML
end
2009-07-01 03:19:46 -04:00
def test_convert_template_render_proc
assert_converts_template_properly { | e | e . render_proc . call }
end
def test_convert_template_render
assert_converts_template_properly { | e | e . render }
end
def test_convert_template_def_method
assert_converts_template_properly do | e |
o = Object . new
e . def_method ( o , :render )
o . render
end
end
2009-09-23 18:32:08 -04:00
def test_encoding_error
render ( " foo \n bar \n b \xFE az " . force_encoding ( " utf-8 " ) )
assert ( false , " Expected exception " )
rescue Haml :: Error = > e
assert_equal ( 3 , e . line )
assert_equal ( 'Invalid UTF-8 character "\xFE"' , e . message )
end
def test_ascii_incompatible_encoding_error
template = " foo \n bar \n b_z " . encode ( " utf-16le " )
template [ 9 ] = " \xFE " . force_encoding ( " utf-16le " )
render ( template )
assert ( false , " Expected exception " )
rescue Haml :: Error = > e
assert_equal ( 3 , e . line )
assert_equal ( 'Invalid UTF-16LE character "\xFE"' , e . message )
end
2010-05-29 19:51:36 -04:00
def test_same_coding_comment_as_encoding
assert_renders_encoded ( <<HTML, <<HAML)
< p > bâr < / p>
< p > föö < / p>
HTML
- # coding: utf-8
% p bâr
% p föö
HAML
end
2010-09-28 23:06:47 -04:00
def test_coding_comments
assert_valid_encoding_comment ( " - # coding: ibm866 " )
assert_valid_encoding_comment ( " - # CodINg: IbM866 " )
assert_valid_encoding_comment ( " - # coding:ibm866 " )
assert_valid_encoding_comment ( " - # CodINg= ibm866 " )
assert_valid_encoding_comment ( " - # foo BAR FAOJcoding: ibm866 " )
assert_valid_encoding_comment ( " - # coding: ibm866 ASFJ (&(& # !$ " )
assert_valid_encoding_comment ( " - # -*- coding: ibm866 " )
assert_valid_encoding_comment ( " - # coding: ibm866 -*- coding: blah " )
assert_valid_encoding_comment ( " - # -*- coding: ibm866 -*- " )
assert_valid_encoding_comment ( " - # -*- encoding: ibm866 -*- " )
assert_valid_encoding_comment ( '-# -*- coding: "ibm866" -*-' )
assert_valid_encoding_comment ( " - # -*-coding:ibm866-*- " )
assert_valid_encoding_comment ( " - # -*-coding:ibm866-*- " )
assert_valid_encoding_comment ( " - # -*- foo: bar; coding: ibm866; baz: bang -*- " )
assert_valid_encoding_comment ( " - # foo bar coding: baz -*- coding: ibm866 -*- " )
assert_valid_encoding_comment ( " - # -*- coding: ibm866 -*- foo bar coding: baz " )
2010-05-29 19:51:36 -04:00
end
def test_different_coding_than_system
assert_renders_encoded ( <<HTML.encode("IBM866"), <<HAML.encode("IBM866"))
< p > т А Ь < / p>
HTML
% p т А Ь
HAML
end
2010-09-28 23:06:47 -04:00
end
2010-05-29 19:51:36 -04:00
2010-09-28 23:06:47 -04:00
private
2010-05-29 19:51:36 -04:00
2010-09-28 23:06:47 -04:00
def assert_valid_encoding_comment ( comment )
2010-09-28 23:18:07 -04:00
assert_renders_encoded ( <<HTML.encode("IBM866"), <<HAML.encode("IBM866").force_encoding("UTF-8"))
< p > Ж Л Ы < / p>
< p > т А Ь < / p>
2010-05-29 19:51:36 -04:00
HTML
2010-09-28 23:06:47 -04:00
#{comment}
2010-09-28 23:18:07 -04:00
% p Ж Л Ы
% p т А Ь
2010-05-29 19:51:36 -04:00
HAML
2009-07-01 03:19:46 -04:00
end
def assert_converts_template_properly
2010-09-29 01:16:38 -04:00
engine = Haml :: Engine . new ( <<HAML.encode("iso-8859-1"), :encoding => "macRoman")
2009-07-01 03:19:46 -04:00
% p bâr
% p föö
HAML
2010-09-29 01:16:38 -04:00
assert_encoded_equal ( <<HTML.encode("macRoman"), yield(engine))
2009-07-01 03:19:46 -04:00
< p > bâr < / p>
< p > föö < / p>
HTML
end
2010-05-29 19:51:36 -04:00
def assert_renders_encoded ( html , haml )
result = render ( haml )
2010-09-29 01:16:38 -04:00
assert_encoded_equal html , result
end
def assert_encoded_equal ( expected , actual )
assert_equal expected . encoding , actual . encoding
assert_equal expected , actual
2010-05-29 19:51:36 -04:00
end
2006-06-30 11:14:44 -04:00
end