require "spec" require "xml" require "spec/helpers/string" private def assert_built(expected, quote_char = nil, *, file = __FILE__, line = __LINE__, &) assert_prints XML.build(quote_char: quote_char) { |xml| with xml yield xml }, expected, file: file, line: line end describe XML::Builder do it "writes document" do assert_built(%[\n\n]) do end end it "writes element" do assert_built(%[\n\n]) do element("foo") { } end end it "errors on invalid element names" do expect_raises(XML::Error, "Invalid element name: '1'") do XML.build do |xml| xml.element("1") do end end end expect_raises(XML::Error, "Invalid element name: 'a b=\"c\"'") do XML.build do |xml| xml.element("a b=\"c\"") do end end end end it "writes nested element" do assert_built(%[\n\n]) do element("foo") do element("bar") { } end end end it "writes element with namespace" do assert_built(%[\n\n]) do element("x", "foo", "http://foo.com", id: 1) { } end end it "writes element with namespace, without block" do assert_built(%[\n\n]) do element("x", "foo", "http://foo.com", id: 1) end end it "writes attribute" do assert_built(%[\n\n]) do element("foo") do attribute("id", 1) end end end it "writes attribute with namespace" do assert_built(%[\n\n]) do element("foo") do attribute("x", "id", "http://ww.foo.com", 1) end end end it "writes element with namespace" do assert_built(%[\nbaz\n]) do element(nil, "foo", "bar") do text "baz" end end end it "writes element with prefix" do assert_built(%[\nbaz\n]) do element("foo", "bar", nil) do text "baz" end end end it "errors on invalid element name with prefix" do expect_raises(XML::Error, "Invalid prefix: 'foo='") do XML.build do |xml| xml.element("foo=", "bar", nil) do xml.text "baz" end end end end it "errors on invalid element name with prefix and namespace" do expect_raises(XML::Error, "Invalid prefix: 'foo '") do XML.build do |xml| xml.element("foo ", "bar", "ns") do xml.text "baz" end end end end it "writes text" do assert_built(%[\n1 < 2\n]) do element("foo") do text "1 < 2" end end end it "sets indent with string" do assert_built("\n\n\t\n\n") do |xml| xml.indent = "\t" element("foo") do element("bar") end end end it "sets indent with count" do assert_built("\n\n \n\n") do |xml| xml.indent = 2 element("foo") do element("bar") end end end it "sets quote char" do assert_built("\n\n", quote_char: '\'') do |xml| element("foo") do attribute("id", 1) end end end it "writes element with attributes as named tuple" do assert_built(%[\n\n]) do |xml| element("foo", id: 1, name: "foo") end end it "writes element with attributes as named tuple, nesting" do assert_built(%[\n\n]) do |xml| element("foo", id: 1, name: "foo") do attribute "baz", 2 end end end it "writes element with attributes as hash" do assert_built(%[\n\n]) do |xml| element("foo", {"id" => 1, "name" => "foo"}) end end it "writes element with attributes as hash, nesting" do assert_built(%[\n\n]) do |xml| element("foo", {"id" => 1, "name" => "foo"}) do attribute "baz", 2 end end end describe "#cdata" do it "writes cdata" do assert_built(%{\n\n}) do |xml| element("foo") do cdata("hello") end end end it "escapes ]]> sequences" do assert_built(%{\nTwo]]]]>Three]]>\n}) do |xml| element("foo") do cdata("One]]>Two]]>Three") end end end it "writes cdata with block" do assert_built(%{\n\n}) do |xml| element("foo") do cdata do text "hello" end end end end end it "writes comment" do assert_built(%{\n\n}) do |xml| element("foo") do comment("hello") end end end it "writes comment with block" do assert_built(%{\n\n}) do |xml| element("foo") do comment do text "hello" end end end end it "writes DTD" do assert_built(%{\n\n}) do |xml| dtd "html", "-//W3C//DTD XHTML 1.0 Transitional//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", "subset" end end it "writes DTD with block" do assert_built(%{\n\n}) do |xml| dtd "html", "-//W3C//DTD XHTML 1.0 Transitional//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" do text "subset" end end end it "writes namespace" do assert_built(%{\n\n}) do |xml| element("foo") do namespace "x", "http://foo.com" end end end it "writes to string" do str = XML.build do |xml| xml.element("foo", id: 1) do xml.text "hello" end end str.should eq("\nhello\n") end it "writes to IO" do io = IO::Memory.new XML.build(io) do |xml| xml.element("foo", id: 1) do xml.text "hello" end end io.rewind io.to_s.should eq("\nhello\n") end it "errors on null byte" do expect_raises(XML::Error, "String cannot contain null character") do XML.build do |xml| xml.element("example", number: "1") do xml.text "foo\0bar" end end end expect_raises(XML::Error, "String cannot contain null character") do XML.build do |xml| xml.element("exam\0ple", number: "1") do xml.text "foobar" end end end end end