Skip to content

Commit

Permalink
test: add test for parsing requirements
Browse files Browse the repository at this point in the history
  • Loading branch information
kou committed Jan 11, 2025
1 parent 12cc88c commit c6adcbb
Show file tree
Hide file tree
Showing 6 changed files with 209 additions and 22 deletions.
22 changes: 1 addition & 21 deletions lib/rubygems-requirements-system/installer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,30 +19,10 @@

require_relative "version"

require_relative "package"
require_relative "platform"
require_relative "requirements-parser"

module RubyGemsRequirementsSystem
Requirement = Struct.new(:packages, :system_packages) do
def satisfied?
packages.any? do |package|
installed?(package)
end
end

private
def installed?(package)
package_config = PKGConfig.package_config(package.id)
begin
package_config.cflags
rescue PackageConfig::NotFoundError
return false
end

package.satisfied?(package_config.version)
end
end

class Installer
include Gem::UserInteraction

Expand Down
1 change: 1 addition & 0 deletions lib/rubygems-requirements-system/platform/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

require "fileutils"
require "open-uri"
require "rubygems/user_interaction"
require "tempfile"

require_relative "../executable-finder"
Expand Down
36 changes: 36 additions & 0 deletions lib/rubygems-requirements-system/requirement.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Copyright (C) 2025 Ruby-GNOME Project Team
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

module RubyGemsRequirementsSystem
Requirement = Struct.new(:packages, :system_packages) do
def satisfied?
packages.any? do |package|
installed?(package)
end
end

private
def installed?(package)
package_config = PKGConfig.package_config(package.id)
begin
package_config.cflags
rescue PackageConfig::NotFoundError
return false
end

package.satisfied?(package_config.version)
end
end
end
75 changes: 75 additions & 0 deletions lib/rubygems-requirements-system/requirements-parser.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Copyright (C) 2025 Ruby-GNOME Project Team
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

require_relative "package"
require_relative "requirement"

module RubyGemsRequirementsSystem
class RequirementsParser
def initialize(gemspec_requirements, platform)
@gemspec_requirements = gemspec_requirements
@platform = platform
end

def parse
all_packages_set = {}
requirements = {}
@gemspec_requirements.each do |gemspec_requirement|
components = gemspec_requirement.split(/: +/, 4)
next unless components.size == 4

id, raw_packages, platform, system_package = components
next unless id == "system"

packages = parse_packages(raw_packages)
next if packages.empty?

all_packages_set[packages] = true

next unless @platform.target?(platform)
requirements[packages] ||= []
requirements[packages] << system_package
end
(all_packages_set.keys - requirements.keys).each do |not_used_packages|
system_packages = @platform.default_system_packages(not_used_packages)
next if system_packages.nil?
requirements[not_used_packages] = system_packages
end
requirements.collect do |packages, system_packages|
Requirement.new(packages, system_packages)
end
end

private
def parse_packages(raw_packages)
packages = raw_packages.split(/\s*\|\s*/).collect do |raw_package|
Package.parse(raw_package)
end
# Ignore this requirement if any invalid package is included.
# We must not report an error for this because
# Gem::Specification#requirements is a free form
# configuration. So there are configuration values that use
# "system: ..." but not for this plugin. We can report a
# warning instead.
packages.each do |package|
unless package.valid?
# TODO: Report a warning
return []
end
end
packages
end
end
end
3 changes: 2 additions & 1 deletion test/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

require_relative "../lib/rubygems-requirements-system/package"
require_relative "../lib/rubygems-requirements-system/platform"
require_relative "../lib/rubygems-requirements-system/requirements-parser"
94 changes: 94 additions & 0 deletions test/test-requirements-parser.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Copyright (C) 2025 Ruby-GNOME Project Team
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

require_relative "helper"

class TestRequiremtsParser < Test::Unit::TestCase
Package = RubyGemsRequirementsSystem::Package
Platform = RubyGemsRequirementsSystem::Platform
Requirement = RubyGemsRequirementsSystem::Requirement
RequirementsParser = RubyGemsRequirementsSystem::RequirementsParser

def setup
@platform = Platform::Ubuntu.new
end

def parse(gemspec_requirements)
RequirementsParser.new(gemspec_requirements, @platform).parse
end

def test_minimal
gemspec_requirements = [
"system: cairo: debian: libcairo2-dev",
]
assert_equal([
Requirement.new([Package.new("cairo")],
["libcairo2-dev"]),
],
parse(gemspec_requirements))
end

def test_required_version
gemspec_requirements = [
"system: cairo >= 1.2.0: debian: libcairo2-dev",
]
assert_equal([
Requirement.new([Package.new("cairo", ">=", "1.2.0")],
["libcairo2-dev"]),
],
parse(gemspec_requirements))
end

def test_or_dependency
gemspec_requirements = [
"system: mysqlclient|libmariadb: debian: libmariadb-dev",
"system: mysqlclient|libmariadb: ubuntu: libmysqlclient-dev",
]
assert_equal([
Requirement.new([
Package.new("mysqlclient"),
Package.new("libmariadb"),
],
[
"libmariadb-dev",
"libmysqlclient-dev",
]),
],
parse(gemspec_requirements))
end

def test_https
deb_url = "https://packages.groonga.org/%{distribution}/groonga-apt-source-latest-%{code_name}.deb"
gemspec_requirements = [
"system: groonga: debian: #{deb_url}",
]
assert_equal([
Requirement.new([Package.new("groonga")],
[deb_url]),
],
parse(gemspec_requirements))
end

def test_ppa
gemspec_requirements = [
"system: groonga: ubuntu: ppa:groonga/ppa",
]
assert_equal([
Requirement.new([Package.new("groonga")],
["ppa:groonga/ppa"]),
],
parse(gemspec_requirements))
end
end

0 comments on commit c6adcbb

Please sign in to comment.