# -*- coding: utf-8 -*-
require "helper"
module Nokogiri
module XML
class TestBuilder < Nokogiri::TestCase
def test_attribute_sensitivity
xml = Nokogiri::XML::Builder.new { |x|
x.tag "hello", "abcDef" => "world"
}.to_xml
doc = Nokogiri.XML xml
assert_equal 'world', doc.root['abcDef']
end
def test_builder_multiple_nodes
Nokogiri::XML::Builder.new do |xml|
0.upto(10) do
xml.text "test"
end
end
end
def test_builder_with_utf8_text
text = "test οΊ΅ "
doc = Nokogiri::XML::Builder.new(:encoding => "UTF-8") { |xml| xml.test text }.doc
assert_equal text, doc.content
end
def test_builder_escape
xml = Nokogiri::XML::Builder.new { |x|
x.condition "value < 1", :attr => "value < 1"
}.to_xml
doc = Nokogiri.XML xml
assert_equal 'value < 1', doc.root['attr']
assert_equal 'value < 1', doc.root.content
end
def test_builder_namespace
doc = Nokogiri::XML::Builder.new { |xml|
xml.a("xmlns:a" => "x") do
xml.b("xmlns:a" => "x", "xmlns:b" => "y")
end
}.doc
b = doc.at('b')
assert b
assert_equal({"xmlns:a"=>"x", "xmlns:b"=>"y"}, b.namespaces)
assert_equal({"xmlns:b"=>"y"}, namespaces_defined_on(b))
end
def test_builder_namespace_part_deux
doc = Nokogiri::XML::Builder.new { |xml|
xml.a("xmlns:b" => "y") do
xml.b("xmlns:a" => "x", "xmlns:b" => "y", "xmlns:c" => "z")
end
}.doc
b = doc.at('b')
assert b
assert_equal({"xmlns:a"=>"x", "xmlns:b"=>"y", "xmlns:c"=>"z"}, b.namespaces)
assert_equal({"xmlns:a"=>"x", "xmlns:c"=>"z"}, namespaces_defined_on(b))
end
def test_builder_with_unlink
b = Nokogiri::XML::Builder.new do |xml|
xml.foo do
xml.bar { xml.parent.unlink }
xml.bar2
end
end
assert b
end
def test_with_root
doc = Nokogiri::XML(File.read(XML_FILE))
Nokogiri::XML::Builder.with(doc.at('employee')) do |xml|
xml.foo
end
assert_equal 1, doc.xpath('//employee/foo').length
end
def test_root_namespace_default_decl
b = Nokogiri::XML::Builder.new { |xml| xml.root(:xmlns => 'one:two') }
doc = b.doc
assert_equal 'one:two', doc.root.namespace.href
assert_equal({ 'xmlns' => 'one:two' }, doc.root.namespaces)
end
def test_root_namespace_multi_decl
b = Nokogiri::XML::Builder.new { |xml|
xml.root(:xmlns => 'one:two', 'xmlns:foo' => 'bar') do
xml.hello
end
}
doc = b.doc
assert_equal 'one:two', doc.root.namespace.href
assert_equal({ 'xmlns' => 'one:two', 'xmlns:foo' => 'bar' }, doc.root.namespaces)
assert_equal 'one:two', doc.at('hello').namespace.href
end
def test_non_root_namespace
b = Nokogiri::XML::Builder.new { |xml|
xml.root { xml.hello(:xmlns => 'one') }
}
assert_equal 'one', b.doc.at('hello', 'xmlns' => 'one').namespace.href
end
def test_specify_namespace
b = Nokogiri::XML::Builder.new { |xml|
xml.root('xmlns:foo' => 'bar') do
xml[:foo].bar
xml['foo'].baz
end
}
doc = b.doc
assert_equal 'bar', doc.at('foo|bar', 'foo' => 'bar').namespace.href
assert_equal 'bar', doc.at('foo|baz', 'foo' => 'bar').namespace.href
end
def test_dtd_in_builder_output
builder = Nokogiri::XML::Builder.new do |xml|
xml.doc.create_internal_subset(
'html',
"-//W3C//DTD HTML 4.01 Transitional//EN",
"http://www.w3.org/TR/html4/loose.dtd"
)
xml.root do
xml.foo
end
end
assert_match(//,
builder.to_xml)
end
def test_specify_namespace_nested
b = Nokogiri::XML::Builder.new { |xml|
xml.root('xmlns:foo' => 'bar') do
xml.yay do
xml[:foo].bar
xml.yikes do
xml['foo'].baz
end
end
end
}
doc = b.doc
assert_equal 'bar', doc.at('foo|bar', 'foo' => 'bar').namespace.href
assert_equal 'bar', doc.at('foo|baz', 'foo' => 'bar').namespace.href
end
def test_specified_namespace_postdeclared
doc = Nokogiri::XML::Builder.new { |xml|
xml.a do
xml[:foo].b("xmlns:foo" => "bar")
end
}.doc
a = doc.at('a')
assert_equal({}, a.namespaces)
b = doc.at_xpath('//foo:b', {:foo=>'bar'})
assert b
assert_equal({"xmlns:foo"=>"bar"}, b.namespaces)
assert_equal("b", b.name)
assert_equal("bar", b.namespace.href)
end
def test_specified_namespace_undeclared
Nokogiri::XML::Builder.new { |xml|
xml.root do
assert_raises(ArgumentError) do
xml[:foo].bar
end
end
}
end
def test_set_encoding
builder = Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
xml.root do
xml.bar 'blah'
end
end
assert_match 'UTF-8', builder.to_xml
end
def test_bang_and_underscore_is_escaped
builder = Nokogiri::XML::Builder.new do |xml|
xml.root do
xml.p_('adsfadsf')
xml.p!('adsfadsf')
end
end
assert_equal 2, builder.doc.xpath('//p').length
end
def test_square_brackets_set_attributes
builder = Nokogiri::XML::Builder.new do |xml|
xml.root do
foo = xml.foo
foo['id'] = 'hello'
assert_equal 'hello', foo['id']
end
end
assert_equal 1, builder.doc.xpath('//foo[@id = "hello"]').length
end
def test_nested_local_variable
@ivar = 'hello'
local_var = 'hello world'
builder = Nokogiri::XML::Builder.new do |xml|
xml.root do
xml.foo local_var
xml.bar @ivar
xml.baz {
xml.text @ivar
}
end
end
assert_equal 'hello world', builder.doc.at('//root/foo').content
assert_equal 'hello', builder.doc.at('//root/bar').content
assert_equal 'hello', builder.doc.at('baz').content
end
def test_raw_append
builder = Nokogiri::XML::Builder.new do |xml|
xml.root do
xml << 'hello'
end
end
assert_equal 'hello', builder.doc.at('/root').content
end
def test_raw_append_with_instance_eval
builder = Nokogiri::XML::Builder.new do
root do
self << 'hello'
end
end
assert_equal 'hello', builder.doc.at('/root').content
end
def test_raw_xml_append
builder = Nokogiri::XML::Builder.new do |xml|
xml.root do
xml << ''
end
end
assert_equal ["aaa"], builder.doc.at_css("root").children.collect(&:name)
assert_equal ["bbb","ccc"], builder.doc.at_css("aaa").children.collect(&:name)
end
def test_raw_xml_append_with_namespaces
doc = Nokogiri::XML::Builder.new do |xml|
xml.root("xmlns:foo" => "x", "xmlns" => "y") do
xml << ''
end
end.doc
el = doc.at 'Element'
assert_not_nil el
assert_equal 'y', el.namespace.href
assert_nil el.namespace.prefix
attr = el.attributes["bar"]
assert_not_nil attr
assert_not_nil attr.namespace
assert_equal "foo", attr.namespace.prefix
end
def test_cdata
builder = Nokogiri::XML::Builder.new do
root {
cdata "hello world"
}
end
assert_equal("",
builder.to_xml.gsub(/\n/, ""))
end
def test_comment
builder = Nokogiri::XML::Builder.new do
root {
comment "this is a comment"
}
end
assert builder.doc.root.children.first.comment?
end
def test_builder_no_block
string = "hello world"
builder = Nokogiri::XML::Builder.new
builder.root {
cdata string
}
assert_equal("",
builder.to_xml.gsub(/\n/, ''))
end
def test_builder_can_inherit_parent_namespace
builder = Nokogiri::XML::Builder.new
builder.products {
builder.parent.default_namespace = "foo"
builder.product {
builder.parent.default_namespace = nil
}
}
doc = builder.doc
['product', 'products'].each do |n|
assert_equal doc.at_xpath("//*[local-name() = '#{n}']").namespace.href, 'foo'
end
end
def test_builder_can_handle_namespace_override
builder = Nokogiri::XML::Builder.new
builder.products('xmlns:foo' => 'bar') {
builder.product('xmlns:foo' => 'baz')
}
doc = builder.doc
assert_equal doc.at_xpath("//*[local-name() = 'product']").namespaces['xmlns:foo'], 'baz'
assert_equal doc.at_xpath("//*[local-name() = 'products']").namespaces['xmlns:foo'], 'bar'
assert_nil doc.at_xpath("//*[local-name() = 'products']").namespace
end
private
def namespaces_defined_on(node)
Hash[*node.namespace_definitions.collect{|n| ["xmlns:" + n.prefix, n.href]}.flatten]
end
end
end
end