#!/usr/bin/env ruby
#--
# Portions copyright 2004 by Jim Weirich (jim@weirichhouse.org).
# Portions copyright 2005 by Sam Ruby (rubys@intertwingly.net).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
# and distribution of modified versions of this work as long as the
# above copyright notice is included.
#++
require 'test/unit'
require 'test/preload'
require 'builder'
require 'builder/xmlmarkup'
class TestMarkup < Test::Unit::TestCase
def setup
@xml = Builder::XmlMarkup.new
end
def test_create
assert_not_nil @xml
end
def test_simple
@xml.simple
assert_equal " HI hi
", @xml.target!
end
def test_reference_methods
@xml.title { |x| x.a { x.b(name) } }
assert_equal "
HI
world"; x.em("H&R Block") }
assert_equal %{ <hi>H&R Block}, @xml.target!
end
def test_non_escaping
@xml.div("ns:xml"=>:"&xml;") { |x| x << " "; x.em("H&R Block") }
assert_equal %{H&R Block}, @xml.target!
end
def test_return_value
str = @xml.x("men")
assert_equal @xml.target!, str
end
def test_stacked_builders
b = Builder::XmlMarkup.new( :target => @xml )
b.div { @xml.span { @xml.a("text", :href=>"ref") } }
assert_equal "", @xml.target!
end
def name
"bob"
end
end
class TestAttributeEscaping < Test::Unit::TestCase
def setup
@xml = Builder::XmlMarkup.new
end
def test_element_gt
@xml.title('1<2')
assert_equal '
}, xml.target! assert_match %r{
}, xml.target! end end class TestDeclarations < Test::Unit::TestCase def setup @xml = Builder::XmlMarkup.new(:indent=>2) end def test_declare @xml.declare! :element assert_equal "\n", @xml.target! end def test_bare_arg @xml.declare! :element, :arg assert_equal"\n", @xml.target! end def test_string_arg @xml.declare! :element, "string" assert_equal"\n", @xml.target! end def test_mixed_args @xml.declare! :element, :x, "y", :z, "-//OASIS//DTD DocBook XML//EN" assert_equal "\n", @xml.target! end def test_nested_declarations @xml = Builder::XmlMarkup.new @xml.declare! :DOCTYPE, :chapter do |x| x.declare! :ELEMENT, :chapter, "(title,para+)".intern end assert_equal "]>", @xml.target! end def test_nested_indented_declarations @xml.declare! :DOCTYPE, :chapter do |x| x.declare! :ELEMENT, :chapter, "(title,para+)".intern end assert_equal "\n]>\n", @xml.target! end def test_complex_declaration @xml.declare! :DOCTYPE, :chapter do |x| x.declare! :ELEMENT, :chapter, "(title,para+)".intern x.declare! :ELEMENT, :title, "(#PCDATA)".intern x.declare! :ELEMENT, :para, "(#PCDATA)".intern end expected = %{ ]> } assert_equal expected, @xml.target! end end class TestSpecialMarkup < Test::Unit::TestCase def setup @xml = Builder::XmlMarkup.new(:indent=>2) end def test_comment @xml.comment!("COMMENT") assert_equal "\n", @xml.target! end def test_indented_comment @xml.p { @xml.comment! "OK" } assert_equal "\n \n
\n", @xml.target! end def test_instruct @xml.instruct! :abc, :version=>"0.9" assert_equal "\n", @xml.target! end def test_indented_instruct @xml.p { @xml.instruct! :xml } assert_match %r{\n <\?xml version="1.0" encoding="UTF-8"\?>\n
\n}, @xml.target! end def test_instruct_without_attributes @xml.instruct! :zz assert_equal "\n", @xml.target! end def test_xml_instruct @xml.instruct! assert_match /^<\?xml version="1.0" encoding="UTF-8"\?>$/, @xml.target! end def test_xml_instruct_with_overrides @xml.instruct! :xml, :encoding=>"UCS-2" assert_match /^<\?xml version="1.0" encoding="UCS-2"\?>$/, @xml.target! end def test_xml_instruct_with_standalong @xml.instruct! :xml, :encoding=>"UCS-2", :standalone=>"yes" assert_match /^<\?xml version="1.0" encoding="UCS-2" standalone="yes"\?>$/, @xml.target! end def test_no_blocks assert_raise(Builder::IllegalBlockError) do @xml.instruct! { |x| x.hi } end assert_raise(Builder::IllegalBlockError) do @xml.comment!(:element) { |x| x.hi } end end def test_cdata @xml.cdata!("TEST") assert_equal "\n", @xml.target! end def test_cdata_with_ampersand @xml.cdata!("TEST&CHECK") assert_equal "\n", @xml.target! end end class TestIndentedXmlMarkup < Test::Unit::TestCase def setup @xml = Builder::XmlMarkup.new(:indent=>2) end def test_one_level @xml.ol { |x| x.li "text" } assert_equal "\n
’
), xml.target!) # end def test_use_entities_if_encoding_is_utf_but_kcode_is_not $KCODE = 'NONE' xml = Builder::XmlMarkup.new xml.instruct!(:xml, :encoding => 'UTF-8') xml.p("\xE2\x80\x99") assert_match(%r(’
), xml.target!) # end else # change in behavior. As there is no $KCODE anymore, the default # moves from "does not understand utf-8" to "supports utf-8". def test_use_entities_if_no_encoding_is_given_and_kcode_is_none xml = Builder::XmlMarkup.new xml.p("\xE2\x80\x99") assert_match("\u2019
", xml.target!) # end def test_use_entities_if_encoding_is_utf_but_kcode_is_not xml = Builder::XmlMarkup.new xml.instruct!(:xml, :encoding => 'UTF-8') xml.p("\xE2\x80\x99") assert_match("\u2019
", xml.target!) # end end def encode string, encoding if !String.method_defined?(:encode) $KCODE = encoding string elsif encoding == 'UTF8' string.force_encoding('UTF-8') else string end end def test_use_entities_if_kcode_is_utf_but_encoding_is_something_else xml = Builder::XmlMarkup.new xml.instruct!(:xml, :encoding => 'UTF-16') xml.p(encode("\xE2\x80\x99", 'UTF8')) assert_match(%r(’
), xml.target!) # end def test_use_utf8_if_encoding_defaults_and_kcode_is_utf8 xml = Builder::XmlMarkup.new xml.p(encode("\xE2\x80\x99",'UTF8')) assert_equal encode("\xE2\x80\x99
",'UTF8'), xml.target! end def test_use_utf8_if_both_encoding_and_kcode_are_utf8 xml = Builder::XmlMarkup.new xml.instruct!(:xml, :encoding => 'UTF-8') xml.p(encode("\xE2\x80\x99",'UTF8')) assert_match encode("\xE2\x80\x99
",'UTF8'), xml.target! end def test_use_utf8_if_both_encoding_and_kcode_are_utf8_with_lowercase xml = Builder::XmlMarkup.new xml.instruct!(:xml, :encoding => 'utf-8') xml.p(encode("\xE2\x80\x99",'UTF8')) assert_match encode("\xE2\x80\x99
",'UTF8'), xml.target! end end class TestXmlEvents < Test::Unit::TestCase def setup @handler = EventHandler.new @xe = Builder::XmlEvents.new(:target=>@handler) end def test_simple @xe.p assert_equal [:start, :p, nil], @handler.events.shift assert_equal [:end, :p], @handler.events.shift end def test_text @xe.p("HI") assert_equal [:start, :p, nil], @handler.events.shift assert_equal [:text, "HI"], @handler.events.shift assert_equal [:end, :p], @handler.events.shift end def test_attributes @xe.p("id"=>"2") ev = @handler.events.shift assert_equal [:start, :p], ev[0,2] assert_equal "2", ev[2]['id'] assert_equal [:end, :p], @handler.events.shift end def test_indented @xml = Builder::XmlEvents.new(:indent=>2, :target=>@handler) @xml.p { |x| x.b("HI") } assert_equal [:start, :p, nil], @handler.events.shift assert_equal "\n ", pop_text assert_equal [:start, :b, nil], @handler.events.shift assert_equal "HI", pop_text assert_equal [:end, :b], @handler.events.shift assert_equal "\n", pop_text assert_equal [:end, :p], @handler.events.shift end def pop_text result = '' while ! @handler.events.empty? && @handler.events[0][0] == :text result << @handler.events[0][1] @handler.events.shift end result end class EventHandler attr_reader :events def initialize @events = [] end def start_tag(sym, attrs) @events << [:start, sym, attrs] end def end_tag(sym) @events << [:end, sym] end def text(txt) @events << [:text, txt] end end end end