From 8f6c714e7b5ef5283bb83f3678a7b973c5f659c7 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Tue, 6 Apr 2021 12:46:39 -0400 Subject: [PATCH] test: cleanup --- test/html/sax/test_push_parser.rb | 42 +- test/html/test_attributes.rb | 124 ++--- test/html/test_attributes_properly_escaped.rb | 42 +- .../test_namespaces_in_parsed_doc.rb | 17 +- test/test_nokogiri.rb | 2 +- test/test_version.rb | 8 +- test/test_xslt_transforms.rb | 490 +++++++++--------- test/xml/sax/test_parser.rb | 2 +- test/xml/sax/test_push_parser.rb | 4 +- test/xml/test_document_encoding.rb | 2 +- test/xml/test_document_fragment.rb | 36 +- test/xml/test_node.rb | 8 +- test/xml/test_node_attributes.rb | 5 +- test/xml/test_node_reparenting.rb | 12 +- test/xml/test_node_set.rb | 17 +- test/xml/test_reader.rb | 29 +- test/xml/test_reader_encoding.rb | 2 +- test/xml/test_relax_ng.rb | 3 +- test/xml/test_schema.rb | 2 +- test/xml/test_xinclude.rb | 8 +- test/xslt/test_custom_functions.rb | 166 +++--- test/xslt/test_exception_handling.rb | 44 +- 22 files changed, 525 insertions(+), 540 deletions(-) diff --git a/test/html/sax/test_push_parser.rb b/test/html/sax/test_push_parser.rb index a3939d07ed..dd64253907 100644 --- a/test/html/sax/test_push_parser.rb +++ b/test/html/sax/test_push_parser.rb @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +# frozen_string_literal: true require "helper" @@ -12,38 +13,37 @@ def setup end def test_end_document_called - @parser.<<(<<-eoxml) + @parser.<<(<<~eoxml)

Paragraph 1

eoxml - assert ! @parser.document.end_document_called + assert(!@parser.document.end_document_called) @parser.finish - assert @parser.document.end_document_called + assert(@parser.document.end_document_called) end def test_start_element - @parser.<<(<<-eoxml) + @parser.<<(<<~eoxml)

eoxml - assert_equal [["html", []], ["head", []], ["body", []], ["p", [["id", "asdfasdf"]]]], - @parser.document.start_elements - - @parser.<<(<<-eoxml) - - Paragraph 1 + assert_equal([["html", []], ["head", []], ["body", []], ["p", [["id", "asdfasdf"]]]], + @parser.document.start_elements) + + @parser.<<(<<~eoxml) + + Paragraph 1

eoxml - assert_equal [' This is a comment '], @parser.document.comments + assert_equal([' This is a comment '], @parser.document.comments) @parser.finish end - def test_chevron_partial_html - @parser.<<(<<-eoxml) + @parser.<<(<<~eoxml)

eoxml @@ -52,34 +52,34 @@ def test_chevron_partial_html Paragraph 1

eoxml - assert_equal [' This is a comment '], @parser.document.comments + assert_equal([' This is a comment '], @parser.document.comments) @parser.finish end def test_chevron - @parser.<<(<<-eoxml) + @parser.<<(<<~eoxml)

Paragraph 1

