From 5ac63483dc07f933a75d053f5ab2d1542004f797 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Mon, 18 Jan 2021 15:24:58 -0500 Subject: [PATCH 1/3] format: rubocop and minispec for xml/test_node.rb --- test/xml/test_node.rb | 2075 +++++++++++++++++++++-------------------- 1 file changed, 1039 insertions(+), 1036 deletions(-) diff --git a/test/xml/test_node.rb b/test/xml/test_node.rb index cb7c0fd031..5aa3ceebb9 100644 --- a/test/xml/test_node.rb +++ b/test/xml/test_node.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true require "helper" require 'stringio' @@ -5,1228 +6,1230 @@ module Nokogiri module XML class TestNode < Nokogiri::TestCase - def setup - super - @xml = Nokogiri::XML(File.read(XML_FILE), XML_FILE) - end + describe Nokogiri::XML::Node do + let(:xml) { Nokogiri::XML(File.read(XML_FILE), XML_FILE) } - def test_first_element_child - node = @xml.root.first_element_child - assert_equal 'employee', node.name - assert node.element?, 'node is an element' - end + def test_first_element_child + node = xml.root.first_element_child + assert_equal('employee', node.name) + assert(node.element?, 'node is an element') + end - def test_element_children - nodes = @xml.root.element_children - assert_equal @xml.root.first_element_child, nodes.first - assert nodes.all?(&:element?), 'all nodes are elements' - end + def test_element_children + nodes = xml.root.element_children + assert_equal(xml.root.first_element_child, nodes.first) + assert(nodes.all?(&:element?), 'all nodes are elements') + end - def test_last_element_child - nodes = @xml.root.element_children - assert_equal nodes.last, @xml.root.element_children.last - end + def test_last_element_child + nodes = xml.root.element_children + assert_equal(nodes.last, xml.root.element_children.last) + end - def test_bad_xpath - bad_xpath = '//foo[' + def test_bad_xpath + bad_xpath = '//foo[' - begin - @xml.xpath(bad_xpath) - rescue Nokogiri::XML::XPath::SyntaxError => e - assert_match(bad_xpath, e.to_s) + begin + xml.xpath(bad_xpath) + rescue Nokogiri::XML::XPath::SyntaxError => e + assert_match(bad_xpath, e.to_s) + end end - end - def test_namespace_type_error - assert_raises(TypeError) do - @xml.root.namespace = Object.new + def test_namespace_type_error + assert_raises(TypeError) do + xml.root.namespace = Object.new + end end - end - def test_remove_namespace - @xml = Nokogiri::XML('') - tag = @xml.at('s') - assert tag.namespace - tag.namespace = nil - assert_nil tag.namespace - end - - def test_parse_needs_doc - list = @xml.root.parse('fooooooo ') - assert_equal 1, list.css('hello').length - end + def test_remove_namespace + xml = Nokogiri::XML('') + tag = xml.at('s') + assert(tag.namespace) + tag.namespace = nil + assert_nil(tag.namespace) + end - def test_parse - list = @xml.root.parse('fooooooo ') - assert_equal 2, list.length - end + def test_parse_needs_doc + list = xml.root.parse('fooooooo ') + assert_equal(1, list.css('hello').length) + end - def test_parse_with_block - called = false - list = @xml.root.parse('') { |cfg| - called = true - assert_instance_of Nokogiri::XML::ParseOptions, cfg - } - assert called, 'config block called' - assert_equal 1, list.length - end + def test_parse + list = xml.root.parse('fooooooo ') + assert_equal(2, list.length) + end - def test_parse_with_io - list = @xml.root.parse(StringIO.new('')) - assert_equal 1, list.length - assert_equal 'hello', list.first.name - end + def test_parse_with_block + called = false + list = xml.root.parse('') do |cfg| + called = true + assert_instance_of(Nokogiri::XML::ParseOptions, cfg) + end + assert(called, 'config block called') + assert_equal(1, list.length) + end - def test_parse_with_empty_string - list = @xml.root.parse('') - assert_equal 0, list.length - end + def test_parse_with_io + list = xml.root.parse(StringIO.new('')) + assert_equal(1, list.length) + assert_equal('hello', list.first.name) + end - def test_parse_config_option - node = @xml.root - options = nil - node.parse("") do |config| - options = config + def test_parse_with_empty_string + list = xml.root.parse('') + assert_equal(0, list.length) end - assert_equal Nokogiri::XML::ParseOptions::DEFAULT_XML, options.to_i - end - def test_node_context_parsing_of_malformed_html_fragment - doc = HTML.parse "
" - context_node = doc.at_css "div" - nodeset = context_node.parse("
") + def test_parse_config_option + node = xml.root + options = nil + node.parse("") do |config| + options = config + end + assert_equal(Nokogiri::XML::ParseOptions::DEFAULT_XML, options.to_i) + end - assert_equal 1, doc.errors.length - assert_equal 1, nodeset.length - assert_equal "
", nodeset.to_s - end + def test_node_context_parsing_of_malformed_html_fragment + doc = HTML.parse("
") + context_node = doc.at_css("div") + nodeset = context_node.parse("
") - def test_node_context_parsing_of_malformed_html_fragment_with_recover_is_corrected - doc = HTML.parse "
" - context_node = doc.at_css "div" - nodeset = context_node.parse("
") do |options| - options.recover + assert_equal(1, doc.errors.length) + assert_equal(1, nodeset.length) + assert_equal("
", nodeset.to_s) end - assert_equal 1, doc.errors.length - assert_equal 1, nodeset.length - assert_equal "
", nodeset.to_s - end + def test_node_context_parsing_of_malformed_html_fragment_with_recover_is_corrected + doc = HTML.parse("
") + context_node = doc.at_css("div") + nodeset = context_node.parse("
") do |options| + options.recover + end + + assert_equal(1, doc.errors.length) + assert_equal(1, nodeset.length) + assert_equal("
", nodeset.to_s) + end - def test_node_context_parsing_of_malformed_html_fragment_without_recover_is_not_corrected - doc = HTML.parse "
" - context_node = doc.at_css "div" - assert_raises(Nokogiri::XML::SyntaxError) do - context_node.parse("
") do |options| - options.strict + def test_node_context_parsing_of_malformed_html_fragment_without_recover_is_not_corrected + doc = HTML.parse("
") + context_node = doc.at_css("div") + assert_raises(Nokogiri::XML::SyntaxError) do + context_node.parse("
") do |options| + options.strict + end end end - end - def test_parse_error_list - error_count = @xml.errors.length - @xml.root.parse('') - assert(error_count < @xml.errors.length, "errors should have increased") - end + def test_parse_error_list + error_count = xml.errors.length + xml.root.parse('') + assert(error_count < xml.errors.length, "errors should have increased") + end - def test_parse_error_on_fragment_with_empty_document - doc = Document.new - fragment = DocumentFragment.new(doc, '') - node = fragment%'bar' - node.parse('<') - end + def test_parse_error_on_fragment_with_empty_document + doc = Document.new + fragment = DocumentFragment.new(doc, '') + node = fragment % 'bar' + node.parse('<') + end - def test_parse_with_unparented_text_context_node - doc = XML::Document.new - elem = XML::Text.new("foo", doc) - x = elem.parse("") # should not raise an exception - assert_equal x.first.name, "bar" - end + def test_parse_with_unparented_text_context_node + doc = XML::Document.new + elem = XML::Text.new("foo", doc) + x = elem.parse("") # should not raise an exception + assert_equal(x.first.name, "bar") + end - def test_parse_with_unparented_html_text_context_node - doc = HTML::Document.new - elem = XML::Text.new("div", doc) - x = elem.parse("
") # should not raise an exception - assert_equal x.first.name, "div" - end + def test_parse_with_unparented_html_text_context_node + doc = HTML::Document.new + elem = XML::Text.new("div", doc) + x = elem.parse("
") # should not raise an exception + assert_equal(x.first.name, "div") + end - def test_parse_with_unparented_fragment_text_context_node - doc = XML::DocumentFragment.parse "
foo
" - elem = doc.at_css "span" - x = elem.parse("") # should not raise an exception - assert_equal x.first.name, "span" - end + def test_parse_with_unparented_fragment_text_context_node + doc = XML::DocumentFragment.parse("
foo
") + elem = doc.at_css("span") + x = elem.parse("") # should not raise an exception + assert_equal(x.first.name, "span") + end - def test_parse_with_unparented_html_fragment_text_context_node - doc = HTML::DocumentFragment.parse "
foo
" - elem = doc.at_css "span" - x = elem.parse("") # should not raise an exception - assert_equal x.first.name, "span" - end + def test_parse_with_unparented_html_fragment_text_context_node + doc = HTML::DocumentFragment.parse("
foo
") + elem = doc.at_css("span") + x = elem.parse("") # should not raise an exception + assert_equal(x.first.name, "span") + end - def test_dup_is_deep_copy_by_default - doc = XML::Document.parse "

