# frozen_string_literal: true
require "test_helper"

describe Licensed::Configuration do
  let(:options) { {} }
  let(:config) { Licensed::Configuration.new(options) }
  let(:fixtures) { File.expand_path("../fixtures/config", __FILE__) }

  describe "load_from" do
    let(:config) { Licensed::Configuration.load_from(load_path) }
    let(:app) { config.apps.first }

    describe "a relative directory path" do
      let(:load_path) { Pathname.new(fixtures).relative_path_from(Pathname.pwd) }
      it "loads the configuration" do
        assert_equal "licensed-yml", app["name"]
      end
    end

    describe "an absolute directory path" do
      let(:load_path) { fixtures }
      it "loads a config from an absolute directory path" do
        assert_equal "licensed-yml", app["name"]
      end
    end

    describe "a relative file path" do
      let(:load_path) do
        file = File.join(fixtures, "config.yml")
        Pathname.new(file).relative_path_from(Pathname.pwd)
      end
      it "loads a config from a relative file path" do
        assert_equal "config-yml", app["name"]
      end
    end

    describe "an absolute file path" do
      let(:load_path) { File.join(fixtures, "config.yml") }
      it "loads a config from an absolute file path" do
        assert_equal "config-yml", app["name"]
      end
    end

    describe "a json configuration file" do
      let(:load_path) { File.join(fixtures, ".licensed.json") }
      it "loads json configurations" do
        assert_equal "licensed-json", app["name"]
      end
    end

    it "raises an error if a default config file is not found" do
      Dir.mktmpdir do |dir|
        assert_raises ::Licensed::Configuration::LoadError do
          Licensed::Configuration.load_from(dir)
        end
      end
    end

    it "raises an error if the config file type is not understood" do
      file = File.join(fixtures, ".licensed.unknown")
      assert_raises ::Licensed::Configuration::LoadError do
        Licensed::Configuration.load_from(file)
      end
    end
  end

  describe "apps" do
    let(:apps) do
      [
        {
          "name" => "app1",
          "override" => "override",
          "cache_path" => "app1/vendor/licenses",
          "source_path" => File.expand_path("../../", __FILE__)
        },
        {
          "name" => "app2",
          "cache_path" => "app2/vendor/licenses",
          "source_path" => File.expand_path("../../", __FILE__)
        }
      ]
    end
    let(:options) { { "apps" => apps } }
    let(:config) { Licensed::Configuration.new(options) }

    it "returns a default app if apps not specified in configuration" do
      options.delete "apps"
      assert_equal 1, config.apps.size
      app = config.apps.first
      assert_equal Pathname.pwd, app.source_path
      assert_equal app.root.join(Licensed::AppConfiguration::DEFAULT_CACHE_PATH),
                   app.cache_path
      assert_equal File.basename(Dir.pwd), app["name"]
    end

    it "expands source_path patterns in default app" do
      options.delete "apps"
      options["source_path"] = File.expand_path("../fixtures/*", __FILE__)
      expected_source_paths = Dir.glob(options["source_path"]).select { |p| File.directory?(p) }
      expected_source_paths.each do |source_path|
        app = config.apps.find { |a| a["source_path"] == source_path }
        assert app
        dir_name = File.basename(source_path)
        assert_equal app.root.join(Licensed::AppConfiguration::DEFAULT_CACHE_PATH, dir_name),
                     app.cache_path
        assert_equal dir_name, app["name"]
      end
    end

    it "returns configured apps" do
      assert_equal 2, config.apps.size
      assert_equal "app1", config.apps[0]["name"]
      assert_equal "app2", config.apps[1]["name"]

      config.apps.each do |app|
        assert_equal File.expand_path("../../", __FILE__), app["source_path"]
      end
    end

    it "includes default options" do
      options["default"] = "default"
      config.apps.each do |app|
        assert_equal "default", app["default"]
      end
    end

    it "can override default options" do
      options["default"] = "default"
      apps[0]["default"] = "override"
      assert_equal "override", config.apps[0]["default"]
    end

    it "expands patterns in configured apps" do
      apps.clear
      apps << { "source_path" => File.expand_path("../fixtures/*", __FILE__) }
      expected_source_paths = Dir.glob(apps[0]["source_path"]).select { |p| File.directory?(p) }
      expected_source_paths.each do |source_path|
        app = config.apps.find { |a| a["source_path"] == source_path }
        assert app
        dir_name = File.basename(source_path)
        assert_equal app.root.join(Licensed::AppConfiguration::DEFAULT_CACHE_PATH, dir_name),
                     app.cache_path
        assert_equal dir_name, app["name"]
      end
    end

    it "expands source_path patterns that result in a single path" do
      apps.clear
      apps << { "source_path" => File.expand_path("../../lib/*", __FILE__) }
      expected_source_paths = Dir.glob(apps[0]["source_path"]).select { |p| File.directory?(p) }
      expected_source_paths.each do |source_path|
        app = config.apps.find { |a| a["source_path"] == source_path }
        assert app
        dir_name = File.basename(source_path)
        assert_equal app.root.join(Licensed::AppConfiguration::DEFAULT_CACHE_PATH, dir_name),
                     app.cache_path
        assert_equal dir_name, app["name"]
      end
    end

    it "assigns uniqueness to explicitly configured values" do
      cache_path = ".test_licenses"
      name = "test"
      apps.clear
      apps << {
        "source_path" => File.expand_path("../fixtures/*", __FILE__),
        "cache_path" => cache_path,
        "name" => name
      }
      expected_source_paths = Dir.glob(apps[0]["source_path"]).select { |p| File.directory?(p) }
      expected_source_paths.each do |source_path|
        app = config.apps.find { |a| a["source_path"] == source_path }
        assert app
        dir_name = File.basename(source_path)
        assert_equal app.root.join(cache_path, dir_name), app.cache_path
        assert_equal "#{name}-#{dir_name}", app["name"]
      end
    end

    it "does not assign unique cache paths if shared_cache is true" do
      cache_path = ".test_licenses"
      apps.clear
      apps << {
        "source_path" => File.expand_path("../fixtures/*", __FILE__),
        "cache_path" => cache_path,
        "shared_cache" => true
      }
      expected_source_paths = Dir.glob(apps[0]["source_path"]).select { |p| File.directory?(p) }
      expected_source_paths.each do |source_path|
        app = config.apps.find { |a| a["source_path"] == source_path }
        assert app
        assert_equal app.root.join(cache_path), app.cache_path
      end
    end

    it "does not apply an inherited shared_cache setting to an app-configured cache path" do
      cache_path = ".test_licenses"
      apps.clear
      apps << {
        "source_path" => File.expand_path("../fixtures/*", __FILE__),
        "cache_path" => cache_path
      }
      options["shared_cache"] = true

      expected_source_paths = Dir.glob(apps[0]["source_path"]).select { |p| File.directory?(p) }
      expected_source_paths.each do |source_path|
        app = config.apps.find { |a| a["source_path"] == source_path }
        assert app
        dir_name = File.basename(source_path)
        assert_equal app.root.join(cache_path, dir_name), app.cache_path
      end
    end
  end

  describe "with an array of source_paths" do
    it "handles empty arrays" do
      options["source_path"] = []
      assert_equal 1, config.apps.count
      assert_equal Licensed::AppConfiguration.root_for(options), config.apps.first.source_path.to_s
    end

    it "handles arrays with nil values" do
      options["source_path"] = [
        File.expand_path("../fixtures/bundler", __FILE__),
        nil
      ]
      assert_equal 1, config.apps.count
      assert_equal File.expand_path("../fixtures/bundler", __FILE__), config.apps.first.source_path.to_s
    end

    it "handles absolute paths" do
      options["source_path"] = [
        File.expand_path("../fixtures/bundler", __FILE__),
        File.expand_path("../fixtures/go", __FILE__)
      ]
      options["source_path"].each do |source_path|
        assert config.apps.find { |a| a.source_path.to_s == source_path }
      end
    end

    it "handles paths relative to the application root directory" do
      options["source_path"] = [
        "test/fixtures/bundler",
        "test/fixtures/go",
      ]
      options["source_path"].each do |relative_path|
        expected_source_path = File.join(Licensed::AppConfiguration.root_for(options), relative_path)
        assert config.apps.find { |a| a.source_path.to_s == expected_source_path }
      end
    end

    it "handles glob patterns" do
      excluded_path = File.expand_path("../fixtures/bundler", __FILE__)
      options["source_path"] = [
        File.expand_path("../fixtures/*", __FILE__),
        "!#{excluded_path}"
      ]
      refute config.apps.find { |a| a.source_path.to_s == excluded_path }
      assert config.apps.find { |a| a.source_path.to_s == File.expand_path("../fixtures/go", __FILE__) }
    end
  end