eoxml @parser.finish - assert_equal [' This is a comment '], @parser.document.comments + assert_equal([' This is a comment '], @parser.document.comments) end def test_default_options - assert_equal 0, @parser.options + assert_equal(0, @parser.options) end - + def test_broken_encoding - skip("ultra hard to fix for pure Java version") if Nokogiri.jruby? + skip_unless_libxml2("ultra hard to fix for pure Java version") @parser.options |= XML::ParseOptions::RECOVER # This is ISO_8859-1: @parser.<< "Gau\337" @parser.finish assert(@parser.document.errors.size >= 1) - assert_equal "Gau\337", @parser.document.data.join - assert_equal [["r"], ["body"], ["html"]], @parser.document.end_elements + assert_equal("Gau\337", @parser.document.data.join) + assert_equal([["r"], ["body"], ["html"]], @parser.document.end_elements) end end end diff --git a/test/html/test_attributes.rb b/test/html/test_attributes.rb index 9d97c1322b..2d5ee58df7 100644 --- a/test/html/test_attributes.rb +++ b/test/html/test_attributes.rb @@ -3,80 +3,80 @@ module Nokogiri module HTML class TestAttr < Nokogiri::TestCase - unless Nokogiri::VersionInfo.instance.libxml2? && Nokogiri::VersionInfo.instance.libxml2_using_system? + # + # libxml2 >= 2.9.2 fails to escape comments within some attributes. It + # wants to ensure these comments can be treated as "server-side includes", + # but as a result fails to ensure that serialization is well-formed, + # resulting in an opportunity for XSS injection of code into a final + # re-parsed document (presumably in a browser). + # + # the offending commit is: + # + # https://github.com/GNOME/libxml2/commit/960f0e2 + # + # we'll test this by parsing the HTML, serializing it, then + # re-parsing it to ensure there isn't any ambiguity in the output + # that might allow code injection into a browser consuming + # "sanitized" output. + # + # complaints have been made upstream about this behavior, notably at + # + # https://bugzilla.gnome.org/show_bug.cgi?id=769760 + # + # and multiple CVEs have been declared and fixed in downstream + # libraries as a result, a list is being kept up to date here: + # + # https://github.com/flavorjones/loofah/issues/144 + # + [ # - # libxml2 >= 2.9.2 fails to escape comments within some attributes. It - # wants to ensure these comments can be treated as "server-side includes", - # but as a result fails to ensure that serialization is well-formed, - # resulting in an opportunity for XSS injection of code into a final - # re-parsed document (presumably in a browser). + # these tags and attributes are determined by the code at: # - # the offending commit is: + # https://git.gnome.org/browse/libxml2/tree/HTMLtree.c?h=v2.9.2#n714 # - # https://github.com/GNOME/libxml2/commit/960f0e2 + {tag: "a", attr: "href"}, + {tag: "div", attr: "href"}, + {tag: "a", attr: "action"}, + {tag: "div", attr: "action"}, + {tag: "a", attr: "src"}, + {tag: "div", attr: "src"}, + {tag: "a", attr: "name"}, # - # we'll test this by parsing the HTML, serializing it, then - # re-parsing it to ensure there isn't any ambiguity in the output - # that might allow code injection into a browser consuming - # "sanitized" output. + # note that div+name is _not_ affected by the libxml2 issue. + # but we test it anyway to ensure our logic isn't modifying + # attributes that don't need modifying. # - # complaints have been made upstream about this behavior, notably at - # - # https://bugzilla.gnome.org/show_bug.cgi?id=769760 - # - # and multiple CVEs have been declared and fixed in downstream - # libraries as a result, a list is being kept up to date here: - # - # https://github.com/flavorjones/loofah/issues/144 - # - [ - # - # these tags and attributes are determined by the code at: - # - # https://git.gnome.org/browse/libxml2/tree/HTMLtree.c?h=v2.9.2#n714 - # - {tag: "a", attr: "href"}, - {tag: "div", attr: "href"}, - {tag: "a", attr: "action"}, - {tag: "div", attr: "action"}, - {tag: "a", attr: "src"}, - {tag: "div", attr: "src"}, - {tag: "a", attr: "name"}, - # - # note that div+name is _not_ affected by the libxml2 issue. - # but we test it anyway to ensure our logic isn't modifying - # attributes that don't need modifying. - # - {tag: "div", attr: "name", unescaped: true}, - ].each do |config| + {tag: "div", attr: "name", unescaped: true}, + ].each do |config| - define_method "test_uri_escaping_of_#{config[:attr]}_attr_in_#{config[:tag]}_tag" do - html = %{<#{config[:tag]} #{config[:attr]}='example.com'>test} + define_method "test_uri_escaping_of_#{config[:attr]}_attr_in_#{config[:tag]}_tag" do + skip if Nokogiri::VersionInfo.instance.libxml2? && Nokogiri::VersionInfo.instance.libxml2_using_system? - reparsed = HTML.fragment(HTML.fragment(html).to_html) - attributes = reparsed.at_css(config[:tag]).attribute_nodes + html = %{<#{config[:tag]} #{config[:attr]}='example.com'>test} - assert_equal [config[:attr]], attributes.collect(&:name) - if Nokogiri::VersionInfo.instance.libxml2? - if config[:unescaped] - # - # this attribute was emitted wrapped in single-quotes, so a double quote is A-OK. - # assert that this attribute's serialization is unaffected. - # - assert_equal %{example.com}, attributes.first.value - else - # - # let's match the behavior in libxml < 2.9.2. - # test that this attribute's serialization is well-formed and sanitized. - # - assert_equal %{example.com}, attributes.first.value - end + reparsed = HTML.fragment(HTML.fragment(html).to_html) + attributes = reparsed.at_css(config[:tag]).attribute_nodes + + assert_equal [config[:attr]], attributes.collect(&:name) + if Nokogiri::VersionInfo.instance.libxml2? + if config[:unescaped] + # + # this attribute was emitted wrapped in single-quotes, so a double quote is A-OK. + # assert that this attribute's serialization is unaffected. + # + assert_equal %{example.com}, attributes.first.value else # - # yay for consistency in javaland. move along, nothing to see here. + # let's match the behavior in libxml < 2.9.2. + # test that this attribute's serialization is well-formed and sanitized. # - assert_equal %{example.com}, attributes.first.value + assert_equal %{example.com}, attributes.first.value end + else + # + # yay for consistency in javaland. move along, nothing to see here. + # + assert_equal %{example.com}, attributes.first.value end end end diff --git a/test/html/test_attributes_properly_escaped.rb b/test/html/test_attributes_properly_escaped.rb index 98a205ee55..91da4ccbe2 100755 --- a/test/html/test_attributes_properly_escaped.rb +++ b/test/html/test_attributes_properly_escaped.rb @@ -3,31 +3,35 @@ module Nokogiri module HTML class TestAttributesProperlyEscaped < Nokogiri::TestCase - unless Nokogiri::VersionInfo.instance.libxml2? && Nokogiri::VersionInfo.instance.libxml2_using_system? - def test_attribute_macros_are_escaped - html = "

}\">

" - document = Nokogiri::HTML::Document.new - nodes = document.parse(html) + def test_attribute_macros_are_escaped + skip if Nokogiri::VersionInfo.instance.libxml2? && Nokogiri::VersionInfo.instance.libxml2_using_system? - assert_equal("

", nodes[0].to_s) - end + html = "

}\">

