scripts/test-gem-installation
#! /usr/bin/env ruby
# frozen_string_literal: true
#
# this script is intended to run as part of the CI test suite.
#
# it inspects the filesystem of a nokogiri gem installation to ensure it's complete and sane, and
# doesn't install anything we don't expect.
#
# this file isn't in the `test/` subdirectory because it's intended to be run standalone against an
# installed gem (and not against the source code or behavior of the gem itself).
#
# this line needs to come before the bundler bit, to assert that we're running against an
# already-installed version (and not some other version that bundler/inline might install if it came
# first)
gemspec = Gem::Specification.find_all_by_name("nokogiri").sort_by(&:version).last
raise "could not find installed gem" unless gemspec
require "bundler/inline"
gemfile do
source "https://rubygems.org"
gem "minitest"
gem "nokogiri"
end
require "nokogiri"
require "yaml"
if ARGV.include?("-v")
puts "---------- Nokogiri version info ----------"
puts Nokogiri::VERSION_INFO.to_yaml
puts
puts "---------- Nokogiri installed gemspec ----------"
puts gemspec.to_ruby
puts
end
require "minitest/autorun"
puts "Testing #{gemspec.full_name} installed in #{gemspec.base_dir}"
describe gemspec.full_name do
let(:ruby_maj_min) { Gem::Version.new(RUBY_VERSION).segments[0..1].join(".") }
let(:nokogiri_lib_dir) { File.join(gemspec.gem_dir, "lib/nokogiri") }
let(:nokogiri_ext_dir) { File.join(gemspec.gem_dir, "ext/nokogiri") }
let(:nokogiri_include_dir) { File.join(nokogiri_ext_dir, "include") }
# representative sample of the files
let(:nokogiri_header_files) { ["nokogiri.h"] }
let(:packaged_library_header_files) { ["libxml2/libxml/tree.h", "libxslt/xslt.h", "libexslt/exslt.h"] }
let(:headers_dirs) { Nokogiri::VERSION_INFO["nokogiri"]["cppflags"].map { |f| f.gsub(/^-I/, "") } }
it "loads the same version as the spec we've loaded" do
assert_equal(Nokogiri::VERSION, gemspec.version.to_s)
end
describe "cruby" do
it "installs nokogiri headers" do
nokogiri_header_files.each do |header|
assert(
File.file?(File.join(nokogiri_ext_dir, header)),
"expected #{header} to be installed in #{nokogiri_ext_dir}",
)
found = false
headers_dirs.each do |header_dir|
found = true if File.file?(File.join(header_dir, "nokogiri.h"))
end
assert(found, "expected to find nokogiri.h in one of: #{headers_dirs.inspect}")
end
end
describe "native platform" do
it "declares packaged, precompiled libraries" do
assert(Nokogiri::VersionInfo.instance.libxml2_using_packaged?)
assert(Nokogiri::VERSION_INFO["libxml"].key?("source"))
assert_equal("packaged", Nokogiri::VERSION_INFO["libxml"]["source"])
assert(Nokogiri::VersionInfo.instance.libxml2_precompiled?)
assert(Nokogiri::VERSION_INFO["libxml"].key?("precompiled"))
assert(Nokogiri::VERSION_INFO["libxml"]["precompiled"])
end
end if gemspec.platform.is_a?(Gem::Platform) && gemspec.platform.cpu
describe "library" do
describe "packaged" do
describe "for third-party library linking" do
it "installs packaged libraries' headers" do
packaged_library_header_files.each do |header|
assert(
File.file?(File.join(nokogiri_include_dir, header)),
"expected #{header} to be installed in #{nokogiri_include_dir}",
)
end
end
end
it "points to packaged libraries' headers" do
packaged_library_header_files.each do |header|
found = false
headers_dirs.each do |header_dir|
found = true if File.file?(File.join(header_dir, header))
end
assert(found, "expected to find #{header} in one of: #{headers_dirs.inspect}")
end
end
it "has ldflags pointing to the shared object file" do
ldflags = Nokogiri::VERSION_INFO["nokogiri"]["ldflags"]
if RUBY_PLATFORM.match?(/mingw|mswin/)
if gemspec.platform.is_a?(Gem::Platform) && gemspec.platform.cpu
assert_includes(ldflags, "-L#{File.join(nokogiri_lib_dir, ruby_maj_min)}")
else
assert_includes(ldflags, "-L#{nokogiri_lib_dir}")
end
assert_includes(ldflags, "-l:nokogiri.so")
else
assert_empty(ldflags)
end
end
end if Nokogiri::VersionInfo.instance.libxml2_using_packaged?
describe "using system libraries" do
it "doesn't declare where headers are installed" do
refute(Nokogiri::VERSION_INFO["libxml"].key?("libxml2_path"))
end
it "does not install packaged libraries' headers" do
packaged_library_header_files.each do |header|
dir = File.join(nokogiri_include_dir, File.dirname(header))
refute(File.directory?(dir), "expected directory #{dir} to not exist")
end
end
end unless Nokogiri::VersionInfo.instance.libxml2_using_packaged?
end
end unless gemspec.platform == Gem::Platform.new("java")
end