#!/usr/bin/env ruby
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 "", @xml.target!
end
def test_value
@xml.value("hi")
assert_equal "hi", @xml.target!
end
def test_nested
@xml.outer { |x| x.inner("x") }
assert_equal "x", @xml.target!
end
def test_attributes
@xml.ref(:id => 12)
assert_equal %{}, @xml.target!
end
def test_multiple_attributes
@xml.ref(:id => 12, :name => "bill")
assert_match %r{^$}, @xml.target!
end
def test_attributes_with_text
@xml.a("link", :href=>"http://onestepback.org")
assert_equal %{link}, @xml.target!
end
def test_complex
@xml.body(:bg=>"#ffffff") { |x|
x.title("T", :style=>"red")
}
assert_equal %{
T}, @xml.target!
end
def test_funky_symbol
@xml.tag!("non-ruby-token", :id=>1) { |x| x.ok }
assert_equal %{}, @xml.target!
end
def test_no_explicit_marker
@xml.p { |x| x.b("HI") }
assert_equal "HI
", @xml.target!
end
def test_reference_local_vars
n = 3
@xml.ol { |x| n.times { x.li(n) } }
assert_equal "- 3
- 3
- 3
", @xml.target!
end
def test_reference_methods
@xml.title { |x| x.a { x.b(name) } }
assert_equal "bob", @xml.target!
end
def test_append_text
@xml.p { |x| x.br; x.text! "HI" }
assert_equal "
HI
", @xml.target!
end
def test_ambiguous_markup
ex = assert_raises(ArgumentError) {
@xml.h1("data1") { b }
}
assert_match /\btext\b/, ex.message
assert_match /\bblock\b/, ex.message
end
def test_capitalized_method
@xml.P { |x| x.B("hi"); x.BR(); x.EM { x.text! "world" } }
assert_equal "hi
world
", @xml.target!
end
def test_escaping
@xml.div { |x| x.text! ""; 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 TestNameSpaces < Test::Unit::TestCase
def setup
@xml = Builder::XmlMarkup.new(:indent=>2)
end
def test_simple_name_spaces
@xml.rdf :RDF
assert_equal "\n", @xml.target!
end
def test_long
xml = Builder::XmlMarkup.new(:indent=>2)
xml.instruct!
xml.rdf :RDF,
"xmlns:rdf" => "&rdf;",
"xmlns:rdfs" => "&rdfs;",
"xmlns:xsd" => "&xsd;",
"xmlns:owl" => "&owl;" do
xml.owl :Class, 'rdf:ID'=>'Bird' do
xml.rdfs :label, 'bird'
xml.rdfs :subClassOf do
xml.owl :Restriction do
xml.owl :onProperty, 'rdf:resource'=>'#wingspan'
xml.owl :maxCardinality,1,'rdf:datatype'=>'&xsd;nonNegativeInteger'
end
end
end
end
assert_match /^<\?xml/, xml.target!
assert_match /\n/m, 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"){2}\?>\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"){2}\?>$/, @xml.target!
end
def test_xml_instruct_with_overrides
@xml.instruct! :xml, :encoding=>"UCS-2"
assert_match /^<\?xml( version="1.0"| encoding="UCS-2"){2}\?>$/, @xml.target!
end
def test_no_blocks
assert_raises(Builder::IllegalBlockError) do
@xml.instruct! { |x| x.hi }
end
assert_raises(Builder::IllegalBlockError) do
@xml.comment!(:element) { |x| x.hi }
end
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 - text
\n
\n", @xml.target!
end
def test_two_levels
@xml.p { |x|
x.ol { x.li "text" }
x.br
}
assert_equal "\n
\n - text
\n
\n
\n\n", @xml.target!
end
def test_initial_level
@xml = Builder::XmlMarkup.new(:indent=>2, :margin=>4)
@xml.name { |x| x.first("Jim") }
assert_equal " \n Jim\n \n", @xml.target!
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