" + document = Nokogiri::HTML::Document.new + nodes = document.parse(html) - def test_libxml_escapes_server_side_includes - original_html = %(

) - document = Nokogiri::HTML::Document.new - html = document.parse(original_html).to_s + assert_equal("

", nodes[0].to_s) + end + + def test_libxml_escapes_server_side_includes + skip if Nokogiri::VersionInfo.instance.libxml2? && Nokogiri::VersionInfo.instance.libxml2_using_system? + + original_html = %(

) + document = Nokogiri::HTML::Document.new + html = document.parse(original_html).to_s + + assert_match(/!--%22><test>/, html) + end - assert_match(/!--%22><test>/, html) - end + def test_libxml_escapes_server_side_includes_without_nested_quotes + skip if Nokogiri::VersionInfo.instance.libxml2? && Nokogiri::VersionInfo.instance.libxml2_using_system? - def test_libxml_escapes_server_side_includes_without_nested_quotes - original_html = %(

) - document = Nokogiri::HTML::Document.new - html = document.parse(original_html).to_s + original_html = %(

) + document = Nokogiri::HTML::Document.new + html = document.parse(original_html).to_s - assert_match(/<!--<test>/, html) - end + assert_match(/<!--<test>/, html) end end end diff --git a/test/namespaces/test_namespaces_in_parsed_doc.rb b/test/namespaces/test_namespaces_in_parsed_doc.rb index c4028150e2..aefbddb8b5 100644 --- a/test/namespaces/test_namespaces_in_parsed_doc.rb +++ b/test/namespaces/test_namespaces_in_parsed_doc.rb @@ -63,16 +63,15 @@ def test_parsed_namespace_count end def test_namespaces_under_memory_pressure_issue1155 - skip("JRuby doesn't do GC.") if Nokogiri.jruby? + refute_valgrind_errors do + # see https://github.com/sparklemotion/nokogiri/issues/1155 for background + filename = File.join ASSETS_DIR, 'namespace_pressure_test.xml' + doc = Nokogiri::XML File.open(filename) - # this test is here to emit warnings when run under valgrind - # see https://github.com/sparklemotion/nokogiri/issues/1155 for background - filename = File.join ASSETS_DIR, 'namespace_pressure_test.xml' - doc = Nokogiri::XML File.open(filename) - - # bizarrely, can't repro without the call to #to_a - doc.xpath('//namespace::*').to_a.each do |ns| - ns.inspect + # bizarrely, can't repro without the call to #to_a + doc.xpath('//namespace::*').to_a.each do |ns| + ns.inspect + end end end end diff --git a/test/test_nokogiri.rb b/test/test_nokogiri.rb index cfefc964d2..e1a90b43f1 100644 --- a/test/test_nokogiri.rb +++ b/test/test_nokogiri.rb @@ -2,7 +2,7 @@ class TestNokogiri < Nokogiri::TestCase def test_libxml_iconv - skip "this constant is only set in the C extension when libxml2 is used" if !Nokogiri.uses_libxml? + skip_unless_libxml2("this constant is only set in the C extension when libxml2 is used") assert Nokogiri.const_defined?(:LIBXML_ICONV_ENABLED) end diff --git a/test/test_version.rb b/test/test_version.rb index e5d33d4936..1261ba9f68 100644 --- a/test/test_version.rb +++ b/test/test_version.rb @@ -29,17 +29,17 @@ def test_version_info_basics end def test_version_info_for_xerces - skip("xerces is only used for JRuby") unless Nokogiri.jruby? + skip_unless_jruby("xerces is only used for JRuby") assert_equal(Nokogiri::XERCES_VERSION, version_info["other_libraries"]["xerces"]) end def test_version_info_for_nekohtml - skip("nekohtml is only used for JRuby") unless Nokogiri.jruby? + skip_unless_jruby("nekohtml is only used for JRuby") assert_equal(Nokogiri::NEKO_VERSION, version_info["other_libraries"]["nekohtml"]) end def test_version_info_for_libxml - skip("libxml2 is only used for CRuby") unless Nokogiri.uses_libxml? + skip_unless_libxml2("libxml2 is only used for CRuby") if Nokogiri::VersionInfo.instance.libxml2_using_packaged? assert_equal("packaged", version_info["libxml"]["source"]) @@ -66,7 +66,7 @@ def test_version_info_for_libxml end def test_version_info_for_libxslt - skip("libxslt is only used for CRuby") unless Nokogiri.uses_libxml? + skip_unless_libxml2("libxslt is only used for CRuby") if Nokogiri::VersionInfo.instance.libxml2_using_packaged? assert_equal("packaged", version_info["libxslt"]["source"]) diff --git a/test/test_xslt_transforms.rb b/test/test_xslt_transforms.rb index 73d0967692..708215dc80 100644 --- a/test/test_xslt_transforms.rb +++ b/test/test_xslt_transforms.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true require "helper" class TestXsltTransforms < Nokogiri::TestCase @@ -9,124 +10,124 @@ def setup def test_class_methods style = Nokogiri::XSLT(File.read(XSLT_FILE)) - assert result = style.apply_to(@doc, ['title', '"Grandma"']) - assert_match %r{

Grandma

}, result + assert(result = style.apply_to(@doc, ['title', '"Grandma"'])) + assert_match(%r{

Grandma

}, result) end def test_transform - assert style = Nokogiri::XSLT.parse(File.read(XSLT_FILE)) - - assert result = style.apply_to(@doc, ['title', '"Booyah"']) - assert_match %r{

Booyah

}, result - assert_match %r{}, result - assert_match %r{}, result - assert_match %r{}, result - assert_match %r{}, result - assert_match %r{EMP0003}, result - assert_match %r{Margaret Martin}, result - assert_match %r{Computer Specialist}, result - assert_match %r{100,000}, result - assert_no_match %r{Dallas|Texas}, result - assert_no_match %r{Female}, result - - assert result = style.apply_to(@doc, ['title', '"Grandma"']) - assert_match %r{

Grandma

}, result - - assert result = style.apply_to(@doc) - assert_match %r{

|

}, result + assert(style = Nokogiri::XSLT.parse(File.read(XSLT_FILE))) + + assert(result = style.apply_to(@doc, ['title', '"Booyah"'])) + assert_match(%r{

Booyah

}, result) + assert_match(%r{}, result) + assert_match(%r{}, result) + assert_match(%r{}, result) + assert_match(%r{}, result) + assert_match(%r{EMP0003}, result) + assert_match(%r{Margaret Martin}, result) + assert_match(%r{Computer Specialist}, result) + assert_match(%r{100,000}, result) + assert_no_match(/Dallas|Texas/, result) + assert_no_match(/Female/, result) + + assert(result = style.apply_to(@doc, ['title', '"Grandma"'])) + assert_match(%r{

Grandma

}, result) + + assert(result = style.apply_to(@doc)) + assert_match(%r{

|

}, result) end def test_xml_declaration - input_xml = <<-EOS - - - My Report - -EOS - - input_xsl = <<-EOS - - - - - - - <xsl:value-of select="report/title"/> - - -