hello

" - div = doc.at_css "div" - node = div.dup - assert_equal 1, node.children.length - assert_equal "

hello

", node.children.first.to_html - end + def test_dup_is_deep_copy_by_default + doc = XML::Document.parse("

hello

") + div = doc.at_css("div") + node = div.dup + assert_equal(1, node.children.length) + assert_equal("

hello

", node.children.first.to_html) + end - def test_dup_deep_copy - doc = XML::Document.parse "

hello

" - div = doc.at_css "div" - node = div.dup(1) - assert_equal 1, node.children.length - assert_equal "

hello

", node.children.first.to_html - end + def test_dup_deep_copy + doc = XML::Document.parse("

hello

") + div = doc.at_css("div") + node = div.dup(1) + assert_equal(1, node.children.length) + assert_equal("

hello

", node.children.first.to_html) + end - def test_dup_shallow_copy - doc = XML::Document.parse "

hello

" - div = doc.at_css "div" - node = div.dup(0) - assert_equal 0, node.children.length - end + def test_dup_shallow_copy + doc = XML::Document.parse("

hello

") + div = doc.at_css("div") + node = div.dup(0) + assert_equal(0, node.children.length) + end - if Nokogiri.uses_libxml? def test_dup_to_another_document - doc1 = HTML::Document.parse "

hello

" - doc2 = HTML::Document.parse "
" + skip("Node.dup with new_parent arg is only implemented on CRuby") unless Nokogiri.uses_libxml? + doc1 = HTML::Document.parse("

hello

") + doc2 = HTML::Document.parse("
") - div = doc1.at_css "div" + div = doc1.at_css("div") duplicate_div = div.dup(1, doc2) - assert_not_nil doc1.at_css("div") - assert_equal doc2, duplicate_div.document - assert_equal 1, duplicate_div.children.length - assert_equal "

hello

", duplicate_div.children.first.to_html + assert_not_nil(doc1.at_css("div")) + assert_equal(doc2, duplicate_div.document) + assert_equal(1, duplicate_div.children.length) + assert_equal("

hello