end

describe Licensed::AppConfiguration do
  let(:options) { { "source_path" => Dir.pwd } }
  let(:config) { Licensed::AppConfiguration.new(options) }
  let(:fixtures) { File.expand_path("../fixtures/config", __FILE__) }

  it "raises an error if source_path is not set" do
    assert_raises ::Licensed::Configuration::LoadError do
      Licensed::AppConfiguration.new
    end
  end

  describe "ignore" do
    let(:package) { { "type" => "go", "name" => "github.com/github/licensed/package", "version" => "1.0.0"  } }

    it "marks the dependency as ignored" do
      assert_nil config.dig("ignored", package["type"])
      config.ignore package
      assert_equal [package["name"]], config.dig("ignored", package["type"])
    end

    it "marks the dependency ignored at the specific version" do
      assert_nil config.dig("ignored", package["type"])
      config.ignore package, at_version: true
      assert_equal ["#{package["name"]}@#{package["version"]}"], config.dig("ignored", package["type"])
    end
  end

  describe "ignored?" do
    let(:package) { { "type" => "go", "name" => "github.com/github/licensed/package", "version" => "1.0.0"  } }

    it "matches exact name matches" do
      refute config.ignored?(package)
      config.ignore package
      assert config.ignored?(package)
    end

    it "does not match trailing ** to multiple path segments" do
      refute config.ignored?(package)
      config.ignore package.merge("name" => "github.com/github/**")
      refute config.ignored?(package)
    end

    it "matches internal ** to multiple path segments" do
      refute config.ignored?(package)
      config.ignore package.merge("name" => "github.com/**/package")
      assert config.ignored?(package)
    end

    it "matches trailing * to single path segment" do
      refute config.ignored?(package)
      config.ignore package.merge("name" => "github.com/github/licensed/*")
      assert config.ignored?(package)
    end

    it "maches internal * to single path segment" do
      refute config.ignored?(package)
      config.ignore package.merge("name" => "github.com/*/licensed/package")
      assert config.ignored?(package)
    end

    it "matches multiple globstars in a pattern" do
      refute config.ignored?(package)
      config.ignore package.merge("name" => "**/licensed/*")
      assert config.ignored?(package)
    end

    it "does not match * to multiple path segments" do
      refute config.ignored?(package)
      config.ignore package.merge("name" => "github.com/github/*")
      refute config.ignored?(package)
    end

    it "is case insensitive" do
      refute config.ignored?(package)
      config.ignore package.merge("name" => "GITHUB.com/github/**")
      refute config.ignored?(package)
    end

    describe "with required_version" do
      it "matches a dependency ignored at the same version" do
        config.ignore package, at_version: true
        assert config.ignored?(package, require_version: true)
      end

      it "does not match a dependency not ignored at a version" do
        config.ignore package
        refute config.ignored?(package, require_version: true)
      end

      it "does not match a dependency ignored at a different version" do
        config.ignore package.merge("version" => "1.0.1"), at_version: true
        refute config.ignored?(package, require_version: true)
      end

      it "matches a dependency ignored at *" do
        config.ignore package.merge("version" => "*"), at_version: true
        assert config.ignored?(package, require_version: true)
      end

      it "matches a dependency ignored at a requirement pattern" do
        config.ignore package.merge("version" => ">= 1.0.0"), at_version: true
        assert config.ignored?(package, require_version: true)
      end

      it "does not match a dependency without a version" do
        config.ignore package, at_version: true
        package.delete("version")
        refute config.ignored?(package, require_version: true)
      end

      it "matches a dependency ignored at a matching non-gem requirement value" do
        package["version"] = "abcdef"
        config.ignore package, at_version: true
        assert config.ignored?(package, require_version: true)
      end
    end

    describe "without required_version" do
      it "matches a dependency ignored at the same version" do
        config.ignore package, at_version: true
        assert config.ignored?(package)
      end

      it "matches a dependency not ignored at a version" do
        config.ignore package
        assert config.ignored?(package)
      end

      it "does not match a dependency ignored at a different version" do
        config.ignore package.merge("version" => "1.0.1"), at_version: true
        refute config.ignored?(package)
      end

      it "matches a dependency ignored at *" do
        config.ignore package.merge("version" => "*"), at_version: true
        assert config.ignored?(package)
      end

      it "matches a dependency ignored at a requirement pattern" do
        config.ignore package.merge("version" => ">= 1.0.0, < 2.0.0"), at_version: true
        assert config.ignored?(package)
      end

      it "matches a dependency without a version" do
        config.ignore package, at_version: true
        package.delete("version")
        assert config.ignored?(package)
      end
    end
  end

  describe "review" do
    let(:package) { { "type" => "go", "name" => "github.com/github/licensed/package", "version" => "1.0.0" } }

    it "marks the dependency as reviewed" do
      assert_nil config.dig("reviewed", package["type"])
      config.review package
      assert_equal [package["name"]], config.dig("reviewed", package["type"])
    end

    it "marks the dependency reviewed at the specific version" do
      assert_nil config.dig("reviewed", package["type"])
      config.review package, at_version: true
      assert_equal ["#{package["name"]}@#{package["version"]}"], config.dig("reviewed", package["type"])
    end
  end

  describe "reviewed?" do
    let(:package) { { "type" => "go", "name" => "github.com/github/licensed/package", "version" => "1.0.0" } }

    it "matches exact name matches" do
      refute config.reviewed?(package)
      config.review package
      assert config.reviewed?(package)
    end

    it "does not match trailing ** to multiple path segments" do
      refute config.reviewed?(package)
      config.review package.merge("name" => "github.com/github/**")
      refute config.reviewed?(package)
    end

    it "matches internal ** to multiple path segments" do
      refute config.reviewed?(package)
      config.review package.merge("name" => "github.com/**/package")
      assert config.reviewed?(package)
    end

    it "matches trailing * to single path segment" do
      refute config.reviewed?(package)
      config.review package.merge("name" => "github.com/github/licensed/*")
      assert config.reviewed?(package)
    end

    it "maches internal * to single path segment" do
      refute config.reviewed?(package)
      config.review package.merge("name" => "github.com/*/licensed/package")
      assert config.reviewed?(package)
    end

    it "matches multiple globstars in a pattern" do
      refute config.reviewed?(package)
      config.review package.merge("name" => "**/licensed/*")
      assert config.reviewed?(package)
    end

    it "does not match * to multiple path segments" do
      refute config.reviewed?(package)
      config.review package.merge("name" => "github.com/github/*")
      refute config.reviewed?(package)
    end

    it "is case insensitive" do
      refute config.reviewed?(package)
      config.review package.merge("name" => "GITHUB.com/github/**")
      refute config.reviewed?(package)
    end

    describe "with required_version" do
      it "matches a dependency reviewed at the same version" do
        config.review package, at_version: true
        assert config.reviewed?(package, require_version: true)
      end

      it "does not match a dependency not reviewed at a version" do
        config.review package
        refute config.reviewed?(package, require_version: true)
      end

      it "does not match a dependency reviewed at a different version" do
        config.review package.merge("version" => "1.0.1"), at_version: true
        refute config.reviewed?(package, require_version: true)
      end

      it "matches a dependency reviewed at *" do
        config.review package.merge("version" => "*"), at_version: true
        assert config.reviewed?(package, require_version: true)
      end

      it "matches a dependency reviewed at a requirement pattern" do
        config.review package.merge("version" => ">= 1.0.0, < 2.0.0"), at_version: true
        assert config.reviewed?(package, require_version: true)
      end

      it "does not match a dependency without a version" do
        config.review package, at_version: true
        package.delete("version")
        refute config.reviewed?(package, require_version: true)
      end

      it "matches a dependency reviewed at a matching non-gem requirement value" do
        package["version"] = "abcdef"
        config.review package, at_version: true
        assert config.reviewed?(package, require_version: true)
      end
    end

    describe "without required_version" do
      it "matches a dependency reviewed at the same version" do
        config.review package, at_version: true
        assert config.reviewed?(package)
      end

      it "matches a dependency not reviewed at a version" do
        config.review package
        assert config.reviewed?(package)
      end

      it "does not match a dependency reviewed at a different version" do
        config.review package.merge("version" => "1.0.1"), at_version: true
        refute config.reviewed?(package)
      end

      it "matches a dependency reviewed at *" do
        config.review package.merge("version" => "*"), at_version: true
        assert config.reviewed?(package.merge("version" => "1.0.1"))
      end

      it "matches a dependency reviewed at a requirement pattern" do
        config.review package.merge("version" => ">= 1.0.0"), at_version: true
        assert config.reviewed?(package)
      end

      it "matches a dependency without a version" do
        config.review package, at_version: true
        package.delete("version")
        assert config.reviewed?(package)
      end
    end
  end

  describe "reviewed_versions" do
    it "returns an array of all matching reviewed dependency names at versions" do
      packages = [
        { "type" => "npm", "name" => "@github/package", "version" => "1.0.0" },
        { "type" => "npm", "name" => "@github/package", "version" => "1.0.1" }
      ]

      packages.each { |p| config.review(p, at_version: true) }
      assert_equal packages.map { |p| "#{p["name"]}@#{p["version"]}" },
        config.reviewed_versions({ "type" => "npm", "name" => "@github/package" })
    end

    it "does not return reviewed dependencies without version" do
      package = { "type" => "npm", "name" => "@github/package", "version" => "1.0.0" }
      config.review(package)
      assert_empty config.reviewed_versions(package)
    end
  end

  describe "allow" do
    it "marks the license as allowed" do
      refute config.allowed?("mit")
      config.allow "mit"
      assert config.allowed?("mit")
    end
  end

  describe "enabled?" do
    it "returns true if source type is enabled" do
      config["sources"]["npm"] = true
      assert config.enabled?("npm")
    end

    it "returns false if source type is disabled" do
      config["sources"]["npm"] = false
      refute config.enabled?("npm")
    end

    it "returns true if no source types are configured" do
      Licensed::Sources::Source.sources.each do |source|
        assert config.enabled?(source.type)
      end
    end

    it "returns true for source types that are not disabled, if no sources are configured enabled" do
      config["sources"]["npm"] = false
      Licensed::Sources::Source.sources - [Licensed::Sources::NPM].each do |source_type|
        assert config.enabled?(source_type)
      end
    end

    it "returns false for source types that are not enabled, if any sources are configured enabled" do
      config["sources"]["npm"] = true
      Licensed::Sources::Source.sources - [Licensed::Sources::NPM].each do |source_type|
        refute config.enabled?(source_type)
      end
    end
  end

  describe "root" do
    it "can be set to a path from a configuration file" do
      file = File.join(fixtures, "root.yml")
      config = Licensed::Configuration.load_from(file).apps.first
      assert_equal File.expand_path("../..", fixtures), config.root.to_s
    end

    it "can be set to true in a configuration file" do
      file = File.join(fixtures, "root_at_configuration.yml")
      config = Licensed::Configuration.load_from(file).apps.first
      assert_equal fixtures, config.root.to_s
    end

    it "defaults to the git repository root" do
      assert_equal Licensed::Git.repository_root, config.root.to_s
    end
  end

  describe "name" do
    it "raises an error if name.generator is not an allowed value" do
      options["name"] = { "generator" => true }
      options["source_path"] = "lib/licensed/sources"
      error = assert_raises Licensed::Configuration::LoadError do
        config
      end

      assert_includes error.message, "Invalid value configured for name.generator: true"
    end

    it "uses the source path directory name when a name value is not set" do
      assert_equal "licensed", config["name"]
    end

    it "uses the source path directory name when name.generator is not set" do
      options["name"] = {}
      assert_equal "licensed", config["name"]
    end

    describe "with directory_name generator" do
      it "uses the source path directory name" do
        options["name"] = { "generator" => "directory_name" }
        assert_equal "licensed", config["name"]
      end
    end

    describe "with relative_path generator" do
      it "generates a name from relative source path parts" do
        options["name"] = { "generator" => "relative_path" }
        options["source_path"] = "lib/licensed/sources"
        assert_equal "lib-licensed-sources", config["name"]
      end

      it "uses a configured separator when creating a name from relative source path parts" do
        options["name"] = { "generator" => "relative_path", "separator" => "." }
        options["source_path"] = "lib/licensed/sources"
        assert_equal "lib.licensed.sources", config["name"]
      end

      it "uses a configured path depth when creating a name from relative source path parts" do
        options["name"] = { "generator" => "relative_path", "depth" => 2 }
        options["source_path"] = "lib/licensed/sources"
        assert_equal "licensed-sources", config["name"]
      end

      it "handles equivalent root and source paths" do
        options["name"] = { "generator" => "relative_path" }
        options["root"] = Licensed::Git.repository_root
        options["source_path"] = Licensed::Git.repository_root

        assert_equal config["name"], "licensed"
      end

      it "uses all path parts when depth is larger than the number of path parts" do
        options["name"] = { "generator" => "relative_path", "depth" => 4 }
        options["source_path"] = "lib/licensed/sources"
        assert_equal "lib-licensed-sources", config["name"]
      end

      it "raises an error when generating a relative path name if source_path is not a descendant of the app root" do
        options["name"] = { "generator" => "relative_path" }
        options["root"] = Licensed::Git.repository_root
        options["source_path"] = "/bad/test/path"
        error = assert_raises Licensed::Configuration::LoadError do
          config
        end

        assert_equal error.message,
          "source_path must be a descendent of the app root to generate an app name from the relative source_path"
      end

      it "raises an error when the configuration value is less than 0" do
        options["name"] = { "generator" => "relative_path", "depth" => -1 }
        options["source_path"] = "lib/licensed/sources"
        error = assert_raises Licensed::Configuration::LoadError do
          config
        end

        assert_equal error.message,
          "name.depth configuration value cannot be less than -1"
      end
    end
  end

  describe "cache_path" do
    it "sets a default cache path with the app name if not configured" do
      assert_equal config.root.join(Licensed::AppConfiguration::DEFAULT_CACHE_PATH, config["name"]),
                   config.cache_path
    end

    it "appends the app name to an inherited cache path" do
      config = Licensed::AppConfiguration.new(
        { "source_path" => Dir.pwd },
        { "cache_path" => "vendor/cache" }
      )
      assert_equal config.root.join("vendor/cache", config["name"]), config.cache_path
    end

    it "does not append the app name to an explicit cache path" do
      config = Licensed::AppConfiguration.new(
        { "source_path" => Dir.pwd, "cache_path" => "vendor/cache" }
      )
      assert_equal config.root.join("vendor/cache"), config.cache_path
      refute config.cache_path.to_s.end_with? config["name"]
    end

    it "applies an inherited shared_cache setting to an inherited cache path" do
      config = Licensed::AppConfiguration.new(
        { "source_path" => Dir.pwd },
        { "shared_cache" => true, "cache_path" => "vendor/cache" }
      )

      assert_equal config.root.join("vendor/cache"), config.cache_path
      refute config.cache_path.to_s.end_with? config["name"]
    end

    it "does not apply an inherited shared_cache setting to the default cache path" do
      config = Licensed::AppConfiguration.new(
        { "source_path" => Dir.pwd },
        { "shared_cache" => true }
      )

      assert_equal config.root.join(Licensed::AppConfiguration::DEFAULT_CACHE_PATH, config["name"]),
                   config.cache_path
    end
  end

  describe "additional_terms_for_dependency" do
    it "returns an empty array if additional terms aren't configured for a dependency" do
      assert_empty config.additional_terms_for_dependency("type" => "test", "name" => "test")
    end

    it "returns an array of absolute paths to amendment files for a string configuration" do
      Dir.mktmpdir do |dir|
        Dir.chdir dir do
          options["additional_terms"] = { "test" => { "test" => "amendment.txt" } }
          File.write "amendment.txt", "amendment"

          path = File.join(Dir.pwd, "amendment.txt")
          assert_equal [path], config.additional_terms_for_dependency("type" => "test", "name" => "test")
        end
      end
    end

    it "returns an array of absolute paths to amendment files for an array configuration" do
      Dir.mktmpdir do |dir|
        Dir.chdir dir do
          options["additional_terms"] = { "test" => { "test" => ["amendment.txt"] } }
          File.write "amendment.txt", "amendment"

          path = File.join(Dir.pwd, "amendment.txt")
          assert_equal [path], config.additional_terms_for_dependency("type" => "test", "name" => "test")
        end
      end
    end

    it "strips any amendment paths for files that don't exist" do
      options["additional_terms"] = { "test" => { "test" => "amendment.txt" } }
      assert_empty config.additional_terms_for_dependency("type" => "test", "name" => "test")
    end

    it "expands glob patterns" do
      Dir.mktmpdir do |dir|
        Dir.chdir dir do
          Dir.mkdir "amendments"

          options["additional_terms"] = { "test" => { "test" => "amendments/*" } }
          paths = 2.times.map do |index|
            path = "amendments/amendment-#{index}.txt"
            File.write path, "amendment-#{index}"
            File.join(Dir.pwd, path)
          end

          assert_equal paths, config.additional_terms_for_dependency("type" => "test", "name" => "test")
        end
      end
    end
  end
end