- - -
-
-EOS + input_xml = <<~EOS + + + My Report + + EOS + + input_xsl = <<~EOS + + + + + + + <xsl:value-of select="report/title"/> + + +

+ + +
+
+ EOS require 'nokogiri' xml = ::Nokogiri::XML(input_xml) xsl = ::Nokogiri::XSLT(input_xsl) - assert_includes xsl.apply_to(xml), '' + assert_includes(xsl.apply_to(xml), '') end def test_transform_with_output_style xslt = "" - if Nokogiri.jruby? - xslt = Nokogiri::XSLT(<<-eoxslt) - - - - - - - - - - - - - - - - - - - - - - - + xslt = if Nokogiri.jruby? + Nokogiri::XSLT(<<~eoxslt) + + + + + + + + + + + + + + + + + + + + + + + eoxslt else - xslt = Nokogiri::XSLT(<<-eoxslt) - - - - - - - - - - - - - - - - - - - - - - - - + Nokogiri::XSLT(<<~eoxslt) + + + + + + + + + + + + + + + + + + + + + + + + eoxslt end result = xslt.apply_to(@doc, ['title', 'foo']) @@ -135,173 +136,178 @@ def test_transform_with_output_style # the entity-form is for systems with this bug with Encodings.properties # https://issues.apache.org/jira/browse/XALANJ-2618 # a.k.a. "Attempt to output character of integral value 48 that is not represented in specified output encoding of iso-8859-1." - assert_match(/This is an adjacent|This is an adjacent/, result) + assert_match( + /This is an adjacent|This is an adjacent/, result + ) end def test_transform_arg_error - assert style = Nokogiri::XSLT(File.read(XSLT_FILE)) + assert(style = Nokogiri::XSLT(File.read(XSLT_FILE))) assert_raises(TypeError) do style.transform(@doc, :foo) end end def test_transform_with_hash - assert style = Nokogiri::XSLT(File.read(XSLT_FILE)) - result = style.transform(@doc, {'title' => '"Booyah"'}) - assert result.html? - assert_equal "Booyah", result.at_css("h1").content + assert(style = Nokogiri::XSLT(File.read(XSLT_FILE))) + result = style.transform(@doc, { 'title' => '"Booyah"' }) + assert(result.html?) + assert_equal("Booyah", result.at_css("h1").content) end def test_transform2 - assert style = Nokogiri::XSLT(File.open(XSLT_FILE)) - assert result_doc = style.transform(@doc) - assert result_doc.html? - assert_equal "", result_doc.at_css("h1").content - - assert style = Nokogiri::XSLT(File.read(XSLT_FILE)) - assert result_doc = style.transform(@doc, ['title', '"Booyah"']) - assert result_doc.html? - assert_equal "Booyah", result_doc.at_css("h1").content - - assert result_string = style.apply_to(@doc, ['title', '"Booyah"']) - assert_equal result_string, style.serialize(result_doc) + assert(style = Nokogiri::XSLT(File.open(XSLT_FILE))) + assert(result_doc = style.transform(@doc)) + assert(result_doc.html?) + assert_equal("", result_doc.at_css("h1").content) + + assert(style = Nokogiri::XSLT(File.read(XSLT_FILE))) + assert(result_doc = style.transform(@doc, ['title', '"Booyah"'])) + assert(result_doc.html?) + assert_equal("Booyah", result_doc.at_css("h1").content) + + assert(result_string = style.apply_to(@doc, ['title', '"Booyah"'])) + assert_equal(result_string, style.serialize(result_doc)) end def test_transform_with_quote_params - assert style = Nokogiri::XSLT(File.open(XSLT_FILE)) - assert result_doc = style.transform(@doc, Nokogiri::XSLT.quote_params(['title', 'Booyah'])) - assert result_doc.html? - assert_equal "Booyah", result_doc.at_css("h1").content - - assert style = Nokogiri::XSLT.parse(File.read(XSLT_FILE)) - assert result_doc = style.transform(@doc, Nokogiri::XSLT.quote_params({'title' => 'Booyah'})) - assert result_doc.html? - assert_equal "Booyah", result_doc.at_css("h1").content + assert(style = Nokogiri::XSLT(File.open(XSLT_FILE))) + assert(result_doc = style.transform(@doc, Nokogiri::XSLT.quote_params(['title', 'Booyah']))) + assert(result_doc.html?) + assert_equal("Booyah", result_doc.at_css("h1").content) + + assert(style = Nokogiri::XSLT.parse(File.read(XSLT_FILE))) + assert(result_doc = style.transform(@doc, Nokogiri::XSLT.quote_params({ 'title' => 'Booyah' }))) + assert(result_doc.html?) + assert_equal("Booyah", result_doc.at_css("h1").content) end def test_quote_params h = { - :sym => %{xxx}, - 'str' => %{"xxx"}, - :sym2 => %{'xxx'}, + :sym => %{xxx}, + 'str' => %{"xxx"}, + :sym2 => %{'xxx'}, 'str2' => %{x'x'x}, - :sym3 => %{x"x"x}, + :sym3 => %{x"x"x}, } - hh=h.dup + hh = h.dup result_hash = Nokogiri::XSLT.quote_params(h) - assert_equal hh, h # non-destructive + assert_equal(hh, h) # non-destructive - a=h.to_a.flatten + a = h.to_a.flatten result_array = Nokogiri::XSLT.quote_params(a) - assert_equal h.to_a.flatten, a #non-destructive + assert_equal(h.to_a.flatten, a) # non-destructive - assert_equal result_array, result_hash + assert_equal(result_array, result_hash) end - if Nokogiri.uses_libxml? - # By now, cannot get it working on JRuby, see: - # http://yokolet.blogspot.com/2010/10/pure-java-nokogiri-xslt-extension.html - def test_exslt - assert doc = Nokogiri::XML.parse(File.read(EXML_FILE)) - assert doc.xml? - - assert style = Nokogiri::XSLT.parse(File.read(EXSLT_FILE)) - params = { - :p1 => 'xxx', - :p2 => "x'x'x", - :p3 => 'x"x"x', - :p4 => '"xxx"' - } - result_doc = Nokogiri::XML.parse(style.apply_to(doc, - Nokogiri::XSLT.quote_params(params))) - - assert_equal 'func-result', result_doc.at('/root/function').content - assert_equal 3, result_doc.at('/root/max').content.to_i - assert_match( - /\d{4}-\d\d-\d\d([-|+]\d\d:\d\d)?/, - result_doc.at('/root/date').content - ) - result_doc.xpath('/root/params/*').each do |p| - assert_equal p.content, params[p.name.intern] - end - check_params result_doc, params - result_doc = Nokogiri::XML.parse(style.apply_to(doc, - Nokogiri::XSLT.quote_params(params.to_a.flatten))) - check_params result_doc, params - end + def test_exslt + # see http://yokolet.blogspot.com/2010/10/pure-java-nokogiri-xslt-extension.html") + skip_unless_libxml2("cannot get it working on JRuby") - def test_xslt_paramaters - xslt_str = <<-EOX - - - - - - EOX + assert(doc = Nokogiri::XML.parse(File.read(EXML_FILE))) + assert(doc.xml?) - xslt = Nokogiri::XSLT(xslt_str) - doc = Nokogiri::XML("") - assert_match %r{bar}, xslt.transform(doc, Nokogiri::XSLT.quote_params('foo' => 'bar')).to_s + assert(style = Nokogiri::XSLT.parse(File.read(EXSLT_FILE))) + params = { + p1: 'xxx', + p2: "x'x'x", + p3: 'x"x"x', + p4: '"xxx"', + } + result_doc = Nokogiri::XML.parse(style.apply_to(doc, + Nokogiri::XSLT.quote_params(params))) + + assert_equal('func-result', result_doc.at('/root/function').content) + assert_equal(3, result_doc.at('/root/max').content.to_i) + assert_match( + /\d{4}-\d\d-\d\d([-|+]\d\d:\d\d)?/, + result_doc.at('/root/date').content + ) + result_doc.xpath('/root/params/*').each do |p| + assert_equal(p.content, params[p.name.intern]) end + check_params(result_doc, params) + result_doc = Nokogiri::XML.parse(style.apply_to(doc, + Nokogiri::XSLT.quote_params(params.to_a.flatten))) + check_params(result_doc, params) + end - def test_xslt_transform_error - xslt_str = <<-EOX - - - - - + def test_xslt_paramaters + # see http://yokolet.blogspot.com/2010/10/pure-java-nokogiri-xslt-extension.html") + skip_unless_libxml2("cannot get it working on JRuby") + + xslt_str = <<~EOX + + + + + EOX - xslt = Nokogiri::XSLT(xslt_str) - doc = Nokogiri::XML("") - assert_raises(RuntimeError) { xslt.transform(doc) } - end + xslt = Nokogiri::XSLT(xslt_str) + doc = Nokogiri::XML("") + assert_match(/bar/, xslt.transform(doc, Nokogiri::XSLT.quote_params('foo' => 'bar')).to_s) end + def test_xslt_transform_error + # see http://yokolet.blogspot.com/2010/10/pure-java-nokogiri-xslt-extension.html") + skip_unless_libxml2("cannot get it working on JRuby") + + xslt_str = <<~EOX + + + + + + EOX + + xslt = Nokogiri::XSLT(xslt_str) + doc = Nokogiri::XML("") + assert_raises(RuntimeError) { xslt.transform(doc) } + end def test_xslt_parse_error - xslt_str = <<-EOX - - - - - - - - - - - -} + xslt_str = <<~EOX + + + + + + + + + + + + } EOX assert_raises(RuntimeError) { Nokogiri::XSLT.parse(xslt_str) } end - def test_passing_a_non_document_to_transform xsl = Nokogiri::XSLT('') assert_raises(ArgumentError) { xsl.transform("
") } assert_raises(ArgumentError) { xsl.transform(Nokogiri::HTML("").css("body")) } end - def check_params result_doc, params - result_doc.xpath('/root/params/*').each do |p| - assert_equal p.content, params[p.name.intern] + def check_params(result_doc, params) + result_doc.xpath('/root/params/*').each do |p| + assert_equal(p.content, params[p.name.intern]) end end def test_non_html_xslt_transform - xml = Nokogiri.XML(<<-EOXML) - - - 123 - - + xml = Nokogiri.XML(<<~EOXML) + + + 123 + + EOXML - xsl = Nokogiri.XSLT(<<-EOXSL) + xsl = Nokogiri.XSLT(<<~EOXSL) @@ -313,8 +319,8 @@ def test_non_html_xslt_transform EOXSL - result = xsl.transform xml - assert !result.html? + result = xsl.transform(xml) + assert(!result.html?) end it "should not crash when given XPath 2.0 features" do @@ -325,35 +331,35 @@ def test_non_html_xslt_transform # this test case is taken from the example provided in the original issue. # xml = <<~EOXML - - - - 48.00 - - + + + + 48.00 + + EOXML xsl = <<~EOXSL - - - - - - - - - - - + + + + + + + + + + + EOXSL doc = Nokogiri::XML(xml) diff --git a/test/xml/sax/test_parser.rb b/test/xml/sax/test_parser.rb index 161ad0c625..de078d6115 100644 --- a/test/xml/sax/test_parser.rb +++ b/test/xml/sax/test_parser.rb @@ -338,7 +338,7 @@ def test_processing_instruction end def test_parse_document - skip("JRuby SAXParser only parses well-formed XML documents") unless Nokogiri.uses_libxml? + skip_unless_libxml2("JRuby SAXParser only parses well-formed XML documents") @parser.parse_memory(<<~eoxml)

