зеркало из https://github.com/github/licensed.git
256 строки
9.1 KiB
Ruby
256 строки
9.1 KiB
Ruby
# frozen_string_literal: true
|
|
require "test_helper"
|
|
require "tmpdir"
|
|
require "fileutils"
|
|
|
|
if Licensed::Shell.tool_available?("npm")
|
|
describe Licensed::Sources::NPM do
|
|
let(:config) { Licensed::AppConfiguration.new({ "source_path" => Dir.pwd }) }
|
|
let(:fixtures) { File.expand_path("../../fixtures/npm", __FILE__) }
|
|
let(:source) { Licensed::Sources::NPM.new(config) }
|
|
let(:version) { Gem::Version.new(Licensed::Shell.execute("npm", "-v")) }
|
|
|
|
describe "enabled?" do
|
|
it "is true if package.json exists" do
|
|
Dir.mktmpdir do |dir|
|
|
Dir.chdir(dir) do
|
|
File.write "package.json", ""
|
|
assert source.enabled?
|
|
end
|
|
end
|
|
end
|
|
|
|
it "is false no npm configs exist" do
|
|
Dir.mktmpdir do |dir|
|
|
Dir.chdir(dir) do
|
|
refute source.enabled?
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "dependencies" do
|
|
it "includes declared dependencies" do
|
|
Dir.chdir fixtures do
|
|
dep = source.dependencies.detect { |d| d.name == "autoprefixer" }
|
|
assert dep
|
|
assert_equal "npm", dep.record["type"]
|
|
assert_equal "5.2.0", dep.version
|
|
if source.npm_version < Gem::Version.new("7.0.0")
|
|
assert dep.record["homepage"]
|
|
end
|
|
assert dep.record["summary"]
|
|
end
|
|
end
|
|
|
|
it "includes homepage information if available" do
|
|
Dir.chdir fixtures do
|
|
dep = source.dependencies.detect { |d| d.name == "amdefine" }
|
|
assert dep
|
|
assert_equal "npm", dep.record["type"]
|
|
assert dep.record["homepage"]
|
|
end
|
|
end
|
|
|
|
it "handles scoped dependency names" do
|
|
Dir.chdir fixtures do
|
|
dep = source.dependencies.detect { |d| d.name == "@github/query-selector" }
|
|
assert dep
|
|
assert_equal "1.0.3", dep.version
|
|
if source.npm_version < Gem::Version.new("7.0.0")
|
|
assert dep.record["homepage"]
|
|
end
|
|
assert dep.record["summary"]
|
|
end
|
|
end
|
|
|
|
it "includes indirect dependencies" do
|
|
Dir.chdir fixtures do
|
|
assert source.dependencies.detect { |dep| dep.name == "autoprefixer" }
|
|
end
|
|
end
|
|
|
|
it "does not include dev dependencies by default" do
|
|
Dir.chdir fixtures do
|
|
refute source.dependencies.detect { |dep| dep.name == "string.prototype.startswith" }
|
|
end
|
|
end
|
|
|
|
it "includes dev dependencies if configured" do
|
|
Dir.chdir fixtures do
|
|
config["npm"] = { "production_only" => false }
|
|
assert source.dependencies.detect { |dep| dep.name == "string.prototype.startswith" }
|
|
end
|
|
end
|
|
|
|
it "does not include ignored dependencies" do
|
|
Dir.chdir fixtures do
|
|
config.ignore({ "type" => Licensed::Sources::NPM.type, "name" => "autoprefixer" })
|
|
refute source.dependencies.detect { |dep| dep.name == "autoprefixer" }
|
|
end
|
|
end
|
|
|
|
it "does not include missing indirect peer dependencies" do
|
|
Dir.chdir fixtures do
|
|
# peer dependency of @optimizely/js-sdk-datafile-manager, which is
|
|
# an indirect dependency through @optimizely/optimizely-sdk
|
|
# this checks the combination of being set in peerDependencies + `"missing": true`
|
|
refute source.dependencies.detect { |dep| dep.name == "@react-native-community/async-storage" }
|
|
|
|
# peer dependency of node-fetch
|
|
# this checks the combination of being set in peerDependencies,
|
|
# + peerDependencyMetadata `"optional": true`, + empty dependency data
|
|
refute source.dependencies.detect { |dep| dep.name == "encoding" }
|
|
end
|
|
end
|
|
|
|
it "raises a Licensed::Sources::Source:Error if npm list returns invalid JSON" do
|
|
Dir.chdir fixtures do
|
|
source.stub(:package_metadata_command, "") do
|
|
assert_raises Licensed::Sources::Source::Error do
|
|
source.dependencies
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "with multiple instances of a dependency" do
|
|
it "includes version in the dependency name for multiple unique versions" do
|
|
Dir.chdir fixtures do
|
|
graceful_fs_dependencies = source.dependencies.select { |dep| dep.name == "graceful-fs" }
|
|
assert_empty graceful_fs_dependencies
|
|
|
|
graceful_fs_dependencies = source.dependencies.select { |dep| dep.name =~ /graceful-fs/ }
|
|
assert_equal 2, graceful_fs_dependencies.size
|
|
graceful_fs_dependencies.each do |dependency|
|
|
assert_equal "#{dependency.record["name"]}-#{dependency.version}", dependency.name
|
|
end
|
|
end
|
|
end
|
|
|
|
it "does not include version in the dependency name for a single unique version" do
|
|
Dir.chdir fixtures do
|
|
dep = source.dependencies.detect { |d| d.name == "wrappy" }
|
|
assert_equal "wrappy", dep.name
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "from a workspace" do
|
|
let(:fixtures) { File.expand_path("../../fixtures/npm/packages/a", __FILE__) }
|
|
|
|
it "finds dependencies" do
|
|
# workspaces will only work as expected with npm > 8.5.0
|
|
skip if source.npm_version < Gem::Version.new("8.5.0")
|
|
|
|
Dir.chdir fixtures do
|
|
dep = source.dependencies.detect { |d| d.name == "callbackify" }
|
|
assert dep
|
|
assert_equal "npm", dep.record["type"]
|
|
assert_equal "1.1.0", dep.version
|
|
end
|
|
end
|
|
|
|
it "does not include the current workspace project" do
|
|
# workspaces will only work as expected with npm > 8.5.0
|
|
skip if source.npm_version < Gem::Version.new("8.5.0")
|
|
|
|
Dir.chdir fixtures do
|
|
refute source.dependencies.detect { |d| d.name == "licensed-fixtures-a" }
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "missing dependencies (glob is missing package)" do
|
|
it "includes missing dependencies when yarn.lock is missing" do
|
|
# this test is incompatible with npm >=7
|
|
skip if source.npm_version >= Gem::Version.new("7.0.0")
|
|
|
|
Dir.mktmpdir do |dir|
|
|
FileUtils.cp_r(fixtures, dir)
|
|
dir = File.join(dir, "npm")
|
|
FileUtils.rm_rf(File.join(dir, "node_modules/glob"))
|
|
|
|
Dir.chdir dir do
|
|
assert source.dependencies.detect { |dep| dep.name == "autoprefixer" }
|
|
assert source.dependencies.detect { |dep| dep.name == "glob" }
|
|
end
|
|
end
|
|
end
|
|
|
|
it "excludes missing dependencies when yarn.lock is present" do
|
|
# this test is incompatible with npm >=7
|
|
skip if source.npm_version >= Gem::Version.new("7.0.0")
|
|
|
|
Dir.mktmpdir do |dir|
|
|
FileUtils.cp_r(fixtures, dir)
|
|
dir = File.join(dir, "npm")
|
|
FileUtils.rm_rf(File.join(dir, "node_modules/glob"))
|
|
File.write(File.join(dir, "yarn.lock"), "")
|
|
|
|
Dir.chdir dir do
|
|
assert source.dependencies.detect { |dep| dep.name == "autoprefixer" }
|
|
refute source.dependencies.detect { |dep| dep.name == "glob" }
|
|
end
|
|
end
|
|
end
|
|
|
|
it "raises Licensed::Sources::Source::Error on missing dependencies" do
|
|
# this test is incompatible with npm <7, >=7.12.0 (possibly earlier versions as well, I haven't been able to verify)
|
|
skip if source.npm_version < Gem::Version.new("7.0.0")
|
|
skip if source.npm_version >= Gem::Version.new("7.12.0")
|
|
|
|
Dir.mktmpdir do |dir|
|
|
FileUtils.cp_r(fixtures, dir)
|
|
dir = File.join(dir, "npm")
|
|
FileUtils.rm_rf(File.join(dir, "node_modules/glob"))
|
|
|
|
Dir.chdir dir do
|
|
error = assert_raises Licensed::Sources::Source::Error do
|
|
source.dependencies
|
|
end
|
|
|
|
assert error.message.include? "missing: glob@^7"
|
|
end
|
|
end
|
|
end
|
|
|
|
it "sets errors on missing dependencies" do
|
|
# this test is incompatible with npm <7.12.0, (possibly earlier versions as well, I haven't been able to verify)
|
|
skip if source.npm_version < Gem::Version.new("7.12.0")
|
|
|
|
Dir.mktmpdir do |dir|
|
|
FileUtils.cp_r(fixtures, dir)
|
|
dir = File.join(dir, "npm")
|
|
FileUtils.rm_rf(File.join(dir, "node_modules/glob"))
|
|
|
|
Dir.chdir dir do
|
|
glob = source.dependencies.find { |dep| dep.name == "glob" }
|
|
assert glob.version
|
|
assert_includes glob.errors, "missing: glob@^7.1.3, required by rimraf@2.7.1"
|
|
end
|
|
end
|
|
end
|
|
|
|
it "does not set errors on packages with reported problems that have a path" do
|
|
# this test is incompatible with npm <7.12.0, (possibly earlier versions as well, I haven't been able to verify)
|
|
skip if source.npm_version < Gem::Version.new("7.12.0")
|
|
|
|
Dir.mktmpdir do |dir|
|
|
FileUtils.cp_r(fixtures, dir)
|
|
dir = File.join(dir, "npm")
|
|
FileUtils.rm_rf(File.join(dir, "node_modules/glob"))
|
|
|
|
Dir.chdir dir do
|
|
# balanced-match is an extraneous dependency
|
|
dep = source.dependencies.find { |dep| dep.name == "balanced-match" }
|
|
assert dep
|
|
assert_empty dep.errors
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|