diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 45b1f796ce..f5e9cd8ec1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -234,7 +234,7 @@ jobs: fail-fast: false matrix: sys: ["enable", "disable"] - ruby: ["2.6", "2.7", "3.0", "3.1", "mingw", "head"] + ruby: ["2.6", "2.7", "3.0", "3.1", "mingw"] runs-on: windows-2022 steps: - name: configure git crlf diff --git a/.github/workflows/upstream.yml b/.github/workflows/upstream.yml index 0a3e6cd9b4..b7cf6f45ff 100644 --- a/.github/workflows/upstream.yml +++ b/.github/workflows/upstream.yml @@ -4,16 +4,6 @@ concurrency: cancel-in-progress: true on: workflow_dispatch: - push: - branches: - - main - - v*.*.x - tags: - - v*.*.* - pull_request: - types: [opened, synchronize] - branches: - - '*' schedule: - cron: "0 8 * * 1,3,5" # At 08:00 on Monday, Wednesday, and Friday # https://crontab.guru/#0_8_*_*_1,3,5 diff --git a/dependencies.yml b/dependencies.yml index 2d00410f9a..5e9b83bbc6 100644 --- a/dependencies.yml +++ b/dependencies.yml @@ -9,8 +9,8 @@ libxslt: # sha-256 hash provided in https://download.gnome.org/sources/libxslt/1.1/libxslt-1.1.35.sha256sum zlib: - version: "1.2.11" - sha256: "c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1" + version: "1.2.12" + sha256: "91844808532e5ce316b3c010929493c0244f3d37593afd6de04f71821d5136d9" # SHA-256 hash provided on http://zlib.net/ libiconv: diff --git a/ext/nokogiri/extconf.rb b/ext/nokogiri/extconf.rb index a1d6be549e..e1596e9e57 100644 --- a/ext/nokogiri/extconf.rb +++ b/ext/nokogiri/extconf.rb @@ -382,6 +382,7 @@ def iconv_configure_flags ["iconv", "opt"].each do |target| config = preserving_globals { dir_config(target) } next unless config.any? && try_link_iconv("--with-#{target}-* flags") { dir_config(target) } + idirs, ldirs = config.map do |dirs| Array(dirs).flat_map do |dir| dir.split(File::PATH_SEPARATOR) @@ -715,14 +716,6 @@ def configure execute("configure", ["env", "CHOST=#{host}", "CFLAGS=#{cflags}", "./configure", "--static", configure_prefix]) end - - def compile - if /darwin/.match?(host) - execute("compile", "make AR=#{host}-libtool") - else - super - end - end end end end diff --git a/lib/nokogiri/css/parser_extras.rb b/lib/nokogiri/css/parser_extras.rb index 587256ec82..6394a847a3 100644 --- a/lib/nokogiri/css/parser_extras.rb +++ b/lib/nokogiri/css/parser_extras.rb @@ -24,12 +24,14 @@ def set_cache(value) # rubocop:disable Naming/AccessorMethodName # Get the css selector in +string+ from the cache def [](string) return nil unless cache_on? + @mutex.synchronize { @cache[string] } end # Set the css selector in +string+ in the cache to +value+ def []=(string, value) return value unless cache_on? + @mutex.synchronize { @cache[string] = value } end diff --git a/lib/nokogiri/html4/document.rb b/lib/nokogiri/html4/document.rb index 2529fe867a..177efc04f7 100644 --- a/lib/nokogiri/html4/document.rb +++ b/lib/nokogiri/html4/document.rb @@ -125,8 +125,9 @@ def set_metadata_element(element) # rubocop:disable Naming/AccessorMethodName private :set_metadata_element #### - # Serialize Node using +options+. Save options can also be set using a - # block. See SaveOptions. + # Serialize Node using +options+. Save options can also be set using a block. + # + # See also Nokogiri::XML::Node::SaveOptions and Node@Serialization+and+Generating+Output. # # These two statements are equivalent: # @@ -241,6 +242,7 @@ def initialize def start_element(name, attrs = []) return unless name == "meta" + attr = Hash[attrs] (charset = attr["charset"]) && (@encoding = charset) diff --git a/lib/nokogiri/html4/sax/parser.rb b/lib/nokogiri/html4/sax/parser.rb index 147515976a..2a074b6b92 100644 --- a/lib/nokogiri/html4/sax/parser.rb +++ b/lib/nokogiri/html4/sax/parser.rb @@ -30,6 +30,7 @@ class Parser < Nokogiri::XML::SAX::Parser def parse_memory(data, encoding = "UTF-8") raise ArgumentError unless data return if data.empty? + ctx = ParserContext.memory(data, encoding) yield ctx if block_given? ctx.parse_with(self) @@ -51,6 +52,7 @@ def parse_file(filename, encoding = "UTF-8") raise ArgumentError unless filename raise Errno::ENOENT unless File.exist?(filename) raise Errno::EISDIR if File.directory?(filename) + ctx = ParserContext.file(filename, encoding) yield ctx if block_given? ctx.parse_with(self) diff --git a/lib/nokogiri/html5.rb b/lib/nokogiri/html5.rb index c980efa8a7..43d426458b 100644 --- a/lib/nokogiri/html5.rb +++ b/lib/nokogiri/html5.rb @@ -468,6 +468,7 @@ def self.escape_text(text, encoding, attribute_mode) def self.prepend_newline?(node) return false unless ["pre", "textarea", "listing"].include?(node.name) && !node.children.empty? + first_child = node.children[0] first_child.text? && first_child.content.start_with?("\n") end diff --git a/lib/nokogiri/html5/document.rb b/lib/nokogiri/html5/document.rb index a6260c0995..2bc1ca9a95 100644 --- a/lib/nokogiri/html5/document.rb +++ b/lib/nokogiri/html5/document.rb @@ -39,16 +39,19 @@ def self.parse(string_or_io, url = nil, encoding = nil, **options, &block) unless string_or_io.respond_to?(:read) || string_or_io.respond_to?(:to_str) raise ArgumentError, "not a string or IO object" end + do_parse(string_or_io, url, encoding, options) end def self.read_io(io, url = nil, encoding = nil, **options) raise ArgumentError, "io object doesn't respond to :read" unless io.respond_to?(:read) + do_parse(io, url, encoding, options) end def self.read_memory(string, url = nil, encoding = nil, **options) raise ArgumentError, "string object doesn't respond to :to_str" unless string.respond_to?(:to_str) + do_parse(string, url, encoding, options) end diff --git a/lib/nokogiri/html5/node.rb b/lib/nokogiri/html5/node.rb index ff6ccdde42..ceacaf115a 100644 --- a/lib/nokogiri/html5/node.rb +++ b/lib/nokogiri/html5/node.rb @@ -27,6 +27,7 @@ module HTML5 module Node def inner_html(options = {}) return super(options) unless document.is_a?(HTML5::Document) + result = options[:preserve_newline] && HTML5.prepend_newline?(self) ? +"\n" : +"" result << children.map { |child| child.to_html(options) }.join result @@ -34,6 +35,7 @@ def inner_html(options = {}) def write_to(io, *options) return super(io, *options) unless document.is_a?(HTML5::Document) + options = options.first.is_a?(Hash) ? options.shift : {} encoding = options[:encoding] || options[0] if Nokogiri.jruby? @@ -64,6 +66,7 @@ def write_to(io, *options) def fragment(tags) return super(tags) unless document.is_a?(HTML5::Document) + DocumentFragment.new(document, tags, self) end @@ -76,6 +79,7 @@ def fragment(tags) # actually create the xml namespace if it doesn't exist already. def add_child_node_and_reparent_attrs(node) return super(node) unless document.is_a?(HTML5::Document) + # I'm not sure what this method is supposed to do. Reparenting # namespaces is handled by libxml2, including child namespaces which # this method wouldn't handle. diff --git a/lib/nokogiri/version/info.rb b/lib/nokogiri/version/info.rb index bd5a735ce5..8470b2d268 100644 --- a/lib/nokogiri/version/info.rb +++ b/lib/nokogiri/version/info.rb @@ -191,6 +191,7 @@ def to_markdown def self.uses_libxml?(requirement = nil) return false unless VersionInfo.instance.libxml2? return true unless requirement + Gem::Requirement.new(requirement).satisfied_by?(VersionInfo.instance.loaded_libxml_version) end diff --git a/lib/nokogiri/xml.rb b/lib/nokogiri/xml.rb index 2bcbc508c2..9d16fb1498 100644 --- a/lib/nokogiri/xml.rb +++ b/lib/nokogiri/xml.rb @@ -27,6 +27,7 @@ def Reader(string_or_io, url = nil, encoding = nil, options = ParseOptions::STRI if string_or_io.respond_to?(:read) return Reader.from_io(string_or_io, url, encoding, options.to_i) end + Reader.from_memory(string_or_io, url, encoding, options.to_i) end diff --git a/lib/nokogiri/xml/builder.rb b/lib/nokogiri/xml/builder.rb index 5eb8dbe8d8..e828d2ffe2 100644 --- a/lib/nokogiri/xml/builder.rb +++ b/lib/nokogiri/xml/builder.rb @@ -363,6 +363,7 @@ def [](ns) @parent.ancestors.each do |a| next if a == doc + @ns = a.namespace_definitions.find { |x| x.prefix == ns.to_s } return self if @ns end @@ -407,6 +408,7 @@ def method_missing(method, *args, &block) # :nodoc: if node.namespace.nil? raise ArgumentError, "Namespace #{@ns[:pending]} has not been defined" end + @ns = nil end diff --git a/lib/nokogiri/xml/document.rb b/lib/nokogiri/xml/document.rb index 941b96d8ad..d97cd3b1a0 100644 --- a/lib/nokogiri/xml/document.rb +++ b/lib/nokogiri/xml/document.rb @@ -321,6 +321,7 @@ def decorators(key) # the document or +nil+ when there is no DTD. def validate return nil unless internal_subset + internal_subset.validate(self) end @@ -353,8 +354,10 @@ def slop! # Apply any decorators to +node+ def decorate(node) return unless @decorators + @decorators.each do |klass, list| next unless node.is_a?(klass) + list.each { |moodule| node.extend(moodule) } end end @@ -380,9 +383,11 @@ def fragment(tags = nil) def add_child(node_or_tags) raise "A document may not have multiple root nodes." if (root && root.name != "nokogiri_text_wrapper") && !(node_or_tags.comment? || node_or_tags.processing_instruction?) + node_or_tags = coerce(node_or_tags) if node_or_tags.is_a?(XML::NodeSet) raise "A document may not have multiple root nodes." if node_or_tags.size > 1 + super(node_or_tags.first) else super diff --git a/lib/nokogiri/xml/node.rb b/lib/nokogiri/xml/node.rb index ce731ce925..59bb2da224 100644 --- a/lib/nokogiri/xml/node.rb +++ b/lib/nokogiri/xml/node.rb @@ -163,6 +163,7 @@ def prepend_child(node_or_tags) if (first = children.first) # Mimic the error add_child would raise. raise "Document already has a root node" if document? && !(node_or_tags.comment? || node_or_tags.processing_instruction?) + first.__send__(:add_sibling, :previous, node_or_tags) else add_child(node_or_tags) @@ -1072,6 +1073,7 @@ def fragment? # nil on XML documents and on unknown tags. def description return nil if document.xml? + Nokogiri::HTML4::ElementDescription[name] end @@ -1119,6 +1121,7 @@ def ancestors(selector = nil) while parents.last.respond_to?(:parent) break unless (ctx_parent = parents.last.parent) + parents << ctx_parent end @@ -1150,6 +1153,7 @@ def accept(visitor) def ==(other) return false unless other return false unless other.respond_to?(:pointer_id) + pointer_id == other.pointer_id end @@ -1159,14 +1163,16 @@ def ==(other) def <=>(other) return nil unless other.is_a?(Nokogiri::XML::Node) return nil unless document == other.document + compare(other) end # :section: Serialization and Generating Output ### - # Serialize Node using +options+. Save options can also be set using a - # block. See SaveOptions. + # Serialize Node using +options+. Save options can also be set using a block. + # + # See also Nokogiri::XML::Node::SaveOptions and Node@Serialization+and+Generating+Output. # # These two statements are equivalent: # diff --git a/lib/nokogiri/xml/node/save_options.rb b/lib/nokogiri/xml/node/save_options.rb index d12171389e..447b517625 100644 --- a/lib/nokogiri/xml/node/save_options.rb +++ b/lib/nokogiri/xml/node/save_options.rb @@ -4,7 +4,8 @@ module Nokogiri module XML class Node ### - # Save options for serializing nodes + # Save options for serializing nodes. + # See the method group entitled Node@Serialization+and+Generating+Output for usage. class SaveOptions # Format serialized xml FORMAT = 1 diff --git a/lib/nokogiri/xml/node_set.rb b/lib/nokogiri/xml/node_set.rb index 29c0744912..803a0f8a95 100644 --- a/lib/nokogiri/xml/node_set.rb +++ b/lib/nokogiri/xml/node_set.rb @@ -27,6 +27,7 @@ def initialize(document, list = []) # Get the first element of the NodeSet. def first(n = nil) return self[0] unless n + list = [] [n, length].min.times { |i| list << self[i] } list @@ -304,6 +305,7 @@ def to_xml(*args) # the set is empty def pop return nil if length == 0 + delete(last) end @@ -312,6 +314,7 @@ def pop # +nil+ if the set is empty. def shift return nil if length == 0 + delete(first) end @@ -322,6 +325,7 @@ def shift def ==(other) return false unless other.is_a?(Nokogiri::XML::NodeSet) return false unless length == other.length + each_with_index do |node, i| return false unless node == other[i] end diff --git a/lib/nokogiri/xml/parse_options.rb b/lib/nokogiri/xml/parse_options.rb index 9d50bb245d..8f304535e7 100644 --- a/lib/nokogiri/xml/parse_options.rb +++ b/lib/nokogiri/xml/parse_options.rb @@ -89,6 +89,7 @@ def initialize(options = STRICT) constants.each do |constant| next if constant.to_sym == :STRICT + class_eval %{ def #{constant.downcase} @options |= #{constant} diff --git a/lib/nokogiri/xml/sax/parser.rb b/lib/nokogiri/xml/sax/parser.rb index 262bde4afb..bd3e8befab 100644 --- a/lib/nokogiri/xml/sax/parser.rb +++ b/lib/nokogiri/xml/sax/parser.rb @@ -101,6 +101,7 @@ def parse_file(filename) raise ArgumentError unless filename raise Errno::ENOENT unless File.exist?(filename) raise Errno::EISDIR if File.directory?(filename) + ctx = ParserContext.file(filename) yield ctx if block_given? ctx.parse_with(self) diff --git a/lib/nokogiri/xml/syntax_error.rb b/lib/nokogiri/xml/syntax_error.rb index 26ca104ad0..9f85e2af34 100644 --- a/lib/nokogiri/xml/syntax_error.rb +++ b/lib/nokogiri/xml/syntax_error.rb @@ -64,6 +64,7 @@ def nil_or_zero?(attribute) def location_to_s return nil if nil_or_zero?(line) && nil_or_zero?(column) + "#{line}:#{column}" end end diff --git a/scripts/test-exported-symbols b/scripts/test-exported-symbols index 1d81a68844..61b61fb3b3 100755 --- a/scripts/test-exported-symbols +++ b/scripts/test-exported-symbols @@ -45,6 +45,7 @@ symbols.to_a.sort.each do |symbol| next if symbol == "Init_nokogiri" next if /^Nokogiri_/.match?(symbol) next if /^noko_/.match?(symbol) + puts "- #{symbol}" end diff --git a/scripts/test-gem-file-contents b/scripts/test-gem-file-contents index 58a59d637d..4651b81354 100755 --- a/scripts/test-gem-file-contents +++ b/scripts/test-gem-file-contents @@ -38,6 +38,7 @@ gemfile_contents = Dir.mktmpdir do |dir| unless system("tar -xf #{gemfile} data.tar.gz") raise "could not unpack gem #{gemfile}" end + %x(tar -ztf data.tar.gz).split("\n") end end @@ -47,6 +48,7 @@ gemspec = Dir.mktmpdir do |dir| unless system("tar -xf #{gemfile} metadata.gz") raise "could not unpack gem #{gemfile}" end + YAML.safe_load(%x(gunzip -c metadata.gz), permitted_classes: [Gem::Specification, Gem::Version, Gem::Dependency, Gem::Requirement, Time, Symbol]) end end @@ -72,6 +74,7 @@ describe File.basename(gemfile) do File.read(cross_rubies_path).split("\n").map do |line| ver, plat = line.split(":") next if plat != gemspec.platform.to_s + ver.split(".").take(2).join(".") # ugh end.compact.uniq.sort end diff --git a/test/helper.rb b/test/helper.rb index 8f296e687f..61634cca62 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -162,6 +162,7 @@ def skip_unless_libxml2_patch(patch_name) if File.directory?(patch_dir) && !File.exist?(File.join(patch_dir, patch_name)) raise("checking for nonexistent patch file #{patch_name.inspect}") end + unless Nokogiri.libxml2_patches.include?(patch_name) skip("this test needs libxml2 patched with #{patch_name}") end @@ -217,6 +218,7 @@ def pending(msg) def pending_if(msg, pend_eh, &block) return yield unless pend_eh + pending(msg, &block) end diff --git a/test/html4/test_comments.rb b/test/html4/test_comments.rb index 39ab13a070..32d7a87855 100644 --- a/test/html4/test_comments.rb +++ b/test/html4/test_comments.rb @@ -26,7 +26,7 @@ class TestComment < Nokogiri::TestCase if Nokogiri.libxml2_patches.include?("0008-htmlParseComment-handle-abruptly-closed-comments.patch") it "behaves as if the comment is closed correctly" do # COMPLIANT assert_equal 1, subject.children.length - assert subject.children.first.comment? + assert_predicate subject.children.first, :comment? assert_equal "", subject.children.first.content assert other_div end @@ -43,7 +43,7 @@ class TestComment < Nokogiri::TestCase if Nokogiri.jruby? it "behaves as if the comment is closed correctly" do # COMPLIANT assert_equal 1, subject.children.length - assert subject.children.first.comment? + assert_predicate subject.children.first, :comment? assert_equal "", subject.children.first.content assert other_div end @@ -57,7 +57,7 @@ class TestComment < Nokogiri::TestCase if Nokogiri.libxml2_patches.include?("0008-htmlParseComment-handle-abruptly-closed-comments.patch") it "behaves as if the comment is closed correctly" do # COMPLIANT assert_equal 1, subject.children.length - assert subject.children.first.comment? + assert_predicate subject.children.first, :comment? assert_equal "", subject.children.first.content assert other_div end @@ -74,7 +74,7 @@ class TestComment < Nokogiri::TestCase if Nokogiri.jruby? it "behaves as if the comment is closed correctly" do # COMPLIANT assert_equal 1, subject.children.length - assert subject.children.first.comment? + assert_predicate subject.children.first, :comment? assert_equal "-", subject.children.first.content # curious, potentially non-compliant? assert other_div end @@ -86,7 +86,7 @@ class TestComment < Nokogiri::TestCase it "behaves as if the comment is closed correctly" do # COMPLIANT assert_equal 1, subject.children.length - assert subject.children.first.comment? + assert_predicate subject.children.first, :comment? assert_equal "", subject.children.first.content assert other_div end @@ -115,7 +115,7 @@ class TestComment < Nokogiri::TestCase if Nokogiri.jruby? it "behaves as if the comment is closed immediately before the end of the input stream" do # COMPLIANT assert_equal 1, subject.children.length - assert subject.children.first.comment? + assert_predicate subject.children.first, :comment? assert_equal "start of unterminated comment", subject.children.first.content end end @@ -136,11 +136,11 @@ class TestComment < Nokogiri::TestCase if Nokogiri::VersionInfo.instance.libxml2_using_packaged? || (Nokogiri::VersionInfo.instance.libxml2_using_system? && Nokogiri.uses_libxml?(">=2.9.11")) it "behaves as if the comment is normally closed" do # COMPLIANT assert_equal 3, subject.children.length - assert subject.children[0].comment? + assert_predicate subject.children[0], :comment? assert_equal "foo", subject.children[0].content assert inner_div assert_equal inner_div, subject.children[1] - assert subject.children[2].comment? + assert_predicate subject.children[2], :comment? assert_equal "bar", subject.children[2].content assert_equal 1, doc.errors.length assert_match(/Comment incorrectly closed/, doc.errors.first.to_s) @@ -150,7 +150,7 @@ class TestComment < Nokogiri::TestCase if Nokogiri.jruby? || (Nokogiri::VersionInfo.instance.libxml2_using_system? && Nokogiri.uses_libxml?("<2.9.11")) it "behaves as if the comment encompasses the inner div" do # NON-COMPLIANT assert_equal 1, subject.children.length - assert subject.children.first.comment? + assert_predicate subject.children.first, :comment? refute inner_div assert_match(/id=do-i-exist/, subject.children.first.content) assert_equal 0, doc.errors.length @@ -178,9 +178,9 @@ class TestComment < Nokogiri::TestCase assert_equal 2, body.children.length assert_equal body.children[0], subject assert_equal 1, subject.children.length - assert subject.children[0].text? + assert_predicate subject.children[0], :text? assert_equal "inner content", subject.children[0].content - assert body.children[1].text? + assert_predicate body.children[1], :text? assert_equal "-->hello", body.children[1].content end end @@ -188,7 +188,7 @@ class TestComment < Nokogiri::TestCase if Nokogiri.jruby? it "ignores up to the next '-->'" do # NON-COMPLIANT assert_equal 1, subject.children.length - assert subject.children[0].text? + assert_predicate subject.children[0], :text? assert_equal "hello", subject.children[0].content end end @@ -208,11 +208,11 @@ class TestComment < Nokogiri::TestCase it "ignores to the next '-->'" do # COMPLIANT assert_equal 3, subject.children.length - assert subject.children[0].comment? + assert_predicate subject.children[0], :comment? assert_equal " outer ", subject.children[2].content end end diff --git a/test/html4/test_document.rb b/test/html4/test_document.rb index 04ca56a285..c253fd1c97 100644 --- a/test/html4/test_document.rb +++ b/test/html4/test_document.rb @@ -38,9 +38,9 @@ def test_document_takes_config_block options = cfg options.nonet.nowarning.dtdattr end - assert(options.nonet?) - assert(options.nowarning?) - assert(options.dtdattr?) + assert_predicate(options, :nonet?) + assert_predicate(options, :nowarning?) + assert_predicate(options, :dtdattr?) end def test_parse_takes_config_block @@ -49,9 +49,9 @@ def test_parse_takes_config_block options = cfg options.nonet.nowarning.dtdattr end - assert(options.nonet?) - assert(options.nowarning?) - assert(options.dtdattr?) + assert_predicate(options, :nonet?) + assert_predicate(options, :nowarning?) + assert_predicate(options, :dtdattr?) end def test_subclass @@ -339,7 +339,7 @@ def test_parse_empty_document def test_HTML_function html = Nokogiri::HTML(File.read(HTML_FILE)) - assert(html.html?) + assert_predicate(html, :html?) end def test_parse_works_with_an_object_that_responds_to_read @@ -535,9 +535,9 @@ def test_search_can_handle_xpath_and_css def test_dup_document assert(dup = html.dup) refute_equal(dup, html) - assert(html.html?) + assert_predicate(html, :html?) assert_instance_of(Nokogiri::HTML::Document, dup) - assert(dup.html?, "duplicate should be html") + assert_predicate(dup, :html?, "duplicate should be html") assert_equal(html.to_s, dup.to_s) end @@ -641,7 +641,7 @@ def test_parse_can_take_io File.open(HTML_FILE, "rb") do |f| html = Nokogiri::HTML(f) end - assert(html.html?) + assert_predicate(html, :html?) assert_equal(HTML_FILE, html.url) end @@ -668,8 +668,8 @@ def test_parse_can_take_pathnames end def test_html? - refute(html.xml?) - assert(html.html?) + refute_predicate(html, :xml?) + assert_predicate(html, :html?) end def test_serialize @@ -780,7 +780,7 @@ def test_leaking_dtd_nodes_after_internal_subset_removal end it "sets the test up correctly" do - assert(html_strict.strict?) + assert_predicate(html_strict, :strict?) end describe "ill-formed < character" do diff --git a/test/html4/test_document_encoding.rb b/test/html4/test_document_encoding.rb index 278ed3067c..6115301764 100644 --- a/test/html4/test_document_encoding.rb +++ b/test/html4/test_document_encoding.rb @@ -138,6 +138,7 @@ def binopen(file) assert_equal(evil, ary_from_string) next unless !Nokogiri.uses_libxml? || Nokogiri::VersionInfo.instance.libxml2_has_iconv? + # libxml2 without iconv does not pass this test assert_equal(evil, ary_from_file_enc) assert_equal(evil, ary_from_file) diff --git a/test/html4/test_document_fragment.rb b/test/html4/test_document_fragment.rb index d4df392eaf..ea3c1ca492 100644 --- a/test/html4/test_document_fragment.rb +++ b/test/html4/test_document_fragment.rb @@ -318,7 +318,7 @@ def test_dup_should_create_an_html_document_fragment let(:input) { "
foo