Paragraph 1

Paragraph 2

diff --git a/test/xml/sax/test_push_parser.rb b/test/xml/sax/test_push_parser.rb index ea185e1d6e..587bd54a1a 100644 --- a/test/xml/sax/test_push_parser.rb +++ b/test/xml/sax/test_push_parser.rb @@ -203,7 +203,7 @@ def test_recover end def test_broken_encoding - skip("ultra hard to fix for pure Java version") if Nokogiri.jruby? + skip_unless_libxml2("ultra hard to fix for pure Java version") @parser.options |= XML::ParseOptions::RECOVER # This is ISO_8859-1: @parser.<< "Gau\337" @@ -236,7 +236,7 @@ def test_replace_entities_attribute_behavior end def test_untouched_entities - skip("entities are always replaced in pure Java version") if Nokogiri.jruby? + skip_unless_libxml2("entities are always replaced in pure Java version") @parser.<<(<<-eoxml)

diff --git a/test/xml/test_document_encoding.rb b/test/xml/test_document_encoding.rb index 0b4a35b5ee..0f1bebc6d4 100644 --- a/test/xml/test_document_encoding.rb +++ b/test/xml/test_document_encoding.rb @@ -17,7 +17,7 @@ def test_encoding end def test_dotted_version - skip "libxml2 is only used for CRuby" unless Nokogiri.uses_libxml? + skip_unless_libxml2 assert_equal "UTF-8", Nokogiri::LIBXML_COMPILED_VERSION.encoding.name assert_equal "UTF-8", Nokogiri::LIBXSLT_COMPILED_VERSION.encoding.name end diff --git a/test/xml/test_document_fragment.rb b/test/xml/test_document_fragment.rb index 0c6468eda1..c728913cae 100644 --- a/test/xml/test_document_fragment.rb +++ b/test/xml/test_document_fragment.rb @@ -250,13 +250,12 @@ def test_issue_1077_parsing_of_frozen_strings Nokogiri::XML::DocumentFragment.parse(input) # assert_nothing_raised end - if Nokogiri.uses_libxml? - def test_dup_should_exist_in_a_new_document - # https://github.com/sparklemotion/nokogiri/issues/1063 - original = Nokogiri::XML::DocumentFragment.parse("

