require File.expand_path(File.join(File.dirname(__FILE__), '..', "helper")) require 'uri' module Nokogiri module XML class TestDocument < Nokogiri::TestCase def setup super @xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE) end def test_empty_node_converted_to_html_is_not_self_closing doc = Nokogiri::XML('') assert_equal "", doc.inner_html end def test_add_child_with_fragment doc = Nokogiri::XML::Document.new fragment = doc.fragment('') doc.add_child fragment assert_equal '/hello', doc.at('//hello').path assert_equal 'hello', doc.root.name end def test_add_child_with_multiple_roots assert_raises(RuntimeError) do @xml << Node.new('foo', @xml) end end def test_move_root_to_document_with_no_root sender = Nokogiri::XML('foo') newdoc = Nokogiri::XML::Document.new newdoc.root = sender.root end def test_move_root_with_existing_root_gets_gcd doc = Nokogiri::XML('test') doc2 = Nokogiri::XML("#{'x' * 5000000}") doc2.root = doc.root end def test_validate assert_equal 44, @xml.validate.length end def test_validate_no_internal_subset doc = Nokogiri::XML('') assert_nil doc.validate end def test_clone assert @xml.clone end def test_document_should_not_have_default_ns doc = Nokogiri::XML::Document.new assert_raises NoMethodError do doc.default_namespace = 'http://innernet.com/' end assert_raises NoMethodError do doc.add_namespace_definition('foo', 'bar') end end def test_parse_handles_nil_gracefully assert_nothing_raised do @doc = Nokogiri::XML::Document.parse(nil) end assert_instance_of Nokogiri::XML::Document, @doc end def test_parse_takes_block options = nil Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE) do |cfg| options = cfg end assert options end def test_parse_yields_parse_options options = nil Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE) do |cfg| options = cfg options.nonet.nowarning.dtdattr end assert options.nonet? assert options.nowarning? assert options.dtdattr? end def test_XML_takes_block options = nil Nokogiri::XML(File.read(XML_FILE), XML_FILE) do |cfg| options = cfg options.nonet.nowarning.dtdattr end assert options.nonet? assert options.nowarning? assert options.dtdattr? end def test_subclass klass = Class.new(Nokogiri::XML::Document) doc = klass.new assert_instance_of klass, doc end def test_subclass_initialize klass = Class.new(Nokogiri::XML::Document) do attr_accessor :initialized_with def initialize(*args) @initialized_with = args end end doc = klass.new("1.0", 1) assert_equal ["1.0", 1], doc.initialized_with end def test_subclass_dup klass = Class.new(Nokogiri::XML::Document) doc = klass.new.dup assert_instance_of klass, doc end def test_subclass_parse klass = Class.new(Nokogiri::XML::Document) doc = klass.parse(File.read(XML_FILE)) assert_equal @xml.to_s, doc.to_s assert_instance_of klass, doc end def test_document_parse_method xml = Nokogiri::XML::Document.parse(File.read(XML_FILE)) assert_equal @xml.to_s, xml.to_s end def test_encoding= @xml.encoding = 'UTF-8' assert_match 'UTF-8', @xml.to_xml @xml.encoding = 'EUC-JP' assert_match 'EUC-JP', @xml.to_xml end def test_namespace_should_not_exist assert_raises(NoMethodError) { @xml.namespace } end def test_non_existant_function # WTF. I don't know why this is different between MRI and ffi. # They should be the same... Either way, raising an exception # is the correct thing to do. exception = RuntimeError if Nokogiri::VERSION_INFO['libxml']['platform'] == 'jruby' exception = Nokogiri::XML::XPath::SyntaxError end assert_raises(exception) { @xml.xpath('//name[foo()]') } end def test_ancestors assert_equal 0, @xml.ancestors.length end def test_root_node_parent_is_document parent = @xml.root.parent assert_equal @xml, parent assert_instance_of Nokogiri::XML::Document, parent end def test_xmlns_is_automatically_registered doc = Nokogiri::XML(<<-eoxml) bar eoxml assert_equal 1, doc.css('xmlns|foo').length assert_equal 1, doc.css('foo').length assert_equal 0, doc.css('|foo').length assert_equal 1, doc.xpath('//xmlns:foo').length assert_equal 1, doc.search('xmlns|foo').length assert_equal 1, doc.search('//xmlns:foo').length assert doc.at('xmlns|foo') assert doc.at('//xmlns:foo') assert doc.at('foo') end def test_xmlns_is_registered_for_nodesets doc = Nokogiri::XML(<<-eoxml) baz eoxml assert_equal 1, doc.css('xmlns|foo').css('xmlns|bar').length assert_equal 1, doc.css('foo').css('bar').length assert_equal 1, doc.xpath('//xmlns:foo').xpath('./xmlns:bar').length assert_equal 1, doc.search('xmlns|foo').search('xmlns|bar').length assert_equal 1, doc.search('//xmlns:foo').search('./xmlns:bar').length end def test_to_xml_with_indent doc = Nokogiri::XML('') doc = Nokogiri::XML(doc.to_xml(:indent => 5)) assert_indent 5, doc end def test_write_xml_to_with_indent io = StringIO.new doc = Nokogiri::XML('') doc.write_xml_to io, :indent => 5 io.rewind doc = Nokogiri::XML(io.read) assert_indent 5, doc end # wtf... osx's libxml sucks. unless Nokogiri::LIBXML_VERSION =~ /^2\.6\./ def test_encoding xml = Nokogiri::XML(File.read(XML_FILE), XML_FILE, 'UTF-8') assert_equal 'UTF-8', xml.encoding end end def test_document_has_errors doc = Nokogiri::XML(<<-eoxml) eoxml assert doc.errors.length > 0 doc.errors.each do |error| assert_match error.message, error.inspect assert_match error.message, error.to_s end end def test_strict_document_throws_syntax_error assert_raises(Nokogiri::XML::SyntaxError) { Nokogiri::XML('', nil, nil, 0) } assert_raises(Nokogiri::XML::SyntaxError) { Nokogiri::XML('') { |cfg| cfg.strict } } end def test_XML_function xml = Nokogiri::XML(File.read(XML_FILE), XML_FILE) assert xml.xml? end def test_url assert @xml.url assert_equal XML_FILE, URI.unescape(@xml.url).sub('file:///', '') end def test_document_parent xml = Nokogiri::XML(File.read(XML_FILE), XML_FILE) assert_raises(NoMethodError) { xml.parent } end def test_document_name xml = Nokogiri::XML(File.read(XML_FILE), XML_FILE) assert_equal 'document', xml.name end def test_parse_can_take_io xml = nil File.open(XML_FILE, 'rb') { |f| xml = Nokogiri::XML(f) } assert xml.xml? set = xml.search('//employee') assert set.length > 0 end def test_search_on_empty_documents doc = Nokogiri::XML::Document.new ns = doc.search('//foo') assert_equal 0, ns.length ns = doc.css('foo') assert_equal 0, ns.length ns = doc.xpath('//foo') assert_equal 0, ns.length end def test_bad_xpath_raises_syntax_error assert_raises(XML::XPath::SyntaxError) { @xml.xpath('\\') } end def test_new_document_collect_namespaces doc = Nokogiri::XML::Document.new assert_equal({}, doc.collect_namespaces) end def test_find_with_namespace doc = Nokogiri::XML.parse(<<-eoxml) snuggles! eoxml ctx = Nokogiri::XML::XPathContext.new(doc) ctx.register_ns 'tenderlove', 'http://tenderlovemaking.com/' set = ctx.evaluate('//tenderlove:foo').node_set assert_equal 1, set.length assert_equal 'foo', set.first.name # It looks like only the URI is important: ctx = Nokogiri::XML::XPathContext.new(doc) ctx.register_ns 'america', 'http://tenderlovemaking.com/' set = ctx.evaluate('//america:foo').node_set assert_equal 1, set.length assert_equal 'foo', set.first.name # Its so important that a missing slash will cause it to return nothing ctx = Nokogiri::XML::XPathContext.new(doc) ctx.register_ns 'america', 'http://tenderlovemaking.com' set = ctx.evaluate('//america:foo').node_set assert_equal 0, set.length end def test_xml? assert @xml.xml? end def test_document assert @xml.document end def test_singleton_methods assert node_set = @xml.search('//name') assert node_set.length > 0 node = node_set.first def node.test 'test' end assert node_set = @xml.search('//name') assert_equal 'test', node_set.first.test end def test_multiple_search assert node_set = @xml.search('//employee', '//name') employees = @xml.search('//employee') names = @xml.search('//name') assert_equal(employees.length + names.length, node_set.length) end def test_node_set_index assert node_set = @xml.search('//employee') assert_equal(5, node_set.length) assert node_set[4] assert_nil node_set[5] end def test_search assert node_set = @xml.search('//employee') assert_equal(5, node_set.length) node_set.each do |node| assert_equal('employee', node.name) end end def test_dump assert @xml.serialize assert @xml.to_xml end def test_dup dup = @xml.dup assert_instance_of Nokogiri::XML::Document, dup assert dup.xml?, 'duplicate should be xml' end def test_subset_is_decorated x = Module.new do def awesome! end end util_decorate(@xml, x) assert @xml.respond_to?(:awesome!) assert node_set = @xml.search('//staff') assert node_set.respond_to?(:awesome!) assert subset = node_set.search('.//employee') assert subset.respond_to?(:awesome!) assert sub_subset = node_set.search('.//name') assert sub_subset.respond_to?(:awesome!) end def test_decorator_is_applied x = Module.new do def awesome! end end util_decorate(@xml, x) assert @xml.respond_to?(:awesome!) assert node_set = @xml.search('//employee') assert node_set.respond_to?(:awesome!) node_set.each do |node| assert node.respond_to?(:awesome!), node.class end assert @xml.root.respond_to?(:awesome!) end def test_new doc = nil assert_nothing_raised { doc = Nokogiri::XML::Document.new } assert doc assert doc.xml? assert_nil doc.root end def test_set_root doc = nil assert_nothing_raised { doc = Nokogiri::XML::Document.new } assert doc assert doc.xml? assert_nil doc.root node = Nokogiri::XML::Node.new("b", doc) { |n| n.content = 'hello world' } assert_equal('hello world', node.content) doc.root = node assert_equal(node, doc.root) end def util_decorate(document, x) document.decorators(XML::Node) << x document.decorators(XML::NodeSet) << x document.decorate! end end end end