require 'test/unit' require 'erb' class TestERB < Test::Unit::TestCase class MyError < RuntimeError ; end def test_without_filename erb = ERB.new("<% raise ::TestERB::MyError %>") e = assert_raise(MyError) { erb.result } assert_match(/\A\(erb\):1\b/, e.backtrace[0]) end def test_with_filename erb = ERB.new("<% raise ::TestERB::MyError %>") erb.filename = "test filename" e = assert_raise(MyError) { erb.result } assert_match(/\Atest filename:1\b/, e.backtrace[0]) end def test_without_filename_with_safe_level erb = ERB.new("<% raise ::TestERB::MyError %>", 1) e = assert_raise(MyError) { erb.result } assert_match(/\A\(erb\):1\b/, e.backtrace[0]) end def test_with_filename_and_safe_level erb = ERB.new("<% raise ::TestERB::MyError %>", 1) erb.filename = "test filename" e = assert_raise(MyError) { erb.result } assert_match(/\Atest filename:1\b/, e.backtrace[0]) end def test_html_escape assert_equal(" !"\#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", ERB::Util.html_escape(" !\"\#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~")) assert_equal("", ERB::Util.html_escape("")) assert_equal("abc", ERB::Util.html_escape("abc")) assert_equal("<<", ERB::Util.html_escape("<<")) assert_equal("", ERB::Util.html_escape(nil)) assert_equal("123", ERB::Util.html_escape(123)) end end class TestERBCore < Test::Unit::TestCase def setup @erb = ERB end def test_core _test_core(nil) _test_core(0) _test_core(1) _test_core(2) orig = $VERBOSE begin $VERBOSE = false _test_core(3) ensure $VERBOSE = orig end end def _test_core(safe) erb = @erb.new("hello") assert_equal("hello", erb.result) erb = @erb.new("hello", safe, 0) assert_equal("hello", erb.result) erb = @erb.new("hello", safe, 1) assert_equal("hello", erb.result) erb = @erb.new("hello", safe, 2) assert_equal("hello", erb.result) src = < % n=0 * <%= n %> <% end %> EOS ans = <') assert_equal(ans.chomp, erb.result) ans = <') assert_equal(ans, erb.result) ans = <') assert_equal(ans.chomp, erb.result) ans = <') assert_equal(ans, erb.result) end def test_safe_04 erb = @erb.new('<%=$SAFE%>', 4) assert_equal('4', erb.result(TOPLEVEL_BINDING.taint)) end class Foo; end def test_def_class erb = @erb.new('hello') cls = erb.def_class assert_equal(Object, cls.superclass) assert(cls.new.respond_to?('result')) cls = erb.def_class(Foo) assert_equal(Foo, cls.superclass) assert(cls.new.respond_to?('result')) cls = erb.def_class(Object, 'erb') assert_equal(Object, cls.superclass) assert(cls.new.respond_to?('erb')) end def test_percent src = < EOS assert_equal("1\n", ERB.new(src, nil, '%').result(binding)) src = < EOS ans = "\n" assert_equal(ans, ERB.new(src, nil, '%').result(binding)) src = "<%\n%>" # ans = "\n" ans = "" assert_equal(ans, ERB.new(src, nil, '%').result(binding)) src = <<%= n%> EOS assert_equal("1\n", ERB.new(src, nil, '%').result(binding)) src = < %% %%><%%<%= i%><% end%> %%% EOS ans = <<%0 % %%><%1 %% EOS assert_equal(ans, ERB.new(src, nil, '%').result(binding)) end def test_def_erb_method klass = Class.new klass.module_eval do extend ERB::DefMethod fname = File.join(File.dirname(File.expand_path(__FILE__)), 'hello.erb') def_erb_method('hello', fname) end assert(klass.new.respond_to?('hello')) assert(! klass.new.respond_to?('hello_world')) erb = @erb.new('hello, world') klass.module_eval do def_erb_method('hello_world', erb) end assert(klass.new.respond_to?('hello_world')) end def test_def_method_without_filename klass = Class.new erb = ERB.new("<% raise ::TestERB::MyError %>") erb.filename = "test filename" assert(! klass.new.respond_to?('my_error')) erb.def_method(klass, 'my_error') e = assert_raise(::TestERB::MyError) { klass.new.my_error } assert_match(/\A\(ERB\):1\b/, e.backtrace[0]) end def test_def_method_with_fname klass = Class.new erb = ERB.new("<% raise ::TestERB::MyError %>") erb.filename = "test filename" assert(! klass.new.respond_to?('my_error')) erb.def_method(klass, 'my_error', 'test fname') e = assert_raise(::TestERB::MyError) { klass.new.my_error } assert_match(/\Atest fname:1\b/, e.backtrace[0]) end def test_escape src = < 2.%%> : <%="%%>"%> 3. % x = "foo" <%=x%> 4. %% print "foo" 5. %% <%="foo"%> 6.<%=" % print 'foo' "%> 7.<%=" %% print 'foo' "%> EOS ans = < : %> 3. foo 4. % print "foo" 5. % foo 6. % print 'foo' 7. %% print 'foo' EOS assert_equal(ans, ERB.new(src, nil, '%').result) end def test_keep_lineno src = < % raise("lineno") EOS erb = ERB.new(src, nil, '%') begin erb.result assert(false) rescue assert_match(/\A\(erb\):4\b/, $@[0].to_s) end src = < Hello, <% x = "World%%> "%> <%= x%> EOS ans = <Hello, World%> EOS assert_equal(ans, ERB.new(src, nil, '>').result) ans = < Hello, World%> EOS assert_equal(ans, ERB.new(src, nil, '<>').result) ans = < Hello, World%> EOS assert_equal(ans, ERB.new(src).result) src = < <%= x%> <% raise("lineno") %> EOS erb = ERB.new(src) begin erb.result assert(false) rescue assert_match(/\A\(erb\):5\b/, $@[0].to_s) end erb = ERB.new(src, nil, '>') begin erb.result assert(false) rescue assert_match(/\A\(erb\):5\b/, $@[0].to_s) end erb = ERB.new(src, nil, '<>') begin erb.result assert(false) rescue assert_match(/\A\(erb\):5\b/, $@[0].to_s) end src = < <%= x %><%- x = nil -%> <% raise("lineno") %> EOS erb = ERB.new(src, nil, '-') begin erb.result assert(false) rescue assert_match(/\A\(erb\):5\b/, $@[0].to_s) end erb = ERB.new(src, nil, '%-') begin erb.result assert(false) rescue assert_match(/\A\(erb\):5\b/, $@[0].to_s) end end def test_explicit src = < NotSkip <%- y = x -%> NotSkip <% x.each do |w| -%> <%- up = w.upcase -%> * <%= up %> <% end -%> <%- z = nil -%> NotSkip <%- z = x %> <%- z.each do |w| -%> <%- down = w.downcase -%> * <%= down %> <%- up = w.upcase -%> * <%= up %> <%- end -%> KeepNewLine <%- z = nil -%> EOS ans = <%", nil, "%").result) end end class TestERBCoreWOStrScan < TestERBCore def setup @save_map = ERB::Compiler::Scanner.instance_variable_get('@scanner_map') map = {[nil, false]=>ERB::Compiler::SimpleScanner} ERB::Compiler::Scanner.instance_variable_set('@scanner_map', map) super end def teardown ERB::Compiler::Scanner.instance_variable_set('@scanner_map', @save_map) end end