", duplicate_div.children.first.to_html) end - end - def test_subclass_dup - subclass = Class.new(Nokogiri::XML::Node) - node = subclass.new('foo', @xml).dup - assert_instance_of subclass, node - end + def test_subclass_dup + subclass = Class.new(Nokogiri::XML::Node) + node = subclass.new('foo', xml).dup + assert_instance_of(subclass, node) + end - def test_gt_string_arg - node = @xml.at('employee') - nodes = (node > 'name') - assert_equal 1, nodes.length - assert_equal node, nodes.first.parent - end + def test_gt_string_arg + node = xml.at('employee') + nodes = (node > 'name') + assert_equal(1, nodes.length) + assert_equal(node, nodes.first.parent) + end - def test_next_element_when_next_sibling_is_element_should_return_next_sibling - doc = Nokogiri::XML "" - node = doc.at_css("foo") - next_element = node.next_element - assert next_element.element? - assert_equal doc.at_css("quux"), next_element - end + def test_next_element_when_next_sibling_is_element_should_return_next_sibling + doc = Nokogiri::XML("") + node = doc.at_css("foo") + next_element = node.next_element + assert(next_element.element?) + assert_equal(doc.at_css("quux"), next_element) + end - def test_next_element_when_there_is_no_next_sibling_should_return_nil - doc = Nokogiri::XML "" - assert_nil doc.at_css("quux").next_element - end + def test_next_element_when_there_is_no_next_sibling_should_return_nil + doc = Nokogiri::XML("") + assert_nil(doc.at_css("quux").next_element) + end - def test_next_element_when_next_sibling_is_not_an_element_should_return_closest_next_element_sibling - doc = Nokogiri::XML "bar" - node = doc.at_css("foo") - next_element = node.next_element - assert next_element.element? - assert_equal doc.at_css("quux"), next_element - end + def test_next_element_when_next_sibling_is_not_an_element_should_return_closest_next_element_sibling + doc = Nokogiri::XML("bar") + node = doc.at_css("foo") + next_element = node.next_element + assert(next_element.element?) + assert_equal(doc.at_css("quux"), next_element) + end - def test_next_element_when_next_sibling_is_not_an_element_and_no_following_element_should_return_nil - doc = Nokogiri::XML "bar" - node = doc.at_css("foo") - next_element = node.next_element - assert_nil next_element - end + def test_next_element_when_next_sibling_is_not_an_element_and_no_following_element_should_return_nil + doc = Nokogiri::XML("bar") + node = doc.at_css("foo") + next_element = node.next_element + assert_nil(next_element) + end - def test_previous_element_when_previous_sibling_is_element_should_return_previous_sibling - doc = Nokogiri::XML "" - node = doc.at_css("quux") - previous_element = node.previous_element - assert previous_element.element? - assert_equal doc.at_css("foo"), previous_element - end + def test_previous_element_when_previous_sibling_is_element_should_return_previous_sibling + doc = Nokogiri::XML("") + node = doc.at_css("quux") + previous_element = node.previous_element + assert(previous_element.element?) + assert_equal(doc.at_css("foo"), previous_element) + end - def test_previous_element_when_there_is_no_previous_sibling_should_return_nil - doc = Nokogiri::XML "" - assert_nil doc.at_css("foo").previous_element - end + def test_previous_element_when_there_is_no_previous_sibling_should_return_nil + doc = Nokogiri::XML("") + assert_nil(doc.at_css("foo").previous_element) + end - def test_previous_element_when_previous_sibling_is_not_an_element_should_return_closest_previous_element_sibling - doc = Nokogiri::XML "bar" - node = doc.at_css("quux") - previous_element = node.previous_element - assert previous_element.element? - assert_equal doc.at_css("foo"), previous_element - end + def test_previous_element_when_previous_sibling_is_not_an_element_should_return_closest_previous_element_sibling + doc = Nokogiri::XML("bar") + node = doc.at_css("quux") + previous_element = node.previous_element + assert(previous_element.element?) + assert_equal(doc.at_css("foo"), previous_element) + end - def test_previous_element_when_previous_sibling_is_not_an_element_and_no_following_element_should_return_nil - doc = Nokogiri::XML "foo" - node = doc.at_css("bar") - previous_element = node.previous_element - assert_nil previous_element - end + def test_previous_element_when_previous_sibling_is_not_an_element_and_no_following_element_should_return_nil + doc = Nokogiri::XML("foo") + node = doc.at_css("bar") + previous_element = node.previous_element + assert_nil(previous_element) + end - def test_element? - assert @xml.root.element?, 'is an element' - end + def test_element? + assert(xml.root.element?, 'is an element') + end - def test_slash_search - assert_equal 'EMP0001', (@xml/:staff/:employee/:employeeId).first.text - end + def test_slash_search + assert_equal('EMP0001', (xml / :staff / :employee / :employeeId).first.text) + end - def test_append_with_document - assert_raises(ArgumentError) do - @xml.root << Nokogiri::XML::Document.new + def test_append_with_document + assert_raises(ArgumentError) do + xml.root << Nokogiri::XML::Document.new + end end - end - def test_append_with_attr - r = Nokogiri.XML('').root - assert_raises(ArgumentError) do - r << r.at_xpath('@a') + def test_append_with_attr + r = Nokogiri.XML('').root + assert_raises(ArgumentError) do + r << r.at_xpath('@a') + end end - end - def test_inspect_ns - xml = Nokogiri::XML(<<-eoxml) { |c| c.noblanks } - - - - eoxml - ins = xml.inspect - - xml.traverse do |node| - assert_match node.class.name, ins - if node.respond_to? :attributes - node.attributes.each do |k,v| - assert_match k, ins - assert_match v, ins + def test_inspect_ns + xml = Nokogiri::XML(<<~eoxml) { |c| c.noblanks } + + + + eoxml + ins = xml.inspect + + xml.traverse do |node| + assert_match(node.class.name, ins) + if node.respond_to?(:attributes) + node.attributes.each do |k, v| + assert_match(k, ins) + assert_match(v, ins) + end end - end - if node.respond_to?(:namespace) && node.namespace - assert_match node.namespace.class.name, ins - assert_match node.namespace.href, ins + if node.respond_to?(:namespace) && node.namespace + assert_match(node.namespace.class.name, ins) + assert_match(node.namespace.href, ins) + end end end - end - def test_namespace_definitions_when_some_exist - xml = Nokogiri::XML <<-eoxml - - - - eoxml - namespace_definitions = xml.root.namespace_definitions - assert_equal 2, namespace_definitions.length - end - - def test_namespace_definitions_when_no_exist - xml = Nokogiri::XML <<-eoxml - - - - eoxml - namespace_definitions = xml.at_xpath('//xmlns:awesome').namespace_definitions - assert_equal 0, namespace_definitions.length - end + def test_namespace_definitions_when_some_exist + xml = Nokogiri::XML(<<~eoxml) + + + + eoxml + namespace_definitions = xml.root.namespace_definitions + assert_equal(2, namespace_definitions.length) + end - def test_namespace_goes_to_children - fruits = Nokogiri::XML(<<-eoxml) - - - eoxml - apple = Nokogiri::XML::Node.new('Apple', fruits) - orange = Nokogiri::XML::Node.new('Orange', fruits) - apple << orange - fruits.root << apple - assert fruits.at('//fruit:Orange',{'fruit'=>'www.fruits.org'}) - assert fruits.at('//fruit:Apple',{'fruit'=>'www.fruits.org'}) - end + def test_namespace_definitions_when_no_exist + xml = Nokogiri::XML(<<~eoxml) + + + + eoxml + namespace_definitions = xml.at_xpath('//xmlns:awesome').namespace_definitions + assert_equal(0, namespace_definitions.length) + end - def test_description - assert_nil @xml.at('employee').description - end + def test_namespace_goes_to_children + fruits = Nokogiri::XML(<<~eoxml) + + + eoxml + apple = Nokogiri::XML::Node.new('Apple', fruits) + orange = Nokogiri::XML::Node.new('Orange', fruits) + apple << orange + fruits.root << apple + assert(fruits.at('//fruit:Orange', { 'fruit' => 'www.fruits.org' })) + assert(fruits.at('//fruit:Apple', { 'fruit' => 'www.fruits.org' })) + end - def test_spaceship - nodes = @xml.xpath('//employee') - assert_equal(-1, (nodes.first <=> nodes.last)) - list = [nodes.first, nodes.last].sort - assert_equal nodes.first, list.first - assert_equal nodes.last, list.last - end + def test_description + assert_nil(xml.at('employee').description) + end - def test_incorrect_spaceship - nodes = @xml.xpath('//employee') - assert_nil(nodes.first <=> 'asdf') - end + def test_spaceship + nodes = xml.xpath('//employee') + assert_equal(-1, (nodes.first <=> nodes.last)) + list = [nodes.first, nodes.last].sort + assert_equal(nodes.first, list.first) + assert_equal(nodes.last, list.last) + end - def test_document_compare - nodes = @xml.xpath('//employee') - result = (nodes.first <=> @xml) + def test_incorrect_spaceship + nodes = xml.xpath('//employee') + assert_nil(nodes.first <=> 'asdf') + end - # Note that this behavior was changed in libxml@a005199 starting in v2.9.5. - # - # But that fix was backported by debian (and other distros?) into their v2.9.4 fork so we - # can't use version to detect what's going on here. Instead just shrug if we're using system - # libraries and the result is -1. - if (Nokogiri::VersionInfo.instance.libxml2_using_system?) - assert(result == 1 || result == -1) - else - assert_equal(1, result) + def test_document_compare + nodes = xml.xpath('//employee') + result = (nodes.first <=> xml) + + # Note that this behavior was changed in libxml@a005199 starting in v2.9.5. + # + # But that fix was backported by debian (and other distros?) into their v2.9.4 fork so we + # can't use version to detect what's going on here. Instead just shrug if we're using system + # libraries and the result is -1. + if Nokogiri::VersionInfo.instance.libxml2_using_system? + assert(result == 1 || result == -1) + else + assert_equal(1, result) + end end - end - def test_different_document_compare - nodes = @xml.xpath('//employee') - doc = Nokogiri::XML('') - b = doc.at('b') - assert_nil(nodes.first <=> b) - end + def test_different_document_compare + nodes = xml.xpath('//employee') + doc = Nokogiri::XML('') + b = doc.at('b') + assert_nil(nodes.first <=> b) + end - def test_duplicate_node_removes_namespace - fruits = Nokogiri::XML(<<-eoxml) - - - - eoxml - apple = fruits.root.xpath('fruit:Apple', {'fruit'=>'www.fruits.org'})[0] - new_apple = apple.dup - fruits.root << new_apple - assert_equal 2, fruits.xpath('//xmlns:Apple').length - assert_equal 1, fruits.to_xml.scan('www.fruits.org').length - end + def test_duplicate_node_removes_namespace + fruits = Nokogiri::XML(<<~eoxml) + + + + eoxml + apple = fruits.root.xpath('fruit:Apple', { 'fruit' => 'www.fruits.org' })[0] + new_apple = apple.dup + fruits.root << new_apple + assert_equal(2, fruits.xpath('//xmlns:Apple').length) + assert_equal(1, fruits.to_xml.scan('www.fruits.org').length) + end - [:clone, :dup].each do |symbol| - define_method "test_#{symbol}" do - node = @xml.at('//employee') - other = node.send(symbol) - assert_equal "employee", other.name - assert_nil other.parent + [:clone, :dup].each do |symbol| + define_method "test_#{symbol}" do + node = xml.at('//employee') + other = node.send(symbol) + assert_equal "employee", other.name + assert_nil other.parent + end end - end - def test_fragment_creates_elements - apple = @xml.fragment('') - apple.children.each do |child| - assert_equal Nokogiri::XML::Node::ELEMENT_NODE, child.type - assert_instance_of Nokogiri::XML::Element, child + def test_fragment_creates_elements + apple = xml.fragment('') + apple.children.each do |child| + assert_equal(Nokogiri::XML::Node::ELEMENT_NODE, child.type) + assert_instance_of(Nokogiri::XML::Element, child) + end end - end - def test_node_added_to_root_should_get_namespace - fruits = Nokogiri::XML(<<-eoxml) - - - eoxml - apple = fruits.fragment('') - fruits.root << apple - assert_equal 1, fruits.xpath('//xmlns:Apple').length - end + def test_node_added_to_root_should_get_namespace + fruits = Nokogiri::XML(<<~eoxml) + + + eoxml + apple = fruits.fragment('') + fruits.root << apple + assert_equal(1, fruits.xpath('//xmlns:Apple').length) + end - def test_new_node_can_have_ancestors - xml = Nokogiri::XML('text') - item = Nokogiri::XML::Element.new('item', xml) - assert_equal 0, item.ancestors.length - end + def test_new_node_can_have_ancestors + xml = Nokogiri::XML('text') + item = Nokogiri::XML::Element.new('item', xml) + assert_equal(0, item.ancestors.length) + end - def test_children - doc = Nokogiri::XML(<<-eoxml) - #{'' * 9 } - eoxml - assert_equal 9, doc.root.children.length - assert_equal 9, doc.root.children.to_a.length - - doc = Nokogiri::XML(<<-eoxml) - #{'' * 15 } - eoxml - assert_equal 15, doc.root.children.length - assert_equal 15, doc.root.children.to_a.length - end + def test_children + doc = Nokogiri::XML(<<~eoxml) + #{'' * 9} + eoxml + assert_equal(9, doc.root.children.length) + assert_equal(9, doc.root.children.to_a.length) + + doc = Nokogiri::XML(<<~eoxml) + #{'' * 15} + eoxml + assert_equal(15, doc.root.children.length) + assert_equal(15, doc.root.children.to_a.length) + end - def test_add_namespace - node = @xml.at('address') - node.add_namespace('foo', 'http://tenderlovemaking.com') - assert_equal 'http://tenderlovemaking.com', node.namespaces['xmlns:foo'] - end + def test_add_namespace + node = xml.at('address') + node.add_namespace('foo', 'http://tenderlovemaking.com') + assert_equal('http://tenderlovemaking.com', node.namespaces['xmlns:foo']) + end - def test_add_namespace_twice - node = @xml.at('address') - ns = node.add_namespace('foo', 'http://tenderlovemaking.com') - ns2 = node.add_namespace('foo', 'http://tenderlovemaking.com') - assert_equal ns, ns2 - end + def test_add_namespace_twice + node = xml.at('address') + ns = node.add_namespace('foo', 'http://tenderlovemaking.com') + ns2 = node.add_namespace('foo', 'http://tenderlovemaking.com') + assert_equal(ns, ns2) + end - def test_add_default_namespace - node = @xml.at('address') - node.add_namespace(nil, 'http://tenderlovemaking.com') - assert_equal 'http://tenderlovemaking.com', node.namespaces['xmlns'] - end + def test_add_default_namespace + node = xml.at('address') + node.add_namespace(nil, 'http://tenderlovemaking.com') + assert_equal('http://tenderlovemaking.com', node.namespaces['xmlns']) + end - def test_add_default_namespace_twice - node = @xml.at('address') - ns = node.add_namespace(nil, 'http://tenderlovemaking.com') - ns2 = node.add_namespace(nil, 'http://tenderlovemaking.com') - assert_equal ns.object_id, ns2.object_id - end + def test_add_default_namespace_twice + node = xml.at('address') + ns = node.add_namespace(nil, 'http://tenderlovemaking.com') + ns2 = node.add_namespace(nil, 'http://tenderlovemaking.com') + assert_equal(ns.object_id, ns2.object_id) + end - def test_add_multiple_namespaces - node = @xml.at('address') + def test_add_multiple_namespaces + node = xml.at('address') - node.add_namespace(nil, 'http://tenderlovemaking.com') - assert_equal 'http://tenderlovemaking.com', node.namespaces['xmlns'] + node.add_namespace(nil, 'http://tenderlovemaking.com') + assert_equal('http://tenderlovemaking.com', node.namespaces['xmlns']) - node.add_namespace('foo', 'http://tenderlovemaking.com') - assert_equal 'http://tenderlovemaking.com', node.namespaces['xmlns:foo'] - end + node.add_namespace('foo', 'http://tenderlovemaking.com') + assert_equal('http://tenderlovemaking.com', node.namespaces['xmlns:foo']) + end - def test_default_namespace= - node = @xml.at('address') - node.default_namespace = 'http://tenderlovemaking.com' - assert_equal 'http://tenderlovemaking.com', node.namespaces['xmlns'] - end + def test_default_namespace= + node = xml.at('address') + node.default_namespace = 'http://tenderlovemaking.com' + assert_equal('http://tenderlovemaking.com', node.namespaces['xmlns']) + end - def test_namespace= - node = @xml.at('address') - assert_nil node.namespace - definition = node.add_namespace_definition 'bar', 'http://tlm.com/' + def test_namespace= + node = xml.at('address') + assert_nil(node.namespace) + definition = node.add_namespace_definition('bar', 'http://tlm.com/') - node.namespace = definition + node.namespace = definition - assert_equal definition, node.namespace + assert_equal(definition, node.namespace) - assert_equal node, @xml.at('//foo:address', { - 'foo' => 'http://tlm.com/' - }) - end + assert_equal(node, xml.at('//foo:address', { + 'foo' => 'http://tlm.com/', + })) + end - def test_add_namespace_with_nil_associates_node - node = @xml.at('address') - assert_nil node.namespace - definition = node.add_namespace_definition nil, 'http://tlm.com/' - assert_equal definition, node.namespace - end + def test_add_namespace_with_nil_associates_node + node = xml.at('address') + assert_nil(node.namespace) + definition = node.add_namespace_definition(nil, 'http://tlm.com/') + assert_equal(definition, node.namespace) + end - def test_add_namespace_does_not_associate_node - node = @xml.at('address') - assert_nil node.namespace - assert node.add_namespace_definition 'foo', 'http://tlm.com/' - assert_nil node.namespace - end + def test_add_namespace_does_not_associate_node + node = xml.at('address') + assert_nil(node.namespace) + assert(node.add_namespace_definition('foo', 'http://tlm.com/')) + assert_nil(node.namespace) + end - def test_set_namespace_from_different_doc - node = @xml.at('address') - doc = Nokogiri::XML(File.read(XML_FILE), XML_FILE) - decl = doc.root.add_namespace_definition 'foo', 'bar' + def test_set_namespace_from_different_doc + node = xml.at('address') + doc = Nokogiri::XML(File.read(XML_FILE), XML_FILE) + decl = doc.root.add_namespace_definition('foo', 'bar') - assert_raises(ArgumentError) do - node.namespace = decl + assert_raises(ArgumentError) do + node.namespace = decl + end end - end - def test_set_namespace_must_only_take_a_namespace - node = @xml.at('address') - assert_raises(TypeError) do - node.namespace = node + def test_set_namespace_must_only_take_a_namespace + node = xml.at('address') + assert_raises(TypeError) do + node.namespace = node + end end - end - - def test_at - node = @xml.at('address') - assert_equal node, @xml.xpath('//address').first - end - def test_at_self - node = @xml.at('address') - assert_equal node, node.at('.') - end + def test_at + node = xml.at('address') + assert_equal(node, xml.xpath('//address').first) + end - def test_at_xpath - node = @xml.at_xpath('//address') - nodes = @xml.xpath('//address') - assert_equal 5, nodes.size - assert_equal node, nodes.first - end + def test_at_self + node = xml.at('address') + assert_equal(node, node.at('.')) + end - def test_at_css - node = @xml.at_css('address') - nodes = @xml.css('address') - assert_equal 5, nodes.size - assert_equal node, nodes.first - end + def test_at_xpath + node = xml.at_xpath('//address') + nodes = xml.xpath('//address') + assert_equal(5, nodes.size) + assert_equal(node, nodes.first) + end - def test_percent - node = @xml % ('address') - assert_equal node, @xml.xpath('//address').first - end + def test_at_css + node = xml.at_css('address') + nodes = xml.css('address') + assert_equal(5, nodes.size) + assert_equal(node, nodes.first) + end - def test_accept - visitor = Class.new { - attr_accessor :visited - def accept target - target.accept(self) - end + def test_percent + node = xml % 'address' + assert_equal(node, xml.xpath('//address').first) + end - def visit node - node.children.each { |c| c.accept(self) } - @visited = true - end - }.new - visitor.accept(@xml.root) - assert visitor.visited - end + def test_accept + visitor = Class.new do + attr_accessor :visited + def accept(target) + target.accept(self) + end - def test_write_to - io = StringIO.new - @xml.write_to io - io.rewind - assert_equal @xml.to_xml, io.read - end + def visit(node) + node.children.each { |c| c.accept(self) } + @visited = true + end + end.new + visitor.accept(xml.root) + assert(visitor.visited) + end - def test_write_to_with_block - called = false - io = StringIO.new - conf = nil - @xml.write_to io do |config| - called = true - conf = config - config.format.as_html.no_empty_tags - end - io.rewind - assert called - string = io.read - assert_equal @xml.serialize(nil, conf.options), string - assert_equal @xml.serialize(nil, conf), string - end + def test_write_to + io = StringIO.new + xml.write_to(io) + io.rewind + assert_equal(xml.to_xml, io.read) + end - %w{ xml html xhtml }.each do |type| - define_method(:"test_write_#{type}_to") do + def test_write_to_with_block + called = false io = StringIO.new - assert @xml.send(:"write_#{type}_to", io) + conf = nil + xml.write_to(io) do |config| + called = true + conf = config + config.format.as_html.no_empty_tags + end io.rewind - assert_match @xml.send(:"to_#{type}"), io.read + assert(called) + string = io.read + assert_equal(xml.serialize(nil, conf.options), string) + assert_equal(xml.serialize(nil, conf), string) end - end - def test_serialize_with_block - called = false - conf = nil - string = @xml.serialize do |config| - called = true - conf = config - config.format.as_html.no_empty_tags - end - assert called - assert_equal @xml.serialize(nil, conf.options), string - assert_equal @xml.serialize(nil, conf), string - end + %w{xml html xhtml}.each do |type| + define_method(:"test_write_#{type}_to") do + io = StringIO.new + assert xml.send(:"write_#{type}_to", io) + io.rewind + assert_match xml.send(:"to_#{type}"), io.read + end + end - def test_hold_refence_to_subnode - doc = Nokogiri::XML(<<-eoxml) - - - - - - eoxml - assert node_a = doc.css('a').first - assert node_b = node_a.css('b').first - node_a.unlink - assert_equal 'b', node_b.name - end + def test_serialize_with_block + called = false + conf = nil + string = xml.serialize do |config| + called = true + conf = config + config.format.as_html.no_empty_tags + end + assert(called) + assert_equal(xml.serialize(nil, conf.options), string) + assert_equal(xml.serialize(nil, conf), string) + end - def test_new - assert node = Nokogiri::XML::Node.new('input', @xml) - assert_equal 1, node.node_type - assert_instance_of Nokogiri::XML::Element, node - end + def test_hold_refence_to_subnode + doc = Nokogiri::XML(<<~eoxml) + + + + + + eoxml + assert(node_a = doc.css('a').first) + assert(node_b = node_a.css('b').first) + node_a.unlink + assert_equal('b', node_b.name) + end - def test_to_str - name = @xml.xpath('//name').first - assert_match(/Margaret/, '' + name) - assert_equal('Margaret Martin', '' + name.children.first) - end + def test_new + assert(node = Nokogiri::XML::Node.new('input', xml)) + assert_equal(1, node.node_type) + assert_instance_of(Nokogiri::XML::Element, node) + end - def test_ancestors - address = @xml.xpath('//address').first - assert_equal 3, address.ancestors.length - assert_equal ['employee', 'staff', 'document'], - address.ancestors.map(&:name) - end + def test_to_str + name = xml.xpath('//name').first + assert_match(/Margaret/, '' + name) + assert_equal('Margaret Martin', '' + name.children.first) + end - def test_read_only? - assert entity_decl = @xml.internal_subset.children.find { |x| - x.type == Node::ENTITY_DECL - } - assert entity_decl.read_only? - end + def test_ancestors + address = xml.xpath('//address').first + assert_equal(3, address.ancestors.length) + assert_equal(['employee', 'staff', 'document'], + address.ancestors.map(&:name)) + end - def test_set_content_with_symbol - node = @xml.at('//name') - node.content = :foo - assert_equal 'foo', node.content - end + def test_read_only? + assert(entity_decl = xml.internal_subset.children.find do |x| + x.type == Node::ENTITY_DECL + end) + assert(entity_decl.read_only?) + end - def test_set_native_content_is_unescaped - comment = Nokogiri.XML('').at('//comment()') + def test_set_content_with_symbol + node = xml.at('//name') + node.content = :foo + assert_equal('foo', node.content) + end - comment.native_content = " < " # content= will escape this string - assert_equal "", comment.to_xml - end + def test_set_native_content_is_unescaped + comment = Nokogiri.XML('').at('//comment()') - def test_find_by_css_class_with_nonstandard_whitespace - doc = Nokogiri::HTML "
" - assert_not_nil doc.at_css(".b") - end + comment.native_content = " < " # content= will escape this string + assert_equal("", comment.to_xml) + end - def test_find_by_css_with_tilde_eql - xml = Nokogiri::XML.parse(<<-eoxml) - - Hello world - Bar - Bar - Bar - Bar - Awesome - Awesome - - eoxml - set = xml.css('a[@class~="bar"]') - assert_equal 4, set.length - assert_equal ['Bar'], set.map(&:content).uniq - end + def test_find_by_css_class_with_nonstandard_whitespace + doc = Nokogiri::HTML("
") + assert_not_nil(doc.at_css(".b")) + end - def test_unlink - xml = Nokogiri::XML.parse(<<-eoxml) - - Bar - Bar - Bar - Hello world - Bar - Awesome - Awesome - - eoxml - node = xml.xpath('//a')[3] - assert_equal('Hello world', node.text) - assert_match(/Hello world/, xml.to_s) - assert node.parent - assert node.document - assert node.previous_sibling - assert node.next_sibling - node.unlink - assert !node.parent - #assert !node.document - assert !node.previous_sibling - assert !node.next_sibling - assert_no_match(/Hello world/, xml.to_s) - end + def test_find_by_css_with_tilde_eql + xml = Nokogiri::XML.parse(<<~eoxml) + + Hello world + Bar + Bar + Bar + Bar + Awesome + Awesome + + eoxml + set = xml.css('a[@class~="bar"]') + assert_equal(4, set.length) + assert_equal(['Bar'], set.map(&:content).uniq) + end - def test_next_sibling - assert node = @xml.root - assert sibling = node.child.next_sibling - assert_equal('employee', sibling.name) - end + def test_unlink + xml = Nokogiri::XML.parse(<<~eoxml) + + Bar + Bar + Bar + Hello world + Bar + Awesome + Awesome + + eoxml + node = xml.xpath('//a')[3] + assert_equal('Hello world', node.text) + assert_match(/Hello world/, xml.to_s) + assert(node.parent) + assert(node.document) + assert(node.previous_sibling) + assert(node.next_sibling) + node.unlink + assert(!node.parent) + # assert !node.document + assert(!node.previous_sibling) + assert(!node.next_sibling) + assert_no_match(/Hello world/, xml.to_s) + end - def test_previous_sibling - assert node = @xml.root - assert sibling = node.child.next_sibling - assert_equal('employee', sibling.name) - assert_equal(sibling.previous_sibling, node.child) - end + def test_next_sibling + assert(node = xml.root) + assert(sibling = node.child.next_sibling) + assert_equal('employee', sibling.name) + end - def test_name= - assert node = @xml.root - node.name = 'awesome' - assert_equal('awesome', node.name) - end + def test_previous_sibling + assert(node = xml.root) + assert(sibling = node.child.next_sibling) + assert_equal('employee', sibling.name) + assert_equal(sibling.previous_sibling, node.child) + end - def test_child - assert node = @xml.root - assert child = node.child - assert_equal('text', child.name) - end + def test_name= + assert(node = xml.root) + node.name = 'awesome' + assert_equal('awesome', node.name) + end - def test_key? - assert node = @xml.search('//address').first - assert(!node.key?('asdfasdf')) - end + def test_child + assert(node = xml.root) + assert(child = node.child) + assert_equal('text', child.name) + end - def test_set_property - assert node = @xml.search('//address').first - node['foo'] = 'bar' - assert_equal('bar', node['foo']) - end + def test_key? + assert(node = xml.search('//address').first) + assert(!node.key?('asdfasdf')) + end - def test_set_property_non_string - assert node = @xml.search('//address').first - node['foo'] = 1 - assert_equal('1', node['foo']) - node['foo'] = false - assert_equal('false', node['foo']) - end + def test_set_property + assert(node = xml.search('//address').first) + node['foo'] = 'bar' + assert_equal('bar', node['foo']) + end - def test_path - assert set = @xml.search('//employee') - assert node = set.first - assert_equal('/staff/employee[1]', node.path) - end + def test_set_property_non_string + assert(node = xml.search('//address').first) + node['foo'] = 1 + assert_equal('1', node['foo']) + node['foo'] = false + assert_equal('false', node['foo']) + end - def test_parent_xpath - assert set = @xml.search('//employee') - assert node = set.first - assert parent_set = node.search('..') - assert parent_node = parent_set.first - assert_equal '/staff', parent_node.path - assert_equal node.parent, parent_node - end + def test_path + assert(set = xml.search('//employee')) + assert(node = set.first) + assert_equal('/staff/employee[1]', node.path) + end - def test_search_self - node = @xml.at('//employee') - assert_equal node.search('.').to_a, [node] - end + def test_parent_xpath + assert(set = xml.search('//employee')) + assert(node = set.first) + assert(parent_set = node.search('..')) + assert(parent_node = parent_set.first) + assert_equal('/staff', parent_node.path) + assert_equal(node.parent, parent_node) + end - def test_search_by_symbol - assert set = @xml.search(:employee) - assert 5, set.length + def test_search_self + node = xml.at('//employee') + assert_equal(node.search('.').to_a, [node]) + end - assert node = @xml.at(:employee) - assert node.text =~ /EMP0001/ - end + def test_search_by_symbol + assert(set = xml.search(:employee)) + assert(5, set.length) - def test_new_node - node = Nokogiri::XML::Node.new('form', @xml) - assert_equal('form', node.name) - assert(node.document) - end + assert(node = xml.at(:employee)) + assert(node.text =~ /EMP0001/) + end - def test_encode_special_chars - foo = @xml.css('employee').first.encode_special_chars('&') - assert_equal '&', foo - end + def test_new_node + node = Nokogiri::XML::Node.new('form', xml) + assert_equal('form', node.name) + assert(node.document) + end - def test_content_equals - node = Nokogiri::XML::Node.new('form', @xml) - assert_equal('', node.content) + def test_encode_special_chars + foo = xml.css('employee').first.encode_special_chars('&') + assert_equal('&', foo) + end - node.content = 'hello world!' - assert_equal('hello world!', node.content) + def test_content_equals + node = Nokogiri::XML::Node.new('form', xml) + assert_equal('', node.content) - node.content = '& &' - assert_equal('& &', node.content) - assert_equal('
& <foo> &amp;
', node.to_xml) + node.content = 'hello world!' + assert_equal('hello world!', node.content) - node.content = "1234 <-> 1234" - assert_equal "1234 <-> 1234", node.content - assert_equal "
1234 <-> 1234
", node.to_xml + node.content = '& &' + assert_equal('& &', node.content) + assert_equal('
& <foo> &amp;
', node.to_xml) - node.content = '1234' - node.add_child '5678' - assert_equal '12345678', node.content - end + node.content = "1234 <-> 1234" + assert_equal("1234 <-> 1234", node.content) + assert_equal("
1234 <-> 1234
", node.to_xml) - # issue #839 - def test_encoding_of_copied_nodes - d1 = Nokogiri::XML('&') - d2 = Nokogiri::XML('') - ne = d1.root.xpath('//a').first.dup(1) - ne.content += "& < & > \" &" - d2.root << ne - assert_match(/&& < & > \" &<\/a>/, d2.to_s) - end + node.content = '1234' + node.add_child('5678') + assert_equal('12345678', node.content) + end - def test_content_after_appending_text - doc = Nokogiri::XML '' - node = doc.children.first - node.content = 'bar' - node << 'baz' - assert_equal 'barbaz', node.content - end + # issue #839 + def test_encoding_of_copied_nodes + d1 = Nokogiri::XML('&
') + d2 = Nokogiri::XML('') + ne = d1.root.xpath('//a').first.dup(1) + ne.content += "& < & > \" &" + d2.root << ne + assert_match(%r{&& < & > \" &}, d2.to_s) + end - def test_content_depth_first - node = Nokogiri::XML 'firstsecondthird' - assert_equal 'firstsecondthird', node.content - end + def test_content_after_appending_text + doc = Nokogiri::XML('') + node = doc.children.first + node.content = 'bar' + node << 'baz' + assert_equal('barbaz', node.content) + end - def test_set_content_should_unlink_existing_content - node = @xml.at_css("employee") - children = node.children - node.content = "hello" - children.each { |child| assert_nil child.parent } - end + def test_content_depth_first + node = Nokogiri::XML('firstsecondthird') + assert_equal('firstsecondthird', node.content) + end - def test_whitespace_nodes - doc = Nokogiri::XML.parse("Foo\nBar

Bazz

") - children = doc.at('//root').children.collect(&:to_s) - assert_equal "\n", children[1] - assert_equal " ", children[3] - end + def test_set_content_should_unlink_existing_content + node = xml.at_css("employee") + children = node.children + node.content = "hello" + children.each { |child| assert_nil(child.parent) } + end - def test_node_equality - doc1 = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE) - doc2 = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE) + def test_whitespace_nodes + doc = Nokogiri::XML.parse("Foo\nBar

Bazz

") + children = doc.at('//root').children.collect(&:to_s) + assert_equal("\n", children[1]) + assert_equal(" ", children[3]) + end - address1_1 = doc1.xpath('//address').first - address1_2 = doc1.xpath('//address').first + def test_node_equality + doc1 = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE) + doc2 = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE) - address2 = doc2.xpath('//address').first + address1_1 = doc1.xpath('//address').first + address1_2 = doc1.xpath('//address').first - assert_not_equal address1_1, address2 # two references to very, very similar nodes - assert_equal address1_1, address1_2 # two references to the exact same node - end + address2 = doc2.xpath('//address').first - def test_namespace_search_with_xpath_and_hash - xml = Nokogiri::XML.parse(<<-eoxml) - - - Michelin Model XGV - - - I'm a bicycle tire! - - - eoxml - - tires = xml.xpath('//bike:tire', {'bike' => 'http://schwinn.com/'}) - assert_equal 1, tires.length - end + assert_not_equal(address1_1, address2) # two references to very, very similar nodes + assert_equal(address1_1, address1_2) # two references to the exact same node + end - def test_namespace_search_with_xpath_and_hash_with_symbol_keys - xml = Nokogiri::XML.parse(<<-eoxml) - - - Michelin Model XGV - - - I'm a bicycle tire! - - - eoxml - - tires = xml.xpath('//bike:tire', :bike => 'http://schwinn.com/') - assert_equal 1, tires.length - end + def test_namespace_search_with_xpath_and_hash + xml = Nokogiri::XML.parse(<<~eoxml) + + + Michelin Model XGV + + + I'm a bicycle tire! + + + eoxml + + tires = xml.xpath('//bike:tire', { 'bike' => 'http://schwinn.com/' }) + assert_equal(1, tires.length) + end - def test_namespace_search_with_css - xml = Nokogiri::XML.parse(<<-eoxml) - - - Michelin Model XGV - - - I'm a bicycle tire! - - - eoxml - - tires = xml.css('bike|tire', 'bike' => 'http://schwinn.com/' ) - assert_equal 1, tires.length - end + def test_namespace_search_with_xpath_and_hash_with_symbol_keys + xml = Nokogiri::XML.parse(<<~eoxml) + + + Michelin Model XGV + + + I'm a bicycle tire! + + + eoxml + + tires = xml.xpath('//bike:tire', bike: 'http://schwinn.com/') + assert_equal(1, tires.length) + end - def test_namespaced_attribute_search_with_xpath - # from #593 - xmlContent = <<-EOXML - - - with namespace - no namespace - -EOXML - xml_doc = Nokogiri::XML(xmlContent) - - no_ns = xml_doc.xpath("//*[@att]") - assert_equal no_ns.length, 1 - assert_equal no_ns.first.content, "no namespace" - - with_ns = xml_doc.xpath("//*[@ns1:att]") - assert_equal with_ns.length, 1 - assert_equal with_ns.first.content, "with namespace" - end + def test_namespace_search_with_css + xml = Nokogiri::XML.parse(<<~eoxml) + + + Michelin Model XGV + + + I'm a bicycle tire! + + + eoxml + + tires = xml.css('bike|tire', 'bike' => 'http://schwinn.com/') + assert_equal(1, tires.length) + end - def test_namespaced_attribute_search_with_css - # from #593 - xmlContent = <<-EOXML - - - with namespace - no namespace - -EOXML - xml_doc = Nokogiri::XML(xmlContent) - - no_ns = xml_doc.css('*[att]') - assert_equal no_ns.length, 1 - assert_equal no_ns.first.content, "no namespace" - - with_ns = xml_doc.css('*[ns1|att]') - assert_equal with_ns.length, 1 - assert_equal with_ns.first.content, "with namespace" - end + def test_namespaced_attribute_search_with_xpath + # from #593 + xmlContent = <<~EOXML + + + with namespace + no namespace + + EOXML + xml_doc = Nokogiri::XML(xmlContent) + + no_ns = xml_doc.xpath("//*[@att]") + assert_equal(no_ns.length, 1) + assert_equal(no_ns.first.content, "no namespace") + + with_ns = xml_doc.xpath("//*[@ns1:att]") + assert_equal(with_ns.length, 1) + assert_equal(with_ns.first.content, "with namespace") + end - def test_namespaces_should_include_all_namespace_definitions - xml = Nokogiri::XML.parse(<<-EOF) - - - hello - - - - EOF - - namespaces = xml.namespaces # Document#namespace - assert_equal({"xmlns" => "http://quux.com/", - "xmlns:a" => "http://foo.com/", - "xmlns:b" => "http://bar.com/"}, namespaces) - - namespaces = xml.root.namespaces - assert_equal({"xmlns" => "http://quux.com/", - "xmlns:a" => "http://foo.com/", - "xmlns:b" => "http://bar.com/"}, namespaces) - - namespaces = xml.at_xpath("//xmlns:y").namespaces - assert_equal({"xmlns" => "http://quux.com/", - "xmlns:a" => "http://foo.com/", - "xmlns:b" => "http://bar.com/", - "xmlns:c" => "http://bazz.com/"}, namespaces) - - namespaces = xml.at_xpath("//xmlns:z").namespaces - assert_equal({"xmlns" => "http://quux.com/", - "xmlns:a" => "http://foo.com/", - "xmlns:b" => "http://bar.com/", - "xmlns:c" => "http://bazz.com/"}, namespaces) - - namespaces = xml.at_xpath("//xmlns:a").namespaces - assert_equal({"xmlns" => "http://quux.com/", - "xmlns:a" => "http://foo.com/", - "xmlns:b" => "http://bar.com/", - "xmlns:c" => "http://newc.com/"}, namespaces) - end + def test_namespaced_attribute_search_with_css + # from #593 + xmlContent = <<~EOXML + + + with namespace + no namespace + + EOXML + xml_doc = Nokogiri::XML(xmlContent) + + no_ns = xml_doc.css('*[att]') + assert_equal(no_ns.length, 1) + assert_equal(no_ns.first.content, "no namespace") + + with_ns = xml_doc.css('*[ns1|att]') + assert_equal(with_ns.length, 1) + assert_equal(with_ns.first.content, "with namespace") + end - def test_namespace - xml = Nokogiri::XML.parse(<<-EOF) - - - hello a - hello b - hello c -
-
hello moon
- - - EOF - set = xml.search("//y/*") - assert_equal "a", set[0].namespace.prefix - assert_equal 'http://foo.com/', set[0].namespace.href - assert_equal "b", set[1].namespace.prefix - assert_equal 'http://bar.com/', set[1].namespace.href - assert_equal "c", set[2].namespace.prefix - assert_equal 'http://bazz.com/', set[2].namespace.href - assert_nil set[3].namespace.prefix # default namespace - assert_equal 'http://ns.example.com/d', set[3].namespace.href - assert_nil set[4].namespace # no namespace - - assert_equal 'b', set[2].attributes['y'].namespace.prefix - assert_equal 'http://bar.com/', set[2].attributes['y'].namespace.href - assert_nil set[2].attributes['x'].namespace - assert_nil set[3].attributes['x'].namespace - assert_nil set[4].attributes['x'].namespace - end + def test_namespaces_should_include_all_namespace_definitions + xml = Nokogiri::XML.parse(<<~EOF) + + + hello +
+ + + EOF + + namespaces = xml.namespaces # Document#namespace + assert_equal({ "xmlns" => "http://quux.com/", + "xmlns:a" => "http://foo.com/", + "xmlns:b" => "http://bar.com/" }, namespaces) + + namespaces = xml.root.namespaces + assert_equal({ "xmlns" => "http://quux.com/", + "xmlns:a" => "http://foo.com/", + "xmlns:b" => "http://bar.com/" }, namespaces) + + namespaces = xml.at_xpath("//xmlns:y").namespaces + assert_equal({ "xmlns" => "http://quux.com/", + "xmlns:a" => "http://foo.com/", + "xmlns:b" => "http://bar.com/", + "xmlns:c" => "http://bazz.com/" }, namespaces) + + namespaces = xml.at_xpath("//xmlns:z").namespaces + assert_equal({ "xmlns" => "http://quux.com/", + "xmlns:a" => "http://foo.com/", + "xmlns:b" => "http://bar.com/", + "xmlns:c" => "http://bazz.com/" }, namespaces) + + namespaces = xml.at_xpath("//xmlns:a").namespaces + assert_equal({ "xmlns" => "http://quux.com/", + "xmlns:a" => "http://foo.com/", + "xmlns:b" => "http://bar.com/", + "xmlns:c" => "http://newc.com/" }, namespaces) + end + + def test_namespace + xml = Nokogiri::XML.parse(<<~EOF) + + + hello a + hello b + hello c +
+
hello moon
+ + + EOF + set = xml.search("//y/*") + assert_equal("a", set[0].namespace.prefix) + assert_equal('http://foo.com/', set[0].namespace.href) + assert_equal("b", set[1].namespace.prefix) + assert_equal('http://bar.com/', set[1].namespace.href) + assert_equal("c", set[2].namespace.prefix) + assert_equal('http://bazz.com/', set[2].namespace.href) + assert_nil(set[3].namespace.prefix) # default namespace + assert_equal('http://ns.example.com/d', set[3].namespace.href) + assert_nil(set[4].namespace) # no namespace + + assert_equal('b', set[2].attributes['y'].namespace.prefix) + assert_equal('http://bar.com/', set[2].attributes['y'].namespace.href) + assert_nil(set[2].attributes['x'].namespace) + assert_nil(set[3].attributes['x'].namespace) + assert_nil(set[4].attributes['x'].namespace) + end - if Nokogiri.uses_libxml? def test_namespace_without_an_href_on_html_node - # because microsoft word's HTML formatting does this. ick. - xml = Nokogiri::HTML.parse <<-EOF + # + # describe how we handle microsoft word's HTML formatting. + # this test is descriptive, not prescriptive. + # + skip("Xerces handles this edge case completely differently") unless Nokogiri.uses_libxml? + + xml = Nokogiri::HTML.parse(<<~EOF)
foo
EOF - assert_not_nil(node = xml.at('p')) + node = xml.at("p") + assert_not_nil(node) - assert_equal 1, node.namespaces.keys.size - assert node.namespaces.has_key?('xmlns:o') - assert_nil node.namespaces['xmlns:o'] + assert_equal(1, node.namespaces.keys.size) + assert(node.namespaces.has_key?('xmlns:o')) + assert_nil(node.namespaces['xmlns:o']) end - end - def test_line - xml = Nokogiri::XML(<<-eoxml) - -
- Hello world - - - eoxml - - set = xml.search("//a") - node = set.first - assert_equal 2, node.line - end - - def test_set_line - skip "Only supported with libxml2" unless Nokogiri.uses_libxml? - document = Nokogiri::XML::Document.new - node = document.create_element('a') - node.line = 54321 - assert_equal 54321, node.line - end + def test_line + xml = Nokogiri::XML(<<~eoxml) + + + Hello world + + + eoxml + + set = xml.search("//a") + node = set.first + assert_equal(2, node.line) + end - def test_xpath_results_have_document_and_are_decorated - x = Module.new do - def awesome! ; end + def test_set_line + skip("Only supported with libxml2") unless Nokogiri.uses_libxml? + document = Nokogiri::XML::Document.new + node = document.create_element('a') + node.line = 54321 + assert_equal(54321, node.line) end - util_decorate(@xml, x) - node_set = @xml.xpath("//employee") - assert_equal @xml, node_set.document - assert node_set.respond_to?(:awesome!) - end - def test_css_results_have_document_and_are_decorated - x = Module.new do - def awesome! ; end + def test_xpath_results_have_document_and_are_decorated + x = Module.new do + def awesome!; end + end + util_decorate(xml, x) + node_set = xml.xpath("//employee") + assert_equal(xml, node_set.document) + assert(node_set.respond_to?(:awesome!)) end - util_decorate(@xml, x) - node_set = @xml.css("employee") - assert_equal @xml, node_set.document - assert node_set.respond_to?(:awesome!) - end - def test_blank - doc = Nokogiri::XML('') - assert_equal false, doc.blank? - end + def test_css_results_have_document_and_are_decorated + x = Module.new do + def awesome!; end + end + util_decorate(xml, x) + node_set = xml.css("employee") + assert_equal(xml, node_set.document) + assert(node_set.respond_to?(:awesome!)) + end - def test_to_xml_allows_to_serialize_with_as_xml_save_option - xml = Nokogiri::XML("
  • Hello world
") - set = xml.search("//ul") - node = set.first + def test_blank + doc = Nokogiri::XML('') + assert_equal(false, doc.blank?) + end - assert_no_match("
    \n
  • ", xml.to_xml(:save_with => XML::Node::SaveOptions::AS_XML)) - assert_no_match("
      \n
    • ", node.to_xml(:save_with => XML::Node::SaveOptions::AS_XML)) - end + def test_to_xml_allows_to_serialize_with_as_xml_save_option + xml = Nokogiri::XML("
      • Hello world
      ") + set = xml.search("//ul") + node = set.first - # issue 647 - def test_default_namespace_should_be_created - subject = Nokogiri::XML.parse('').root - ns = subject.attributes['bar'].namespace - assert_not_nil ns - assert_equal ns.class, Nokogiri::XML::Namespace - assert_equal 'xml', ns.prefix - assert_equal "http://www.w3.org/XML/1998/namespace", ns.href - end + assert_no_match("
        \n
      • ", xml.to_xml(save_with: XML::Node::SaveOptions::AS_XML)) + assert_no_match("
          \n
        • ", node.to_xml(save_with: XML::Node::SaveOptions::AS_XML)) + end - # issue 648 - def test_namespace_without_prefix_should_be_set - node = Nokogiri::XML.parse('').root - subject = Nokogiri::XML::Node.new 'foo', node.document - subject.namespace = node.namespace - ns = subject.namespace - assert_equal ns.class, Nokogiri::XML::Namespace - assert_nil ns.prefix - assert_equal ns.href, "http://bar.com" - end + # issue 647 + def test_default_namespace_should_be_created + subject = Nokogiri::XML.parse('').root + ns = subject.attributes['bar'].namespace + assert_not_nil(ns) + assert_equal(ns.class, Nokogiri::XML::Namespace) + assert_equal('xml', ns.prefix) + assert_equal("http://www.w3.org/XML/1998/namespace", ns.href) + end - # issue 695 - def test_namespace_in_rendered_xml - document = Nokogiri::XML::Document.new - subject = Nokogiri::XML::Node.new 'foo', document - ns = subject.add_namespace nil, 'bar' - subject.namespace = ns - assert_match(/xmlns="bar"/, subject.to_xml) - end + # issue 648 + def test_namespace_without_prefix_should_be_set + node = Nokogiri::XML.parse('').root + subject = Nokogiri::XML::Node.new('foo', node.document) + subject.namespace = node.namespace + ns = subject.namespace + assert_equal(ns.class, Nokogiri::XML::Namespace) + assert_nil(ns.prefix) + assert_equal(ns.href, "http://bar.com") + end - # issue 771 - def test_format_noblank - content = < - hello - -eoxml - subject = Nokogiri::XML(content) do |conf| - conf.default_xml.noblanks + # issue 695 + def test_namespace_in_rendered_xml + document = Nokogiri::XML::Document.new + subject = Nokogiri::XML::Node.new('foo', document) + ns = subject.add_namespace(nil, 'bar') + subject.namespace = ns + assert_match(/xmlns="bar"/, subject.to_xml) end - assert_match %r{hello}, subject.to_xml(:indent => 2) - end + # issue 771 + def test_format_noblank + content = <<~eoxml + + hello + + eoxml + subject = Nokogiri::XML(content) do |conf| + conf.default_xml.noblanks + end - def test_text_node_colon - document = Nokogiri::XML::Document.new - root = Nokogiri::XML::Node.new 'foo', document - document.root = root - root << "hello:with_colon" - assert_match(/hello:with_colon/, document.to_xml) - end + assert_match(%r{hello}, subject.to_xml(indent: 2)) + end - def test_document_eh - html_doc = Nokogiri::HTML "
          foo
          " - xml_doc = Nokogiri::XML "
          foo
          " - html_node = html_doc.at_css "div" - xml_node = xml_doc.at_css "div" + def test_text_node_colon + document = Nokogiri::XML::Document.new + root = Nokogiri::XML::Node.new('foo', document) + document.root = root + root << "hello:with_colon" + assert_match(/hello:with_colon/, document.to_xml) + end - assert html_doc.document? - assert xml_doc.document? - assert ! html_node.document? - assert ! xml_node.document? - end + def test_document_eh + html_doc = Nokogiri::HTML("
          foo
          ") + xml_doc = Nokogiri::XML("
          foo
          ") + html_node = html_doc.at_css("div") + xml_node = xml_doc.at_css("div") - def test_processing_instruction_eh - xml_doc = Nokogiri::XML %Q{\n\n\n
          foo
          } - pi_node = xml_doc.children.first - div_node = xml_doc.at_css "div" - assert pi_node.processing_instruction? - assert ! div_node.processing_instruction? - end + assert(html_doc.document?) + assert(xml_doc.document?) + assert(!html_node.document?) + assert(!xml_node.document?) + end - def test_node_lang - document = Nokogiri::XML <<-EOXML - -
          -
          foo
          -
          -
          bar
          -
          bar
          -
          - EOXML - assert_equal "en", document.at_css(".english").lang - assert_equal "en", document.at_css(".english_child").lang - assert_equal "jp", document.at_css(".japanese").lang - assert_nil document.at_css(".unspecified").lang - end + def test_processing_instruction_eh + xml_doc = Nokogiri::XML(%{\n\n\n
          foo
          }) + pi_node = xml_doc.children.first + div_node = xml_doc.at_css("div") + assert(pi_node.processing_instruction?) + assert(!div_node.processing_instruction?) + end - def test_set_node_lang - document = Nokogiri::XML "
          foo
          " - subject = document.at_css(".subject") + def test_node_lang + document = Nokogiri::XML(<<~EOXML) + +
          +
          foo
          +
          +
          bar
          +
          bar
          +
          + EOXML + assert_equal("en", document.at_css(".english").lang) + assert_equal("en", document.at_css(".english_child").lang) + assert_equal("jp", document.at_css(".japanese").lang) + assert_nil(document.at_css(".unspecified").lang) + end - subject.lang = "de" - assert_equal "de", subject.lang + def test_set_node_lang + document = Nokogiri::XML("
          foo
          ") + subject = document.at_css(".subject") - subject.lang = "fr" - assert_equal "fr", subject.lang - end + subject.lang = "de" + assert_equal("de", subject.lang) - def test_text_node_robustness_gh1426 - skip "No need to test libxml-ruby workarounds on JRuby" if Nokogiri.jruby? - # notably, the original bug report was about libxml-ruby interactions - # this test should blow up under valgrind if we regress on libxml-ruby workarounds - message = "

          BOOM!

          " - 10_000.times do - node = Nokogiri::HTML::DocumentFragment.parse(message).at_css("h2") - node.add_previous_sibling(Nokogiri::XML::Text.new('before', node.document)) - node.add_next_sibling(Nokogiri::XML::Text.new('after', node.document)) + subject.lang = "fr" + assert_equal("fr", subject.lang) end - end - def test_wrap - xml = '
          important thing
          ' - doc = Nokogiri::XML(xml) - thing = doc.at_css("thing") - thing.wrap("") - assert_equal 'wrapper', thing.parent.name - assert_equal 'thing', doc.at_css("wrapper").children.first.name + def test_text_node_robustness_gh1426 + skip("No need to test libxml-ruby workarounds on JRuby") if Nokogiri.jruby? + # notably, the original bug report was about libxml-ruby interactions + # this test should blow up under valgrind if we regress on libxml-ruby workarounds + message = "

          BOOM!

          " + 10_000.times do + node = Nokogiri::HTML::DocumentFragment.parse(message).at_css("h2") + node.add_previous_sibling(Nokogiri::XML::Text.new('before', node.document)) + node.add_next_sibling(Nokogiri::XML::Text.new('after', node.document)) + end + end + + def test_wrap + xml = '
          important thing
          ' + doc = Nokogiri::XML(xml) + thing = doc.at_css("thing") + thing.wrap("") + assert_equal('wrapper', thing.parent.name) + assert_equal('thing', doc.at_css("wrapper").children.first.name) + end end end end From 369e6bdb5027c9ac8cb632f551ccd1e9d6d8e363 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Mon, 18 Jan 2021 17:01:43 -0500 Subject: [PATCH 2/3] dep: hoe-markdown to ~> 1.4 --- nokogiri.gemspec | 2 +- rakelib/markdown.rake | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nokogiri.gemspec b/nokogiri.gemspec index dc025e47d6..17e436d767 100644 --- a/nokogiri.gemspec +++ b/nokogiri.gemspec @@ -300,7 +300,7 @@ Gem::Specification.new do |spec| spec.add_development_dependency("bundler", "~> 2.2") spec.add_development_dependency("concourse", "~> 0.41") - spec.add_development_dependency("hoe-markdown", "~> 1.1") + spec.add_development_dependency("hoe-markdown", "~> 1.4") spec.add_development_dependency("minitest", "~> 5.8") spec.add_development_dependency("minitest-reporters", "~> 1.4") spec.add_development_dependency("rake", "~> 13.0") diff --git a/rakelib/markdown.rake b/rakelib/markdown.rake index 068e8e30c9..4fd559d27a 100644 --- a/rakelib/markdown.rake +++ b/rakelib/markdown.rake @@ -1,2 +1,2 @@ require "hoe/markdown" -Hoe::Markdown::Standalone.new("nokogiri").define_markdown_tasks +Hoe::Markdown::Standalone.new("nokogiri").define_markdown_tasks("CHANGELOG.md") From b32c875100a8e0f0b25c4254c9b9a497f97f4599 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Mon, 18 Jan 2021 16:26:59 -0500 Subject: [PATCH 3/3] fix(jruby): improve how Node#line is calculated Note that Java's w3c.dom.Node interface does not have any way to get (or set) the line number for that node. The original JRuby implementation counted newlines, but did it poorly -- see #1223. This commit improves the newline-counting approach. But the solution itself -- counting newlines! -- is still questionable IMHO and absolutely inefficient. I had played around with an approach that I wrote about at #1223, where the SAX Parser knows what line it's on when `startElement` is invoked (via the XMLLocator). But I couldn't figure out how to preserve that information in the final Document or Node. If you, like me, think this approach is terrible; and if you *also* understand how to set this metadata on the Node or the Document, then please help us out. --- CHANGELOG.md | 5 ++++ ext/java/nokogiri/XmlNode.java | 20 +++++++++---- test/xml/test_node.rb | 51 +++++++++++++++++++--------------- 3 files changed, 48 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4661cf2598..76f2586be3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,11 @@ Nokogiri follows [Semantic Versioning](https://semver.org/), please see the [REA * [JRuby] `{XML,HTML}::Document.parse` now invokes `#initialize` exactly once. Previously `#initialize` was not called, which was a problem for subclassing such as done by `Loofah`. +### Improved + +* [JRuby] Update the algorithm used to calculate `Node#line` to be wrong less-often. The underlying parser, Xerces, does not track line numbers, and so we've always used a hacky solution for this method. [[#1223](https://github.com/sparklemotion/nokogiri/issues/1223)] + + ## v1.11.1 / 2021-01-06 ### Fixed diff --git a/ext/java/nokogiri/XmlNode.java b/ext/java/nokogiri/XmlNode.java index cfbea83dfa..790b849ec2 100644 --- a/ext/java/nokogiri/XmlNode.java +++ b/ext/java/nokogiri/XmlNode.java @@ -1406,14 +1406,22 @@ private boolean count(Node node, int[] counter) { if (node == this.node) { return true; } + NodeList list = node.getChildNodes(); - for (int i=0; i - - Hello world - - - eoxml - - set = xml.search("//a") - node = set.first - assert_equal(2, node.line) - end - - def test_set_line - skip("Only supported with libxml2") unless Nokogiri.uses_libxml? - document = Nokogiri::XML::Document.new - node = document.create_element('a') - node.line = 54321 - assert_equal(54321, node.line) - end - def test_xpath_results_have_document_and_are_decorated x = Module.new do def awesome!; end @@ -1230,6 +1208,35 @@ def test_wrap assert_equal('wrapper', thing.parent.name) assert_equal('thing', doc.at_css("wrapper").children.first.name) end + + describe "#line" do + it "returns a sensible line number for each node" do + xml = Nokogiri::XML(<<~eoxml) + + + Hello world + + + Goodbye world + + + eoxml + + set = xml.search("//b") + assert_equal(2, set[0].line) + assert_equal(5, set[1].line) + end + end + + describe "#line=" do + it "overrides the line number of a node" do + skip("Xerces does not have line numbers for nodes") unless Nokogiri.uses_libxml? + document = Nokogiri::XML::Document.new + node = document.create_element('a') + node.line = 54321 + assert_equal(54321, node.line) + end + end end end end