hello

") - duplicate = original.dup - assert_not_equal(original.document, duplicate.document) - end + def test_dup_should_exist_in_a_new_document + skip_unless_libxml2("this is only true in the C extension") + # https://github.com/sparklemotion/nokogiri/issues/1063 + original = Nokogiri::XML::DocumentFragment.parse("

hello

") + duplicate = original.dup + assert_not_equal(original.document, duplicate.document) end def test_dup_should_create_an_xml_document_fragment @@ -280,21 +279,18 @@ def test_dup_creates_mutable_tree 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 - fragment = Nokogiri::XML.fragment("
") - parent = fragment.children.first - child = parent.parse("

").first - parent.add_child(child) - - GC.start - end + def test_for_libxml_in_context_fragment_parsing_bug_workaround + refute_valgrind_errors do + fragment = Nokogiri::XML.fragment("
") + parent = fragment.children.first + child = parent.parse("

").first + parent.add_child(child) 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. + def test_for_libxml_in_context_memory_badness_when_encountering_encoding_errors + # see issue #643 for background + refute_valgrind_errors do html = <<~EOHTML diff --git a/test/xml/test_node.rb b/test/xml/test_node.rb index 346e4b5f15..5995055cb7 100644 --- a/test/xml/test_node.rb +++ b/test/xml/test_node.rb @@ -187,7 +187,7 @@ def test_dup_shallow_copy end def test_dup_to_another_document - skip("Node.dup with new_parent arg is only implemented on CRuby") unless Nokogiri.uses_libxml? + skip_unless_libxml2("Node.dup with new_parent arg is only implemented on CRuby") doc1 = HTML::Document.parse("

hello

