require "helper"
module Nokogiri
module XML
class TestDocumentFragment < Nokogiri::TestCase
def setup
super
@xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
end
def test_replace_text_node
html = "foo"
doc = Nokogiri::XML::DocumentFragment.parse(html)
doc.children[0].replace "bar"
assert_equal 'bar', doc.children[0].content
end
def test_fragment_is_relative
doc = Nokogiri::XML('')
ctx = doc.root.child
fragment = Nokogiri::XML::DocumentFragment.new(doc, '', ctx)
hello = fragment.child
assert_equal 'hello', hello.name
assert_equal doc.root.child.namespace, hello.namespace
end
def test_node_fragment_is_relative
doc = Nokogiri::XML('')
assert doc.root.child
fragment = doc.root.child.fragment('')
hello = fragment.child
assert_equal 'hello', hello.name
assert_equal doc.root.child.namespace, hello.namespace
end
def test_new
assert Nokogiri::XML::DocumentFragment.new(@xml)
end
def test_fragment_should_have_document
fragment = Nokogiri::XML::DocumentFragment.new(@xml)
assert_equal @xml, fragment.document
end
def test_name
fragment = Nokogiri::XML::DocumentFragment.new(@xml)
assert_equal '#document-fragment', fragment.name
end
def test_static_method
fragment = Nokogiri::XML::DocumentFragment.parse("
a
")
assert_instance_of Nokogiri::XML::DocumentFragment, fragment
end
def test_static_method_with_namespaces
# follows different path in FragmentHandler#start_element which blew up after 597195ff
fragment = Nokogiri::XML::DocumentFragment.parse("a")
assert_instance_of Nokogiri::XML::DocumentFragment, fragment
end
def test_many_fragments
100.times { Nokogiri::XML::DocumentFragment.new(@xml) }
end
def test_subclass
klass = Class.new(Nokogiri::XML::DocumentFragment)
fragment = klass.new(@xml, "a
")
assert_instance_of klass, fragment
end
def test_subclass_parse
klass = Class.new(Nokogiri::XML::DocumentFragment)
doc = klass.parse("a
")
assert_instance_of klass, doc
end
def test_unparented_text_node_parse
fragment = Nokogiri::XML::DocumentFragment.parse("foo")
fragment.children.after("")
end
def test_xml_fragment
fragment = Nokogiri::XML.fragment("a
")
assert_equal "a
", fragment.to_s
end
def test_xml_fragment_has_multiple_toplevel_children
doc = "b
e
"
fragment = Nokogiri::XML::Document.new.fragment(doc)
assert_equal "b
e
", fragment.to_s
end
def test_xml_fragment_has_outer_text
# this test is descriptive, not prescriptive.
doc = "ab
"
fragment = Nokogiri::XML::Document.new.fragment(doc)
assert_equal "ab
", fragment.to_s
doc = "b
c"
fragment = Nokogiri::XML::Document.new.fragment(doc)
assert_equal "b
c", fragment.to_s
end
def test_xml_fragment_case_sensitivity
doc = "b"
fragment = Nokogiri::XML::Document.new.fragment(doc)
assert_equal "b", fragment.to_s
end
def test_xml_fragment_with_leading_whitespace
doc = " b
"
fragment = Nokogiri::XML::Document.new.fragment(doc)
assert_equal " b
", fragment.to_s
end
def test_xml_fragment_with_leading_whitespace_and_newline
doc = " \nb
"
fragment = Nokogiri::XML::Document.new.fragment(doc)
assert_equal " \nb
", fragment.to_s
end
def test_fragment_children_search
fragment = Nokogiri::XML::Document.new.fragment(
''
)
expected = fragment.children.xpath('.//p')
assert_equal 1, expected.length
css = fragment.children.css('p')
search_css = fragment.children.search('p')
search_xpath = fragment.children.search('.//p')
assert_equal expected, css
assert_equal expected, search_css
assert_equal expected, search_xpath
end
def test_fragment_css_search_with_whitespace_and_node_removal
# The same xml without leading whitespace in front of the first line
# does not expose the error. Putting both nodes on the same line
# instead also fixes the crash.
fragment = Nokogiri::XML::DocumentFragment.parse <<-EOXML
hi
x another paragraph
EOXML
children = fragment.css('p')
assert_equal 2, children.length
# removing the last node instead does not yield the error. Probably the
# node removal leaves around two consecutive text nodes which make the
# css search crash?
children.first.remove
assert_equal 1, fragment.xpath('.//p | self::p').length
assert_equal 1, fragment.css('p').length
end
def test_fragment_search_three_ways
frag = Nokogiri::XML::Document.new.fragment 'foo
bar
'
expected = frag.xpath('./*[@id = "content"]')
assert_equal 2, expected.length
[
[:css, '#content'],
[:search, '#content'],
[:search, './*[@id = \'content\']'],
].each do |method, query|
result = frag.send(method, query)
assert_equal(expected, result,
"fragment search with :#{method} using '#{query}' expected '#{expected}' got '#{result}'")
end
end
def test_fragment_search_with_multiple_queries
xml = '
important thing
stuff
more stuff
'
fragment = Nokogiri::XML.fragment(xml)
assert_kind_of Nokogiri::XML::DocumentFragment, fragment
assert_equal 3, fragment.xpath('.//div', './/p').length
assert_equal 3, fragment.css('.title', '.content', 'p').length
assert_equal 3, fragment.search('.//div', 'p.blah').length
end
def test_fragment_without_a_namespace_does_not_get_a_namespace
doc = Nokogiri::XML <<-EOX
EOX
frag = doc.fragment ""
assert_nil frag.namespace
end
def test_fragment_namespace_resolves_against_document_root
doc = Nokogiri::XML <<-EOX
EOX
ns = doc.root.namespace_definitions.detect { |x| x.prefix == "bar" }
frag = doc.fragment ""
assert frag.children.first.namespace
assert_equal ns, frag.children.first.namespace
end
def test_fragment_invalid_namespace_is_silently_ignored
doc = Nokogiri::XML <<-EOX
EOX
frag = doc.fragment ""
assert_nil frag.children.first.namespace
end
def test_decorator_is_applied
x = Module.new do
def awesome!
end
end
util_decorate(@xml, x)
fragment = Nokogiri::XML::DocumentFragment.new(@xml, "a
b
")
assert node_set = fragment.css('div')
assert node_set.respond_to?(:awesome!)
node_set.each do |node|
assert node.respond_to?(:awesome!), node.class
end
assert fragment.children.respond_to?(:awesome!), fragment.children.class
end
def test_decorator_is_applied_to_empty_set
x = Module.new do
def awesome!
end
end
util_decorate(@xml, x)
fragment = Nokogiri::XML::DocumentFragment.new(@xml, "")
assert fragment.children.respond_to?(:awesome!), fragment.children.class
end
def test_add_node_to_doc_fragment_segfault
frag = Nokogiri::XML::DocumentFragment.new(@xml, 'hello world
')
Nokogiri::XML::Comment.new(frag,'moo')
end
def test_issue_1077_parsing_of_frozen_strings
input = <<-EOS
EOS
input.freeze
Nokogiri::XML::DocumentFragment.parse(input) # assert_nothing_raised
end
def test_dup_creates_tree_with_identical_structure
original = Nokogiri::XML::DocumentFragment.parse("")
duplicate = original.dup
assert_equal original.to_html, duplicate.to_html
end
def test_dup_creates_mutable_tree
original = Nokogiri::XML::DocumentFragment.parse("")
duplicate = original.dup
duplicate.at_css("div").add_child("hello there")
assert_nil original.at_css("b")
assert_not_nil duplicate.at_css("b")
end
if Nokogiri.uses_libxml?
def test_for_libxml_in_context_fragment_parsing_bug_workaround
10.times do
begin
fragment = Nokogiri::XML.fragment("")
parent = fragment.children.first
child = parent.parse("").first
parent.add_child child
end
GC.start
end
end
def test_for_libxml_in_context_memory_badness_when_encountering_encoding_errors
# see issue #643 for background
# this test exists solely to raise an error during valgrind test runs.
html = <<-EOHTML
Foo
EOHTML
doc = Nokogiri::HTML html
doc.at_css("div").replace("Bar")
end
end
end
end
end