Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
#!/usr/bin/env ruby
# -*- coding: utf-8 -*-
require File.dirname(__FILE__) + '/../test_helper'
class EngineTest < Test::Unit::TestCase
# A map of erroneous Haml documents to the error messages they should produce.
# 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.
EXCEPTION_MAP = {
"!!!\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.",
"%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.",
"%p/\n a" => "Illegal nesting: nesting within a self-closing tag is illegal.",
":a\n b" => ['Filter "a" is not defined.', 1],
":a= b" => 'Invalid filter name ":a= b".',
"." => "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.",
".() a" => "Illegal element: classes and ids must have values.",
".= a" => "Illegal element: classes and ids must have values.",
"%p..a" => "Illegal element: classes and ids must have values.",
"%a/ b" => "Self-closing tags can't have content.",
"%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],
" %p foo" => "Indenting at the beginning of the document is illegal.",
" %p foo" => "Indenting at the beginning of the document is illegal.",
"- end" => < ["Indenting at the beginning of the document is illegal.", 3],
"\n\n %p foo" => ["Indenting at the beginning of the document is illegal.", 3],
"%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\tfoo\n\tfoo" => ["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],
"%p\n \tfoo" => ["Indentation can't use both tabs and spaces.", 2],
"%p(" => "Invalid attribute list: \"(\".",
"%p(foo=\nbar)" => ["Invalid attribute list: \"(foo=\".", 1],
"%p(foo=)" => "Invalid attribute list: \"(foo=)\".",
"%p(foo 'bar')" => "Invalid attribute list: \"(foo 'bar')\".",
"%p(foo 'bar'\nbaz='bang')" => ["Invalid attribute list: \"(foo 'bar'\".", 1],
"%p(foo='bar'\nbaz 'bang'\nbip='bop')" => ["Invalid attribute list: \"(foo='bar' baz 'bang'\".", 2],
"%p{:foo => 'bar' :bar => 'baz'}" => :compile,
"%p{:foo => }" => :compile,
"%p{=> 'bar'}" => :compile,
"%p{:foo => 'bar}" => :compile,
"%p{'foo => 'bar'}" => :compile,
"%p{:foo => 'bar\"}" => :compile,
# Regression tests
"- raise 'foo'\n\n\n\nbar" => ["foo", 1],
"= 'foo'\n-raise 'foo'" => ["foo", 2],
"\n\n\n- raise 'foo'" => ["foo", 4],
"%p foo |\n bar |\n baz |\nbop\n- raise 'foo'" => ["foo", 5],
"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],
"foo\n:ruby\n 1\n 2\n 3\n- raise 'foo'" => ["foo", 6],
"foo\n:erb\n 1\n 2\n 3\n- raise 'foo'" => ["foo", 6],
"foo\n:plain\n 1\n 2\n 3\n- raise 'foo'" => ["foo", 6],
"foo\n:plain\n 1\n 2\n 3\n4\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\#{''}\n4\n- raise 'foo'" => ["foo", 7],
"foo\n:plain\n 1\n 2\n \#{raise 'foo'}" => ["foo", 5],
"= raise 'foo'\nfoo\nbar\nbaz\nbang" => ["foo", 1],
"- case 1\n\n- when 1\n - raise 'foo'" => ["foo", 4],
}
User = Struct.new('User', :id)
class CustomHamlClass < Struct.new(:id)
def haml_object_ref
"my_thing"
end
end
def render(text, options = {}, &block)
scope = options.delete(:scope) || Object.new
locals = options.delete(:locals) || {}
engine(text, options).to_html(scope, locals, &block)
end
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
def setup
return if Haml::Util.ruby1_8?
@old_default_internal = Encoding.default_internal
Encoding.default_internal = nil
end
def teardown
return if Haml::Util.ruby1_8?
Encoding.default_internal = @old_default_internal
end
def test_empty_render
assert_equal "", render("")
end
def test_flexible_tabulation
assert_equal("
HTML
%p
%p<= "\\nfoo\\n"
HAML
end
def test_whitespace_nuke_with_tags_and_else
assert_equal(<
foo
HTML
%a
%b<
- if false
= "foo"
- else
foo
HAML
assert_equal(<
foo
HTML
%a
%b
- if false
= "foo"
- else
foo
HAML
end
def test_outer_whitespace_nuke_with_empty_script
assert_equal(<
foo
HTML
%p
foo
= " "
%a>
HAML
end
def test_both_case_indentation_work_with_deeply_nested_code
result = <
other
RESULT
assert_equal(result, render(< true))
= capture_haml do
foo
HAML
end
def test_plain_equals_with_ugly
assert_equal("foo\nbar\n", render(< true))
= "foo"
bar
HAML
end
def test_inline_if
assert_equal(<One
Three
HTML
- for name in ["One", "Two", "Three"]
%p= name unless name == "Two"
HAML
end
def test_end_with_method_call
assert_equal(<
2|3|4
b-a-r
HTML
%p
= [1, 2, 3].map do |i|
- i + 1
- end.join("|")
= "bar".gsub(/./) do |s|
- s + "-"
- end.gsub(/-$/) do |s|
- ''
HAML
end
def test_silent_end_with_stuff
assert_equal(<hi!
HTML
- if true
%p hi!
- end if "foo".gsub(/f/) do
- "z"
- end + "bar"
HAML
end
def test_multiline_with_colon_after_filter
assert_equal(< "Bar", |
:b => "Baz" }[:a] |
HAML
assert_equal(< "Bar", |
:b => "Baz" }[:a] |
HAML
end
def test_multiline_in_filter
assert_equal(< false))
bar
HTML
#foo{:class => ''}
bar
HAML
end
def test_escape_attrs_always
assert_equal(< :always))
HTML
assert_equal(tag_html, render(< true))
%p&= "&"
%p!= "&"
%p= "&"
HAML
assert_equal(tag_html, render(< true))
%p&~ "&"
%p!~ "&"
%p~ "&"
HAML
assert_equal(tag_html, render(< true))
%p& \#{"&"}
%p! \#{"&"}
%p \#{"&"}
HAML
assert_equal(tag_html, render(< true))
%p&== \#{"&"}
%p!== \#{"&"}
%p== \#{"&"}
HAML
end
def test_new_attrs_with_hash
assert_equal("\n", render('%a(href="#")'))
end
def test_javascript_filter_with_dynamic_interp_and_escape_html
assert_equal(< true))
HTML
:javascript
& < > \#{"&"}
HAML
end
def test_html5_javascript_filter
assert_equal(< :html5))
HTML
:javascript
foo bar
HAML
end
def test_html5_css_filter
assert_equal(< :html5))
HTML
:css
foo bar
HAML
end
def test_erb_filter_with_multiline_expr
assert_equal(<
HAML
end
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(<foo-end
bar-end
HTML
- ("foo-end-bar-end".gsub(/\\w+-end/) do |s|
%p= s
- end; nil)
HAML
end
def test_if_without_content_and_else
assert_equal(<Foo\n",
render('%a(href="#" rel="top") Foo'))
assert_equal("Foo\n",
render('%a(href="#") #{"Foo"}'))
assert_equal("\n", render('%a(href="#\\"")'))
end
def test_filter_with_newline_and_interp
assert_equal(< true))
foo,
HTML
foo\#{"," if true}
HAML
end
# HTML escaping tests
def test_ampersand_equals_should_escape
assert_equal("
HTML
= ["bar",
"baz",
"bang"].join(", ")
%p foo
%p bar
HAML
end
def test_escaped_loud_ruby_multiline
assert_equal(<foo
bar
HTML
&= ["bar<",
"baz",
"bang"].join(", ")
%p foo
%p bar
HAML
end
def test_unescaped_loud_ruby_multiline
assert_equal(< true))
bar<, baz, bang
foo
bar
HTML
!= ["bar<",
"baz",
"bang"].join(", ")
%p foo
%p bar
HAML
end
def test_flattened_loud_ruby_multiline
assert_equal(<bar
baz
bang
foo
bar
HTML
~ "
" + ["bar",
"baz",
"bang"].join("\\n") + "
"
%p foo
%p bar
HAML
end
def test_loud_ruby_multiline_with_block
assert_equal(<foo
bar
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(<foo
bar
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(<foo, bar, baz
foo
bar
HTML
%p= ["foo",
"bar",
"baz"].join(", ")
%p foo
%p bar
HAML
end
def test_escaped_ruby_multiline_in_tag
assert_equal(<foo<, bar, baz
foo
bar
HTML
%p&= ["foo<",
"bar",
"baz"].join(", ")
%p foo
%p bar
HAML
end
def test_unescaped_ruby_multiline_in_tag
assert_equal(< true))
foo<, bar, baz
foo
bar
HTML
%p!= ["foo<",
"bar",
"baz"].join(", ")
%p foo
%p bar
HAML
end
def test_ruby_multiline_with_normal_multiline
assert_equal(<foo
bar
HTML
= "foo" + |
"bar" + |
["bar", |
"baz",
"bang"].join(", ")
%p foo
%p bar
HAML
end
def test_ruby_multiline_after_filter
assert_equal(<foo
bar
HTML
:plain
foo
bar
= ["bar",
"baz",
"bang"].join(", ")
%p foo
%p bar
HAML
end
# Encodings
def test_utf_8_bom
assert_equal <
baz
HTML
\xEF\xBB\xBF.foo
%p baz
HAML
end
unless Haml::Util.ruby1_8?
def test_default_encoding
assert_equal(Encoding.find("utf-8"), render(< "ascii-8bit"))
bâr
föö
HTML
%p bâr
%p föö
HAML
end
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
def test_encoding_error
render("foo\nbar\nb\xFEaz".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\nbar\nb_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
def test_same_coding_comment_as_encoding
assert_renders_encoded(<bâr
föö
HTML
-# coding: utf-8
%p bâr
%p föö
HAML
end
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")
end
def test_different_coding_than_system
assert_renders_encoded(<тАЬ
HTML
%p тАЬ
HAML
end
end
private
def assert_valid_encoding_comment(comment)
assert_renders_encoded(<ЖЛЫ
тАЬ
HTML
#{comment}
%p ЖЛЫ
%p тАЬ
HAML
end
def assert_converts_template_properly
engine = Haml::Engine.new(< "macRoman")
%p bâr
%p föö
HAML
assert_encoded_equal(<bâr
föö
HTML
end
def assert_renders_encoded(html, haml)
result = render(haml)
assert_encoded_equal html, result
end
def assert_encoded_equal(expected, actual)
assert_equal expected.encoding, actual.encoding
assert_equal expected, actual
end
end