") doc2 = HTML::Document.parse("
") @@ -1049,7 +1049,7 @@ def test_namespace_without_an_href_on_html_node # 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? + skip_unless_libxml2("Xerces handles this edge case completely differently") xml = Nokogiri::HTML.parse(<<~EOF)
foo
@@ -1198,7 +1198,7 @@ def test_set_node_lang def test_text_node_robustness_gh1426 skip("only run if NOKOGIRI_GC is set") unless ENV['NOKOGIRI_GC'] - skip("No need to test libxml-ruby workarounds on JRuby") if Nokogiri.jruby? + skip_unless_libxml2("No need to test libxml-ruby workarounds on 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 # side note: this was fixed in libxml-ruby 2.9.0 by https://github.com/xml4r/libxml-ruby/pull/119 @@ -1240,7 +1240,7 @@ def test_wrap 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? + skip_unless_libxml2("Xerces does not have line numbers for nodes") document = Nokogiri::XML::Document.new node = document.create_element('a') node.line = 54321 diff --git a/test/xml/test_node_attributes.rb b/test/xml/test_node_attributes.rb index efe8813724..a7b3af9c1f 100644 --- a/test/xml/test_node_attributes.rb +++ b/test/xml/test_node_attributes.rb @@ -96,8 +96,9 @@ def test_namespace_key? assert !node.namespaced_key?('foo', 'foo') end - def test_set_attribute_frees_nodes # testing a segv - skip("JRuby doesn't do GC.") if Nokogiri.jruby? + def test_set_attribute_frees_nodes + # testing a segv + skip_unless_libxml2("JRuby doesn't do GC.") document = Nokogiri::XML.parse("") node = document.root diff --git a/test/xml/test_node_reparenting.rb b/test/xml/test_node_reparenting.rb index 526eb55a57..7ff761f246 100644 --- a/test/xml/test_node_reparenting.rb +++ b/test/xml/test_node_reparenting.rb @@ -204,10 +204,6 @@ class TestNodeReparenting < Nokogiri::TestCase let(:doc) { Nokogiri::XML::Document.parse(xml) } let(:context_node) { doc.at_css("context") } - after do - GC.start - end - describe "with a parent" do let(:expected_callee) do if which == :self @@ -659,9 +655,9 @@ def coerce(data) end describe "unlinking a node and then reparenting it" do - it "not blow up" do - # see http://github.com/sparklemotion/nokogiri/issues#issue/22 - 10.times do + it "should not cause illegal memory access during GC" do + refute_valgrind_errors do + # see http://github.com/sparklemotion/nokogiri/issues#issue/22 doc = Nokogiri::XML(<<~EOHTML) @@ -677,8 +673,6 @@ def coerce(data) assert c = a.at("c") a.add_next_sibling(b.unlink) c.unlink - - GC.start end end end diff --git a/test/xml/test_node_set.rb b/test/xml/test_node_set.rb index 3c76b1375d..f1e32faacf 100644 --- a/test/xml/test_node_set.rb +++ b/test/xml/test_node_set.rb @@ -883,21 +883,14 @@ def awesome!; end describe "adding nodes from different documents to the same NodeSet" do # see https://github.com/sparklemotion/nokogiri/issues/1952 it "should not segfault" do - skip("this tests a libxml2-specific issue") if Nokogiri.jruby? + node_set = refute_valgrind_errors do + xml = <<~EOF + + + EOF - xml = <<~EOF - - - EOF - - # proc that returns Nodes but allows the Documents to be GCed - scope = lambda do Nokogiri::XML::Document.parse(xml).css("container") + Nokogiri::XML::Document.parse(xml).css("container") end - node_set = scope.call - - # kick off major GC - GC.start # see if everything's still there node_set.to_s diff --git a/test/xml/test_reader.rb b/test/xml/test_reader.rb index be9e19a6e6..f8ca29e867 100644 --- a/test/xml/test_reader.rb +++ b/test/xml/test_reader.rb @@ -206,7 +206,7 @@ def test_errors_is_an_array end def test_pushing_to_non_array_raises_TypeError - skip "TODO: JRuby ext does not internally call `errors`" if Nokogiri.jruby? + skip_unless_libxml2("TODO: JRuby ext does not internally call `errors`") reader = Nokogiri::XML::Reader(StringIO.new('&bogus;')) def reader.errors 1 @@ -420,25 +420,22 @@ def test_ns_uri end def test_reader_node_attributes_keep_a_reference_to_the_reader - xml = <<~EOF - - - - EOF attribute_nodes = [] - reader = Nokogiri::XML::Reader.from_memory(xml) - reader.each do |element| - attribute_nodes += element.attribute_nodes - end - assert_operator(attribute_nodes.length, :>, 0) + refute_valgrind_errors do + xml = <<~EOF + + + + EOF - # make sure that the only reference to the reader is from the nodes, and run a major GC - reader = nil - GC.start + reader = Nokogiri::XML::Reader.from_memory(xml) + reader.each do |element| + attribute_nodes += element.attribute_nodes + end + end - # and now dereference the attributes. this will raise valgrind warnings if we haven't done - # it right. + assert_operator(attribute_nodes.length, :>, 0) attribute_nodes.inspect end diff --git a/test/xml/test_reader_encoding.rb b/test/xml/test_reader_encoding.rb index 1a2f9e9c96..a8644f78b3 100644 --- a/test/xml/test_reader_encoding.rb +++ b/test/xml/test_reader_encoding.rb @@ -122,7 +122,7 @@ def test_name def test_value_lookup_segfault skip("only run if NOKOGIRI_GC is set") unless ENV['NOKOGIRI_GC'] - skip("JRuby doesn't do GC.") if Nokogiri.jruby? + skip_unless_libxml2 stress_memory_while do while node = @reader.read nodes = node.attribute_nodes diff --git a/test/xml/test_relax_ng.rb b/test/xml/test_relax_ng.rb index c6c8dc7776..8e7103a6e8 100644 --- a/test/xml/test_relax_ng.rb +++ b/test/xml/test_relax_ng.rb @@ -53,7 +53,8 @@ def test_from_document_with_parse_options end def test_read_memory_with_parse_options - skip("https://github.com/sparklemotion/nokogiri/issues/2115") if Nokogiri.jruby? + # https://github.com/sparklemotion/nokogiri/issues/2115 + skip_unless_libxml2 schema = Nokogiri::XML::RelaxNG.read_memory(File.read(ADDRESS_SCHEMA_FILE)) assert_equal Nokogiri::XML::ParseOptions::DEFAULT_SCHEMA, schema.parse_options diff --git a/test/xml/test_schema.rb b/test/xml/test_schema.rb index e5d581dc9a..6cba39abe7 100644 --- a/test/xml/test_schema.rb +++ b/test/xml/test_schema.rb @@ -9,7 +9,7 @@ def setup end def test_issue_1985_segv_on_schema_parse - skip("Pure Java version doesn't have this bug") unless Nokogiri.uses_libxml? + skip_unless_libxml2("Pure Java version doesn't have this bug") # This is a test for a workaround for a bug in LibXML2. The upstream # bug is here: https://gitlab.gnome.org/GNOME/libxml2/issues/148 diff --git a/test/xml/test_xinclude.rb b/test/xml/test_xinclude.rb index f0baac03ee..205f33c221 100644 --- a/test/xml/test_xinclude.rb +++ b/test/xml/test_xinclude.rb @@ -10,7 +10,7 @@ def setup end def test_xinclude_on_document_parse - skip("Pure Java version XInlcude has a conflict with NekoDTD setting. This will be fixed later.") if Nokogiri.jruby? + skip_unless_libxml2("Pure Java version XInlcude has a conflict with NekoDTD setting. This will be fixed later.") # first test that xinclude works when requested xml_doc = nil @@ -38,7 +38,7 @@ def test_xinclude_on_document_parse end def test_xinclude_on_document_node - skip("Pure Java version turns XInlcude on against a parser.") if Nokogiri.jruby? + skip_unless_libxml2("Pure Java version turns XInlcude on against a parser.") assert_nil @xml.at_xpath('//included') @xml.do_xinclude assert_not_nil included = @xml.at_xpath('//included') @@ -46,7 +46,7 @@ def test_xinclude_on_document_node end def test_xinclude_on_element_subtree - skip("Pure Java version turns XInlcude on against a parser.") if Nokogiri.jruby? + skip_unless_libxml2("Pure Java version turns XInlcude on against a parser.") assert_nil @xml.at_xpath('//included') @xml.root.do_xinclude assert_not_nil included = @xml.at_xpath('//included') @@ -63,7 +63,7 @@ def test_do_xinclude_accepts_block end def test_include_nonexistent_throws_exception - skip("Pure Java version behaves differently") if Nokogiri.jruby? + skip_unless_libxml2("Pure Java version behaves differently") # break inclusion deliberately @xml.at_xpath('//xi:include')['href'] = "nonexistent.xml" diff --git a/test/xslt/test_custom_functions.rb b/test/xslt/test_custom_functions.rb index b373da040a..01daba28dd 100644 --- a/test/xslt/test_custom_functions.rb +++ b/test/xslt/test_custom_functions.rb @@ -1,4 +1,5 @@ # -*- encoding: utf-8 -*- +# frozen_string_literal: true require "helper" @@ -7,125 +8,118 @@ module XSLT class TestCustomFunctions < Nokogiri::TestCase def setup super - @xml = Nokogiri.XML(<<-EOXML) - - - - - - Foo - - -

Foo

-

Lorem ipsum.

- - -EOXML + @xml = Nokogiri.XML(<<~EOXML) + + + + + + Foo + + +

Foo

+

Lorem ipsum.

+ + + EOXML end def test_function - skip("Pure Java version doesn't support this feature.") if !Nokogiri.uses_libxml? + skip_unless_libxml2("java version doesn't support this feature") foo = Class.new do - def capitalize nodes + def capitalize(nodes) nodes.first.content.upcase end end - XSLT.register "http://e.org/functions", foo - - xsl = Nokogiri.XSLT(<<-EOXSL) - - - - - - - - - - - - - - - -EOXSL - result = xsl.transform @xml + XSLT.register("http://e.org/functions", foo) + + xsl = Nokogiri.XSLT(<<~EOXSL) + + + + + + + + + + + + + EOXSL + result = xsl.transform(@xml) assert_match(/FOO/, result.css('title').first.text) end - def test_function_arguments - skip("Pure Java version doesn't support this feature.") if !Nokogiri.uses_libxml? + skip_unless_libxml2("java version doesn't support this feature") foo = Class.new do include MiniTest::Assertions # Minitest 5 uses `self.assertions` in `assert()` which is not # defined in the Minitest::Assertions module :-( attr_writer :assertions - def assertions; @assertions ||= 0; end + def assertions + @assertions ||= 0 + end - def multiarg *args - assert_equal ["abc", "xyz"], args + def multiarg(*args) + assert_equal(["abc", "xyz"], args) args.first end - def numericarg arg - assert_equal 42, arg + def numericarg(arg) + assert_equal(42, arg) arg end end - xsl = Nokogiri.XSLT(<<-EOXSL, "http://e.org/functions" => foo) - - - - - - - - -EOXSL - - xsl.transform @xml + xsl = Nokogiri.XSLT(<<~EOXSL, "http://e.org/functions" => foo) + + + + + + + + EOXSL + + xsl.transform(@xml) end - def test_function_XSLT - skip("Pure Java version doesn't support this feature.") if !Nokogiri.uses_libxml? + skip_unless_libxml2("java version doesn't support this feature") foo = Class.new do - def america nodes + def america(nodes) nodes.first.content.upcase end end - xsl = Nokogiri.XSLT(<<-EOXSL, "http://e.org/functions" => foo) - - - - - - - - - - - - - - - -EOXSL - result = xsl.transform @xml + xsl = Nokogiri.XSLT(<<~EOXSL, "http://e.org/functions" => foo) + + + + + + + + + + + + + EOXSL + result = xsl.transform(@xml) assert_match(/FOO/, result.css('title').first.text) end end diff --git a/test/xslt/test_exception_handling.rb b/test/xslt/test_exception_handling.rb index 373dae5a5e..a74d3e95cb 100644 --- a/test/xslt/test_exception_handling.rb +++ b/test/xslt/test_exception_handling.rb @@ -1,37 +1,37 @@ +# frozen_string_literal: true require "helper" module Nokogiri module XSLT class TestExceptionHandling < Nokogiri::TestCase def test_java_exception_handling - skip('This test is for Java only') if Nokogiri.uses_libxml? + skip_unless_jruby('This test is for Java only') - xml = Nokogiri.XML(<<-EOXML) - - - -EOXML + xml = Nokogiri.XML(<<~EOXML) + + + + EOXML - xsl = Nokogiri.XSLT(<<-EOXSL) - - + xsl = Nokogiri.XSLT(<<~EOXSL) + + -
- - - -EOXSL + xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> + + + + + + EOXSL - begin - xsl.transform xml - fail('It should not get here') - rescue RuntimeError => e - assert_match(/Can't have more than one root/, e.to_s, 'The exception message does not contain the expected information') + e = assert_raises(RuntimeError) do + xsl.transform(xml) end - end + assert_match(/Can't have more than one root/, e.to_s, + 'The exception message does not contain the expected information') + end end end end