test paragraph diff --git a/test/html5/test_api.rb b/test/html5/test_api.rb index fd1c80c2ce..af10dc11db 100644 --- a/test/html5/test_api.rb +++ b/test/html5/test_api.rb @@ -156,7 +156,7 @@ def test_fragment_from_node assert_equal(1, frag.children.length) nested_form = frag.at_xpath("form") assert_nil(nested_form) - assert(frag.children[0].text?) + assert_predicate(frag.children[0], :text?) end def test_fragment_from_node_no_form @@ -179,7 +179,7 @@ def test_empty_fragment def test_html_eh doc = Nokogiri.HTML5("

") - assert(doc.html?) - refute(doc.xml?) + assert_predicate(doc, :html?) + refute_predicate(doc, :xml?) end end if Nokogiri.uses_gumbo? diff --git a/test/html5/test_nokogumbo.rb b/test/html5/test_nokogumbo.rb index af95659b74..bba13a7634 100644 --- a/test/html5/test_nokogumbo.rb +++ b/test/html5/test_nokogumbo.rb @@ -16,7 +16,7 @@ def test_element_cdata_textarea def test_element_cdata_script doc = Nokogiri::HTML5.fragment(buffer) - assert(doc.document.html?) + assert_predicate(doc.document, :html?) assert_equal("", doc.at("script").to_s) end @@ -318,7 +318,7 @@ def test_line_cdata html = "\n\n" doc = Nokogiri.HTML5(html) node = doc.at_xpath("/html/body/svg:svg/svg:script/text()") - assert(node.cdata?) + assert_predicate(node, :cdata?) assert_equal(3, node.line) end diff --git a/test/html5/test_null.rb b/test/html5/test_null.rb index e4eb7ed284..a2d814529d 100644 --- a/test/html5/test_null.rb +++ b/test/html5/test_null.rb @@ -107,7 +107,7 @@ def test_cdata_section_state def test_error_api_with_null frag = fragment("

") - assert(frag.errors.any?) + assert_predicate(frag.errors, :any?) assert_includes(frag.errors[0].to_s, "

") end end if Nokogiri.uses_gumbo? diff --git a/test/html5/test_tree-construction.rb b/test/html5/test_tree-construction.rb index 2c6fba78ed..1b52f93ea9 100644 --- a/test/html5/test_tree-construction.rb +++ b/test/html5/test_tree-construction.rb @@ -82,6 +82,7 @@ def parse_test(test_data) elsif node_text.start_with?("") + index += 1 node_text << "\n" + lines[index] end @@ -214,6 +215,7 @@ def run_test compare_nodes(exp_child, act_child) children[-1] = child_index + 1 next unless exp_child.key?(:children) + exp_nodes << exp_child act_nodes << act_child children << 0 @@ -272,6 +274,7 @@ def run_test klass = Class.new(TestHtml5TreeConstructionBase) do tests.each_with_index do |test, index| next if test[:script] == :on + define_method "test_#{index}".to_sym do @test = test @index = index diff --git a/test/test_css_cache.rb b/test/test_css_cache.rb index 7bfa21761f..4f2ee5cfdc 100644 --- a/test/test_css_cache.rb +++ b/test/test_css_cache.rb @@ -24,7 +24,7 @@ def [](key) end end - assert(Nokogiri::CSS::Parser.cache_on?) + assert_predicate(Nokogiri::CSS::Parser, :cache_on?) end def teardown @@ -105,9 +105,9 @@ def test_without_cache_resets_cache_value Nokogiri::CSS::Parser.set_cache(true) Nokogiri::CSS::Parser.without_cache do - refute(Nokogiri::CSS::Parser.cache_on?) + refute_predicate(Nokogiri::CSS::Parser, :cache_on?) end - assert(Nokogiri::CSS::Parser.cache_on?) + assert_predicate(Nokogiri::CSS::Parser, :cache_on?) end def test_without_cache_resets_cache_value_even_after_exception @@ -118,7 +118,7 @@ def test_without_cache_resets_cache_value_even_after_exception raise RuntimeError end end - assert(Nokogiri::CSS::Parser.cache_on?) + assert_predicate(Nokogiri::CSS::Parser, :cache_on?) end def test_cache_key_on_ns_prefix_and_visitor_config @@ -161,6 +161,6 @@ def test_race_condition threads.each(&:join) - assert(Nokogiri::CSS::Parser.cache_on?) + assert_predicate(Nokogiri::CSS::Parser, :cache_on?) end end diff --git a/test/test_memory_leak.rb b/test/test_memory_leak.rb index 13bfaf7a98..8b546c561c 100644 --- a/test/test_memory_leak.rb +++ b/test/test_memory_leak.rb @@ -206,6 +206,7 @@ def test_leaking_dtd_nodes_after_internal_subset_removal 100_001.times do |j| Nokogiri::XML::RelaxNG.from_document(Nokogiri::XML::Document.parse(File.read(ADDRESS_SCHEMA_FILE))) next unless j % 10_000 == 0 + curr_rss = MemInfo.rss diff_rss = curr_rss - prev_rss printf("\n(iter %d) %d", j, curr_rss) @@ -232,6 +233,7 @@ def self.rss if STATM_FOUND return (File.read(STATM_PATH).split(" ")[1].to_i * PAGE_SIZE) / 1024 end + 0 end end diff --git a/test/test_nokogiri.rb b/test/test_nokogiri.rb index b0a084f2c9..8acc42ce4a 100644 --- a/test/test_nokogiri.rb +++ b/test/test_nokogiri.rb @@ -16,20 +16,20 @@ def test_parse_with_io def test_xml? doc = Nokogiri.parse(File.read(XML_FILE)) - assert(doc.xml?) - refute(doc.html?) + assert_predicate(doc, :xml?) + refute_predicate(doc, :html?) end def test_atom_is_xml? doc = Nokogiri.parse(File.read(XML_ATOM_FILE)) - assert(doc.xml?) - refute(doc.html?) + assert_predicate(doc, :xml?) + refute_predicate(doc, :html?) end def test_html? doc = Nokogiri.parse(File.read(HTML_FILE)) - refute(doc.xml?) - assert(doc.html?) + refute_predicate(doc, :xml?) + assert_predicate(doc, :html?) end def test_nokogiri_method_with_html diff --git a/test/test_xslt_transforms.rb b/test/test_xslt_transforms.rb index 068498484f..30678d0116 100644 --- a/test/test_xslt_transforms.rb +++ b/test/test_xslt_transforms.rb @@ -155,19 +155,19 @@ def test_transform_arg_error def test_transform_with_hash assert(style = Nokogiri::XSLT(File.read(XSLT_FILE))) result = style.transform(doc, { "title" => '"Booyah"' }) - assert(result.html?) + assert_predicate(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_predicate(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_predicate(result_doc, :html?) assert_equal("Booyah", result_doc.at_css("h1").content) assert(result_string = style.apply_to(doc, ["title", '"Booyah"'])) @@ -177,12 +177,12 @@ def test_transform2 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_predicate(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_predicate(result_doc, :html?) assert_equal("Booyah", result_doc.at_css("h1").content) end @@ -191,7 +191,7 @@ def test_exslt skip_unless_libxml2("cannot get it working on JRuby") assert(doc = Nokogiri::XML.parse(File.read(EXML_FILE))) - assert(doc.xml?) + assert_predicate(doc, :xml?) assert(style = Nokogiri::XSLT.parse(File.read(EXSLT_FILE))) params = { @@ -301,7 +301,7 @@ def test_non_html_xslt_transform EOXSL result = xsl.transform(xml) - refute(result.html?) + refute_predicate(result, :html?) end it "should not crash when given XPath 2.0 features" do diff --git a/test/xml/test_builder.rb b/test/xml/test_builder.rb index 30932b6f5b..7e1635ad70 100644 --- a/test/xml/test_builder.rb +++ b/test/xml/test_builder.rb @@ -369,7 +369,7 @@ def test_comment comment("this is a comment") end end - assert(builder.doc.root.children.first.comment?) + assert_predicate(builder.doc.root.children.first, :comment?) end def test_builder_no_block diff --git a/test/xml/test_cdata.rb b/test/xml/test_cdata.rb index 257c94bfac..8c8da023b1 100644 --- a/test/xml/test_cdata.rb +++ b/test/xml/test_cdata.rb @@ -13,7 +13,7 @@ def setup def test_cdata_node name = @xml.xpath("//employee[2]/name").first assert(cdata = name.children[1]) - assert(cdata.cdata?) + assert_predicate(cdata, :cdata?) assert_equal("#cdata-section", cdata.name) end diff --git a/test/xml/test_comment.rb b/test/xml/test_comment.rb index b83238635f..61d1bbb8d7 100644 --- a/test/xml/test_comment.rb +++ b/test/xml/test_comment.rb @@ -17,8 +17,8 @@ def test_new def test_comment? comment = Nokogiri::XML::Comment.new(@xml, "hello world") - assert(comment.comment?) - refute(@xml.root.comment?) + assert_predicate(comment, :comment?) + refute_predicate(@xml.root, :comment?) end def test_passing_a_node_uses_the_node_document diff --git a/test/xml/test_document.rb b/test/xml/test_document.rb index 36fe6d6116..4afdca5d48 100644 --- a/test/xml/test_document.rb +++ b/test/xml/test_document.rb @@ -468,9 +468,9 @@ def test_parse_yields_parse_options options = cfg options.nonet.nowarning.dtdattr end - assert(options.nonet?) - assert(options.nowarning?) - assert(options.dtdattr?) + assert_predicate(options, :nonet?) + assert_predicate(options, :nowarning?) + assert_predicate(options, :dtdattr?) end def test_XML_takes_block @@ -479,9 +479,9 @@ def test_XML_takes_block options = cfg options.nonet.nowarning.dtdattr end - assert(options.nonet?) - assert(options.nowarning?) - assert(options.dtdattr?) + assert_predicate(options, :nonet?) + assert_predicate(options, :nowarning?) + assert_predicate(options, :dtdattr?) end def test_document_parse_method @@ -634,7 +634,7 @@ def test_strict_document_throws_syntax_error def test_XML_function xml = Nokogiri::XML(File.read(XML_FILE), XML_FILE) - assert(xml.xml?) + assert_predicate(xml, :xml?) end def test_url @@ -659,7 +659,7 @@ def test_parse_can_take_io File.open(XML_FILE, "rb") do |f| xml = Nokogiri::XML(f) end - assert(xml.xml?) + assert_predicate(xml, :xml?) assert_equal(XML_FILE, xml.url) set = xml.search("//employee") refute_empty(set) @@ -777,7 +777,7 @@ def test_find_with_namespace end def test_xml? - assert(xml.xml?) + assert_predicate(xml, :xml?) end def test_document @@ -828,13 +828,13 @@ def test_dump def test_dup dup = xml.dup assert_instance_of(Nokogiri::XML::Document, dup) - assert(dup.xml?, "duplicate should be xml") + assert_predicate(dup, :xml?, "duplicate should be xml") end def test_new doc = Nokogiri::XML::Document.new assert(doc) - assert(doc.xml?) + assert_predicate(doc, :xml?) assert_nil(doc.root) end @@ -1021,7 +1021,7 @@ def test_can_be_closed end it "sets the test up correctly" do - assert(xml_strict.strict?) + assert_predicate(xml_strict, :strict?) end describe "read memory" do diff --git a/test/xml/test_document_fragment.rb b/test/xml/test_document_fragment.rb index 073ea1d088..6e2dfa0cb8 100644 --- a/test/xml/test_document_fragment.rb +++ b/test/xml/test_document_fragment.rb @@ -344,7 +344,7 @@ def test_for_libxml_in_context_memory_badness_when_encountering_encoding_errors let(:input) { "foo") node = doc.at_css("foo") next_element = node.next_element - assert(next_element.element?) + assert_predicate(next_element, :element?) assert_equal(doc.at_css("quux"), next_element) end @@ -273,7 +273,7 @@ def test_next_element_when_next_sibling_is_not_an_element_should_return_closest_ doc = Nokogiri::XML("bar") node = doc.at_css("foo") next_element = node.next_element - assert(next_element.element?) + assert_predicate(next_element, :element?) assert_equal(doc.at_css("quux"), next_element) end @@ -288,7 +288,7 @@ def test_previous_element_when_previous_sibling_is_element_should_return_previou doc = Nokogiri::XML("") node = doc.at_css("quux") previous_element = node.previous_element - assert(previous_element.element?) + assert_predicate(previous_element, :element?) assert_equal(doc.at_css("foo"), previous_element) end @@ -301,7 +301,7 @@ def test_previous_element_when_previous_sibling_is_not_an_element_should_return_ doc = Nokogiri::XML("bar") node = doc.at_css("quux") previous_element = node.previous_element - assert(previous_element.element?) + assert_predicate(previous_element, :element?) assert_equal(doc.at_css("foo"), previous_element) end @@ -313,7 +313,7 @@ def test_previous_element_when_previous_sibling_is_not_an_element_and_no_followi end def test_element? - assert(xml.root.element?, "is an element") + assert_predicate(xml.root, :element?, "is an element") end def test_slash_search @@ -753,7 +753,7 @@ 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?) + assert_predicate(entity_decl, :read_only?) end def test_set_content_with_symbol @@ -1168,11 +1168,11 @@ def awesome!; end end def test_blank_eh - refute(Nokogiri("").blank?) - refute(Nokogiri("").root.child.blank?) - assert(Nokogiri("\t \n").root.child.blank?) - assert(Nokogiri("").root.child.blank?) - assert(Nokogiri("not-blank").root.child.tap { |n| n.content = "" }.blank?) + refute_predicate(Nokogiri(""), :blank?) + refute_predicate(Nokogiri("").root.child, :blank?) + assert_predicate(Nokogiri("\t \n").root.child, :blank?) + assert_predicate(Nokogiri("").root.child, :blank?) + assert_predicate(Nokogiri("not-blank").root.child.tap { |n| n.content = "" }, :blank?) end def test_to_xml_allows_to_serialize_with_as_xml_save_option @@ -1242,18 +1242,18 @@ def test_document_eh html_node = html_doc.at_css("div") xml_node = xml_doc.at_css("div") - assert(html_doc.document?) - assert(xml_doc.document?) - refute(html_node.document?) - refute(xml_node.document?) + assert_predicate(html_doc, :document?) + assert_predicate(xml_doc, :document?) + refute_predicate(html_node, :document?) + refute_predicate(xml_node, :document?) 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?) - refute(div_node.processing_instruction?) + assert_predicate(pi_node, :processing_instruction?) + refute_predicate(div_node, :processing_instruction?) end def test_node_lang diff --git a/test/xml/test_node_set.rb b/test/xml/test_node_set.rb index 2ff2af1d64..4860338203 100644 --- a/test/xml/test_node_set.rb +++ b/test/xml/test_node_set.rb @@ -554,7 +554,7 @@ def awesome(ns) assert_equal("root", wrappers.first.parent.name) assert_equal("foo", wrappers.first.children.first.name) assert_equal("foo", wrappers.last.parent.name) - assert(wrappers.last.children.first.text?) + assert_predicate(wrappers.last.children.first, :text?) assert_equal("contents", wrappers.last.children.first.text) end diff --git a/test/xml/test_parse_options.rb b/test/xml/test_parse_options.rb index a899433c8a..9acb06a39f 100644 --- a/test/xml/test_parse_options.rb +++ b/test/xml/test_parse_options.rb @@ -17,6 +17,7 @@ def test_to_i ParseOptions.constants.each do |constant| next if constant == "STRICT" + class_eval %{ def test_predicate_#{constant.downcase} options = ParseOptions.new(ParseOptions::#{constant}) @@ -29,7 +30,7 @@ def test_predicate_#{constant.downcase} def test_strict_noent options = ParseOptions.new.recover.noent - refute(options.strict?) + refute_predicate(options, :strict?) end def test_new_with_argument @@ -39,20 +40,20 @@ def test_new_with_argument def test_unsetting options = Nokogiri::XML::ParseOptions.new(Nokogiri::XML::ParseOptions::DEFAULT_HTML) - assert(options.nonet?) - assert(options.recover?) + assert_predicate(options, :nonet?) + assert_predicate(options, :recover?) options.nononet.norecover - refute(options.nonet?) - refute(options.recover?) + refute_predicate(options, :nonet?) + refute_predicate(options, :recover?) options.nonet.recover - assert(options.nonet?) - assert(options.recover?) + assert_predicate(options, :nonet?) + assert_predicate(options, :recover?) end def test_chaining options = Nokogiri::XML::ParseOptions.new.recover.noent - assert(options.recover?) - assert(options.noent?) + assert_predicate(options, :recover?) + assert_predicate(options, :noent?) end def test_inspect diff --git a/test/xml/test_reader.rb b/test/xml/test_reader.rb index 1ab1da3f67..b3019691e6 100644 --- a/test/xml/test_reader.rb +++ b/test/xml/test_reader.rb @@ -82,9 +82,9 @@ def test_reader_takes_block options = cfg options.nonet.nowarning.dtdattr end - assert(options.nonet?) - assert(options.nowarning?) - assert(options.dtdattr?) + assert_predicate(options, :nonet?) + assert_predicate(options, :nowarning?) + assert_predicate(options, :dtdattr?) end def test_nil_raises @@ -99,7 +99,7 @@ def test_nil_raises def test_from_io io = File.open(SNUGGLES_FILE) reader = Nokogiri::XML::Reader.from_io(io) - refute(reader.default?) + refute_predicate(reader, :default?) assert_equal([false, false, false, false, false, false, false], reader.map(&:default?)) end @@ -107,7 +107,7 @@ def test_from_io def test_io io = File.open(SNUGGLES_FILE) reader = Nokogiri::XML::Reader(io) - refute(reader.default?) + refute_predicate(reader, :default?) assert_equal([false, false, false, false, false, false, false], reader.map(&:default?)) end @@ -119,7 +119,7 @@ def test_string_io eoxml reader = Nokogiri::XML::Reader(io) - refute(reader.default?) + refute_predicate(reader, :default?) assert_equal([false, false, false, false, false, false, false], reader.map(&:default?)) end @@ -169,7 +169,7 @@ def test_default? snuggles! eoxml - refute(reader.default?) + refute_predicate(reader, :default?) assert_equal([false, false, false, false, false, false, false], reader.map(&:default?)) end @@ -180,7 +180,7 @@ def test_value? snuggles! eoxml - refute(reader.value?) + refute_predicate(reader, :value?) assert_equal([false, true, false, true, false, true, false], reader.map(&:value?)) end @@ -223,7 +223,7 @@ def test_attributes? snuggles! eoxml - refute(reader.attributes?) + refute_predicate(reader, :attributes?) assert_equal([true, false, true, false, true, false, true], reader.map(&:attributes?)) end @@ -521,6 +521,7 @@ def test_xlink_href_without_base_uri reader.each do |node| next unless node.node_type == Nokogiri::XML::Reader::TYPE_ELEMENT + if node.name == "link" assert_nil(node.base_uri) end diff --git a/test/xml/test_reader_encoding.rb b/test/xml/test_reader_encoding.rb index e9a3e607d9..3986ecdbc1 100644 --- a/test/xml/test_reader_encoding.rb +++ b/test/xml/test_reader_encoding.rb @@ -44,6 +44,7 @@ def test_libxml2_overrides_internal_encoding_when_specified def test_attribute_at @reader.each do |node| next unless (attribute = node.attribute_at(0)) + assert_equal(@reader.encoding, attribute.encoding.name) end end @@ -66,6 +67,7 @@ def test_attribute reader = Nokogiri::XML::Reader(xml, nil, "UTF-8") reader.each do |node| next unless (attribute = node.attribute("awesome")) + assert_equal(reader.encoding, attribute.encoding.name) end end @@ -73,6 +75,7 @@ def test_attribute def test_xml_version @reader.each do |node| next unless (version = node.xml_version) + assert_equal(@reader.encoding, version.encoding.name) end end @@ -88,6 +91,7 @@ def test_lang reader = Nokogiri::XML::Reader(xml, nil, "UTF-8") reader.each do |node| next unless (lang = node.lang) + assert_equal(reader.encoding, lang.encoding.name) end end @@ -96,6 +100,7 @@ def test_value called = false @reader.each do |node| next unless (value = node.value) + assert_equal(@reader.encoding, value.encoding.name) called = true end @@ -111,6 +116,7 @@ def test_prefix reader = Nokogiri::XML::Reader(xml, nil, "UTF-8") reader.each do |node| next unless (prefix = node.prefix) + assert_equal(reader.encoding, prefix.encoding.name) end end @@ -124,6 +130,7 @@ def test_ns_uri reader = Nokogiri::XML::Reader(xml, nil, "UTF-8") reader.each do |node| next unless (uri = node.namespace_uri) + assert_equal(reader.encoding, uri.encoding.name) end end @@ -137,6 +144,7 @@ def test_local_name reader = Nokogiri::XML::Reader(xml, nil, "UTF-8") reader.each do |node| next unless (lname = node.local_name) + assert_equal(reader.encoding, lname.encoding.name) end end @@ -144,6 +152,7 @@ def test_local_name def test_name @reader.each do |node| next unless (name = node.name) + assert_equal(@reader.encoding, name.encoding.name) end end diff --git a/test/xml/test_unparented_node.rb b/test/xml/test_unparented_node.rb index b214179ee9..371191b6c5 100644 --- a/test/xml/test_unparented_node.rb +++ b/test/xml/test_unparented_node.rb @@ -113,7 +113,7 @@ def test_read_only? x.type == Node::ENTITY_DECL end assert(entity_decl) - assert(entity_decl.read_only?) + assert_predicate(entity_decl, :read_only?) end def test_remove_attribute @@ -203,8 +203,8 @@ def test_add_previous_sibling_merge left_space = a_tag.previous right_space = a_tag.next - assert(left_space.text?) - assert(right_space.text?) + assert_predicate(left_space, :text?) + assert_predicate(right_space, :text?) left_space.add_previous_sibling(right_space) assert_equal(left_space, right_space) @@ -221,8 +221,8 @@ def test_add_next_sibling_merge left_space = a_tag.previous right_space = a_tag.next - assert(left_space.text?) - assert(right_space.text?) + assert_predicate(left_space, :text?) + assert_predicate(right_space, :text?) right_space.add_next_sibling(left_space) assert_equal(left_space, right_space)