diff options
| author | Naoto Kaneko | 2017-02-27 14:23:53 +0900 |
|---|---|---|
| committer | Naoto Kaneko | 2017-02-27 14:23:53 +0900 |
| commit | 928eaca26720fd38b07c1e7df3f9f567477d48db (patch) | |
| tree | c08fd030cca960e74bab72b59ce057684e554334 /Library/Homebrew/test | |
| parent | ccc9b2dc6dc27026673db3c8871c691be9541342 (diff) | |
| parent | e3f4701f385c286a2cc72c5d07870cc9a6ce0bf4 (diff) | |
| download | brew-928eaca26720fd38b07c1e7df3f9f567477d48db.tar.bz2 | |
Merge branch 'master' into exclude-executable-metafiles
Added tests in keg_test and pathname_test was
moved into keg_spec and pathname_spec.
Diffstat (limited to 'Library/Homebrew/test')
158 files changed, 6170 insertions, 5083 deletions
diff --git a/Library/Homebrew/test/ARGV_spec.rb b/Library/Homebrew/test/ARGV_spec.rb index bcb7c3f70..89ef9cabc 100644 --- a/Library/Homebrew/test/ARGV_spec.rb +++ b/Library/Homebrew/test/ARGV_spec.rb @@ -1,7 +1,7 @@ require "extend/ARGV" describe HomebrewArgvExtension do - subject { argv.extend(HomebrewArgvExtension) } + subject { argv.extend(described_class) } let(:argv) { ["mxcl"] } describe "#formulae" do diff --git a/Library/Homebrew/test/ENV_spec.rb b/Library/Homebrew/test/ENV_spec.rb new file mode 100644 index 000000000..7b50ca1d4 --- /dev/null +++ b/Library/Homebrew/test/ENV_spec.rb @@ -0,0 +1,189 @@ +require "extend/ENV" + +shared_examples EnvActivation do + subject { env.extend(described_class) } + let(:env) { {}.extend(EnvActivation) } + + it "supports switching compilers" do + subject.clang + expect(subject["LD"]).to be nil + expect(subject["CC"]).to eq(subject["OBJC"]) + end + + describe "#with_build_environment" do + it "restores the environment" do + before = subject.dup + + subject.with_build_environment do + subject["foo"] = "bar" + end + + expect(subject["foo"]).to be nil + expect(subject).to eq(before) + end + + it "ensures the environment is restored" do + before = subject.dup + + expect { + subject.with_build_environment do + subject["foo"] = "bar" + raise StandardError + end + }.to raise_error(StandardError) + + expect(subject["foo"]).to be nil + expect(subject).to eq(before) + end + + it "returns the value of the block" do + expect(subject.with_build_environment { 1 }).to eq(1) + end + + it "does not mutate the interface" do + expected = subject.methods + + subject.with_build_environment do + expect(subject.methods).to eq(expected) + end + + expect(subject.methods).to eq(expected) + end + end + + describe "#append" do + it "appends to an existing key" do + subject["foo"] = "bar" + subject.append "foo", "1" + expect(subject["foo"]).to eq("bar 1") + end + + it "appends to an existing empty key" do + subject["foo"] = "" + subject.append "foo", "1" + expect(subject["foo"]).to eq("1") + end + + it "appends to a non-existant key" do + subject.append "foo", "1" + expect(subject["foo"]).to eq("1") + end + + # NOTE: this may be a wrong behavior; we should probably reject objects that + # do not respond to #to_str. For now this documents existing behavior. + it "coerces a value to a string" do + subject.append "foo", 42 + expect(subject["foo"]).to eq("42") + end + end + + describe "#prepend" do + it "prepends to an existing key" do + subject["foo"] = "bar" + subject.prepend "foo", "1" + expect(subject["foo"]).to eq("1 bar") + end + + it "prepends to an existing empty key" do + subject["foo"] = "" + subject.prepend "foo", "1" + expect(subject["foo"]).to eq("1") + end + + it "prepends to a non-existant key" do + subject.prepend "foo", "1" + expect(subject["foo"]).to eq("1") + end + + # NOTE: this may be a wrong behavior; we should probably reject objects that + # do not respond to #to_str. For now this documents existing behavior. + it "coerces a value to a string" do + subject.prepend "foo", 42 + expect(subject["foo"]).to eq("42") + end + end + + describe "#append_path" do + it "appends to a path" do + subject.append_path "FOO", "/usr/bin" + expect(subject["FOO"]).to eq("/usr/bin") + + subject.append_path "FOO", "/bin" + expect(subject["FOO"]).to eq("/usr/bin#{File::PATH_SEPARATOR}/bin") + end + end + + describe "#prepend_path" do + it "prepends to a path" do + subject.prepend_path "FOO", "/usr/bin" + expect(subject["FOO"]).to eq("/usr/bin") + + subject.prepend_path "FOO", "/bin" + expect(subject["FOO"]).to eq("/bin#{File::PATH_SEPARATOR}/usr/bin") + end + end + + describe "#compiler" do + it "allows switching compilers" do + [:clang, :gcc_4_2, :gcc_4_0].each do |compiler| + subject.public_send(compiler) + expect(subject.compiler).to eq(compiler) + end + end + end + + example "deparallelize_block_form_restores_makeflags" do + subject["MAKEFLAGS"] = "-j4" + + subject.deparallelize do + expect(subject["MAKEFLAGS"]).to be nil + end + + expect(subject["MAKEFLAGS"]).to eq("-j4") + end +end + +describe Stdenv do + include_examples EnvActivation +end + +describe Superenv do + include_examples EnvActivation + + it "initializes deps" do + expect(subject.deps).to eq([]) + expect(subject.keg_only_deps).to eq([]) + end + + describe "#cxx11" do + it "raises an error when the compiler isn't supported" do + %w[gcc gcc-4.7].each do |compiler| + subject["HOMEBREW_CC"] = compiler + + expect { subject.cxx11 } + .to raise_error(/The selected compiler doesn't support C\+\+11:/) + + expect(subject["HOMEBREW_CCCFG"]).to be nil + end + end + + it "supports gcc-5" do + subject["HOMEBREW_CC"] = "gcc-5" + subject.cxx11 + expect(subject["HOMEBREW_CCCFG"]).to include("x") + end + + example "supports gcc-6" do + subject["HOMEBREW_CC"] = "gcc-6" + subject.cxx11 + expect(subject["HOMEBREW_CCCFG"]).to include("x") + end + + it "supports clang" do + subject["HOMEBREW_CC"] = "clang" + subject.cxx11 + expect(subject["HOMEBREW_CCCFG"]).to include("x") + expect(subject["HOMEBREW_CCCFG"]).to include("g") + end + end +end diff --git a/Library/Homebrew/test/ENV_test.rb b/Library/Homebrew/test/ENV_test.rb deleted file mode 100644 index cbfd01e25..000000000 --- a/Library/Homebrew/test/ENV_test.rb +++ /dev/null @@ -1,202 +0,0 @@ -require "testing_env" -require "extend/ENV" -require "testing_env" - -class IntegrationCommandTestEnv < IntegrationCommandTestCase - def test_env - assert_match(/CMAKE_PREFIX_PATH="#{Regexp.escape(HOMEBREW_PREFIX)}[:"]/, - cmd("--env")) - end - - def test_env_fish - assert_match(/set [-]gx CMAKE_PREFIX_PATH "#{Regexp.quote(HOMEBREW_PREFIX.to_s)}"/, - cmd("--env", "--shell=fish")) - end - - def test_env_csh - assert_match(/setenv CMAKE_PREFIX_PATH #{Regexp.quote(HOMEBREW_PREFIX.to_s)};/, - cmd("--env", "--shell=tcsh")) - end - - def test_env_bash - assert_match(/export CMAKE_PREFIX_PATH="#{Regexp.quote(HOMEBREW_PREFIX.to_s)}"/, - cmd("--env", "--shell=bash")) - end - - def test_env_plain - assert_match(/CMAKE_PREFIX_PATH: #{Regexp.quote(HOMEBREW_PREFIX)}/, - cmd("--env", "--plain")) - end -end - -module SharedEnvTests - def setup - super - @env = {}.extend(EnvActivation) - end - - def test_switching_compilers - @env.clang - assert_nil @env["LD"] - assert_equal @env["OBJC"], @env["CC"] - end - - def test_with_build_environment_restores_env - before = @env.dup - @env.with_build_environment do - @env["foo"] = "bar" - end - assert_nil @env["foo"] - assert_equal before, @env - end - - def test_with_build_environment_ensures_env_restored - before = @env.dup - begin - @env.with_build_environment do - @env["foo"] = "bar" - raise Exception - end - rescue Exception - end - assert_nil @env["foo"] - assert_equal before, @env - end - - def test_with_build_environment_returns_block_value - assert_equal 1, @env.with_build_environment { 1 } - end - - def test_with_build_environment_does_not_mutate_interface - expected = @env.methods - @env.with_build_environment { assert_equal expected, @env.methods } - assert_equal expected, @env.methods - end - - def test_append_existing_key - @env["foo"] = "bar" - @env.append "foo", "1" - assert_equal "bar 1", @env["foo"] - end - - def test_append_existing_key_empty - @env["foo"] = "" - @env.append "foo", "1" - assert_equal "1", @env["foo"] - end - - def test_append_missing_key - @env.append "foo", "1" - assert_equal "1", @env["foo"] - end - - def test_prepend_existing_key - @env["foo"] = "bar" - @env.prepend "foo", "1" - assert_equal "1 bar", @env["foo"] - end - - def test_prepend_existing_key_empty - @env["foo"] = "" - @env.prepend "foo", "1" - assert_equal "1", @env["foo"] - end - - def test_prepend_missing_key - @env.prepend "foo", "1" - assert_equal "1", @env["foo"] - end - - # NOTE: this may be a wrong behavior; we should probably reject objects that - # do not respond to #to_str. For now this documents existing behavior. - def test_append_coerces_value_to_string - @env.append "foo", 42 - assert_equal "42", @env["foo"] - end - - def test_prepend_coerces_value_to_string - @env.prepend "foo", 42 - assert_equal "42", @env["foo"] - end - - def test_append_path - @env.append_path "FOO", "/usr/bin" - assert_equal "/usr/bin", @env["FOO"] - @env.append_path "FOO", "/bin" - assert_equal "/usr/bin#{File::PATH_SEPARATOR}/bin", @env["FOO"] - end - - def test_prepend_path - @env.prepend_path "FOO", "/usr/bin" - assert_equal "/usr/bin", @env["FOO"] - @env.prepend_path "FOO", "/bin" - assert_equal "/bin#{File::PATH_SEPARATOR}/usr/bin", @env["FOO"] - end - - def test_switching_compilers_updates_compiler - [:clang, :gcc_4_2, :gcc_4_0].each do |compiler| - @env.send(compiler) - assert_equal compiler, @env.compiler - end - end - - def test_deparallelize_block_form_restores_makeflags - @env["MAKEFLAGS"] = "-j4" - @env.deparallelize do - assert_nil @env["MAKEFLAGS"] - end - assert_equal "-j4", @env["MAKEFLAGS"] - end -end - -class StdenvTests < Homebrew::TestCase - include SharedEnvTests - - def setup - super - @env.extend(Stdenv) - end -end - -class SuperenvTests < Homebrew::TestCase - include SharedEnvTests - - def setup - super - @env.extend(Superenv) - end - - def test_initializes_deps - assert_equal [], @env.deps - assert_equal [], @env.keg_only_deps - end - - def test_unsupported_cxx11 - %w[gcc gcc-4.7].each do |compiler| - @env["HOMEBREW_CC"] = compiler - assert_raises do - @env.cxx11 - end - refute_match "x", @env["HOMEBREW_CCCFG"] - end - end - - def test_supported_cxx11_gcc_5 - @env["HOMEBREW_CC"] = "gcc-5" - @env.cxx11 - assert_match "x", @env["HOMEBREW_CCCFG"] - end - - def test_supported_cxx11_gcc_6 - @env["HOMEBREW_CC"] = "gcc-6" - @env.cxx11 - assert_match "x", @env["HOMEBREW_CCCFG"] - end - - def test_supported_cxx11_clang - @env["HOMEBREW_CC"] = "clang" - @env.cxx11 - assert_match "x", @env["HOMEBREW_CCCFG"] - assert_match "g", @env["HOMEBREW_CCCFG"] - end -end diff --git a/Library/Homebrew/test/audit_test.rb b/Library/Homebrew/test/audit_test.rb index 9165edef1..66e5af567 100644 --- a/Library/Homebrew/test/audit_test.rb +++ b/Library/Homebrew/test/audit_test.rb @@ -419,9 +419,8 @@ class FormulaAuditorTests < Homebrew::TestCase EOS fa.audit_homepage - assert_equal ["The homepage should start with http or https " \ - "(URL is #{fa.formula.homepage}).", "The homepage #{fa.formula.homepage} is not reachable " \ - "(HTTP status code 000)"], fa.problems + assert_equal ["The homepage should start with http or https (URL is #{fa.formula.homepage})."], + fa.problems formula_homepages = { "bar" => "http://www.freedesktop.org/wiki/bar", @@ -466,4 +465,49 @@ class FormulaAuditorTests < Homebrew::TestCase end end end + + def test_audit_without_homepage + fa = formula_auditor "foo", <<-EOS.undent, online: true + class Foo < Formula + url "http://example.com/foo-1.0.tgz" + end + EOS + + fa.audit_homepage + assert_match "Formula should have a homepage.", fa.problems.first + end + + def test_audit_xcodebuild_suggests_symroot + fa = formula_auditor "foo", <<-EOS.undent + class Foo < Formula + url "http://example.com/foo-1.0.tgz" + homepage "http://example.com" + + def install + xcodebuild "-project", "meow.xcodeproject" + end + end + EOS + + fa.audit_text + + assert_match 'xcodebuild should be passed an explicit "SYMROOT"', fa.problems.first + end + + def test_audit_bare_xcodebuild_suggests_symroot_also + fa = formula_auditor "foo", <<-EOS.undent + class Foo < Formula + url "http://example.com/foo-1.0.tgz" + homepage "http://example.com" + + def install + xcodebuild + end + end + EOS + + fa.audit_text + + assert_match 'xcodebuild should be passed an explicit "SYMROOT"', fa.problems.first + end end diff --git a/Library/Homebrew/test/bottle_test.rb b/Library/Homebrew/test/bottle_test.rb deleted file mode 100644 index 7981ccf79..000000000 --- a/Library/Homebrew/test/bottle_test.rb +++ /dev/null @@ -1,21 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestBottle < IntegrationCommandTestCase - def test_bottle - cmd("install", "--build-bottle", testball) - assert_match "Formula not from core or any taps", - cmd_fail("bottle", "--no-rebuild", testball) - - setup_test_formula "testball" - - # `brew bottle` should not fail with dead symlink - # https://github.com/Homebrew/legacy-homebrew/issues/49007 - (HOMEBREW_CELLAR/"testball/0.1").cd do - FileUtils.ln_s "not-exist", "symlink" - end - assert_match(/testball-0\.1.*\.bottle\.tar\.gz/, - cmd("bottle", "--no-rebuild", "testball")) - ensure - FileUtils.rm_f Dir["testball-0.1*.bottle.tar.gz"] - end -end diff --git a/Library/Homebrew/test/build_options_spec.rb b/Library/Homebrew/test/build_options_spec.rb new file mode 100644 index 000000000..5acc12f30 --- /dev/null +++ b/Library/Homebrew/test/build_options_spec.rb @@ -0,0 +1,52 @@ +require "build_options" +require "options" + +RSpec::Matchers.alias_matcher :be_built_with, :be_with +RSpec::Matchers.alias_matcher :be_built_without, :be_without + +describe BuildOptions do + subject { described_class.new(args, opts) } + let(:bad_build) { described_class.new(bad_args, opts) } + let(:args) { Options.create(%w[--with-foo --with-bar --without-qux]) } + let(:opts) { Options.create(%w[--with-foo --with-bar --without-baz --without-qux]) } + let(:bad_args) { Options.create(%w[--with-foo --with-bar --without-bas --without-qux --without-abc]) } + + specify "#include?" do + expect(subject).to include("with-foo") + expect(subject).not_to include("with-qux") + expect(subject).not_to include("--with-foo") + end + + specify "#with?" do + expect(subject).to be_built_with("foo") + expect(subject).to be_built_with("bar") + expect(subject).to be_built_with("baz") + end + + specify "#without?" do + expect(subject).to be_built_without("qux") + expect(subject).to be_built_without("xyz") + end + + specify "#used_options" do + expect(subject.used_options).to include("--with-foo") + expect(subject.used_options).to include("--with-bar") + end + + specify "#unused_options" do + expect(subject.unused_options).to include("--without-baz") + end + + specify "#invalid_options" do + expect(subject.invalid_options).to be_empty + expect(bad_build.invalid_options).to include("--without-bas") + expect(bad_build.invalid_options).to include("--without-abc") + expect(bad_build.invalid_options).not_to include("--with-foo") + expect(bad_build.invalid_options).not_to include("--with-baz") + end + + specify "#invalid_option_names" do + expect(subject.invalid_option_names).to be_empty + expect(bad_build.invalid_option_names).to eq(%w[--without-abc --without-bas]) + end +end diff --git a/Library/Homebrew/test/build_options_test.rb b/Library/Homebrew/test/build_options_test.rb deleted file mode 100644 index 05e7ccd94..000000000 --- a/Library/Homebrew/test/build_options_test.rb +++ /dev/null @@ -1,50 +0,0 @@ -require "testing_env" -require "build_options" -require "options" - -class BuildOptionsTests < Homebrew::TestCase - def setup - super - args = Options.create(%w[--with-foo --with-bar --without-qux]) - opts = Options.create(%w[--with-foo --with-bar --without-baz --without-qux]) - @build = BuildOptions.new(args, opts) - bad_args = Options.create(%w[--with-foo --with-bar --without-bas --without-qux --without-abc]) - @bad_build = BuildOptions.new(bad_args, opts) - end - - def test_include - assert_includes @build, "with-foo" - refute_includes @build, "with-qux" - refute_includes @build, "--with-foo" - end - - def test_with_without - assert @build.with?("foo") - assert @build.with?("bar") - assert @build.with?("baz") - assert @build.without?("qux") - assert @build.without?("xyz") - end - - def test_used_options - assert_includes @build.used_options, "--with-foo" - assert_includes @build.used_options, "--with-bar" - end - - def test_unused_options - assert_includes @build.unused_options, "--without-baz" - end - - def test_invalid_options - assert_empty @build.invalid_options - assert_includes @bad_build.invalid_options, "--without-bas" - assert_includes @bad_build.invalid_options, "--without-abc" - refute_includes @bad_build.invalid_options, "--with-foo" - refute_includes @bad_build.invalid_options, "--with-baz" - end - - def test_invalid_option_names - assert_empty @build.invalid_option_names - assert_equal @bad_build.invalid_option_names, %w[--without-abc --without-bas] - end -end diff --git a/Library/Homebrew/test/bundle_test.rb b/Library/Homebrew/test/bundle_test.rb deleted file mode 100644 index ae47977d8..000000000 --- a/Library/Homebrew/test/bundle_test.rb +++ /dev/null @@ -1,22 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestBundle < IntegrationCommandTestCase - def test_bundle - needs_test_cmd_taps - setup_remote_tap("homebrew/bundle") - HOMEBREW_REPOSITORY.cd do - shutup do - system "git", "init" - system "git", "commit", "--allow-empty", "-m", "This is a test commit" - end - end - - mktmpdir do |path| - FileUtils.touch "#{path}/Brewfile" - Dir.chdir path do - assert_equal "The Brewfile's dependencies are satisfied.", - cmd("bundle", "check") - end - end - end -end diff --git a/Library/Homebrew/test/cache_formula_test.rb b/Library/Homebrew/test/cache_formula_test.rb deleted file mode 100644 index 6dcb6a745..000000000 --- a/Library/Homebrew/test/cache_formula_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestCacheFormula < IntegrationCommandTestCase - def test_cache_formula - assert_match %r{#{HOMEBREW_CACHE}/testball-}, - cmd("--cache", testball) - end -end diff --git a/Library/Homebrew/test/cache_test.rb b/Library/Homebrew/test/cache_test.rb deleted file mode 100644 index 3a9e6b011..000000000 --- a/Library/Homebrew/test/cache_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestCache < IntegrationCommandTestCase - def test_cache - assert_equal HOMEBREW_CACHE.to_s, - cmd("--cache") - end -end diff --git a/Library/Homebrew/test/cask_test.rb b/Library/Homebrew/test/cask_test.rb deleted file mode 100644 index d5b81facb..000000000 --- a/Library/Homebrew/test/cask_test.rb +++ /dev/null @@ -1,10 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestCask < IntegrationCommandTestCase - def test_cask - needs_test_cmd_taps - needs_macos - setup_remote_tap("caskroom/cask") - cmd("cask", "list", "--caskroom=#{HOMEBREW_PREFIX}/Caskroom") - end -end diff --git a/Library/Homebrew/test/cat_test.rb b/Library/Homebrew/test/cat_test.rb deleted file mode 100644 index bb37b5fde..000000000 --- a/Library/Homebrew/test/cat_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestCat < IntegrationCommandTestCase - def test_cat - formula_file = setup_test_formula "testball" - assert_equal formula_file.read.chomp, cmd("cat", "testball") - end -end diff --git a/Library/Homebrew/test/caveats_spec.rb b/Library/Homebrew/test/caveats_spec.rb new file mode 100644 index 000000000..d8be9dc52 --- /dev/null +++ b/Library/Homebrew/test/caveats_spec.rb @@ -0,0 +1,29 @@ +require "formula" +require "caveats" + +describe Caveats do + subject { described_class.new(f) } + let(:f) { formula { url "foo-1.0" } } + + specify "#f" do + expect(subject.f).to eq(f) + end + + describe "#empty?" do + it "returns true if the Formula has no caveats" do + expect(subject).to be_empty + end + + it "returns false if the Formula has caveats" do + f = formula do + url "foo-1.0" + + def caveats + "something" + end + end + + expect(described_class.new(f)).not_to be_empty + end + end +end diff --git a/Library/Homebrew/test/caveats_test.rb b/Library/Homebrew/test/caveats_test.rb deleted file mode 100644 index 3a582b907..000000000 --- a/Library/Homebrew/test/caveats_test.rb +++ /dev/null @@ -1,30 +0,0 @@ -require "testing_env" -require "formula" -require "caveats" - -class CaveatsTests < Homebrew::TestCase - def setup - super - @f = formula { url "foo-1.0" } - @c = Caveats.new @f - end - - def test_f - assert_equal @f, @c.f - end - - def test_empty? - assert @c.empty? - - f = formula do - url "foo-1.0" - - def caveats - "something" - end - end - c = Caveats.new f - - refute c.empty? - end -end diff --git a/Library/Homebrew/test/cellar_formula_test.rb b/Library/Homebrew/test/cellar_formula_test.rb deleted file mode 100644 index 38a934a7b..000000000 --- a/Library/Homebrew/test/cellar_formula_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestCellarFormula < IntegrationCommandTestCase - def test_cellar_formula - assert_match "#{HOMEBREW_CELLAR}/testball", - cmd("--cellar", testball) - end -end diff --git a/Library/Homebrew/test/cellar_test.rb b/Library/Homebrew/test/cellar_test.rb deleted file mode 100644 index 74d5389f8..000000000 --- a/Library/Homebrew/test/cellar_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestCellar < IntegrationCommandTestCase - def test_cellar - assert_equal HOMEBREW_CELLAR.to_s, - cmd("--cellar") - end -end diff --git a/Library/Homebrew/test/cleanup_test.rb b/Library/Homebrew/test/cleanup_test.rb index e6fc31dfe..bc7a6713c 100644 --- a/Library/Homebrew/test/cleanup_test.rb +++ b/Library/Homebrew/test/cleanup_test.rb @@ -5,13 +5,6 @@ require "fileutils" require "pathname" require "testing_env" -class IntegrationCommandTestCleanup < IntegrationCommandTestCase - def test_cleanup - (HOMEBREW_CACHE/"test").write "test" - assert_match "#{HOMEBREW_CACHE}/test", cmd("cleanup", "--prune=all") - end -end - class CleanupTests < Homebrew::TestCase def setup super diff --git a/Library/Homebrew/test/cmd/--cache_spec.rb b/Library/Homebrew/test/cmd/--cache_spec.rb new file mode 100644 index 000000000..fb3c9cee6 --- /dev/null +++ b/Library/Homebrew/test/cmd/--cache_spec.rb @@ -0,0 +1,15 @@ +describe "brew --cache", :integration_test do + it "print the location of Homebrew's cache when no argument is given" do + expect { brew "--cache" } + .to output("#{HOMEBREW_CACHE}\n").to_stdout + .and not_to_output.to_stderr + .and be_a_success + end + + it "prints all cache files for a given Formula" do + expect { brew "--cache", testball } + .to output(%r{#{HOMEBREW_CACHE}/testball-}).to_stdout + .and not_to_output.to_stderr + .and be_a_success + end +end diff --git a/Library/Homebrew/test/cmd/--cellar_spec.rb b/Library/Homebrew/test/cmd/--cellar_spec.rb new file mode 100644 index 000000000..6c8d7dea6 --- /dev/null +++ b/Library/Homebrew/test/cmd/--cellar_spec.rb @@ -0,0 +1,15 @@ +describe "brew --cellar", :integration_test do + it "print the location of Homebrew's Cellar when no argument is given" do + expect { brew "--cellar" } + .to output("#{HOMEBREW_CELLAR}\n").to_stdout + .and not_to_output.to_stderr + .and be_a_success + end + + it "returns the Cellar subdirectory for a given Formula" do + expect { brew "--cellar", testball } + .to output(%r{#{HOMEBREW_CELLAR}/testball}).to_stdout + .and not_to_output.to_stderr + .and be_a_success + end +end diff --git a/Library/Homebrew/test/cmd/--env_spec.rb b/Library/Homebrew/test/cmd/--env_spec.rb new file mode 100644 index 000000000..7dd84132a --- /dev/null +++ b/Library/Homebrew/test/cmd/--env_spec.rb @@ -0,0 +1,44 @@ +describe "brew --env", :integration_test do + it "prints the Homebrew build environment variables" do + expect { brew "--env" } + .to output(/CMAKE_PREFIX_PATH="#{Regexp.escape(HOMEBREW_PREFIX)}[:"]/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + end + + describe "--shell=bash" do + it "prints the Homebrew build environment variables in Bash syntax" do + expect { brew "--env", "--shell=bash" } + .to output(/export CMAKE_PREFIX_PATH="#{Regexp.quote(HOMEBREW_PREFIX.to_s)}"/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + end + end + + describe "--shell=fish" do + it "prints the Homebrew build environment variables in Fish syntax" do + expect { brew "--env", "--shell=fish" } + .to output(/set [-]gx CMAKE_PREFIX_PATH "#{Regexp.quote(HOMEBREW_PREFIX.to_s)}"/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + end + end + + describe "--shell=tcsh" do + it "prints the Homebrew build environment variables in Tcsh syntax" do + expect { brew "--env", "--shell=tcsh" } + .to output(/setenv CMAKE_PREFIX_PATH #{Regexp.quote(HOMEBREW_PREFIX.to_s)};/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + end + end + + describe "--plain" do + it "prints the Homebrew build environment variables without quotes" do + expect { brew "--env", "--plain" } + .to output(/CMAKE_PREFIX_PATH: #{Regexp.quote(HOMEBREW_PREFIX)}/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + end + end +end diff --git a/Library/Homebrew/test/cmd/--prefix_spec.rb b/Library/Homebrew/test/cmd/--prefix_spec.rb new file mode 100644 index 000000000..80ef73a97 --- /dev/null +++ b/Library/Homebrew/test/cmd/--prefix_spec.rb @@ -0,0 +1,15 @@ +describe "brew --prefix", :integration_test do + it "prints the Homebrew prefix when no argument is given" do + expect { brew "--prefix" } + .to output("#{HOMEBREW_PREFIX}\n").to_stdout + .and not_to_output.to_stderr + .and be_a_success + end + + it "prints a given Formula's prefix" do + expect { brew "--prefix", testball } + .to output(%r{#{HOMEBREW_CELLAR}/testball}).to_stdout + .and not_to_output.to_stderr + .and be_a_success + end +end diff --git a/Library/Homebrew/test/cmd/--repository_spec.rb b/Library/Homebrew/test/cmd/--repository_spec.rb new file mode 100644 index 000000000..d3e531f7b --- /dev/null +++ b/Library/Homebrew/test/cmd/--repository_spec.rb @@ -0,0 +1,15 @@ +describe "brew --repository", :integration_test do + it "prints the path of the Homebrew repository" do + expect { brew "--repository" } + .to output("#{HOMEBREW_REPOSITORY}\n").to_stdout + .and not_to_output.to_stderr + .and be_a_success + end + + it "prints the path of a given Tap" do + expect { brew "--repository", "foo/bar" } + .to output("#{HOMEBREW_LIBRARY}/Taps/foo/homebrew-bar\n").to_stdout + .and not_to_output.to_stderr + .and be_a_success + end +end diff --git a/Library/Homebrew/test/cmd/--version_spec.rb b/Library/Homebrew/test/cmd/--version_spec.rb new file mode 100644 index 000000000..8992629d7 --- /dev/null +++ b/Library/Homebrew/test/cmd/--version_spec.rb @@ -0,0 +1,8 @@ +describe "brew --version", :integration_test do + it "prints the Homebrew version" do + expect { brew "--version" } + .to output(/^Homebrew #{Regexp.escape(HOMEBREW_VERSION.to_s)}\n/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + end +end diff --git a/Library/Homebrew/test/cmd/bundle_spec.rb b/Library/Homebrew/test/cmd/bundle_spec.rb new file mode 100644 index 000000000..755f9ab3d --- /dev/null +++ b/Library/Homebrew/test/cmd/bundle_spec.rb @@ -0,0 +1,24 @@ +describe "brew bundle", :integration_test, :needs_test_cmd_taps do + describe "check" do + it "checks if a Brewfile's dependencies are satisfied" do + setup_remote_tap "homebrew/bundle" + + HOMEBREW_REPOSITORY.cd do + shutup do + system "git", "init" + system "git", "commit", "--allow-empty", "-m", "This is a test commit" + end + end + + Dir.mktmpdir do |path| + FileUtils.touch "#{path}/Brewfile" + Dir.chdir path do + expect { brew "bundle", "check" } + .to output("The Brewfile's dependencies are satisfied.\n").to_stdout + .and not_to_output.to_stderr + .and be_a_success + end + end + end + end +end diff --git a/Library/Homebrew/test/cmd/cask_spec.rb b/Library/Homebrew/test/cmd/cask_spec.rb new file mode 100644 index 000000000..e46843cab --- /dev/null +++ b/Library/Homebrew/test/cmd/cask_spec.rb @@ -0,0 +1,8 @@ +describe "brew cask", :integration_test, :needs_macos, :needs_official_cmd_taps do + describe "list" do + it "returns a list of installed Casks" do + setup_remote_tap("caskroom/cask") + expect { brew "cask", "list" }.to be_a_success + end + end +end diff --git a/Library/Homebrew/test/cmd/cat_spec.rb b/Library/Homebrew/test/cmd/cat_spec.rb new file mode 100644 index 000000000..8c230abee --- /dev/null +++ b/Library/Homebrew/test/cmd/cat_spec.rb @@ -0,0 +1,11 @@ +describe "brew cat", :integration_test do + it "prints the content of a given Formula" do + formula_file = setup_test_formula "testball" + content = formula_file.read + + expect { brew "cat", "testball" } + .to output(content).to_stdout + .and not_to_output.to_stderr + .and be_a_success + end +end diff --git a/Library/Homebrew/test/cmd/cleanup_spec.rb b/Library/Homebrew/test/cmd/cleanup_spec.rb new file mode 100644 index 000000000..9e2cf493f --- /dev/null +++ b/Library/Homebrew/test/cmd/cleanup_spec.rb @@ -0,0 +1,12 @@ +describe "brew cleanup", :integration_test do + describe "--prune=all" do + it "removes all files in Homebrew's cache" do + (HOMEBREW_CACHE/"test").write "test" + + expect { brew "cleanup", "--prune=all" } + .to output(%r{#{Regexp.escape(HOMEBREW_CACHE)}/test}).to_stdout + .and not_to_output.to_stderr + .and be_a_success + end + end +end diff --git a/Library/Homebrew/test/cmd/command_spec.rb b/Library/Homebrew/test/cmd/command_spec.rb new file mode 100644 index 000000000..5d6a67b70 --- /dev/null +++ b/Library/Homebrew/test/cmd/command_spec.rb @@ -0,0 +1,13 @@ +describe "brew command", :integration_test do + it "returns the file for a given command" do + expect { brew "command", "info" } + .to output(%r{#{Regexp.escape(HOMEBREW_LIBRARY_PATH)}/cmd/info.rb}).to_stdout + .and be_a_success + end + + it "fails when the given command is unknown" do + expect { brew "command", "does-not-exist" } + .to output(/Unknown command/).to_stderr + .and be_a_failure + end +end diff --git a/Library/Homebrew/test/cmd/commands_spec.rb b/Library/Homebrew/test/cmd/commands_spec.rb new file mode 100644 index 000000000..f42072956 --- /dev/null +++ b/Library/Homebrew/test/cmd/commands_spec.rb @@ -0,0 +1,7 @@ +describe "brew commands", :integration_test do + it "prints a list of all available commands" do + expect { brew "commands" } + .to output(/Built-in commands/).to_stdout + .and be_a_success + end +end diff --git a/Library/Homebrew/test/cmd/config_spec.rb b/Library/Homebrew/test/cmd/config_spec.rb new file mode 100644 index 000000000..7687fcdc7 --- /dev/null +++ b/Library/Homebrew/test/cmd/config_spec.rb @@ -0,0 +1,8 @@ +describe "brew config", :integration_test do + it "prints information about the current Homebrew configuration" do + expect { brew "config" } + .to output(/HOMEBREW_VERSION: #{HOMEBREW_VERSION}/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + end +end diff --git a/Library/Homebrew/test/cmd/custom-external-command_spec.rb b/Library/Homebrew/test/cmd/custom-external-command_spec.rb new file mode 100644 index 000000000..8ccc21fa7 --- /dev/null +++ b/Library/Homebrew/test/cmd/custom-external-command_spec.rb @@ -0,0 +1,21 @@ +describe "brew custom-external-command", :integration_test do + it "is supported" do + Dir.mktmpdir do |path| + path = Pathname.new(path) + + cmd = "custom-external-command-#{rand}" + file = path/"brew-#{cmd}" + + file.write <<-EOS.undent + #!/bin/sh + echo 'I am #{cmd}.' + EOS + FileUtils.chmod "+x", file + + expect { brew cmd, "PATH" => "#{path}#{File::PATH_SEPARATOR}#{ENV["PATH"]}" } + .to output("I am #{cmd}.\n").to_stdout + .and not_to_output.to_stderr + .and be_a_success + end + end +end diff --git a/Library/Homebrew/test/cmd/desc_spec.rb b/Library/Homebrew/test/cmd/desc_spec.rb new file mode 100644 index 000000000..b09819d81 --- /dev/null +++ b/Library/Homebrew/test/cmd/desc_spec.rb @@ -0,0 +1,40 @@ +describe "brew desc", :integration_test do + let(:desc_cache) { HOMEBREW_CACHE/"desc_cache.json" } + + it "shows a given Formula's description" do + setup_test_formula "testball" + + expect { brew "desc", "testball" } + .to output("testball: Some test\n").to_stdout + .and not_to_output.to_stderr + .and be_a_success + end + + it "fails when both --search and --name are specified" do + expect { brew "desc", "--search", "--name" } + .to output(/Pick one, and only one/).to_stderr + .and not_to_output.to_stdout + .and be_a_failure + end + + describe "--search" do + it "fails when no search term is given" do + expect { brew "desc", "--search" } + .to output(/You must provide a search term/).to_stderr + .and not_to_output.to_stdout + .and be_a_failure + end + end + + describe "--description" do + it "creates a description cache" do + expect(desc_cache).not_to exist + + shutup do + expect { brew "desc", "--description", "testball" }.to be_a_success + end + + expect(desc_cache).to exist + end + end +end diff --git a/Library/Homebrew/test/cmd/doctor_spec.rb b/Library/Homebrew/test/cmd/doctor_spec.rb new file mode 100644 index 000000000..530adcd98 --- /dev/null +++ b/Library/Homebrew/test/cmd/doctor_spec.rb @@ -0,0 +1,6 @@ +describe "brew doctor", :integration_test do + specify "check_integration_test" do + expect { brew "doctor", "check_integration_test" } + .to output(/This is an integration test/).to_stderr + end +end diff --git a/Library/Homebrew/test/cmd/fetch_spec.rb b/Library/Homebrew/test/cmd/fetch_spec.rb new file mode 100644 index 000000000..111d9f85c --- /dev/null +++ b/Library/Homebrew/test/cmd/fetch_spec.rb @@ -0,0 +1,13 @@ +describe "brew fetch", :integration_test do + it "downloads the Formula's URL" do + setup_test_formula "testball" + + expect(HOMEBREW_CACHE/"testball-0.1.tbz").not_to exist + + shutup do + expect { brew "fetch", "testball" }.to be_a_success + end + + expect(HOMEBREW_CACHE/"testball-0.1.tbz").to exist + end +end diff --git a/Library/Homebrew/test/cmd/help_spec.rb b/Library/Homebrew/test/cmd/help_spec.rb new file mode 100644 index 000000000..6d94d7444 --- /dev/null +++ b/Library/Homebrew/test/cmd/help_spec.rb @@ -0,0 +1,47 @@ +describe "brew", :integration_test do + it "prints help when no argument is given" do + expect { brew } + .to output(/Example usage:\n/).to_stderr + .and be_a_failure + end + + describe "help" do + it "prints help" do + expect { brew "help" } + .to output(/Example usage:\n/).to_stdout + .and be_a_success + end + + it "prints help for a documented Ruby command" do + expect { brew "help", "cat" } + .to output(/^brew cat/).to_stdout + .and be_a_success + end + + it "prints help for a documented shell command" do + expect { brew "help", "update" } + .to output(/^brew update/).to_stdout + .and be_a_success + end + + it "prints help for a documented Ruby developer command" do + expect { brew "help", "update-test" } + .to output(/^brew update-test/).to_stdout + .and be_a_success + end + + it "fails when given an unknown command" do + expect { brew "help", "command-that-does-not-exist" } + .to output(/Unknown command: command-that-does-not-exist/).to_stderr + .and be_a_failure + end + end + + describe "cat" do + it "prints help when no argument is given" do + expect { brew "cat" } + .to output(/^brew cat/).to_stderr + .and be_a_failure + end + end +end diff --git a/Library/Homebrew/test/cmd/home_spec.rb b/Library/Homebrew/test/cmd/home_spec.rb new file mode 100644 index 000000000..5a4070492 --- /dev/null +++ b/Library/Homebrew/test/cmd/home_spec.rb @@ -0,0 +1,17 @@ +describe "brew home", :integration_test do + it "opens the Homebrew homepage when no argument is given" do + expect { brew "home", "HOMEBREW_BROWSER" => "echo" } + .to output("#{HOMEBREW_WWW}\n").to_stdout + .and not_to_output.to_stderr + .and be_a_success + end + + it "opens the homepage for a given Formula" do + setup_test_formula "testball" + + expect { brew "home", "testball", "HOMEBREW_BROWSER" => "echo" } + .to output("#{Formula["testball"].homepage}\n").to_stdout + .and not_to_output.to_stderr + .and be_a_success + end +end diff --git a/Library/Homebrew/test/cmd/info_spec.rb b/Library/Homebrew/test/cmd/info_spec.rb new file mode 100644 index 000000000..8deef3d23 --- /dev/null +++ b/Library/Homebrew/test/cmd/info_spec.rb @@ -0,0 +1,30 @@ +require "cmd/info" + +describe "brew info", :integration_test do + it "prints information about a given Formula" do + setup_test_formula "testball" + + expect { brew "info", "testball" } + .to output(/testball: stable 0.1/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + end +end + +describe Homebrew do + let(:remote) { "https://github.com/Homebrew/homebrew-core" } + + specify "::github_remote_path" do + expect(subject.github_remote_path(remote, "Formula/git.rb")) + .to eq("https://github.com/Homebrew/homebrew-core/blob/master/Formula/git.rb") + + expect(subject.github_remote_path("#{remote}.git", "Formula/git.rb")) + .to eq("https://github.com/Homebrew/homebrew-core/blob/master/Formula/git.rb") + + expect(subject.github_remote_path("git@github.com:user/repo", "foo.rb")) + .to eq("https://github.com/user/repo/blob/master/foo.rb") + + expect(subject.github_remote_path("https://mywebsite.com", "foo/bar.rb")) + .to eq("https://mywebsite.com/foo/bar.rb") + end +end diff --git a/Library/Homebrew/test/cmd/install_spec.rb b/Library/Homebrew/test/cmd/install_spec.rb new file mode 100644 index 000000000..c1240a30e --- /dev/null +++ b/Library/Homebrew/test/cmd/install_spec.rb @@ -0,0 +1,243 @@ +describe "brew install", :integration_test do + it "installs Formulae" do + setup_test_formula "testball1" + + expect { brew "install", "testball1", "--head" } + .to output(/Specify `\-\-HEAD`/).to_stderr + .and not_to_output.to_stdout + .and be_a_failure + + expect { brew "install", "testball1", "--HEAD" } + .to output(/No head is defined/).to_stderr + .and not_to_output.to_stdout + .and be_a_failure + + expect { brew "install", "testball1", "--devel" } + .to output(/No devel block/).to_stderr + .and not_to_output.to_stdout + .and be_a_failure + + expect { brew "install", "testball1" } + .to output(%r{#{HOMEBREW_CELLAR}/testball1/0\.1}).to_stdout + .and not_to_output.to_stderr + .and be_a_success + + expect { brew "install", "testball1" } + .to output(/testball1\-0\.1 already installed/).to_stderr + .and not_to_output.to_stdout + .and be_a_success + + expect { brew "install", "macruby" } + .to output(/MacRuby is not packaged/).to_stderr + .and not_to_output.to_stdout + .and be_a_failure + + expect { brew "install", "formula" } + .to output(/No available formula/).to_stderr + .and output(/Searching for similarly named formulae/).to_stdout + .and be_a_failure + + expect { brew "install", "testball" } + .to output(/This similarly named formula was found/).to_stdout + .and output(/No available formula/).to_stderr + .and be_a_failure + + setup_test_formula "testball2" + expect { brew "install", "testball" } + .to output(/These similarly named formulae were found/).to_stdout + .and output(/No available formula/).to_stderr + .and be_a_failure + + install_and_rename_coretap_formula "testball1", "testball2" + expect { brew "install", "testball2" } + .to output(/testball1 already installed, it's just not migrated/).to_stderr + .and output(/You can migrate formula with `brew migrate testball2`/).to_stdout + .and be_a_success + end + + specify "install failures" do + path = setup_test_formula "testball1", <<-EOS.undent + version "1.0" + EOS + + expect { brew "install", "testball1" } + .to output(%r{#{HOMEBREW_CELLAR}/testball1/1\.0}).to_stdout + .and not_to_output.to_stderr + .and be_a_success + + FileUtils.rm path + setup_test_formula "testball1", <<-EOS.undent + version "2.0" + + devel do + url "#{Formulary.factory("testball1").stable.url}" + sha256 "#{TESTBALL_SHA256}" + version "3.0" + end + EOS + + expect { brew "install", "testball1" } + .to output(/first `brew unlink testball1`/).to_stderr + .and not_to_output.to_stdout + .and be_a_failure + + expect { brew "unlink", "testball1" } + .to output(%r{#{HOMEBREW_CELLAR}/testball1/1\.0}).to_stdout + .and not_to_output.to_stderr + .and be_a_success + + expect { brew "install", "testball1", "--devel" } + .to output(%r{#{HOMEBREW_CELLAR}/testball1/3\.0}).to_stdout + .and not_to_output.to_stderr + .and be_a_success + + expect { brew "unlink", "testball1" } + .to output(%r{#{HOMEBREW_CELLAR}/testball1/3\.0}).to_stdout + .and not_to_output.to_stderr + .and be_a_success + + expect { brew "install", "testball1" } + .to output(%r{#{HOMEBREW_CELLAR}/testball1/2\.0}).to_stdout + .and not_to_output.to_stderr + .and be_a_success + + shutup do + expect { brew "switch", "testball1", "3.0" }.to be_a_success + end + + expect { brew "install", "testball1" } + .to output(/already installed, however linked version is/).to_stderr + .and output(/`brew switch testball1 2.0`/).to_stdout + .and be_a_success + + expect { brew "unlink", "testball1" } + .to output(%r{#{HOMEBREW_CELLAR}/testball1/3\.0}).to_stdout + .and not_to_output.to_stderr + .and be_a_success + + expect { brew "install", "testball1" } + .to output(/just not linked/).to_stderr + .and not_to_output.to_stdout + .and be_a_success + end + + it "can install keg-only Formulae" do + path_keg_only = setup_test_formula "testball1", <<-EOS.undent + version "1.0" + + keg_only "test reason" + EOS + + expect { brew "install", "testball1" } + .to output(%r{#{HOMEBREW_CELLAR}/testball1/1\.0}).to_stdout + .and not_to_output.to_stderr + .and be_a_success + + FileUtils.rm path_keg_only + setup_test_formula "testball1", <<-EOS.undent + version "2.0" + + keg_only "test reason" + EOS + + expect { brew "install", "testball1" } + .to output(/keg-only and another version is linked to opt/).to_stderr + .and output(/Use `brew install --force`/).to_stdout + .and be_a_success + + expect { brew "install", "testball1", "--force" } + .to output(%r{#{HOMEBREW_CELLAR}/testball1/2\.0}).to_stdout + .and not_to_output.to_stderr + .and be_a_success + end + + it "can install HEAD Formulae" do + repo_path = HOMEBREW_CACHE.join("repo") + repo_path.join("bin").mkpath + + repo_path.cd do + shutup do + system "git", "init" + system "git", "remote", "add", "origin", "https://github.com/Homebrew/homebrew-foo" + FileUtils.touch "bin/something.bin" + FileUtils.touch "README" + system "git", "add", "--all" + system "git", "commit", "-m", "Initial repo commit" + end + end + + setup_test_formula "testball1", <<-EOS.undent + version "1.0" + + head "file://#{repo_path}", :using => :git + + def install + prefix.install Dir["*"] + end + EOS + + # Ignore dependencies, because we'll try to resolve requirements in build.rb + # and there will be the git requirement, but we cannot instantiate git + # formula since we only have testball1 formula. + expect { brew "install", "testball1", "--HEAD", "--ignore-dependencies" } + .to output(%r{#{HOMEBREW_CELLAR}/testball1/HEAD\-d5eb689}).to_stdout + .and output(/Cloning into/).to_stderr + .and be_a_success + + expect { brew "install", "testball1", "--HEAD", "--ignore-dependencies" } + .to output(/testball1\-HEAD\-d5eb689 already installed/).to_stderr + .and not_to_output.to_stdout + .and be_a_success + + expect { brew "unlink", "testball1" } + .to output(%r{#{HOMEBREW_CELLAR}/testball1/HEAD\-d5eb689}).to_stdout + .and not_to_output.to_stderr + .and be_a_success + + expect { brew "install", "testball1" } + .to output(%r{#{HOMEBREW_CELLAR}/testball1/1\.0}).to_stdout + .and not_to_output.to_stderr + .and be_a_success + end + + it "ignores invalid options" do + setup_test_formula "testball1" + expect { brew "install", "testball1", "--with-fo" } + .to output(/testball1: this formula has no \-\-with\-fo option so it will be ignored!/).to_stderr + .and output(/Downloading file/).to_stdout + .and be_a_success + end + + it "succeeds when a non-fatal requirement isn't satisfied" do + setup_test_formula "testball1", <<-EOS.undent + class NonFatalRequirement < Requirement + satisfy { false } + end + + depends_on NonFatalRequirement + EOS + + # FIXME: This should output to STDERR. + expect { brew "install", "testball1" } + .to output(/NonFatalRequirement unsatisfied!/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + end + + it "fails when a fatal requirement isn't satisfied" do + setup_test_formula "testball1", <<-EOS.undent + class FatalRequirement < Requirement + fatal true + satisfy { false } + end + + depends_on FatalRequirement + EOS + + # FIXME: This should output to STDERR. + expect { brew "install", "testball1" } + .to output(/FatalRequirement unsatisfied!/).to_stdout + .and output(/An unsatisfied requirement failed this build./).to_stderr + .and be_a_failure + end +end diff --git a/Library/Homebrew/test/cmd/irb_spec.rb b/Library/Homebrew/test/cmd/irb_spec.rb new file mode 100644 index 000000000..44410fabe --- /dev/null +++ b/Library/Homebrew/test/cmd/irb_spec.rb @@ -0,0 +1,24 @@ +describe "brew irb", :integration_test do + it "starts an interactive Homebrew shell session" do + setup_test_formula "testball" + + irb_test = HOMEBREW_TEMP/"irb-test.rb" + irb_test.write <<-EOS.undent + "testball".f + :testball.f + exit + EOS + + expect { brew "irb", irb_test } + .to output(/Interactive Homebrew Shell/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + end + + specify "--examples" do + expect { brew "irb", "--examples" } + .to output(/'v8'\.f # => instance of the v8 formula/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + end +end diff --git a/Library/Homebrew/test/cmd/leaves_spec.rb b/Library/Homebrew/test/cmd/leaves_spec.rb new file mode 100644 index 000000000..cd93d7e3d --- /dev/null +++ b/Library/Homebrew/test/cmd/leaves_spec.rb @@ -0,0 +1,23 @@ +describe "brew leaves", :integration_test do + it "prints all Formulae that are not dependencies of other Formulae" do + setup_test_formula "foo" + setup_test_formula "bar" + + expect { brew "leaves" } + .to be_a_success + .and not_to_output.to_stdout + .and not_to_output.to_stderr + + (HOMEBREW_CELLAR/"foo/0.1/somedir").mkpath + expect { brew "leaves" } + .to output("foo\n").to_stdout + .and not_to_output.to_stderr + .and be_a_success + + (HOMEBREW_CELLAR/"bar/0.1/somedir").mkpath + expect { brew "leaves" } + .to output("bar\n").to_stdout + .and not_to_output.to_stderr + .and be_a_success + end +end diff --git a/Library/Homebrew/test/cmd/link_spec.rb b/Library/Homebrew/test/cmd/link_spec.rb new file mode 100644 index 000000000..7b85c96dc --- /dev/null +++ b/Library/Homebrew/test/cmd/link_spec.rb @@ -0,0 +1,56 @@ +describe "brew link", :integration_test do + it "fails when no argument is given" do + expect { brew "link" } + .to output(/This command requires a keg argument/).to_stderr + .and not_to_output.to_stdout + .and be_a_failure + end + + it "does not fail if the given Formula is already linked" do + setup_test_formula "testball1" + + shutup do + expect { brew "install", "testball1" }.to be_a_success + expect { brew "link", "testball1" }.to be_a_success + end + end + + it "links a given Formula" do + setup_test_formula "testball1" + + shutup do + expect { brew "install", "testball1" }.to be_a_success + expect { brew "unlink", "testball1" }.to be_a_success + end + + expect { brew "link", "--dry-run", "testball1" } + .to output(/Would link/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + + expect { brew "link", "--dry-run", "--overwrite", "testball1" } + .to output(/Would remove/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + + expect { brew "link", "testball1" } + .to output(/Linking/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + end + + it "refuses to link keg-only Formulae" do + setup_test_formula "testball1", <<-EOS.undent + keg_only "just because" + EOS + + shutup do + expect { brew "install", "testball1" }.to be_a_success + end + + expect { brew "link", "testball1" } + .to output(/testball1 is keg-only/).to_stderr + .and output(/Note that doing so can interfere with building software\./).to_stdout + .and be_a_success + end +end diff --git a/Library/Homebrew/test/cmd/linkapps_spec.rb b/Library/Homebrew/test/cmd/linkapps_spec.rb new file mode 100644 index 000000000..42118a215 --- /dev/null +++ b/Library/Homebrew/test/cmd/linkapps_spec.rb @@ -0,0 +1,24 @@ +describe "brew linkapps", :integration_test do + let(:home_dir) { @home_dir = Pathname.new(Dir.mktmpdir) } + let(:apps_dir) { home_dir/"Applications" } + + after(:each) do + home_dir.rmtree unless @home_dir.nil? + end + + it "symlinks applications" do + apps_dir.mkpath + + setup_test_formula "testball" + + source_app = HOMEBREW_CELLAR/"testball/0.1/TestBall.app" + source_app.mkpath + + expect { brew "linkapps", "--local", "HOME" => home_dir } + .to output(/Linking: #{Regexp.escape(source_app)}/).to_stdout + .and output(/`brew linkapps` has been deprecated/).to_stderr + .and be_a_success + + expect(apps_dir/"TestBall.app").to be_a_symlink + end +end diff --git a/Library/Homebrew/test/cmd/list_spec.rb b/Library/Homebrew/test/cmd/list_spec.rb new file mode 100644 index 000000000..df7394d7b --- /dev/null +++ b/Library/Homebrew/test/cmd/list_spec.rb @@ -0,0 +1,14 @@ +describe "brew list", :integration_test do + let(:formulae) { %w[bar foo qux] } + + it "prints all installed Formulae" do + formulae.each do |f| + (HOMEBREW_CELLAR/f/"1.0/somedir").mkpath + end + + expect { brew "list" } + .to output("#{formulae.join("\n")}\n").to_stdout + .and not_to_output.to_stderr + .and be_a_success + end +end diff --git a/Library/Homebrew/test/cmd/log_spec.rb b/Library/Homebrew/test/cmd/log_spec.rb new file mode 100644 index 000000000..bdbca8912 --- /dev/null +++ b/Library/Homebrew/test/cmd/log_spec.rb @@ -0,0 +1,41 @@ +describe "brew log", :integration_test do + it "shows the Git log for the Homebrew repository when no argument is given" do + HOMEBREW_REPOSITORY.cd do + shutup do + system "git", "init" + system "git", "commit", "--allow-empty", "-m", "This is a test commit" + end + end + + expect { brew "log" } + .to output(/This is a test commit/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + end + + it "shows the Git log for a given Formula" do + setup_test_formula "testball" + + core_tap = CoreTap.new + core_tap.path.cd do + shutup do + system "git", "init" + system "git", "add", "--all" + system "git", "commit", "-m", "This is a test commit for Testball" + end + end + + core_tap_url = "file://#{core_tap.path}" + shallow_tap = Tap.fetch("homebrew", "shallow") + shutup do + system "git", "clone", "--depth=1", core_tap_url, shallow_tap.path + end + + expect { brew "log", "#{shallow_tap}/testball" } + .to output(/This is a test commit for Testball/).to_stdout + .and output(/Warning: The git repository is a shallow clone/).to_stderr + .and be_a_success + + expect(shallow_tap.path/".git/shallow").to exist, "A shallow clone should have been created." + end +end diff --git a/Library/Homebrew/test/cmd/migrate_spec.rb b/Library/Homebrew/test/cmd/migrate_spec.rb new file mode 100644 index 000000000..18c94fa01 --- /dev/null +++ b/Library/Homebrew/test/cmd/migrate_spec.rb @@ -0,0 +1,46 @@ +describe "brew migrate", :integration_test do + before(:each) do + setup_test_formula "testball1" + setup_test_formula "testball2" + end + + it "fails when no argument is given" do + expect { brew "migrate" } + .to output(/Invalid usage/).to_stderr + .and not_to_output.to_stdout + .and be_a_failure + end + + it "fails when a given Formula doesn't exist" do + expect { brew "migrate", "testball" } + .to output(/No available formula with the name "testball"/).to_stderr + .and not_to_output.to_stdout + .and be_a_failure + end + + it "fails if a given Formula doesn't replace another one" do + expect { brew "migrate", "testball1" } + .to output(/testball1 doesn't replace any formula/).to_stderr + .and not_to_output.to_stdout + .and be_a_failure + end + + it "migrates a renamed Formula" do + install_and_rename_coretap_formula "testball1", "testball2" + + expect { brew "migrate", "testball1" } + .to output(/Migrating testball1 to testball2/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + end + + it "fails if a given Formula is not installed" do + install_and_rename_coretap_formula "testball1", "testball2" + (HOMEBREW_CELLAR/"testball1").rmtree + + expect { brew "migrate", "testball1" } + .to output(/Error: No such keg/).to_stderr + .and not_to_output.to_stdout + .and be_a_failure + end +end diff --git a/Library/Homebrew/test/cmd/missing_spec.rb b/Library/Homebrew/test/cmd/missing_spec.rb new file mode 100644 index 000000000..4668e72e0 --- /dev/null +++ b/Library/Homebrew/test/cmd/missing_spec.rb @@ -0,0 +1,41 @@ +describe "brew missing", :integration_test do + before(:each) do + setup_test_formula "foo" + setup_test_formula "bar" + end + + def make_prefix(name) + (HOMEBREW_CELLAR/name/"1.0").mkpath + end + + it "prints missing dependencies" do + make_prefix "bar" + + expect { brew "missing" } + .to output("foo\n").to_stdout + .and not_to_output.to_stderr + .and be_a_success + end + + it "prints nothing if all dependencies are installed" do + make_prefix "foo" + make_prefix "bar" + + expect { brew "missing" } + .to be_a_success + .and not_to_output.to_stdout + .and not_to_output.to_stderr + end + + describe "--hide=" do + it "pretends that the specified Formulae are not installed" do + make_prefix "foo" + make_prefix "bar" + + expect { brew "missing", "--hide=foo" } + .to output("bar: foo\n").to_stdout + .and not_to_output.to_stderr + .and be_a_success + end + end +end diff --git a/Library/Homebrew/test/cmd/options_spec.rb b/Library/Homebrew/test/cmd/options_spec.rb new file mode 100644 index 000000000..33fe8b107 --- /dev/null +++ b/Library/Homebrew/test/cmd/options_spec.rb @@ -0,0 +1,12 @@ +describe "brew options", :integration_test do + it "prints a given Formula's options" do + setup_test_formula "testball", <<-EOS.undent + depends_on "bar" => :recommended + EOS + + expect { brew "options", "testball" } + .to output("--with-foo\n\tBuild with foo\n--without-bar\n\tBuild without bar support\n\n").to_stdout + .and not_to_output.to_stderr + .and be_a_success + end +end diff --git a/Library/Homebrew/test/cmd/outdated_spec.rb b/Library/Homebrew/test/cmd/outdated_spec.rb new file mode 100644 index 000000000..2ce0825e8 --- /dev/null +++ b/Library/Homebrew/test/cmd/outdated_spec.rb @@ -0,0 +1,11 @@ +describe "brew outdated", :integration_test do + it "prints outdated Formulae" do + setup_test_formula "testball" + (HOMEBREW_CELLAR/"testball/0.0.1/foo").mkpath + + expect { brew "outdated" } + .to output("testball\n").to_stdout + .and not_to_output.to_stderr + .and be_a_success + end +end diff --git a/Library/Homebrew/test/cmd/pin_spec.rb b/Library/Homebrew/test/cmd/pin_spec.rb new file mode 100644 index 000000000..9ffc052c3 --- /dev/null +++ b/Library/Homebrew/test/cmd/pin_spec.rb @@ -0,0 +1,13 @@ +describe "brew pin", :integration_test do + it "pins a Formula's version" do + setup_test_formula "testball" + (HOMEBREW_CELLAR/"testball/0.0.1/foo").mkpath + + shutup do + expect { brew "pin", "testball" }.to be_a_success + expect { brew "upgrade" }.to be_a_success + end + + expect(HOMEBREW_CELLAR/"testball/0.1").not_to be_a_directory + end +end diff --git a/Library/Homebrew/test/cmd/prune_spec.rb b/Library/Homebrew/test/cmd/prune_spec.rb new file mode 100644 index 000000000..c5a9df70c --- /dev/null +++ b/Library/Homebrew/test/cmd/prune_spec.rb @@ -0,0 +1,28 @@ +describe "brew prune", :integration_test do + it "removes empty directories and broken symlinks" do + share = (HOMEBREW_PREFIX/"share") + + (share/"pruneable/directory/here").mkpath + (share/"notpruneable/file").write "I'm here" + FileUtils.ln_s "/i/dont/exist/no/really/i/dont", share/"pruneable_symlink" + + expect { brew "prune", "--dry-run" } + .to output(%r{Would remove \(empty directory\): .*/pruneable/directory/here}).to_stdout + .and not_to_output.to_stderr + .and be_a_success + + expect { brew "prune" } + .to output(/Pruned 1 symbolic links and 3 directories/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + + expect(share/"pruneable").not_to be_a_directory + expect(share/"notpruneable").to be_a_directory + expect(share/"pruneable_symlink").not_to be_a_symlink + + expect { brew "prune", "--verbose" } + .to output(/Nothing pruned/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + end +end diff --git a/Library/Homebrew/test/cmd/readall_spec.rb b/Library/Homebrew/test/cmd/readall_spec.rb new file mode 100644 index 000000000..9165e0cb0 --- /dev/null +++ b/Library/Homebrew/test/cmd/readall_spec.rb @@ -0,0 +1,20 @@ +describe "brew readall", :integration_test do + it "imports all Formulae for a given Tap" do + formula_file = setup_test_formula "testball" + + alias_file = CoreTap.new.alias_dir/"foobar" + alias_file.parent.mkpath + + FileUtils.ln_s formula_file, alias_file + + expect { brew "readall", "--aliases", "--syntax" } + .to be_a_success + .and not_to_output.to_stdout + .and not_to_output.to_stderr + + expect { brew "readall", "homebrew/core" } + .to be_a_success + .and not_to_output.to_stdout + .and not_to_output.to_stderr + end +end diff --git a/Library/Homebrew/test/cmd/reinstall_spec.rb b/Library/Homebrew/test/cmd/reinstall_spec.rb new file mode 100644 index 000000000..63584e6be --- /dev/null +++ b/Library/Homebrew/test/cmd/reinstall_spec.rb @@ -0,0 +1,44 @@ +require "extend/ENV" + +describe "brew reinstall", :integration_test do + before(:each) do + setup_test_formula "testball" + + shutup do + expect { brew "install", "testball", "--with-foo" }.to be_a_success + end + end + + it "reinstalls a Formula" do + foo_dir = HOMEBREW_CELLAR/"testball/0.1/foo" + expect(foo_dir).to exist + foo_dir.rmtree + + expect { brew "reinstall", "testball" } + .to output(/Reinstalling testball --with-foo/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + + expect(foo_dir).to exist + end + + it "reinstalls a Formula even when one of the options is invalid" do + expect { brew "reinstall", "testball", "--with-fo" } + .to output(/Reinstalling testball --with-foo/).to_stdout + .and output(/testball: this formula has no \-\-with-fo option so it will be ignored!/).to_stderr + .and be_a_success + end + + it "refuses to reinstall a pinned Formula, but doesn't fail" do + (HOMEBREW_CELLAR/"testball/0.1").mkpath + HOMEBREW_PINNED_KEGS.mkpath + FileUtils.ln_s HOMEBREW_CELLAR/"testball/0.1", HOMEBREW_PINNED_KEGS/"testball" + + expect { brew "reinstall", "testball" } + .to output(/testball is pinned. You must unpin it to reinstall./).to_stderr + .and not_to_output.to_stdout + .and be_a_success + + HOMEBREW_PINNED_KEGS.rmtree + end +end diff --git a/Library/Homebrew/test/cmd/search_spec.rb b/Library/Homebrew/test/cmd/search_spec.rb new file mode 100644 index 000000000..06b7073d8 --- /dev/null +++ b/Library/Homebrew/test/cmd/search_spec.rb @@ -0,0 +1,57 @@ +describe "brew search", :integration_test do + before(:each) do + setup_test_formula "testball" + end + + it "lists all available Formulae when no argument is given" do + expect { brew "search" } + .to output(/testball/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + end + + it "supports searching by name" do + expect { brew "search", "testball" } + .to output(/testball/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + end + + it "supports searching a fully-qualified name " do + expect { brew "search", "homebrew/homebrew-core/testball" } + .to output(/testball/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + end + + describe "--desc" do + let(:desc_cache) { HOMEBREW_CACHE/"desc_cache.json" } + + it "supports searching in descriptions and creates a description cache" do + expect(desc_cache).not_to exist + + expect { brew "search", "--desc", "Some test" } + .to output(/testball/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + + expect(desc_cache).to exist + end + end + + { + "macports" => "https://www.macports.org/ports.php?by=name&substr=testball", + "fink" => "http://pdb.finkproject.org/pdb/browse.php?summary=testball", + "debian" => "https://packages.debian.org/search?keywords=testball&searchon=names&suite=all§ion=all", + "opensuse" => "https://software.opensuse.org/search?q=testball", + "fedora" => "https://admin.fedoraproject.org/pkgdb/packages/%2Atestball%2A/", + "ubuntu" => "http://packages.ubuntu.com/search?keywords=testball&searchon=names&suite=all§ion=all", + }.each do |flag, url| + specify "--#{flag}" do + expect { brew "search", "--#{flag}", "testball", "HOMEBREW_BROWSER" => "echo" } + .to output("#{url}\n").to_stdout + .and not_to_output.to_stderr + .and be_a_success + end + end +end diff --git a/Library/Homebrew/test/cmd/services_spec.rb b/Library/Homebrew/test/cmd/services_spec.rb new file mode 100644 index 000000000..c456fea17 --- /dev/null +++ b/Library/Homebrew/test/cmd/services_spec.rb @@ -0,0 +1,10 @@ +describe "brew services", :integration_test, :needs_macos, :needs_official_cmd_taps do + it "allows controlling services" do + setup_remote_tap "homebrew/services" + + expect { brew "services", "list" } + .to output("Warning: No services available to control with `brew services`\n").to_stderr + .and not_to_output.to_stdout + .and be_a_success + end +end diff --git a/Library/Homebrew/test/cmd/sh_spec.rb b/Library/Homebrew/test/cmd/sh_spec.rb new file mode 100644 index 000000000..5260ddb75 --- /dev/null +++ b/Library/Homebrew/test/cmd/sh_spec.rb @@ -0,0 +1,8 @@ +describe "brew sh", :integration_test do + it "runs a shell with the Homebrew environment" do + expect { brew "sh", "SHELL" => which("true") } + .to output(/Your shell has been configured/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + end +end diff --git a/Library/Homebrew/test/cmd/switch_spec.rb b/Library/Homebrew/test/cmd/switch_spec.rb new file mode 100644 index 000000000..c27c96c14 --- /dev/null +++ b/Library/Homebrew/test/cmd/switch_spec.rb @@ -0,0 +1,34 @@ +describe "brew switch", :integration_test do + it "allows switching between Formula versions" do + expect { brew "switch" } + .to output(/Usage: brew switch <name> <version>/).to_stderr + .and not_to_output.to_stdout + .and be_a_failure + + expect { brew "switch", "testball", "0.1" } + .to output(/testball not found/).to_stderr + .and not_to_output.to_stdout + .and be_a_failure + + setup_test_formula "testball", <<-EOS.undent + keg_only "just because" + EOS + + shutup do + expect { brew "install", "testball" }.to be_a_success + end + + testball_rack = HOMEBREW_CELLAR/"testball" + FileUtils.cp_r testball_rack/"0.1", testball_rack/"0.2" + + expect { brew "switch", "testball", "0.2" } + .to output(/link created/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + + expect { brew "switch", "testball", "0.3" } + .to output("Versions available: 0.1, 0.2\n").to_stdout + .and output(/testball does not have a version "0.3"/).to_stderr + .and be_a_failure + end +end diff --git a/Library/Homebrew/test/cmd/tap-new_spec.rb b/Library/Homebrew/test/cmd/tap-new_spec.rb new file mode 100644 index 000000000..ea4b8aa73 --- /dev/null +++ b/Library/Homebrew/test/cmd/tap-new_spec.rb @@ -0,0 +1,10 @@ +describe "brew tap-new", :integration_test do + it "initializes a new Tap with a ReadMe file" do + expect { brew "tap-new", "homebrew/foo", "--verbose" } + .to be_a_success + .and not_to_output.to_stdout + .and not_to_output.to_stderr + + expect(HOMEBREW_LIBRARY/"Taps/homebrew/homebrew-foo/README.md").to exist + end +end diff --git a/Library/Homebrew/test/cmd/uninstall_spec.rb b/Library/Homebrew/test/cmd/uninstall_spec.rb new file mode 100644 index 000000000..65f69e802 --- /dev/null +++ b/Library/Homebrew/test/cmd/uninstall_spec.rb @@ -0,0 +1,12 @@ +describe "brew uninstall", :integration_test do + it "uninstalls a given Formula" do + shutup do + expect { brew "install", testball }.to be_a_success + end + + expect { brew "uninstall", "--force", testball } + .to output(/Uninstalling testball/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + end +end diff --git a/Library/Homebrew/test/cmd/unlink_spec.rb b/Library/Homebrew/test/cmd/unlink_spec.rb new file mode 100644 index 000000000..5961651fe --- /dev/null +++ b/Library/Homebrew/test/cmd/unlink_spec.rb @@ -0,0 +1,14 @@ +describe "brew unlink", :integration_test do + it "unlinks a Formula" do + setup_test_formula "testball" + + shutup do + expect { brew "install", "testball" }.to be_a_success + end + + expect { brew "unlink", "--dry-run", "testball" } + .to output(/Would remove/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + end +end diff --git a/Library/Homebrew/test/cmd/unlinkapps_spec.rb b/Library/Homebrew/test/cmd/unlinkapps_spec.rb new file mode 100644 index 000000000..1e21bd851 --- /dev/null +++ b/Library/Homebrew/test/cmd/unlinkapps_spec.rb @@ -0,0 +1,24 @@ +describe "brew unlinkapps", :integration_test do + let(:home_dir) { @home_dir = Pathname.new(Dir.mktmpdir) } + let(:apps_dir) { home_dir/"Applications" } + + after(:each) do + home_dir.rmtree unless @home_dir.nil? + end + + it "unlinks symlinked applications" do + apps_dir.mkpath + + setup_test_formula "testball" + + source_app = HOMEBREW_CELLAR/"testball/0.1/TestBall.app" + source_app.mkpath + + FileUtils.ln_s source_app, apps_dir/"TestBall.app" + + expect { brew "unlinkapps", "--local", "HOME" => home_dir } + .to output(%r{Unlinking: #{Regexp.escape(apps_dir)}/TestBall.app}).to_stdout + .and output(/`brew unlinkapps` has been deprecated/).to_stderr + .and be_a_success + end +end diff --git a/Library/Homebrew/test/cmd/unpack_spec.rb b/Library/Homebrew/test/cmd/unpack_spec.rb new file mode 100644 index 000000000..244fc0852 --- /dev/null +++ b/Library/Homebrew/test/cmd/unpack_spec.rb @@ -0,0 +1,16 @@ +describe "brew unpack", :integration_test do + it "unpacks a given Formula's archive" do + setup_test_formula "testball" + + Dir.mktmpdir do |path| + path = Pathname.new(path) + + shutup do + expect { brew "unpack", "testball", "--destdir=#{path}" } + .to be_a_success + end + + expect(path/"testball-0.1").to be_a_directory + end + end +end diff --git a/Library/Homebrew/test/cmd/unpin_spec.rb b/Library/Homebrew/test/cmd/unpin_spec.rb new file mode 100644 index 000000000..4f14626d8 --- /dev/null +++ b/Library/Homebrew/test/cmd/unpin_spec.rb @@ -0,0 +1,14 @@ +describe "brew unpin", :integration_test do + it "unpins a Formula's version" do + setup_test_formula "testball" + (HOMEBREW_CELLAR/"testball/0.0.1/foo").mkpath + + shutup do + expect { brew "pin", "testball" }.to be_a_success + expect { brew "unpin", "testball" }.to be_a_success + expect { brew "upgrade" }.to be_a_success + end + + expect(HOMEBREW_CELLAR/"testball/0.1").to be_a_directory + end +end diff --git a/Library/Homebrew/test/cmd/update-report_spec.rb b/Library/Homebrew/test/cmd/update-report_spec.rb new file mode 100644 index 000000000..3665e3c78 --- /dev/null +++ b/Library/Homebrew/test/cmd/update-report_spec.rb @@ -0,0 +1,127 @@ +require "cmd/update-report" +require "formula_versions" +require "yaml" + +describe Reporter do + def perform_update(fixture_name = "") + allow(Formulary).to receive(:factory).and_return(double(pkg_version: "1.0")) + allow(FormulaVersions).to receive(:new).and_return(double(formula_at_revision: "2.0")) + + diff = YAML.load_file("#{TEST_FIXTURE_DIR}/updater_fixture.yaml")[fixture_name] + allow(subject).to receive(:diff).and_return(diff || "") + + hub.add(subject) if subject.updated? + end + + let(:reporter_class) do + Class.new(described_class) do + def initialize(tap) + @tap = tap + + ENV["HOMEBREW_UPDATE_BEFORE#{repo_var}"] = "12345678" + ENV["HOMEBREW_UPDATE_AFTER#{repo_var}"] = "abcdef00" + + super(tap) + end + end + end + subject { reporter_class.new(tap) } + let(:tap) { CoreTap.new } + let(:hub) { ReporterHub.new } + + specify "without revision variable" do + ENV.delete_if { |k, _v| k.start_with? "HOMEBREW_UPDATE" } + + expect { + described_class.new(tap) + }.to raise_error(Reporter::ReporterRevisionUnsetError) + end + + specify "without any changes" do + perform_update + expect(hub).to be_empty + end + + specify "without Formula changes" do + perform_update("update_git_diff_output_without_formulae_changes") + + expect(hub.select_formula(:M)).to be_empty + expect(hub.select_formula(:A)).to be_empty + expect(hub.select_formula(:D)).to be_empty + end + + specify "with Formula changes" do + perform_update("update_git_diff_output_with_formulae_changes") + + expect(hub.select_formula(:M)).to eq(%w[xar yajl]) + expect(hub.select_formula(:A)).to eq(%w[antiword bash-completion ddrescue dict lua]) + end + + specify "with removed Formulae" do + perform_update("update_git_diff_output_with_removed_formulae") + + expect(hub.select_formula(:D)).to eq(%w[libgsasl]) + end + + specify "with changed file type" do + perform_update("update_git_diff_output_with_changed_filetype") + + expect(hub.select_formula(:M)).to eq(%w[elixir]) + expect(hub.select_formula(:A)).to eq(%w[libbson]) + expect(hub.select_formula(:D)).to eq(%w[libgsasl]) + end + + specify "with renamed Formula" do + allow(tap).to receive(:formula_renames).and_return("cv" => "progress") + perform_update("update_git_diff_output_with_formula_rename") + + expect(hub.select_formula(:A)).to be_empty + expect(hub.select_formula(:D)).to be_empty + expect(hub.select_formula(:R)).to eq([["cv", "progress"]]) + end + + context "when updating a Tap other than the core Tap" do + let(:tap) { Tap.new("foo", "bar") } + + before(:each) do + (tap.path/"Formula").mkpath + end + + after(:each) do + tap.path.parent.rmtree + end + + specify "with restructured Tap" do + perform_update("update_git_diff_output_with_restructured_tap") + + expect(hub.select_formula(:A)).to be_empty + expect(hub.select_formula(:D)).to be_empty + expect(hub.select_formula(:R)).to be_empty + end + + specify "with renamed Formula and restructured Tap" do + allow(tap).to receive(:formula_renames).and_return("xchat" => "xchat2") + perform_update("update_git_diff_output_with_formula_rename_and_restructuring") + + expect(hub.select_formula(:A)).to be_empty + expect(hub.select_formula(:D)).to be_empty + expect(hub.select_formula(:R)).to eq([%w[foo/bar/xchat foo/bar/xchat2]]) + end + + specify "with simulated 'homebrew/php' restructuring" do + perform_update("update_git_diff_simulate_homebrew_php_restructuring") + + expect(hub.select_formula(:A)).to be_empty + expect(hub.select_formula(:D)).to be_empty + expect(hub.select_formula(:R)).to be_empty + end + + specify "with Formula changes" do + perform_update("update_git_diff_output_with_tap_formulae_changes") + + expect(hub.select_formula(:A)).to eq(%w[foo/bar/lua]) + expect(hub.select_formula(:M)).to eq(%w[foo/bar/git]) + expect(hub.select_formula(:D)).to be_empty + end + end +end diff --git a/Library/Homebrew/test/cmd/upgrade_spec.rb b/Library/Homebrew/test/cmd/upgrade_spec.rb new file mode 100644 index 000000000..84f5c09f4 --- /dev/null +++ b/Library/Homebrew/test/cmd/upgrade_spec.rb @@ -0,0 +1,12 @@ +describe "brew upgrade", :integration_test do + it "upgrades a Formula to the latest version" do + setup_test_formula "testball" + (HOMEBREW_CELLAR/"testball/0.0.1/foo").mkpath + + shutup do + expect { brew "upgrade" }.to be_a_success + end + + expect(HOMEBREW_CELLAR/"testball/0.1").to be_a_directory + end +end diff --git a/Library/Homebrew/test/cmd/uses_spec.rb b/Library/Homebrew/test/cmd/uses_spec.rb new file mode 100644 index 000000000..2a6f48cb7 --- /dev/null +++ b/Library/Homebrew/test/cmd/uses_spec.rb @@ -0,0 +1,25 @@ +describe "brew uses", :integration_test do + it "prints the Formulae a given Formula is used by" do + setup_test_formula "foo" + setup_test_formula "bar" + setup_test_formula "baz", <<-EOS.undent + url "https://example.com/baz-1.0" + depends_on "bar" + EOS + + expect { brew "uses", "baz" } + .to be_a_success + .and not_to_output.to_stdout + .and not_to_output.to_stderr + + expect { brew "uses", "bar" } + .to output("baz\n").to_stdout + .and not_to_output.to_stderr + .and be_a_success + + expect { brew "uses", "--recursive", "foo" } + .to output(/(bar\nbaz|baz\nbar)/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + end +end diff --git a/Library/Homebrew/test/command_test.rb b/Library/Homebrew/test/command_test.rb deleted file mode 100644 index d5c7aaa88..000000000 --- a/Library/Homebrew/test/command_test.rb +++ /dev/null @@ -1,11 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestCommand < IntegrationCommandTestCase - def test_command - assert_equal "#{HOMEBREW_LIBRARY_PATH}/cmd/info.rb", - cmd("command", "info") - - assert_match "Unknown command", - cmd_fail("command", "I-don't-exist") - end -end diff --git a/Library/Homebrew/test/commands_test.rb b/Library/Homebrew/test/commands_test.rb index 5f5dc9586..da88ee2d5 100644 --- a/Library/Homebrew/test/commands_test.rb +++ b/Library/Homebrew/test/commands_test.rb @@ -4,13 +4,6 @@ require "cmd/commands" require "fileutils" require "testing_env" -class IntegrationCommandTestCommands < IntegrationCommandTestCase - def test_commands - assert_match "Built-in commands", - cmd("commands") - end -end - class CommandsTests < Homebrew::TestCase def setup super diff --git a/Library/Homebrew/test/compiler_selector_spec.rb b/Library/Homebrew/test/compiler_selector_spec.rb new file mode 100644 index 000000000..0f6f6b5f2 --- /dev/null +++ b/Library/Homebrew/test/compiler_selector_spec.rb @@ -0,0 +1,122 @@ +require "compilers" +require "software_spec" + +describe CompilerSelector do + subject { described_class.new(software_spec, versions, compilers) } + let(:compilers) { [:clang, :gcc, :llvm, :gnu] } + let(:software_spec) { SoftwareSpec.new } + let(:cc) { :clang } + let(:versions) do + double( + gcc_4_0_build_version: Version::NULL, + gcc_build_version: Version.create("5666"), + llvm_build_version: Version::NULL, + clang_build_version: Version.create("425"), + ) + end + + before(:each) do + allow(versions).to receive(:non_apple_gcc_version) do |name| + case name + when "gcc-4.8" then Version.create("4.8.1") + when "gcc-4.7" then Version.create("4.7.1") + else Version::NULL + end + end + end + + describe "#compiler" do + it "raises an error if no matching compiler can be found" do + software_spec.fails_with(:clang) + software_spec.fails_with(:llvm) + software_spec.fails_with(:gcc) + software_spec.fails_with(gcc: "4.8") + software_spec.fails_with(gcc: "4.7") + + expect { subject.compiler }.to raise_error(CompilerSelectionError) + end + + it "defaults to cc" do + expect(subject.compiler).to eq(cc) + end + + it "returns gcc if it fails with clang" do + software_spec.fails_with(:clang) + expect(subject.compiler).to eq(:gcc) + end + + it "returns clang if it fails with llvm" do + software_spec.fails_with(:llvm) + expect(subject.compiler).to eq(:clang) + end + + it "returns clang if it fails with gcc" do + software_spec.fails_with(:gcc) + expect(subject.compiler).to eq(:clang) + end + + it "returns clang if it fails with non-Apple gcc" do + software_spec.fails_with(gcc: "4.8") + expect(subject.compiler).to eq(:clang) + end + + it "still returns gcc-4.8 if it fails with gcc without a specific version" do + software_spec.fails_with(:clang) + software_spec.fails_with(:gcc) + expect(subject.compiler).to eq("gcc-4.8") + end + + it "returns gcc if it fails with clang and llvm" do + software_spec.fails_with(:clang) + software_spec.fails_with(:llvm) + expect(subject.compiler).to eq(:gcc) + end + + it "returns clang if it fails with gcc and llvm" do + software_spec.fails_with(:gcc) + software_spec.fails_with(:llvm) + expect(subject.compiler).to eq(:clang) + end + + example "returns gcc if it fails with a specific gcc version" do + software_spec.fails_with(:clang) + software_spec.fails_with(gcc: "4.8") + expect(subject.compiler).to eq(:gcc) + end + + example "returns a lower version of gcc if it fails with the highest version" do + software_spec.fails_with(:clang) + software_spec.fails_with(:gcc) + software_spec.fails_with(:llvm) + software_spec.fails_with(gcc: "4.8") + expect(subject.compiler).to eq("gcc-4.7") + end + + it "prefers gcc" do + software_spec.fails_with(:clang) + software_spec.fails_with(:gcc) + expect(subject.compiler).to eq("gcc-4.8") + end + + it "raises an error when gcc is missing" do + allow(versions).to receive(:gcc_build_version).and_return(Version::NULL) + + software_spec.fails_with(:clang) + software_spec.fails_with(:llvm) + software_spec.fails_with(gcc: "4.8") + software_spec.fails_with(gcc: "4.7") + + expect { subject.compiler }.to raise_error(CompilerSelectionError) + end + + it "raises an error when llvm and gcc are missing" do + allow(versions).to receive(:gcc_build_version).and_return(Version::NULL) + + software_spec.fails_with(:clang) + software_spec.fails_with(gcc: "4.8") + software_spec.fails_with(gcc: "4.7") + + expect { subject.compiler }.to raise_error(CompilerSelectionError) + end + end +end diff --git a/Library/Homebrew/test/compiler_selector_test.rb b/Library/Homebrew/test/compiler_selector_test.rb deleted file mode 100644 index aa1a6f97e..000000000 --- a/Library/Homebrew/test/compiler_selector_test.rb +++ /dev/null @@ -1,117 +0,0 @@ -require "testing_env" -require "compilers" -require "software_spec" - -class CompilerSelectorTests < Homebrew::TestCase - class Double < SoftwareSpec - def <<(cc) - fails_with(cc) - self - end - end - - class CompilerVersions - attr_accessor :gcc_4_0_build_version, :gcc_build_version, - :clang_build_version - - def initialize - @gcc_4_0_build_version = Version::NULL - @gcc_build_version = Version.create("5666") - @llvm_build_version = Version::NULL - @clang_build_version = Version.create("425") - end - - def non_apple_gcc_version(name) - case name - when "gcc-4.8" then Version.create("4.8.1") - when "gcc-4.7" then Version.create("4.7.1") - else Version::NULL - end - end - end - - def setup - super - @f = Double.new - @cc = :clang - @versions = CompilerVersions.new - @selector = CompilerSelector.new( - @f, @versions, [:clang, :gcc, :llvm, :gnu] - ) - end - - def actual_cc - @selector.compiler - end - - def test_all_compiler_failures - @f << :clang << :llvm << :gcc << { gcc: "4.8" } << { gcc: "4.7" } - assert_raises(CompilerSelectionError) { actual_cc } - end - - def test_no_compiler_failures - assert_equal @cc, actual_cc - end - - def test_fails_with_clang - @f << :clang - assert_equal :gcc, actual_cc - end - - def test_fails_with_llvm - @f << :llvm - assert_equal :clang, actual_cc - end - - def test_fails_with_gcc - @f << :gcc - assert_equal :clang, actual_cc - end - - def test_fails_with_non_apple_gcc - @f << { gcc: "4.8" } - assert_equal :clang, actual_cc - end - - def test_mixed_failures_1 - @f << :clang << :gcc - assert_equal "gcc-4.8", actual_cc - end - - def test_mixed_failures_2 - @f << :clang << :llvm - assert_equal :gcc, actual_cc - end - - def test_mixed_failures_3 - @f << :gcc << :llvm - assert_equal :clang, actual_cc - end - - def test_mixed_failures_4 - @f << :clang << { gcc: "4.8" } - assert_equal :gcc, actual_cc - end - - def test_mixed_failures_5 - @f << :clang << :gcc << :llvm << { gcc: "4.8" } - assert_equal "gcc-4.7", actual_cc - end - - def test_gcc_precedence - @f << :clang << :gcc - assert_equal "gcc-4.8", actual_cc - end - - def test_missing_gcc - @versions.gcc_build_version = Version::NULL - @f << :clang << :llvm << { gcc: "4.8" } << { gcc: "4.7" } - assert_raises(CompilerSelectionError) { actual_cc } - end - - def test_missing_llvm_and_gcc - @versions.gcc_build_version = Version::NULL - @f << :clang << { gcc: "4.8" } << { gcc: "4.7" } - assert_raises(CompilerSelectionError) { actual_cc } - end -end diff --git a/Library/Homebrew/test/config_test.rb b/Library/Homebrew/test/config_test.rb deleted file mode 100644 index 81da4660a..000000000 --- a/Library/Homebrew/test/config_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestConfig < IntegrationCommandTestCase - def test_config - assert_match "HOMEBREW_VERSION: #{HOMEBREW_VERSION}", - cmd("config") - end -end diff --git a/Library/Homebrew/test/create_test.rb b/Library/Homebrew/test/create_test.rb deleted file mode 100644 index aeee428aa..000000000 --- a/Library/Homebrew/test/create_test.rb +++ /dev/null @@ -1,12 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestCreate < IntegrationCommandTestCase - def test_create - url = "file://#{TEST_FIXTURE_DIR}/tarballs/testball-0.1.tbz" - cmd("create", url, "HOMEBREW_EDITOR" => "/bin/cat") - - formula_file = CoreTap.new.formula_dir/"testball.rb" - assert formula_file.exist?, "The formula source should have been created" - assert_match %Q(sha256 "#{TESTBALL_SHA256}"), formula_file.read - end -end diff --git a/Library/Homebrew/test/custom_command_test.rb b/Library/Homebrew/test/custom_command_test.rb deleted file mode 100644 index 8d05bc6c7..000000000 --- a/Library/Homebrew/test/custom_command_test.rb +++ /dev/null @@ -1,18 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestCustomCommand < IntegrationCommandTestCase - def test_custom_command - mktmpdir do |path| - cmd = "int-test-#{rand}" - file = "#{path}/brew-#{cmd}" - - File.open(file, "w") do |f| - f.write "#!/bin/sh\necho 'I am #{cmd}'\n" - end - FileUtils.chmod 0777, file - - assert_match "I am #{cmd}", - cmd(cmd, "PATH" => "#{path}#{File::PATH_SEPARATOR}#{ENV["PATH"]}") - end - end -end diff --git a/Library/Homebrew/test/dependency_expansion_spec.rb b/Library/Homebrew/test/dependency_expansion_spec.rb new file mode 100644 index 000000000..f955237a9 --- /dev/null +++ b/Library/Homebrew/test/dependency_expansion_spec.rb @@ -0,0 +1,136 @@ +require "dependency" + +describe Dependency do + def build_dep(name, tags = [], deps = []) + dep = described_class.new(name.to_s, tags) + allow(dep).to receive(:to_formula).and_return(double(deps: deps, name: name)) + dep + end + + let(:foo) { build_dep(:foo) } + let(:bar) { build_dep(:bar) } + let(:baz) { build_dep(:baz) } + let(:qux) { build_dep(:qux) } + let(:deps) { [foo, bar, baz, qux] } + let(:formula) { double(deps: deps, name: "f") } + + describe "::expand" do + it "yields dependent and dependency pairs" do + i = 0 + described_class.expand(formula) do |dependent, dep| + expect(dependent).to eq(formula) + expect(deps[i]).to eq(dep) + i += 1 + end + end + + it "returns the dependencies" do + expect(described_class.expand(formula)).to eq(deps) + end + + it "prunes all when given a block with ::prune" do + expect(described_class.expand(formula) { described_class.prune }).to be_empty + end + + it "can prune selectively" do + deps = described_class.expand(formula) do |_, dep| + described_class.prune if dep.name == "foo" + end + + expect(deps).to eq([bar, baz, qux]) + end + + it "preserves dependency order" do + allow(foo).to receive(:to_formula).and_return(double(name: "f", deps: [qux, baz])) + expect(described_class.expand(formula)).to eq([qux, baz, foo, bar]) + end + end + + it "skips optionals by default" do + deps = [build_dep(:foo, [:optional]), bar, baz, qux] + f = double(deps: deps, build: double(with?: false), name: "f") + expect(described_class.expand(f)).to eq([bar, baz, qux]) + end + + it "keeps recommended dependencies by default" do + deps = [build_dep(:foo, [:recommended]), bar, baz, qux] + f = double(deps: deps, build: double(with?: true), name: "f") + expect(described_class.expand(f)).to eq(deps) + end + + it "merges repeated dependencies with differing options" do + foo2 = build_dep(:foo, ["option"]) + baz2 = build_dep(:baz, ["option"]) + deps << foo2 << baz2 + deps = [foo2, bar, baz2, qux] + deps.zip(described_class.expand(formula)) do |expected, actual| + expect(expected.tags).to eq(actual.tags) + expect(expected).to eq(actual) + end + end + + it "merges dependencies and perserves env_proc" do + env_proc = double + dep = described_class.new("foo", [], env_proc) + allow(dep).to receive(:to_formula).and_return(double(deps: [], name: "foo")) + deps.replace([dep]) + expect(described_class.expand(formula).first.env_proc).to eq(env_proc) + end + + it "merges tags without duplicating them" do + foo2 = build_dep(:foo, ["option"]) + foo3 = build_dep(:foo, ["option"]) + deps << foo2 << foo3 + + expect(described_class.expand(formula).first.tags).to eq(%w[option]) + end + + it "skips parent but yields children with ::skip" do + f = double( + name: "f", + deps: [ + build_dep(:foo, [], [bar, baz]), + build_dep(:foo, [], [baz]), + ], + ) + + deps = described_class.expand(f) do |_dependent, dep| + described_class.skip if %w[foo qux].include? dep.name + end + + expect(deps).to eq([bar, baz]) + end + + it "keeps dependency but prunes recursive dependencies with ::keep_but_prune_recursive_deps" do + foo = build_dep(:foo, [:build], bar) + baz = build_dep(:baz, [:build]) + f = double(name: "f", deps: [foo, baz]) + + deps = described_class.expand(f) do |_dependent, dep| + described_class.keep_but_prune_recursive_deps if dep.build? + end + + expect(deps).to eq([foo, baz]) + end + + it "returns only the dependencies given as a collection as second argument" do + expect(formula.deps).to eq([foo, bar, baz, qux]) + expect(described_class.expand(formula, [bar, baz])).to eq([bar, baz]) + end + + it "doesn't raise an error when a dependency is cyclic" do + foo = build_dep(:foo) + bar = build_dep(:bar, [], [foo]) + allow(foo).to receive(:to_formula).and_return(double(deps: [bar], name: foo.name)) + f = double(name: "f", deps: [foo, bar]) + expect { described_class.expand(f) }.not_to raise_error + end + + it "cleans the expand stack" do + foo = build_dep(:foo) + allow(foo).to receive(:to_formula).and_raise(FormulaUnavailableError, foo.name) + f = double(name: "f", deps: [foo]) + expect { described_class.expand(f) }.to raise_error(FormulaUnavailableError) + expect(described_class.instance_variable_get(:@expand_stack)).to be_empty + end +end diff --git a/Library/Homebrew/test/dependency_expansion_test.rb b/Library/Homebrew/test/dependency_expansion_test.rb deleted file mode 100644 index 58a731121..000000000 --- a/Library/Homebrew/test/dependency_expansion_test.rb +++ /dev/null @@ -1,138 +0,0 @@ -require "testing_env" -require "dependency" - -class DependencyExpansionTests < Homebrew::TestCase - def build_dep(name, tags = [], deps = []) - dep = Dependency.new(name.to_s, tags) - dep.stubs(:to_formula).returns(stub(deps: deps, name: name)) - dep - end - - def setup - super - @foo = build_dep(:foo) - @bar = build_dep(:bar) - @baz = build_dep(:baz) - @qux = build_dep(:qux) - @deps = [@foo, @bar, @baz, @qux] - @f = stub(deps: @deps, name: "f") - end - - def test_expand_yields_dependent_and_dep_pairs - i = 0 - Dependency.expand(@f) do |dependent, dep| - assert_equal @f, dependent - assert_equal dep, @deps[i] - i += 1 - end - end - - def test_expand_no_block - assert_equal @deps, Dependency.expand(@f) - end - - def test_expand_prune_all - assert_empty Dependency.expand(@f) { Dependency.prune } - end - - def test_expand_selective_pruning - deps = Dependency.expand(@f) do |_, dep| - Dependency.prune if dep.name == "foo" - end - - assert_equal [@bar, @baz, @qux], deps - end - - def test_expand_preserves_dependency_order - @foo.stubs(:to_formula).returns(stub(name: "f", deps: [@qux, @baz])) - assert_equal [@qux, @baz, @foo, @bar], Dependency.expand(@f) - end - - def test_expand_skips_optionals_by_default - deps = [build_dep(:foo, [:optional]), @bar, @baz, @qux] - f = stub(deps: deps, build: stub(with?: false), name: "f") - assert_equal [@bar, @baz, @qux], Dependency.expand(f) - end - - def test_expand_keeps_recommendeds_by_default - deps = [build_dep(:foo, [:recommended]), @bar, @baz, @qux] - f = stub(deps: deps, build: stub(with?: true), name: "f") - assert_equal deps, Dependency.expand(f) - end - - def test_merges_repeated_deps_with_differing_options - @foo2 = build_dep(:foo, ["option"]) - @baz2 = build_dep(:baz, ["option"]) - @deps << @foo2 << @baz2 - deps = [@foo2, @bar, @baz2, @qux] - deps.zip(Dependency.expand(@f)) do |expected, actual| - assert_equal expected.tags, actual.tags - assert_equal expected, actual - end - end - - def test_merger_preserves_env_proc - env_proc = stub - dep = Dependency.new("foo", [], env_proc) - dep.stubs(:to_formula).returns(stub(deps: [], name: "foo")) - @deps.replace [dep] - assert_equal env_proc, Dependency.expand(@f).first.env_proc - end - - def test_merged_tags_no_dupes - @foo2 = build_dep(:foo, ["option"]) - @foo3 = build_dep(:foo, ["option"]) - @deps << @foo2 << @foo3 - - assert_equal %w[option], Dependency.expand(@f).first.tags - end - - def test_skip_skips_parent_but_yields_children - f = stub( - name: "f", - deps: [ - build_dep(:foo, [], [@bar, @baz]), - build_dep(:foo, [], [@baz]), - ], - ) - - deps = Dependency.expand(f) do |_dependent, dep| - Dependency.skip if %w[foo qux].include? dep.name - end - - assert_equal [@bar, @baz], deps - end - - def test_keep_dep_but_prune_recursive_deps - foo = build_dep(:foo, [:build], @bar) - baz = build_dep(:baz, [:build]) - f = stub(name: "f", deps: [foo, baz]) - - deps = Dependency.expand(f) do |_dependent, dep| - Dependency.keep_but_prune_recursive_deps if dep.build? - end - - assert_equal [foo, baz], deps - end - - def test_deps_with_collection_argument - assert_equal [@foo, @bar, @baz, @qux], @f.deps - assert_equal [@bar, @baz], Dependency.expand(@f, [@bar, @baz]) - end - - def test_cyclic_dependency - foo = build_dep(:foo) - bar = build_dep(:bar, [], [foo]) - foo.stubs(:to_formula).returns(stub(deps: [bar], name: "foo")) - f = stub(name: "f", deps: [foo, bar]) - assert_nothing_raised { Dependency.expand(f) } - end - - def test_clean_expand_stack - foo = build_dep(:foo) - foo.stubs(:to_formula).raises(FormulaUnavailableError, "foo") - f = stub(name: "f", deps: [foo]) - assert_raises(FormulaUnavailableError) { Dependency.expand(f) } - assert_empty Dependency.instance_variable_get(:@expand_stack) - end -end diff --git a/Library/Homebrew/test/deps_spec.rb b/Library/Homebrew/test/deps_spec.rb new file mode 100644 index 000000000..4c892c93d --- /dev/null +++ b/Library/Homebrew/test/deps_spec.rb @@ -0,0 +1,31 @@ +describe "brew deps", :integration_test do + before(:each) do + setup_test_formula "foo" + setup_test_formula "bar" + setup_test_formula "baz", <<-EOS.undent + url "https://example.com/baz-1.0" + depends_on "bar" + EOS + end + + it "outputs no dependencies for a Formula that has no dependencies" do + expect { brew "deps", "foo" } + .to be_a_success + .and not_to_output.to_stdout + .and not_to_output.to_stderr + end + + it "outputs a dependency for a Formula that has one dependency" do + expect { brew "deps", "bar" } + .to be_a_success + .and output("foo\n").to_stdout + .and not_to_output.to_stderr + end + + it "outputs all of a Formula's dependencies and their dependencies on separate lines" do + expect { brew "deps", "baz" } + .to be_a_success + .and output("bar\nfoo\n").to_stdout + .and not_to_output.to_stderr + end +end diff --git a/Library/Homebrew/test/deps_test.rb b/Library/Homebrew/test/deps_test.rb deleted file mode 100644 index 01639857c..000000000 --- a/Library/Homebrew/test/deps_test.rb +++ /dev/null @@ -1,16 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestDeps < IntegrationCommandTestCase - def test_deps - setup_test_formula "foo" - setup_test_formula "bar" - setup_test_formula "baz", <<-EOS.undent - url "https://example.com/baz-1.0" - depends_on "bar" - EOS - - assert_equal "", cmd("deps", "foo") - assert_equal "foo", cmd("deps", "bar") - assert_equal "bar\nfoo", cmd("deps", "baz") - end -end diff --git a/Library/Homebrew/test/desc_test.rb b/Library/Homebrew/test/desc_test.rb deleted file mode 100644 index 2ba498135..000000000 --- a/Library/Homebrew/test/desc_test.rb +++ /dev/null @@ -1,17 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestDesc < IntegrationCommandTestCase - def test_desc - setup_test_formula "testball" - - assert_equal "testball: Some test", cmd("desc", "testball") - assert_match "Pick one, and only one", cmd_fail("desc", "--search", "--name") - assert_match "You must provide a search term", cmd_fail("desc", "--search") - - desc_cache = HOMEBREW_CACHE/"desc_cache.json" - refute_predicate desc_cache, :exist?, "Cached file should not exist" - - cmd("desc", "--description", "testball") - assert_predicate desc_cache, :exist?, "Cached file should not exist" - end -end diff --git a/Library/Homebrew/test/dev-cmd/bottle_spec.rb b/Library/Homebrew/test/dev-cmd/bottle_spec.rb new file mode 100644 index 000000000..468ef2e90 --- /dev/null +++ b/Library/Homebrew/test/dev-cmd/bottle_spec.rb @@ -0,0 +1,30 @@ +describe "brew bottle", :integration_test do + it "builds a bottle for the given Formula" do + begin + shutup do + expect { brew "install", "--build-bottle", testball } + .to be_a_success + end + + expect { brew "bottle", "--no-rebuild", testball } + .to output(/Formula not from core or any taps/).to_stderr + .and not_to_output.to_stdout + .and be_a_failure + + setup_test_formula "testball" + + # `brew bottle` should not fail with dead symlink + # https://github.com/Homebrew/legacy-homebrew/issues/49007 + (HOMEBREW_CELLAR/"testball/0.1").cd do + FileUtils.ln_s "not-exist", "symlink" + end + + expect { brew "bottle", "--no-rebuild", "testball" } + .to output(/testball-0\.1.*\.bottle\.tar\.gz/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + ensure + FileUtils.rm_f Dir.glob("testball-0.1*.bottle.tar.gz") + end + end +end diff --git a/Library/Homebrew/test/dev-cmd/create_spec.rb b/Library/Homebrew/test/dev-cmd/create_spec.rb new file mode 100644 index 000000000..b7f96ec7f --- /dev/null +++ b/Library/Homebrew/test/dev-cmd/create_spec.rb @@ -0,0 +1,13 @@ +describe "brew create", :integration_test do + let(:url) { "file://#{TEST_FIXTURE_DIR}/tarballs/testball-0.1.tbz" } + let(:formula_file) { CoreTap.new.formula_dir/"testball.rb" } + + it "creates a new Formula file for a given URL" do + shutup do + brew "create", url, "HOMEBREW_EDITOR" => "/bin/cat" + end + + expect(formula_file).to exist + expect(formula_file.read).to match(%Q(sha256 "#{TESTBALL_SHA256}")) + end +end diff --git a/Library/Homebrew/test/dev-cmd/edit_spec.rb b/Library/Homebrew/test/dev-cmd/edit_spec.rb new file mode 100644 index 000000000..5cedb0524 --- /dev/null +++ b/Library/Homebrew/test/dev-cmd/edit_spec.rb @@ -0,0 +1,16 @@ +describe "brew edit", :integration_test do + it "opens a given Formula in an editor" do + HOMEBREW_REPOSITORY.cd do + shutup do + system "git", "init" + end + end + + setup_test_formula "testball" + + expect { brew "edit", "testball", "HOMEBREW_EDITOR" => "/bin/cat" } + .to output(/# something here/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + end +end diff --git a/Library/Homebrew/test/dev-cmd/formula_spec.rb b/Library/Homebrew/test/dev-cmd/formula_spec.rb new file mode 100644 index 000000000..cc5b3e9e8 --- /dev/null +++ b/Library/Homebrew/test/dev-cmd/formula_spec.rb @@ -0,0 +1,10 @@ +describe "brew formula", :integration_test do + it "prints a given Formula's path" do + formula_file = setup_test_formula "testball" + + expect { brew "formula", "testball" } + .to output("#{formula_file}\n").to_stdout + .and not_to_output.to_stderr + .and be_a_success + end +end diff --git a/Library/Homebrew/test/dev-cmd/pull_spec.rb b/Library/Homebrew/test/dev-cmd/pull_spec.rb new file mode 100644 index 000000000..3c0108df2 --- /dev/null +++ b/Library/Homebrew/test/dev-cmd/pull_spec.rb @@ -0,0 +1,60 @@ +describe "brew pull", :integration_test do + it "fails when no argument is given" do + expect { brew "pull" } + .to output(/This command requires at least one argument/).to_stderr + .and not_to_output.to_stdout + .and be_a_failure + end + + it "fetches a patch from a GitHub commit or pull request and applies it" do + skip "Requires network connection." if ENV["HOMEBREW_NO_GITHUB_API"] + + CoreTap.instance.path.cd do + shutup do + system "git", "init" + system "git", "checkout", "-b", "new-branch" + end + end + + expect { brew "pull", "https://bot.brew.sh/job/Homebrew\%20Testing/1028/" } + .to output(/Testing URLs require `\-\-bottle`!/).to_stderr + .and not_to_output.to_stdout + .and be_a_failure + + expect { brew "pull", "1" } + .to output(/Fetching patch/).to_stdout + .and output(/Current branch is new\-branch/).to_stderr + .and be_a_failure + + expect { brew "pull", "--bump", "8" } + .to output(/Fetching patch/).to_stdout + .and output(/No changed formulae found to bump/).to_stderr + .and be_a_failure + + expect { brew "pull", "--bump", "https://api.github.com/repos/Homebrew/homebrew-core/pulls/122" } + .to output(/Fetching patch/).to_stdout + .and output(/Can only bump one changed formula/).to_stderr + .and be_a_failure + + expect { brew "pull", "https://github.com/Homebrew/homebrew-core/pull/1" } + .to output(/Fetching patch/).to_stdout + .and output(/Patch failed to apply/).to_stderr + .and be_a_failure + end + + describe "--rebase" do + it "fails" do + expect { brew "pull", "--rebase" } + .to output(/You meant `git pull --rebase`./).to_stderr + .and not_to_output.to_stdout + .and be_a_failure + end + end + + it "fails when given 0" do + expect { brew "pull", "0" } + .to output(/Not a GitHub pull request or commit/).to_stderr + .and not_to_output.to_stdout + .and be_a_failure + end +end diff --git a/Library/Homebrew/test/dev-cmd/tap_spec.rb b/Library/Homebrew/test/dev-cmd/tap_spec.rb new file mode 100644 index 000000000..a24c67aae --- /dev/null +++ b/Library/Homebrew/test/dev-cmd/tap_spec.rb @@ -0,0 +1,75 @@ +describe "brew tap", :integration_test do + it "taps a given Tap" do + path = Tap::TAP_DIRECTORY/"homebrew/homebrew-foo" + path.mkpath + path.cd do + shutup do + system "git", "init" + system "git", "remote", "add", "origin", "https://github.com/Homebrew/homebrew-foo" + FileUtils.touch "readme" + system "git", "add", "--all" + system "git", "commit", "-m", "init" + end + end + + expect { brew "tap" } + .to output(%r{homebrew/foo}).to_stdout + .and not_to_output.to_stderr + .and be_a_success + + expect { brew "tap", "--list-official" } + .to output(%r{homebrew/science}).to_stdout + .and not_to_output.to_stderr + .and be_a_success + + expect { brew "tap-info" } + .to output(/2 taps/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + + expect { brew "tap-info", "homebrew/foo" } + .to output(%r{https://github\.com/Homebrew/homebrew-foo}).to_stdout + .and not_to_output.to_stderr + .and be_a_success + + expect { brew "tap-info", "--json=v1", "--installed" } + .to output(%r{https://github\.com/Homebrew/homebrew-foo}).to_stdout + .and not_to_output.to_stderr + .and be_a_success + + expect { brew "tap-pin", "homebrew/foo" } + .to output(%r{Pinned homebrew/foo}).to_stdout + .and not_to_output.to_stderr + .and be_a_success + + expect { brew "tap", "--list-pinned" } + .to output(%r{homebrew/foo}).to_stdout + .and not_to_output.to_stderr + .and be_a_success + + expect { brew "tap-unpin", "homebrew/foo" } + .to output(%r{Unpinned homebrew/foo}).to_stdout + .and not_to_output.to_stderr + .and be_a_success + + expect { brew "tap", "homebrew/bar", path/".git" } + .to output(/Tapped/).to_stdout + .and output(/Cloning/).to_stderr + .and be_a_success + + expect { brew "untap", "homebrew/bar" } + .to output(/Untapped/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + + expect { brew "tap", "homebrew/bar", path/".git", "-q", "--full" } + .to be_a_success + .and not_to_output.to_stdout + .and not_to_output.to_stderr + + expect { brew "untap", "homebrew/bar" } + .to output(/Untapped/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + end +end diff --git a/Library/Homebrew/test/dev-cmd/test_spec.rb b/Library/Homebrew/test/dev-cmd/test_spec.rb new file mode 100644 index 000000000..b73d042e4 --- /dev/null +++ b/Library/Homebrew/test/dev-cmd/test_spec.rb @@ -0,0 +1,56 @@ +describe "brew test", :integration_test do + it "fails when no argument is given" do + expect { brew "test" } + .to output(/This command requires a formula argument/).to_stderr + .and not_to_output.to_stdout + .and be_a_failure + end + + it "fails when a Formula is not installed" do + expect { brew "test", testball } + .to output(/Testing requires the latest version of testball/).to_stderr + .and not_to_output.to_stdout + .and be_a_failure + end + + it "fails when a Formula has no test" do + shutup do + expect { brew "install", testball }.to be_a_success + end + + expect { brew "test", testball } + .to output(/testball defines no test/).to_stderr + .and not_to_output.to_stdout + .and be_a_failure + end + + it "tests a given Formula" do + setup_test_formula "testball", <<-EOS.undent + head "https://github.com/example/testball2.git" + + devel do + url "file://#{TEST_FIXTURE_DIR}/tarballs/testball-0.1.tbz" + sha256 "#{TESTBALL_SHA256}" + end + + keg_only "just because" + + test do + end + EOS + + shutup do + expect { brew "install", "testball" }.to be_a_success + end + + expect { brew "test", "--HEAD", "testball" } + .to output(/Testing testball/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + + expect { brew "test", "--devel", "testball" } + .to output(/Testing testball/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + end +end diff --git a/Library/Homebrew/test/doctor_test.rb b/Library/Homebrew/test/doctor_test.rb deleted file mode 100644 index d2dc871f4..000000000 --- a/Library/Homebrew/test/doctor_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestDoctor < IntegrationCommandTestCase - def test_doctor - assert_match "This is an integration test", - cmd_fail("doctor", "check_integration_test") - end -end diff --git a/Library/Homebrew/test/edit_test.rb b/Library/Homebrew/test/edit_test.rb deleted file mode 100644 index 9b6ded651..000000000 --- a/Library/Homebrew/test/edit_test.rb +++ /dev/null @@ -1,11 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestEdit < IntegrationCommandTestCase - def test_edit - (HOMEBREW_REPOSITORY/".git").mkpath - setup_test_formula "testball" - - assert_match "# something here", - cmd("edit", "testball", "HOMEBREW_EDITOR" => "/bin/cat") - end -end diff --git a/Library/Homebrew/test/fetch_test.rb b/Library/Homebrew/test/fetch_test.rb deleted file mode 100644 index e08e545e3..000000000 --- a/Library/Homebrew/test/fetch_test.rb +++ /dev/null @@ -1,11 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestFetch < IntegrationCommandTestCase - def test_fetch - setup_test_formula "testball" - - cmd("fetch", "testball") - assert((HOMEBREW_CACHE/"testball-0.1.tbz").exist?, - "The tarball should have been cached") - end -end diff --git a/Library/Homebrew/test/formula_cmd_test.rb b/Library/Homebrew/test/formula_cmd_test.rb deleted file mode 100644 index abbe42d98..000000000 --- a/Library/Homebrew/test/formula_cmd_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestFormula < IntegrationCommandTestCase - def test_formula - formula_file = setup_test_formula "testball" - assert_equal formula_file.to_s, cmd("formula", "testball") - end -end diff --git a/Library/Homebrew/test/formula_spec.rb b/Library/Homebrew/test/formula_spec.rb new file mode 100644 index 000000000..1e064912f --- /dev/null +++ b/Library/Homebrew/test/formula_spec.rb @@ -0,0 +1,1295 @@ +require "test/support/fixtures/testball" +require "formula" + +RSpec::Matchers.alias_matcher :follow_installed_alias, :be_follow_installed_alias +RSpec::Matchers.alias_matcher :have_any_version_installed, :be_any_version_installed +RSpec::Matchers.alias_matcher :need_migration, :be_migration_needed + +RSpec::Matchers.alias_matcher :have_changed_installed_alias_target, :be_installed_alias_target_changed +RSpec::Matchers.alias_matcher :supersede_an_installed_formula, :be_supersedes_an_installed_formula +RSpec::Matchers.alias_matcher :have_changed_alias, :be_alias_changed + +RSpec::Matchers.alias_matcher :have_option_defined, :be_option_defined +RSpec::Matchers.alias_matcher :have_post_install_defined, :be_post_install_defined +RSpec::Matchers.alias_matcher :have_test_defined, :be_test_defined +RSpec::Matchers.alias_matcher :pour_bottle, :be_pour_bottle + +describe Formula do + describe "::new" do + let(:klass) do + Class.new(described_class) do + url "http://example.com/foo-1.0.tar.gz" + end + end + + let(:name) { "formula_name" } + let(:path) { Formulary.core_path(name) } + let(:spec) { :stable } + let(:alias_name) { "baz@1" } + let(:alias_path) { CoreTap.instance.alias_dir/alias_name } + let(:f) { klass.new(name, path, spec) } + let(:f_alias) { klass.new(name, path, spec, alias_path: alias_path) } + + specify "formula instantiation" do + expect(f.name).to eq(name) + expect(f.specified_name).to eq(name) + expect(f.full_name).to eq(name) + expect(f.full_specified_name).to eq(name) + expect(f.path).to eq(path) + expect(f.alias_path).to be nil + expect(f.alias_name).to be nil + expect(f.full_alias_name).to be nil + expect { klass.new }.to raise_error(ArgumentError) + end + + specify "formula instantiation with alias" do + expect(f_alias.name).to eq(name) + expect(f_alias.full_name).to eq(name) + expect(f_alias.path).to eq(path) + expect(f_alias.alias_path).to eq(alias_path) + expect(f_alias.alias_name).to eq(alias_name) + expect(f_alias.specified_name).to eq(alias_name) + expect(f_alias.full_alias_name).to eq(alias_name) + expect(f_alias.full_specified_name).to eq(alias_name) + expect { klass.new }.to raise_error(ArgumentError) + end + + context "in a Tap" do + let(:tap) { Tap.new("foo", "bar") } + let(:path) { (tap.path/"Formula/#{name}.rb") } + let(:full_name) { "#{tap.user}/#{tap.repo}/#{name}" } + let(:full_alias_name) { "#{tap.user}/#{tap.repo}/#{alias_name}" } + + specify "formula instantiation" do + expect(f.name).to eq(name) + expect(f.specified_name).to eq(name) + expect(f.full_name).to eq(full_name) + expect(f.full_specified_name).to eq(full_name) + expect(f.path).to eq(path) + expect(f.alias_path).to be nil + expect(f.alias_name).to be nil + expect(f.full_alias_name).to be nil + expect { klass.new }.to raise_error(ArgumentError) + end + + specify "formula instantiation with alias" do + expect(f_alias.name).to eq(name) + expect(f_alias.full_name).to eq(full_name) + expect(f_alias.path).to eq(path) + expect(f_alias.alias_path).to eq(alias_path) + expect(f_alias.alias_name).to eq(alias_name) + expect(f_alias.specified_name).to eq(alias_name) + expect(f_alias.full_alias_name).to eq(full_alias_name) + expect(f_alias.full_specified_name).to eq(full_alias_name) + expect { klass.new }.to raise_error(ArgumentError) + end + end + end + + describe "#follow_installed_alias?" do + let(:f) do + formula do + url "foo-1.0" + end + end + + it "returns true by default" do + expect(f).to follow_installed_alias + end + + it "can be set to true" do + f.follow_installed_alias = true + expect(f).to follow_installed_alias + end + + it "can be set to false" do + f.follow_installed_alias = false + expect(f).not_to follow_installed_alias + end + end + + example "installed alias with core" do + f = formula do + url "foo-1.0" + end + + build_values_with_no_installed_alias = [ + nil, + BuildOptions.new({}, {}), + Tab.new(source: { "path" => f.path.to_s }), + ] + build_values_with_no_installed_alias.each do |build| + f.build = build + expect(f.installed_alias_path).to be nil + expect(f.installed_alias_name).to be nil + expect(f.full_installed_alias_name).to be nil + expect(f.installed_specified_name).to eq(f.name) + expect(f.full_installed_specified_name).to eq(f.name) + end + + alias_name = "bar" + alias_path = "#{CoreTap.instance.alias_dir}/#{alias_name}" + + f.build = Tab.new(source: { "path" => alias_path }) + + expect(f.installed_alias_path).to eq(alias_path) + expect(f.installed_alias_name).to eq(alias_name) + expect(f.full_installed_alias_name).to eq(alias_name) + expect(f.installed_specified_name).to eq(alias_name) + expect(f.full_installed_specified_name).to eq(alias_name) + end + + example "installed alias with tap" do + tap = Tap.new("user", "repo") + name = "foo" + path = "#{tap.path}/Formula/#{name}.rb" + f = formula name, path: path do + url "foo-1.0" + end + + build_values_with_no_installed_alias = [nil, BuildOptions.new({}, {}), Tab.new(source: { "path" => f.path })] + build_values_with_no_installed_alias.each do |build| + f.build = build + expect(f.installed_alias_path).to be nil + expect(f.installed_alias_name).to be nil + expect(f.full_installed_alias_name).to be nil + expect(f.installed_specified_name).to eq(f.name) + expect(f.full_installed_specified_name).to eq(f.full_name) + end + + alias_name = "bar" + full_alias_name = "#{tap.user}/#{tap.repo}/#{alias_name}" + alias_path = "#{tap.alias_dir}/#{alias_name}" + + f.build = Tab.new(source: { "path" => alias_path }) + + expect(f.installed_alias_path).to eq(alias_path) + expect(f.installed_alias_name).to eq(alias_name) + expect(f.full_installed_alias_name).to eq(full_alias_name) + expect(f.installed_specified_name).to eq(alias_name) + expect(f.full_installed_specified_name).to eq(full_alias_name) + end + + specify "#prefix" do + f = Testball.new + expect(f.prefix).to eq(HOMEBREW_CELLAR/f.name/"0.1") + expect(f.prefix).to be_kind_of(Pathname) + end + + example "revised prefix" do + f = Class.new(Testball) { revision(1) }.new + expect(f.prefix).to eq(HOMEBREW_CELLAR/f.name/"0.1_1") + end + + specify "#any_version_installed?" do + f = formula do + url "foo" + version "1.0" + end + + expect(f).not_to have_any_version_installed + + prefix = HOMEBREW_CELLAR/f.name/"0.1" + prefix.mkpath + FileUtils.touch prefix/Tab::FILENAME + + expect(f).to have_any_version_installed + end + + specify "#migration_needed" do + f = Testball.new("newname") + f.instance_variable_set(:@oldname, "oldname") + f.instance_variable_set(:@tap, CoreTap.instance) + + oldname_prefix = (HOMEBREW_CELLAR/"oldname/2.20") + newname_prefix = (HOMEBREW_CELLAR/"newname/2.10") + + oldname_prefix.mkpath + oldname_tab = Tab.empty + oldname_tab.tabfile = oldname_prefix/Tab::FILENAME + oldname_tab.write + + expect(f).not_to need_migration + + oldname_tab.tabfile.unlink + oldname_tab.source["tap"] = "homebrew/core" + oldname_tab.write + + expect(f).to need_migration + + newname_prefix.mkpath + + expect(f).not_to need_migration + end + + describe "#installed?" do + let(:f) { Testball.new } + + it "returns false if the #installed_prefix is not a directory" do + allow(f).to receive(:installed_prefix).and_return(double(directory?: false)) + expect(f).not_to be_installed + end + + it "returns false if the #installed_prefix does not have children" do + allow(f).to receive(:installed_prefix).and_return(double(directory?: true, children: [])) + expect(f).not_to be_installed + end + + it "returns true if the #installed_prefix has children" do + allow(f).to receive(:installed_prefix).and_return(double(directory?: true, children: [double])) + expect(f).to be_installed + end + end + + describe "#installed prefix" do + let(:f) do + formula do + url "foo" + version "1.9" + + head "foo" + + devel do + url "foo" + version "2.1-devel" + end + end + end + + let(:stable_prefix) { HOMEBREW_CELLAR/f.name/f.version } + let(:devel_prefix) { HOMEBREW_CELLAR/f.name/f.devel.version } + let(:head_prefix) { HOMEBREW_CELLAR/f.name/f.head.version } + + it "is the same as #prefix by default" do + expect(f.installed_prefix).to eq(f.prefix) + end + + it "returns the stable prefix if it is installed" do + stable_prefix.mkpath + expect(f.installed_prefix).to eq(stable_prefix) + end + + it "returns the devel prefix if it is installed" do + devel_prefix.mkpath + expect(f.installed_prefix).to eq(devel_prefix) + end + + it "returns the head prefix if it is installed" do + head_prefix.mkpath + expect(f.installed_prefix).to eq(head_prefix) + end + + it "returns the stable prefix if head is outdated" do + head_prefix.mkpath + + tab = Tab.empty + tab.tabfile = head_prefix/Tab::FILENAME + tab.source["versions"] = { "stable" => "1.0" } + tab.write + + expect(f.installed_prefix).to eq(stable_prefix) + end + + it "returns the stable prefix if head and devel are outdated" do + head_prefix.mkpath + + tab = Tab.empty + tab.tabfile = head_prefix/Tab::FILENAME + tab.source["versions"] = { "stable" => "1.9", "devel" => "2.0" } + tab.write + + expect(f.installed_prefix).to eq(stable_prefix) + end + + it "returns the devel prefix if the active specification is :devel" do + f.active_spec = :devel + expect(f.installed_prefix).to eq(devel_prefix) + end + + it "returns the head prefix if the active specification is :head" do + f.active_spec = :head + expect(f.installed_prefix).to eq(head_prefix) + end + end + + describe "#latest_head_prefix" do + let(:f) { Testball.new } + + it "returns the latest head prefix" do + stamps_with_revisions = [ + [111111, 1], + [222222, 0], + [222222, 1], + [222222, 2], + ] + + stamps_with_revisions.each do |stamp, revision| + version = "HEAD-#{stamp}" + version << "_#{revision}" unless revision.zero? + + prefix = f.rack/version + prefix.mkpath + + tab = Tab.empty + tab.tabfile = prefix/Tab::FILENAME + tab.source_modified_time = stamp + tab.write + end + + prefix = HOMEBREW_CELLAR/f.name/"HEAD-222222_2" + + expect(f.latest_head_prefix).to eq(prefix) + end + end + + specify "equality" do + x = Testball.new + y = Testball.new + + expect(x).to eq(y) + expect(x).to eql(y) + expect(x.hash).to eq(y.hash) + end + + specify "inequality" do + x = Testball.new("foo") + y = Testball.new("bar") + + expect(x).not_to eq(y) + expect(x).not_to eql(y) + expect(x.hash).not_to eq(y.hash) + end + + specify "comparison with non formula objects does not raise" do + expect(Object.new).not_to eq(Testball.new) + end + + specify "#<=>" do + expect(Testball.new <=> Object.new).to be nil + end + + describe "#installed_alias_path" do + example "alias paths with build options" do + alias_path = (CoreTap.instance.alias_dir/"another_name") + + f = formula alias_path: alias_path do + url "foo-1.0" + end + f.build = BuildOptions.new({}, {}) + + expect(f.alias_path).to eq(alias_path) + expect(f.installed_alias_path).to be nil + end + + example "alias paths with tab with non alias source path" do + alias_path = (CoreTap.instance.alias_dir/"another_name") + source_path = (CoreTap.instance.formula_dir/"another_other_name") + + f = formula alias_path: alias_path do + url "foo-1.0" + end + f.build = Tab.new(source: { "path" => source_path.to_s }) + + expect(f.alias_path).to eq(alias_path) + expect(f.installed_alias_path).to be nil + end + + example "alias paths with tab with alias source path" do + alias_path = (CoreTap.instance.alias_dir/"another_name") + source_path = (CoreTap.instance.alias_dir/"another_other_name") + + f = formula alias_path: alias_path do + url "foo-1.0" + end + f.build = Tab.new(source: { "path" => source_path.to_s }) + + expect(f.alias_path).to eq(alias_path) + expect(f.installed_alias_path).to eq(source_path.to_s) + end + end + + describe "::installed_with_alias_path" do + specify "with alias path with nil" do + expect(described_class.installed_with_alias_path(nil)).to be_empty + end + + specify "with alias path with a path" do + alias_path = "#{CoreTap.instance.alias_dir}/alias" + different_alias_path = "#{CoreTap.instance.alias_dir}/another_alias" + + formula_with_alias = formula "foo" do + url "foo-1.0" + end + formula_with_alias.build = Tab.empty + formula_with_alias.build.source["path"] = alias_path + + formula_without_alias = formula "bar" do + url "bar-1.0" + end + formula_without_alias.build = Tab.empty + formula_without_alias.build.source["path"] = formula_without_alias.path.to_s + + formula_with_different_alias = formula "baz" do + url "baz-1.0" + end + formula_with_different_alias.build = Tab.empty + formula_with_different_alias.build.source["path"] = different_alias_path + + formulae = [ + formula_with_alias, + formula_without_alias, + formula_with_different_alias, + ] + + allow(described_class).to receive(:installed).and_return(formulae) + + expect(described_class.installed_with_alias_path(alias_path)) + .to eq([formula_with_alias]) + end + end + + specify "spec integration" do + f = formula do + homepage "http://example.com" + + url "http://example.com/test-0.1.tbz" + mirror "http://example.org/test-0.1.tbz" + sha256 TEST_SHA256 + + head "http://example.com/test.git", tag: "foo" + + devel do + url "http://example.com/test-0.2.tbz" + mirror "http://example.org/test-0.2.tbz" + sha256 TEST_SHA256 + end + end + + expect(f.homepage).to eq("http://example.com") + expect(f.version).to eq(Version.create("0.1")) + expect(f).to be_stable + expect(f.stable.version).to eq(Version.create("0.1")) + expect(f.devel.version).to eq(Version.create("0.2")) + expect(f.head.version).to eq(Version.create("HEAD")) + end + + specify "#active_spec=" do + f = formula do + url "foo" + version "1.0" + revision 1 + + devel do + url "foo" + version "1.0beta" + end + end + + expect(f.active_spec_sym).to eq(:stable) + expect(f.send(:active_spec)).to eq(f.stable) + expect(f.pkg_version.to_s).to eq("1.0_1") + + f.active_spec = :devel + + expect(f.active_spec_sym).to eq(:devel) + expect(f.send(:active_spec)).to eq(f.devel) + expect(f.pkg_version.to_s).to eq("1.0beta_1") + expect { f.active_spec = :head }.to raise_error(FormulaSpecificationError) + end + + specify "class specs are always initialized" do + f = formula do + url "foo-1.0" + end + + expect(f.class.stable).to be_kind_of(SoftwareSpec) + expect(f.class.devel).to be_kind_of(SoftwareSpec) + expect(f.class.head).to be_kind_of(SoftwareSpec) + end + + specify "incomplete instance specs are not accessible" do + f = formula do + url "foo-1.0" + end + + expect(f.devel).to be nil + expect(f.head).to be nil + end + + it "honors attributes declared before specs" do + f = formula do + url "foo-1.0" + + depends_on "foo" + + devel do + url "foo-1.1" + end + end + + expect(f.class.stable.deps.first.name).to eq("foo") + expect(f.class.devel.deps.first.name).to eq("foo") + expect(f.class.head.deps.first.name).to eq("foo") + end + + describe "#pkg_version" do + specify "simple version" do + f = formula do + url "foo-1.0.bar" + end + + expect(f.pkg_version).to eq(PkgVersion.parse("1.0")) + end + + specify "version with revision" do + f = formula do + url "foo-1.0.bar" + revision 1 + end + + expect(f.pkg_version).to eq(PkgVersion.parse("1.0_1")) + end + + specify "head uses revisions" do + f = formula "test", spec: :head do + url "foo-1.0.bar" + revision 1 + + head "foo" + end + + expect(f.pkg_version).to eq(PkgVersion.parse("HEAD_1")) + end + end + + specify "#update_head_version" do + f = formula do + head "foo", using: :git + end + + cached_location = f.head.downloader.cached_location + cached_location.mkpath + cached_location.cd do + FileUtils.touch "LICENSE" + + shutup do + system("git", "init") + system("git", "add", "--all") + system("git", "commit", "-m", "Initial commit") + end + end + + f.update_head_version + + expect(f.head.version).to eq(Version.create("HEAD-5658946")) + end + + specify "legacy options" do + f = formula do + url "foo-1.0" + + def options + [ + ["--foo", "desc"], + ["--bar", "desc"], + ] + end + + option("baz") + end + + expect(f).to have_option_defined("foo") + expect(f).to have_option_defined("bar") + expect(f).to have_option_defined("baz") + end + + specify "#desc" do + f = formula do + desc "a formula" + + url "foo-1.0" + end + + expect(f.desc).to eq("a formula") + end + + specify "#post_install_defined?" do + f1 = formula do + url "foo-1.0" + + def post_install + # do nothing + end + end + + f2 = formula do + url "foo-1.0" + end + + expect(f1).to have_post_install_defined + expect(f2).not_to have_post_install_defined + end + + specify "#test_defined?" do + f1 = formula do + url "foo-1.0" + + def test + # do nothing + end + end + + f2 = formula do + url "foo-1.0" + end + + expect(f1).to have_test_defined + expect(f2).not_to have_test_defined + end + + specify "test fixtures" do + f1 = formula do + url "foo-1.0" + end + + expect(f1.test_fixtures("foo")).to eq(Pathname.new("#{HOMEBREW_LIBRARY_PATH}/test/support/fixtures/foo")) + end + + specify "dependencies" do + f1 = formula "f1" do + url "f1-1.0" + end + + f2 = formula "f2" do + url "f2-1.0" + end + + f3 = formula "f3" do + url "f3-1.0" + + depends_on "f1" => :build + depends_on "f2" + end + + f4 = formula "f4" do + url "f4-1.0" + + depends_on "f1" + end + + stub_formula_loader(f1) + stub_formula_loader(f2) + stub_formula_loader(f3) + stub_formula_loader(f4) + + f5 = formula "f5" do + url "f5-1.0" + + depends_on "f3" => :build + depends_on "f4" + end + + expect(f5.deps.map(&:name)).to eq(["f3", "f4"]) + expect(f5.recursive_dependencies.map(&:name)).to eq(["f1", "f2", "f3", "f4"]) + expect(f5.runtime_dependencies.map(&:name)).to eq(["f1", "f4"]) + end + + specify "runtime dependencies with optional deps from tap" do + tap_loader = double + + allow(tap_loader).to receive(:get_formula).and_raise(RuntimeError, "tried resolving tap formula") + allow(Formulary).to receive(:loader_for).with("foo/bar/f1", from: nil).and_return(tap_loader) + stub_formula_loader(formula("f2") { url("f2-1.0") }, "baz/qux/f2") + + f3 = formula "f3" do + url "f3-1.0" + + depends_on "foo/bar/f1" => :optional + depends_on "baz/qux/f2" + end + + expect(f3.runtime_dependencies.map(&:name)).to eq(["baz/qux/f2"]) + + stub_formula_loader(formula("f1") { url("f1-1.0") }, "foo/bar/f1") + f3.build = BuildOptions.new(Options.create(["--with-f1"]), f3.options) + + expect(f3.runtime_dependencies.map(&:name)).to eq(["foo/bar/f1", "baz/qux/f2"]) + end + + specify "requirements" do + f1 = formula "f1" do + url "f1-1" + + depends_on :python + depends_on x11: :recommended + depends_on xcode: ["1.0", :optional] + end + stub_formula_loader(f1) + + python = PythonRequirement.new + x11 = X11Requirement.new("x11", [:recommended]) + xcode = XcodeRequirement.new(["1.0", :optional]) + + expect(Set.new(f1.recursive_requirements)).to eq(Set[python, x11]) + + f1.build = BuildOptions.new(["--with-xcode", "--without-x11"], f1.options) + + expect(Set.new(f1.recursive_requirements)).to eq(Set[python, xcode]) + + f1.build = f1.stable.build + f2 = formula "f2" do + url "f2-1" + + depends_on "f1" + end + + expect(Set.new(f2.recursive_requirements)).to eq(Set[python, x11]) + expect(Set.new(f2.recursive_requirements {})).to eq(Set[python, x11, xcode]) + + requirements = f2.recursive_requirements do |_dependent, requirement| + Requirement.prune if requirement.is_a?(PythonRequirement) + end + + expect(Set.new(requirements)).to eq(Set[x11, xcode]) + end + + specify "#to_hash" do + f1 = formula "foo" do + url "foo-1.0" + + bottle do + cellar(:any) + sha256(TEST_SHA256 => Utils::Bottles.tag) + end + end + + h = f1.to_hash + + expect(h).to be_a(Hash) + expect(h["name"]).to eq("foo") + expect(h["full_name"]).to eq("foo") + expect(h["versions"]["stable"]).to eq("1.0") + expect(h["versions"]["bottle"]).to be_truthy + end + + describe "#eligible_kegs_for_cleanup" do + it "returns Kegs eligible for cleanup" do + f1 = Class.new(Testball) do + version("1.0") + end.new + + f2 = Class.new(Testball) do + version("0.2") + version_scheme(1) + end.new + + f3 = Class.new(Testball) do + version("0.3") + version_scheme(1) + end.new + + f4 = Class.new(Testball) do + version("0.1") + version_scheme(2) + end.new + + shutup do + [f1, f2, f3, f4].each do |f| + f.brew { f.install } + Tab.create(f, DevelopmentTools.default_compiler, :libcxx).write + end + end + + expect(f1).to be_installed + expect(f2).to be_installed + expect(f3).to be_installed + expect(f4).to be_installed + expect(f3.eligible_kegs_for_cleanup.sort_by(&:version)) + .to eq([f2, f1].map { |f| Keg.new(f.prefix) }) + end + + specify "with pinned Keg" do + f1 = Class.new(Testball) { version("0.1") }.new + f2 = Class.new(Testball) { version("0.2") }.new + f3 = Class.new(Testball) { version("0.3") }.new + + shutup do + f1.brew { f1.install } + f1.pin + f2.brew { f2.install } + f3.brew { f3.install } + end + + expect(f1.prefix).to eq((HOMEBREW_PINNED_KEGS/f1.name).resolved_path) + expect(f1).to be_installed + expect(f2).to be_installed + expect(f3).to be_installed + expect(shutup { f3.eligible_kegs_for_cleanup }).to eq([Keg.new(f2.prefix)]) + end + + specify "with HEAD installed" do + f = formula do + version("0.1") + head("foo") + end + + stable_prefix = f.installed_prefix + stable_prefix.mkpath + + [["000000_1", 1], ["111111", 2], ["111111_1", 2]].each do |pkg_version_suffix, stamp| + prefix = f.prefix("HEAD-#{pkg_version_suffix}") + prefix.mkpath + tab = Tab.empty + tab.tabfile = prefix/Tab::FILENAME + tab.source_modified_time = stamp + tab.write + end + + eligible_kegs = f.installed_kegs - [Keg.new(f.prefix("HEAD-111111_1"))] + expect(f.eligible_kegs_for_cleanup).to eq(eligible_kegs) + end + end + + describe "#pour_bottle?" do + it "returns false if set to false" do + f = formula "foo" do + url "foo-1.0" + + def pour_bottle? + false + end + end + + expect(f).not_to pour_bottle + end + + it "returns true if set to true" do + f = formula "foo" do + url "foo-1.0" + + def pour_bottle? + true + end + end + + expect(f).to pour_bottle + end + + it "returns false if set to false via DSL" do + f = formula "foo" do + url "foo-1.0" + + pour_bottle? do + reason "false reason" + satisfy { (var == etc) } + end + end + + expect(f).not_to pour_bottle + end + + it "returns true if set to true via DSL" do + f = formula "foo" do + url "foo-1.0" + + pour_bottle? do + reason "true reason" + satisfy { true } + end + end + + expect(f).to pour_bottle + end + end + + describe "alias changes" do + let(:f) do + formula "formula_name", alias_path: alias_path do + url "foo-1.0" + end + end + + let(:new_formula) do + formula "new_formula_name", alias_path: alias_path do + url "foo-1.1" + end + end + + let(:tab) { Tab.empty } + let(:alias_path) { "#{CoreTap.instance.alias_dir}/bar" } + + before(:each) do + allow(described_class).to receive(:installed).and_return([f]) + + f.build = tab + new_formula.build = tab + end + + specify "alias changes when not installed with alias" do + tab.source["path"] = Formulary.core_path(f.name).to_s + + expect(f.current_installed_alias_target).to be nil + expect(f.latest_formula).to eq(f) + expect(f).not_to have_changed_installed_alias_target + expect(f).not_to supersede_an_installed_formula + expect(f).not_to have_changed_alias + expect(f.old_installed_formulae).to be_empty + end + + specify "alias changes when not changed" do + tab.source["path"] = alias_path + stub_formula_loader(f, alias_path) + + expect(f.current_installed_alias_target).to eq(f) + expect(f.latest_formula).to eq(f) + expect(f).not_to have_changed_installed_alias_target + expect(f).not_to supersede_an_installed_formula + expect(f).not_to have_changed_alias + expect(f.old_installed_formulae).to be_empty + end + + specify "alias changes when new alias target" do + tab.source["path"] = alias_path + stub_formula_loader(new_formula, alias_path) + + expect(f.current_installed_alias_target).to eq(new_formula) + expect(f.latest_formula).to eq(new_formula) + expect(f).to have_changed_installed_alias_target + expect(f).not_to supersede_an_installed_formula + expect(f).to have_changed_alias + expect(f.old_installed_formulae).to be_empty + end + + specify "alias changes when old formulae installed" do + tab.source["path"] = alias_path + stub_formula_loader(new_formula, alias_path) + + expect(new_formula.current_installed_alias_target).to eq(new_formula) + expect(new_formula.latest_formula).to eq(new_formula) + expect(new_formula).not_to have_changed_installed_alias_target + expect(new_formula).to supersede_an_installed_formula + expect(new_formula).to have_changed_alias + expect(new_formula.old_installed_formulae).to eq([f]) + end + end + + describe "#outdated_kegs" do + let(:outdated_prefix) { (HOMEBREW_CELLAR/"#{f.name}/1.11") } + let(:same_prefix) { (HOMEBREW_CELLAR/"#{f.name}/1.20") } + let(:greater_prefix) { (HOMEBREW_CELLAR/"#{f.name}/1.21") } + let(:head_prefix) { (HOMEBREW_CELLAR/"#{f.name}/HEAD") } + let(:old_alias_target_prefix) { (HOMEBREW_CELLAR/"#{old_formula.name}/1.0") } + + let(:f) do + formula do + url "foo" + version "1.20" + end + end + + let(:old_formula) do + formula "foo@1" do + url "foo-1.0" + end + end + + let(:new_formula) do + formula "foo@2" do + url "foo-2.0" + end + end + + let(:alias_path) { "#{f.tap.alias_dir}/bar" } + + def setup_tab_for_prefix(prefix, options = {}) + prefix.mkpath + tab = Tab.empty + tab.tabfile = prefix/Tab::FILENAME + tab.source["path"] = options[:path].to_s if options[:path] + tab.source["tap"] = options[:tap] if options[:tap] + tab.source["versions"] = options[:versions] if options[:versions] + tab.source_modified_time = options[:source_modified_time].to_i + tab.write unless options[:no_write] + tab + end + + def reset_outdated_kegs + f.instance_variable_set(:@outdated_kegs, nil) + end + + example "greater different tap installed" do + setup_tab_for_prefix(greater_prefix, tap: "user/repo") + expect(f.outdated_kegs).to be_empty + end + + example "greater same tap installed" do + f.instance_variable_set(:@tap, CoreTap.instance) + setup_tab_for_prefix(greater_prefix, tap: "homebrew/core") + expect(f.outdated_kegs).to be_empty + end + + example "outdated different tap installed" do + setup_tab_for_prefix(outdated_prefix, tap: "user/repo") + expect(f.outdated_kegs).not_to be_empty + end + + example "outdated same tap installed" do + f.instance_variable_set(:@tap, CoreTap.instance) + setup_tab_for_prefix(outdated_prefix, tap: "homebrew/core") + expect(f.outdated_kegs).not_to be_empty + end + + example "outdated follow alias and alias unchanged" do + f.follow_installed_alias = true + f.build = setup_tab_for_prefix(same_prefix, path: alias_path) + stub_formula_loader(f, alias_path) + expect(f.outdated_kegs).to be_empty + end + + example "outdated follow alias and alias changed and new target not installed" do + f.follow_installed_alias = true + f.build = setup_tab_for_prefix(same_prefix, path: alias_path) + stub_formula_loader(new_formula, alias_path) + expect(f.outdated_kegs).not_to be_empty + end + + example "outdated follow alias and alias changed and new target installed" do + f.follow_installed_alias = true + f.build = setup_tab_for_prefix(same_prefix, path: alias_path) + stub_formula_loader(new_formula, alias_path) + setup_tab_for_prefix(new_formula.prefix) + expect(f.outdated_kegs).to be_empty + end + + example "outdated no follow alias and alias unchanged" do + f.follow_installed_alias = false + f.build = setup_tab_for_prefix(same_prefix, path: alias_path) + stub_formula_loader(f, alias_path) + expect(f.outdated_kegs).to be_empty + end + + example "outdated no follow alias and alias changed" do + f.follow_installed_alias = false + f.build = setup_tab_for_prefix(same_prefix, path: alias_path) + + f2 = formula "foo@2" do + url "foo-2.0" + end + + stub_formula_loader(f2, alias_path) + expect(f.outdated_kegs).to be_empty + end + + example "outdated old alias targets installed" do + f = formula alias_path: alias_path do + url "foo-1.0" + end + + tab = setup_tab_for_prefix(old_alias_target_prefix, path: alias_path) + old_formula.build = tab + allow(described_class).to receive(:installed).and_return([old_formula]) + expect(f.outdated_kegs).not_to be_empty + end + + example "outdated old alias targets not installed" do + f = formula alias_path: alias_path do + url "foo-1.0" + end + + tab = setup_tab_for_prefix(old_alias_target_prefix, path: old_formula.path) + old_formula.build = tab + allow(described_class).to receive(:installed).and_return([old_formula]) + expect(f.outdated_kegs).to be_empty + end + + example "outdated same head installed" do + f.instance_variable_set(:@tap, CoreTap.instance) + setup_tab_for_prefix(head_prefix, tap: "homebrew/core") + expect(f.outdated_kegs).to be_empty + end + + example "outdated different head installed" do + f.instance_variable_set(:@tap, CoreTap.instance) + setup_tab_for_prefix(head_prefix, tap: "user/repo") + expect(f.outdated_kegs).to be_empty + end + + example "outdated mixed taps greater version installed" do + f.instance_variable_set(:@tap, CoreTap.instance) + setup_tab_for_prefix(outdated_prefix, tap: "homebrew/core") + setup_tab_for_prefix(greater_prefix, tap: "user/repo") + + expect(f.outdated_kegs).to be_empty + + setup_tab_for_prefix(greater_prefix, tap: "homebrew/core") + reset_outdated_kegs + + expect(f.outdated_kegs).to be_empty + end + + example "outdated mixed taps outdated version installed" do + f.instance_variable_set(:@tap, CoreTap.instance) + + extra_outdated_prefix = HOMEBREW_CELLAR/f.name/"1.0" + + setup_tab_for_prefix(outdated_prefix) + setup_tab_for_prefix(extra_outdated_prefix, tap: "homebrew/core") + reset_outdated_kegs + + expect(f.outdated_kegs).not_to be_empty + + setup_tab_for_prefix(outdated_prefix, tap: "user/repo") + reset_outdated_kegs + + expect(f.outdated_kegs).not_to be_empty + end + + example "outdated same version tap installed" do + f.instance_variable_set(:@tap, CoreTap.instance) + setup_tab_for_prefix(same_prefix, tap: "homebrew/core") + + expect(f.outdated_kegs).to be_empty + + setup_tab_for_prefix(same_prefix, tap: "user/repo") + reset_outdated_kegs + + expect(f.outdated_kegs).to be_empty + end + + example "outdated installed head less than stable" do + tab = setup_tab_for_prefix(head_prefix, versions: { "stable" => "1.0" }) + + expect(f.outdated_kegs).not_to be_empty + + tab.source["versions"] = { "stable" => f.version.to_s } + tab.write + reset_outdated_kegs + + expect(f.outdated_kegs).to be_empty + end + + describe ":fetch_head" do + let(:f) do + repo = testball_repo + formula "testball" do + url "foo" + version "2.10" + head "file://#{repo}", using: :git + end + end + let(:testball_repo) { HOMEBREW_PREFIX/"testball_repo" } + + example do + begin + outdated_stable_prefix = HOMEBREW_CELLAR/"testball/1.0" + head_prefix_a = HOMEBREW_CELLAR/"testball/HEAD" + head_prefix_b = HOMEBREW_CELLAR/"testball/HEAD-aaaaaaa_1" + head_prefix_c = HOMEBREW_CELLAR/"testball/HEAD-18a7103" + + setup_tab_for_prefix(outdated_stable_prefix) + tab_a = setup_tab_for_prefix(head_prefix_a, versions: { "stable" => "1.0" }) + setup_tab_for_prefix(head_prefix_b) + + testball_repo.mkdir + testball_repo.cd do + FileUtils.touch "LICENSE" + + shutup do + system("git", "init") + system("git", "add", "--all") + system("git", "commit", "-m", "Initial commit") + end + end + + expect(f.outdated_kegs(fetch_head: true)).not_to be_empty + + tab_a.source["versions"] = { "stable" => f.version.to_s } + tab_a.write + reset_outdated_kegs + expect(f.outdated_kegs(fetch_head: true)).not_to be_empty + + head_prefix_a.rmtree + reset_outdated_kegs + expect(f.outdated_kegs(fetch_head: true)).not_to be_empty + + setup_tab_for_prefix(head_prefix_c, source_modified_time: 1) + reset_outdated_kegs + expect(f.outdated_kegs(fetch_head: true)).to be_empty + ensure + testball_repo.rmtree if testball_repo.exist? + end + end + end + + describe "with changed version scheme" do + let(:f) do + formula "testball" do + url "foo" + version "20141010" + version_scheme 1 + end + end + + example do + prefix = HOMEBREW_CELLAR/"testball/0.1" + setup_tab_for_prefix(prefix, versions: { "stable" => "0.1" }) + + expect(f.outdated_kegs).not_to be_empty + end + end + + describe "with mixed version schemes" do + let(:f) do + formula "testball" do + url "foo" + version "20141010" + version_scheme 3 + end + end + + example do + prefix_a = HOMEBREW_CELLAR/"testball/20141009" + setup_tab_for_prefix(prefix_a, versions: { "stable" => "20141009", "version_scheme" => 1 }) + + prefix_b = HOMEBREW_CELLAR/"testball/2.14" + setup_tab_for_prefix(prefix_b, versions: { "stable" => "2.14", "version_scheme" => 2 }) + + expect(f.outdated_kegs).not_to be_empty + reset_outdated_kegs + + prefix_c = HOMEBREW_CELLAR/"testball/20141009" + setup_tab_for_prefix(prefix_c, versions: { "stable" => "20141009", "version_scheme" => 3 }) + + expect(f.outdated_kegs).not_to be_empty + reset_outdated_kegs + + prefix_d = HOMEBREW_CELLAR/"testball/20141011" + setup_tab_for_prefix(prefix_d, versions: { "stable" => "20141009", "version_scheme" => 3 }) + expect(f.outdated_kegs).to be_empty + end + end + + describe "with version scheme" do + let(:f) do + formula "testball" do + url "foo" + version "1.0" + version_scheme 2 + end + end + + example do + head_prefix = HOMEBREW_CELLAR/"testball/HEAD" + + setup_tab_for_prefix(head_prefix, versions: { "stable" => "1.0", "version_scheme" => 1 }) + expect(f.outdated_kegs).not_to be_empty + + reset_outdated_kegs + head_prefix.rmtree + + setup_tab_for_prefix(head_prefix, versions: { "stable" => "1.0", "version_scheme" => 2 }) + expect(f.outdated_kegs).to be_empty + end + end + end +end diff --git a/Library/Homebrew/test/formula_test.rb b/Library/Homebrew/test/formula_test.rb deleted file mode 100644 index 318175d49..000000000 --- a/Library/Homebrew/test/formula_test.rb +++ /dev/null @@ -1,1205 +0,0 @@ -require "testing_env" -require "test/support/fixtures/testball" -require "formula" - -class FormulaTests < Homebrew::TestCase - def test_formula_instantiation - klass = Class.new(Formula) { url "http://example.com/foo-1.0.tar.gz" } - name = "formula_name" - path = Formulary.core_path(name) - spec = :stable - - f = klass.new(name, path, spec) - assert_equal name, f.name - assert_equal name, f.specified_name - assert_equal name, f.full_name - assert_equal name, f.full_specified_name - assert_equal path, f.path - assert_nil f.alias_path - assert_nil f.alias_name - assert_nil f.full_alias_name - assert_raises(ArgumentError) { klass.new } - end - - def test_formula_instantiation_with_alias - klass = Class.new(Formula) { url "http://example.com/foo-1.0.tar.gz" } - name = "formula_name" - path = Formulary.core_path(name) - spec = :stable - alias_name = "baz@1" - alias_path = CoreTap.instance.alias_dir/alias_name - - f = klass.new(name, path, spec, alias_path: alias_path) - assert_equal name, f.name - assert_equal name, f.full_name - assert_equal path, f.path - assert_equal alias_path, f.alias_path - assert_equal alias_name, f.alias_name - assert_equal alias_name, f.specified_name - assert_equal alias_name, f.full_alias_name - assert_equal alias_name, f.full_specified_name - assert_raises(ArgumentError) { klass.new } - end - - def test_tap_formula_instantiation - tap = Tap.new("foo", "bar") - klass = Class.new(Formula) { url "baz-1.0" } - name = "baz" - full_name = "#{tap.user}/#{tap.repo}/#{name}" - path = tap.path/"Formula/#{name}.rb" - spec = :stable - - f = klass.new(name, path, spec) - assert_equal name, f.name - assert_equal name, f.specified_name - assert_equal full_name, f.full_name - assert_equal full_name, f.full_specified_name - assert_equal path, f.path - assert_nil f.alias_path - assert_nil f.alias_name - assert_nil f.full_alias_name - assert_raises(ArgumentError) { klass.new } - end - - def test_tap_formula_instantiation_with_alias - tap = Tap.new("foo", "bar") - klass = Class.new(Formula) { url "baz-1.0" } - name = "baz" - full_name = "#{tap.user}/#{tap.repo}/#{name}" - path = tap.path/"Formula/#{name}.rb" - spec = :stable - alias_name = "baz@1" - full_alias_name = "#{tap.user}/#{tap.repo}/#{alias_name}" - alias_path = CoreTap.instance.alias_dir/alias_name - - f = klass.new(name, path, spec, alias_path: alias_path) - assert_equal name, f.name - assert_equal full_name, f.full_name - assert_equal path, f.path - assert_equal alias_path, f.alias_path - assert_equal alias_name, f.alias_name - assert_equal alias_name, f.specified_name - assert_equal full_alias_name, f.full_alias_name - assert_equal full_alias_name, f.full_specified_name - assert_raises(ArgumentError) { klass.new } - end - - def test_follow_installed_alias - f = formula { url "foo-1.0" } - assert_predicate f, :follow_installed_alias? - - f.follow_installed_alias = true - assert_predicate f, :follow_installed_alias? - - f.follow_installed_alias = false - refute_predicate f, :follow_installed_alias? - end - - def test_installed_alias_with_core - f = formula { url "foo-1.0" } - - build_values_with_no_installed_alias = [ - nil, - BuildOptions.new({}, {}), - Tab.new(source: { "path" => f.path.to_s }), - ] - - build_values_with_no_installed_alias.each do |build| - f.build = build - assert_nil f.installed_alias_path - assert_nil f.installed_alias_name - assert_nil f.full_installed_alias_name - assert_equal f.name, f.installed_specified_name - assert_equal f.name, f.full_installed_specified_name - end - - alias_name = "bar" - alias_path = "#{CoreTap.instance.alias_dir}/#{alias_name}" - f.build = Tab.new(source: { "path" => alias_path }) - assert_equal alias_path, f.installed_alias_path - assert_equal alias_name, f.installed_alias_name - assert_equal alias_name, f.full_installed_alias_name - assert_equal alias_name, f.installed_specified_name - assert_equal alias_name, f.full_installed_specified_name - end - - def test_installed_alias_with_tap - tap = Tap.new("user", "repo") - name = "foo" - path = "#{tap.path}/Formula/#{name}.rb" - f = formula(name, path) { url "foo-1.0" } - - build_values_with_no_installed_alias = [ - nil, - BuildOptions.new({}, {}), - Tab.new(source: { "path" => f.path }), - ] - - build_values_with_no_installed_alias.each do |build| - f.build = build - assert_nil f.installed_alias_path - assert_nil f.installed_alias_name - assert_nil f.full_installed_alias_name - assert_equal f.name, f.installed_specified_name - assert_equal f.full_name, f.full_installed_specified_name - end - - alias_name = "bar" - full_alias_name = "#{tap.user}/#{tap.repo}/#{alias_name}" - alias_path = "#{tap.alias_dir}/#{alias_name}" - f.build = Tab.new(source: { "path" => alias_path }) - assert_equal alias_path, f.installed_alias_path - assert_equal alias_name, f.installed_alias_name - assert_equal full_alias_name, f.full_installed_alias_name - assert_equal alias_name, f.installed_specified_name - assert_equal full_alias_name, f.full_installed_specified_name - end - - def test_prefix - f = Testball.new - assert_equal HOMEBREW_CELLAR/f.name/"0.1", f.prefix - assert_kind_of Pathname, f.prefix - end - - def test_revised_prefix - f = Class.new(Testball) { revision 1 }.new - assert_equal HOMEBREW_CELLAR/f.name/"0.1_1", f.prefix - end - - def test_any_version_installed? - f = formula do - url "foo" - version "1.0" - end - refute_predicate f, :any_version_installed? - prefix = HOMEBREW_CELLAR+f.name+"0.1" - prefix.mkpath - FileUtils.touch prefix+Tab::FILENAME - assert_predicate f, :any_version_installed? - end - - def test_migration_needed - f = Testball.new("newname") - f.instance_variable_set(:@oldname, "oldname") - f.instance_variable_set(:@tap, CoreTap.instance) - - oldname_prefix = HOMEBREW_CELLAR/"oldname/2.20" - newname_prefix = HOMEBREW_CELLAR/"newname/2.10" - oldname_prefix.mkpath - oldname_tab = Tab.empty - oldname_tab.tabfile = oldname_prefix.join("INSTALL_RECEIPT.json") - oldname_tab.write - - refute_predicate f, :migration_needed? - - oldname_tab.tabfile.unlink - oldname_tab.source["tap"] = "homebrew/core" - oldname_tab.write - - assert_predicate f, :migration_needed? - - newname_prefix.mkpath - - refute_predicate f, :migration_needed? - end - - def test_installed? - f = Testball.new - f.stubs(:installed_prefix).returns(stub(directory?: false)) - refute_predicate f, :installed? - - f.stubs(:installed_prefix).returns( - stub(directory?: true, children: []), - ) - refute_predicate f, :installed? - - f.stubs(:installed_prefix).returns( - stub(directory?: true, children: [stub]), - ) - assert_predicate f, :installed? - end - - def test_installed_prefix - f = Testball.new - assert_equal f.prefix, f.installed_prefix - end - - def test_installed_prefix_head_installed - f = formula do - head "foo" - devel do - url "foo" - version "1.0" - end - end - prefix = HOMEBREW_CELLAR+f.name+f.head.version - prefix.mkpath - assert_equal prefix, f.installed_prefix - end - - def test_installed_prefix_devel_installed - f = formula do - head "foo" - devel do - url "foo" - version "1.0" - end - end - prefix = HOMEBREW_CELLAR+f.name+f.devel.version - prefix.mkpath - assert_equal prefix, f.installed_prefix - end - - def test_installed_prefix_stable_installed - f = formula do - head "foo" - devel do - url "foo" - version "1.0-devel" - end - end - prefix = HOMEBREW_CELLAR+f.name+f.version - prefix.mkpath - assert_equal prefix, f.installed_prefix - end - - def test_installed_prefix_outdated_stable_head_installed - f = formula do - url "foo" - version "1.9" - head "foo" - end - - head_prefix = HOMEBREW_CELLAR/"#{f.name}/HEAD" - head_prefix.mkpath - tab = Tab.empty - tab.tabfile = head_prefix.join("INSTALL_RECEIPT.json") - tab.source["versions"] = { "stable" => "1.0" } - tab.write - - assert_equal HOMEBREW_CELLAR/"#{f.name}/#{f.version}", f.installed_prefix - end - - def test_installed_prefix_outdated_devel_head_installed - f = formula do - url "foo" - version "1.9" - devel do - url "foo" - version "2.1" - end - end - - head_prefix = HOMEBREW_CELLAR/"#{f.name}/HEAD" - head_prefix.mkpath - tab = Tab.empty - tab.tabfile = head_prefix.join("INSTALL_RECEIPT.json") - tab.source["versions"] = { "stable" => "1.9", "devel" => "2.0" } - tab.write - - assert_equal HOMEBREW_CELLAR/"#{f.name}/#{f.version}", f.installed_prefix - end - - def test_installed_prefix_head - f = formula("test", Pathname.new(__FILE__).expand_path, :head) do - head "foo" - devel do - url "foo" - version "1.0-devel" - end - end - prefix = HOMEBREW_CELLAR+f.name+f.head.version - assert_equal prefix, f.installed_prefix - end - - def test_installed_prefix_devel - f = formula("test", Pathname.new(__FILE__).expand_path, :devel) do - head "foo" - devel do - url "foo" - version "1.0-devel" - end - end - prefix = HOMEBREW_CELLAR+f.name+f.devel.version - assert_equal prefix, f.installed_prefix - end - - def test_latest_head_prefix - f = Testball.new - - stamps_with_revisions = [[111111, 1], [222222, 1], [222222, 2], [222222, 0]] - - stamps_with_revisions.each do |stamp, revision| - version = "HEAD-#{stamp}" - version += "_#{revision}" if revision > 0 - prefix = f.rack.join(version) - prefix.mkpath - - tab = Tab.empty - tab.tabfile = prefix.join("INSTALL_RECEIPT.json") - tab.source_modified_time = stamp - tab.write - end - - prefix = HOMEBREW_CELLAR/"#{f.name}/HEAD-222222_2" - assert_equal prefix, f.latest_head_prefix - end - - def test_equality - x = Testball.new - y = Testball.new - assert_equal x, y - assert_eql x, y - assert_equal x.hash, y.hash - end - - def test_inequality - x = Testball.new("foo") - y = Testball.new("bar") - refute_equal x, y - refute_eql x, y - refute_equal x.hash, y.hash - end - - def test_comparison_with_non_formula_objects_does_not_raise - refute_equal Testball.new, Object.new - end - - def test_sort_operator - assert_nil Testball.new <=> Object.new - end - - def test_alias_paths_with_build_options - alias_path = CoreTap.instance.alias_dir/"another_name" - f = formula(alias_path: alias_path) { url "foo-1.0" } - f.build = BuildOptions.new({}, {}) - assert_equal alias_path, f.alias_path - assert_nil f.installed_alias_path - end - - def test_alias_paths_with_tab_with_non_alias_source_path - alias_path = CoreTap.instance.alias_dir/"another_name" - source_path = CoreTap.instance.formula_dir/"another_other_name" - f = formula(alias_path: alias_path) { url "foo-1.0" } - f.build = Tab.new(source: { "path" => source_path.to_s }) - assert_equal alias_path, f.alias_path - assert_nil f.installed_alias_path - end - - def test_alias_paths_with_tab_with_alias_source_path - alias_path = CoreTap.instance.alias_dir/"another_name" - source_path = CoreTap.instance.alias_dir/"another_other_name" - f = formula(alias_path: alias_path) { url "foo-1.0" } - f.build = Tab.new(source: { "path" => source_path.to_s }) - assert_equal alias_path, f.alias_path - assert_equal source_path.to_s, f.installed_alias_path - end - - def test_installed_with_alias_path_with_nil - assert_predicate Formula.installed_with_alias_path(nil), :empty? - end - - def test_installed_with_alias_path_with_a_path - alias_path = "#{CoreTap.instance.alias_dir}/alias" - different_alias_path = "#{CoreTap.instance.alias_dir}/another_alias" - - formula_with_alias = formula("foo") { url "foo-1.0" } - formula_with_alias.build = Tab.empty - formula_with_alias.build.source["path"] = alias_path - - formula_without_alias = formula("bar") { url "bar-1.0" } - formula_without_alias.build = Tab.empty - formula_without_alias.build.source["path"] = formula_without_alias.path.to_s - - formula_with_different_alias = formula("baz") { url "baz-1.0" } - formula_with_different_alias.build = Tab.empty - formula_with_different_alias.build.source["path"] = different_alias_path - - formulae = [ - formula_with_alias, - formula_without_alias, - formula_with_different_alias, - ] - - Formula.stubs(:installed).returns(formulae) - assert_equal [formula_with_alias], Formula.installed_with_alias_path(alias_path) - end - - def test_formula_spec_integration - f = formula do - homepage "http://example.com" - url "http://example.com/test-0.1.tbz" - mirror "http://example.org/test-0.1.tbz" - sha256 TEST_SHA256 - - head "http://example.com/test.git", tag: "foo" - - devel do - url "http://example.com/test-0.2.tbz" - mirror "http://example.org/test-0.2.tbz" - sha256 TEST_SHA256 - end - end - - assert_equal "http://example.com", f.homepage - assert_version_equal "0.1", f.version - assert_predicate f, :stable? - - assert_version_equal "0.1", f.stable.version - assert_version_equal "0.2", f.devel.version - assert_version_equal "HEAD", f.head.version - end - - def test_formula_active_spec= - f = formula do - url "foo" - version "1.0" - revision 1 - - devel do - url "foo" - version "1.0beta" - end - end - assert_equal :stable, f.active_spec_sym - assert_equal f.stable, f.send(:active_spec) - assert_equal "1.0_1", f.pkg_version.to_s - f.active_spec = :devel - assert_equal :devel, f.active_spec_sym - assert_equal f.devel, f.send(:active_spec) - assert_equal "1.0beta_1", f.pkg_version.to_s - assert_raises(FormulaSpecificationError) { f.active_spec = :head } - end - - def test_path - name = "foo-bar" - assert_equal Pathname.new("#{HOMEBREW_LIBRARY}/Taps/homebrew/homebrew-core/Formula/#{name}.rb"), Formulary.core_path(name) - end - - def test_class_specs_are_always_initialized - f = formula { url "foo-1.0" } - - %w[stable devel head].each do |spec| - assert_kind_of SoftwareSpec, f.class.send(spec) - end - end - - def test_incomplete_instance_specs_are_not_accessible - f = formula { url "foo-1.0" } - - %w[devel head].each { |spec| assert_nil f.send(spec) } - end - - def test_honors_attributes_declared_before_specs - f = formula do - url "foo-1.0" - depends_on "foo" - devel { url "foo-1.1" } - end - - %w[stable devel head].each do |spec| - assert_equal "foo", f.class.send(spec).deps.first.name - end - end - - def test_simple_version - assert_equal PkgVersion.parse("1.0"), formula { url "foo-1.0.bar" }.pkg_version - end - - def test_version_with_revision - f = formula do - url "foo-1.0.bar" - revision 1 - end - - assert_equal PkgVersion.parse("1.0_1"), f.pkg_version - end - - def test_head_uses_revisions - f = formula("test", Pathname.new(__FILE__).expand_path, :head) do - url "foo-1.0.bar" - revision 1 - head "foo" - end - - assert_equal PkgVersion.parse("HEAD_1"), f.pkg_version - end - - def test_update_head_version - f = formula do - head "foo", using: :git - end - - cached_location = f.head.downloader.cached_location - cached_location.mkpath - - cached_location.cd do - FileUtils.touch "LICENSE" - shutup do - system "git", "init" - system "git", "add", "--all" - system "git", "commit", "-m", "Initial commit" - end - end - - f.update_head_version - assert_equal Version.create("HEAD-5658946"), f.head.version - end - - def test_legacy_options - f = formula do - url "foo-1.0" - - def options - [["--foo", "desc"], ["--bar", "desc"]] - end - - option "baz" - end - - assert f.option_defined?("foo") - assert f.option_defined?("bar") - assert f.option_defined?("baz") - end - - def test_desc - f = formula do - desc "a formula" - url "foo-1.0" - end - - assert_equal "a formula", f.desc - end - - def test_post_install_defined - f1 = formula do - url "foo-1.0" - - def post_install; end - end - - f2 = formula do - url "foo-1.0" - end - - assert f1.post_install_defined? - refute f2.post_install_defined? - end - - def test_test_defined - f1 = formula do - url "foo-1.0" - - def test; end - end - - f2 = formula do - url "foo-1.0" - end - - assert f1.test_defined? - refute f2.test_defined? - end - - def test_test_fixtures - f1 = formula do - url "foo-1.0" - end - - assert_equal Pathname.new("#{HOMEBREW_LIBRARY_PATH}/test/support/fixtures/foo"), - f1.test_fixtures("foo") - end - - def test_dependencies - stub_formula_loader formula("f1") { url "f1-1.0" } - stub_formula_loader formula("f2") { url "f2-1.0" } - - f3 = formula("f3") do - url "f3-1.0" - depends_on "f1" => :build - depends_on "f2" - end - stub_formula_loader f3 - - f4 = formula("f4") do - url "f4-1.0" - depends_on "f1" - end - stub_formula_loader f4 - - f5 = formula("f5") do - url "f5-1.0" - depends_on "f3" => :build - depends_on "f4" - end - - assert_equal %w[f3 f4], f5.deps.map(&:name) - assert_equal %w[f1 f2 f3 f4], f5.recursive_dependencies.map(&:name) - assert_equal %w[f1 f4], f5.runtime_dependencies.map(&:name) - end - - def test_runtime_dependencies_with_optional_deps_from_tap - tap_loader = mock - tap_loader.stubs(:get_formula).raises(RuntimeError, "tried resolving tap formula") - Formulary.stubs(:loader_for).with("foo/bar/f1", from: nil).returns(tap_loader) - - stub_formula_loader formula("f2") { url "f2-1.0" }, "baz/qux/f2" - - f3 = formula("f3") do - url "f3-1.0" - depends_on "foo/bar/f1" => :optional - depends_on "baz/qux/f2" - end - - # f1 shouldn't be loaded by default. - # If it is, an exception will be raised. - assert_equal %w[baz/qux/f2], f3.runtime_dependencies.map(&:name) - - # If --with-f1, f1 should be loaded. - stub_formula_loader formula("f1") { url "f1-1.0" }, "foo/bar/f1" - f3.build = BuildOptions.new(Options.create(%w[--with-f1]), f3.options) - assert_equal %w[foo/bar/f1 baz/qux/f2], f3.runtime_dependencies.map(&:name) - end - - def test_requirements - f1 = formula("f1") do - url "f1-1" - - depends_on :python - depends_on x11: :recommended - depends_on xcode: ["1.0", :optional] - end - stub_formula_loader f1 - - python = PythonRequirement.new - x11 = X11Requirement.new("x11", [:recommended]) - xcode = XcodeRequirement.new(["1.0", :optional]) - - # Default block should filter out deps that aren't being used - assert_equal Set[python, x11], Set.new(f1.recursive_requirements) - - f1.build = BuildOptions.new(["--with-xcode", "--without-x11"], f1.options) - assert_equal Set[python, xcode], Set.new(f1.recursive_requirements) - f1.build = f1.stable.build - - f2 = formula("f2") do - url "f2-1" - depends_on "f1" - end - - assert_equal Set[python, x11], Set.new(f2.recursive_requirements) - - # Empty block should allow all requirements - assert_equal Set[python, x11, xcode], Set.new(f2.recursive_requirements {}) - - # Requirements can be pruned - requirements = f2.recursive_requirements do |_dependent, requirement| - Requirement.prune if requirement.is_a?(PythonRequirement) - end - assert_equal Set[x11, xcode], Set.new(requirements) - end - - def test_to_hash - f1 = formula("foo") do - url "foo-1.0" - end - - h = f1.to_hash - assert h.is_a?(Hash), "Formula#to_hash should return a Hash" - assert_equal "foo", h["name"] - assert_equal "foo", h["full_name"] - assert_equal "1.0", h["versions"]["stable"] - end - - def test_to_hash_bottle - f1 = formula("foo") do - url "foo-1.0" - - bottle do - cellar :any - sha256 TEST_SHA256 => Utils::Bottles.tag - end - end - - h = f1.to_hash - assert h.is_a?(Hash), "Formula#to_hash should return a Hash" - assert h["versions"]["bottle"], "The hash should say the formula is bottled" - end - - def test_eligible_kegs_for_cleanup - f1 = Class.new(Testball) do - version "1.0" - end.new - f2 = Class.new(Testball) do - version "0.2" - version_scheme 1 - end.new - f3 = Class.new(Testball) do - version "0.3" - version_scheme 1 - end.new - f4 = Class.new(Testball) do - version "0.1" - version_scheme 2 - end.new - - shutup do - [f1, f2, f3, f4].each do |f| - f.brew { f.install } - Tab.create(f, DevelopmentTools.default_compiler, :libcxx).write - end - end - - assert_predicate f1, :installed? - assert_predicate f2, :installed? - assert_predicate f3, :installed? - assert_predicate f4, :installed? - - assert_equal [f2, f1].map { |f| Keg.new(f.prefix) }, - f3.eligible_kegs_for_cleanup.sort_by(&:version) - end - - def test_eligible_kegs_for_cleanup_keg_pinned - f1 = Class.new(Testball) { version "0.1" }.new - f2 = Class.new(Testball) { version "0.2" }.new - f3 = Class.new(Testball) { version "0.3" }.new - - shutup do - f1.brew { f1.install } - f1.pin - f2.brew { f2.install } - f3.brew { f3.install } - end - - assert_equal (HOMEBREW_PINNED_KEGS/f1.name).resolved_path, f1.prefix - - assert_predicate f1, :installed? - assert_predicate f2, :installed? - assert_predicate f3, :installed? - - assert_equal [Keg.new(f2.prefix)], shutup { f3.eligible_kegs_for_cleanup } - end - - def test_eligible_kegs_for_cleanup_head_installed - f = formula do - version "0.1" - head "foo" - end - - stable_prefix = f.installed_prefix - stable_prefix.mkpath - - [["000000_1", 1], ["111111", 2], ["111111_1", 2]].each do |pkg_version_suffix, stamp| - prefix = f.prefix("HEAD-#{pkg_version_suffix}") - prefix.mkpath - tab = Tab.empty - tab.tabfile = prefix.join("INSTALL_RECEIPT.json") - tab.source_modified_time = stamp - tab.write - end - - eligible_kegs = f.installed_kegs - [Keg.new(f.prefix("HEAD-111111_1"))] - assert_equal eligible_kegs, f.eligible_kegs_for_cleanup - end - - def test_pour_bottle - f_false = formula("foo") do - url "foo-1.0" - def pour_bottle? - false - end - end - refute f_false.pour_bottle? - - f_true = formula("foo") do - url "foo-1.0" - def pour_bottle? - true - end - end - assert f_true.pour_bottle? - end - - def test_pour_bottle_dsl - f_false = formula("foo") do - url "foo-1.0" - pour_bottle? do - reason "false reason" - satisfy { var == etc } - end - end - refute f_false.pour_bottle? - - f_true = formula("foo") do - url "foo-1.0" - pour_bottle? do - reason "true reason" - satisfy { true } - end - end - assert f_true.pour_bottle? - end -end - -class AliasChangeTests < Homebrew::TestCase - attr_reader :f, :new_formula, :tab, :alias_path - - def make_formula(name, version) - f = formula(name, alias_path: alias_path) { url "foo-#{version}" } - f.build = tab - f - end - - def setup - super - - alias_name = "bar" - @alias_path = "#{CoreTap.instance.alias_dir}/#{alias_name}" - - @tab = Tab.empty - - @f = make_formula("formula_name", "1.0") - @new_formula = make_formula("new_formula_name", "1.1") - - Formula.stubs(:installed).returns([f]) - end - - def test_alias_changes_when_not_installed_with_alias - tab.source["path"] = Formulary.core_path(f.name).to_s - - assert_nil f.current_installed_alias_target - assert_equal f, f.latest_formula - refute_predicate f, :installed_alias_target_changed? - refute_predicate f, :supersedes_an_installed_formula? - refute_predicate f, :alias_changed? - assert_predicate f.old_installed_formulae, :empty? - end - - def test_alias_changes_when_not_changed - tab.source["path"] = alias_path - stub_formula_loader(f, alias_path) - - assert_equal f, f.current_installed_alias_target - assert_equal f, f.latest_formula - refute_predicate f, :installed_alias_target_changed? - refute_predicate f, :supersedes_an_installed_formula? - refute_predicate f, :alias_changed? - assert_predicate f.old_installed_formulae, :empty? - end - - def test_alias_changes_when_new_alias_target - tab.source["path"] = alias_path - stub_formula_loader(new_formula, alias_path) - - assert_equal new_formula, f.current_installed_alias_target - assert_equal new_formula, f.latest_formula - assert_predicate f, :installed_alias_target_changed? - refute_predicate f, :supersedes_an_installed_formula? - assert_predicate f, :alias_changed? - assert_predicate f.old_installed_formulae, :empty? - end - - def test_alias_changes_when_old_formulae_installed - tab.source["path"] = alias_path - stub_formula_loader(new_formula, alias_path) - - assert_equal new_formula, new_formula.current_installed_alias_target - assert_equal new_formula, new_formula.latest_formula - refute_predicate new_formula, :installed_alias_target_changed? - assert_predicate new_formula, :supersedes_an_installed_formula? - assert_predicate new_formula, :alias_changed? - assert_equal [f], new_formula.old_installed_formulae - end -end - -class OutdatedVersionsTests < Homebrew::TestCase - attr_reader :outdated_prefix, - :same_prefix, - :greater_prefix, - :head_prefix, - :old_alias_target_prefix - attr_reader :f, :old_formula, :new_formula - - def setup - super - - @f = formula do - url "foo" - version "1.20" - end - - @old_formula = formula("foo@1") { url "foo-1.0" } - @new_formula = formula("foo@2") { url "foo-2.0" } - - @outdated_prefix = HOMEBREW_CELLAR/"#{f.name}/1.11" - @same_prefix = HOMEBREW_CELLAR/"#{f.name}/1.20" - @greater_prefix = HOMEBREW_CELLAR/"#{f.name}/1.21" - @head_prefix = HOMEBREW_CELLAR/"#{f.name}/HEAD" - @old_alias_target_prefix = HOMEBREW_CELLAR/"#{old_formula.name}/1.0" - end - - def alias_path - "#{@f.tap.alias_dir}/bar" - end - - def setup_tab_for_prefix(prefix, options = {}) - prefix.mkpath - tab = Tab.empty - tab.tabfile = prefix.join("INSTALL_RECEIPT.json") - tab.source["path"] = options[:path].to_s if options[:path] - tab.source["tap"] = options[:tap] if options[:tap] - tab.source["versions"] = options[:versions] if options[:versions] - tab.source_modified_time = options[:source_modified_time].to_i - tab.write unless options[:no_write] - tab - end - - def reset_outdated_kegs - f.instance_variable_set(:@outdated_kegs, nil) - end - - def test_greater_different_tap_installed - setup_tab_for_prefix(greater_prefix, tap: "user/repo") - assert_predicate f.outdated_kegs, :empty? - end - - def test_greater_same_tap_installed - f.instance_variable_set(:@tap, CoreTap.instance) - setup_tab_for_prefix(greater_prefix, tap: "homebrew/core") - assert_predicate f.outdated_kegs, :empty? - end - - def test_outdated_different_tap_installed - setup_tab_for_prefix(outdated_prefix, tap: "user/repo") - refute_predicate f.outdated_kegs, :empty? - end - - def test_outdated_same_tap_installed - f.instance_variable_set(:@tap, CoreTap.instance) - setup_tab_for_prefix(outdated_prefix, tap: "homebrew/core") - refute_predicate f.outdated_kegs, :empty? - end - - def test_outdated_follow_alias_and_alias_unchanged - f.follow_installed_alias = true - f.build = setup_tab_for_prefix(same_prefix, path: alias_path) - stub_formula_loader(f, alias_path) - assert_predicate f.outdated_kegs, :empty? - end - - def test_outdated_follow_alias_and_alias_changed_and_new_target_not_installed - f.follow_installed_alias = true - f.build = setup_tab_for_prefix(same_prefix, path: alias_path) - stub_formula_loader(new_formula, alias_path) - refute_predicate f.outdated_kegs, :empty? - end - - def test_outdated_follow_alias_and_alias_changed_and_new_target_installed - f.follow_installed_alias = true - f.build = setup_tab_for_prefix(same_prefix, path: alias_path) - stub_formula_loader(new_formula, alias_path) - setup_tab_for_prefix(new_formula.prefix) # install new_formula - assert_predicate f.outdated_kegs, :empty? - end - - def test_outdated_no_follow_alias_and_alias_unchanged - f.follow_installed_alias = false - f.build = setup_tab_for_prefix(same_prefix, path: alias_path) - stub_formula_loader(f, alias_path) - assert_predicate f.outdated_kegs, :empty? - end - - def test_outdated_no_follow_alias_and_alias_changed - f.follow_installed_alias = false - f.build = setup_tab_for_prefix(same_prefix, path: alias_path) - stub_formula_loader(formula("foo@2") { url "foo-2.0" }, alias_path) - assert_predicate f.outdated_kegs, :empty? - end - - def test_outdated_old_alias_targets_installed - @f = formula(alias_path: alias_path) { url "foo-1.0" } - tab = setup_tab_for_prefix(old_alias_target_prefix, path: alias_path) - old_formula.build = tab - Formula.stubs(:installed).returns([old_formula]) - refute_predicate f.outdated_kegs, :empty? - end - - def test_outdated_old_alias_targets_not_installed - @f = formula(alias_path: alias_path) { url "foo-1.0" } - tab = setup_tab_for_prefix(old_alias_target_prefix, path: old_formula.path) - old_formula.build = tab - Formula.stubs(:installed).returns([old_formula]) - assert_predicate f.outdated_kegs, :empty? - end - - def test_outdated_same_head_installed - f.instance_variable_set(:@tap, CoreTap.instance) - setup_tab_for_prefix(head_prefix, tap: "homebrew/core") - assert_predicate f.outdated_kegs, :empty? - end - - def test_outdated_different_head_installed - f.instance_variable_set(:@tap, CoreTap.instance) - setup_tab_for_prefix(head_prefix, tap: "user/repo") - assert_predicate f.outdated_kegs, :empty? - end - - def test_outdated_mixed_taps_greater_version_installed - f.instance_variable_set(:@tap, CoreTap.instance) - setup_tab_for_prefix(outdated_prefix, tap: "homebrew/core") - setup_tab_for_prefix(greater_prefix, tap: "user/repo") - - assert_predicate f.outdated_kegs, :empty? - - setup_tab_for_prefix(greater_prefix, tap: "homebrew/core") - reset_outdated_kegs - - assert_predicate f.outdated_kegs, :empty? - end - - def test_outdated_mixed_taps_outdated_version_installed - f.instance_variable_set(:@tap, CoreTap.instance) - - extra_outdated_prefix = HOMEBREW_CELLAR/"#{f.name}/1.0" - - setup_tab_for_prefix(outdated_prefix) - setup_tab_for_prefix(extra_outdated_prefix, tap: "homebrew/core") - reset_outdated_kegs - - refute_predicate f.outdated_kegs, :empty? - - setup_tab_for_prefix(outdated_prefix, tap: "user/repo") - reset_outdated_kegs - - refute_predicate f.outdated_kegs, :empty? - end - - def test_outdated_same_version_tap_installed - f.instance_variable_set(:@tap, CoreTap.instance) - setup_tab_for_prefix(same_prefix, tap: "homebrew/core") - - assert_predicate f.outdated_kegs, :empty? - - setup_tab_for_prefix(same_prefix, tap: "user/repo") - reset_outdated_kegs - - assert_predicate f.outdated_kegs, :empty? - end - - def test_outdated_installed_head_less_than_stable - tab = setup_tab_for_prefix(head_prefix, versions: { "stable" => "1.0" }) - refute_predicate f.outdated_kegs, :empty? - - # Tab.for_keg(head_prefix) will be fetched from CACHE but we write it anyway - tab.source["versions"] = { "stable" => f.version.to_s } - tab.write - reset_outdated_kegs - - assert_predicate f.outdated_kegs, :empty? - end - - def test_outdated_fetch_head - outdated_stable_prefix = HOMEBREW_CELLAR.join("testball/1.0") - head_prefix_a = HOMEBREW_CELLAR.join("testball/HEAD") - head_prefix_b = HOMEBREW_CELLAR.join("testball/HEAD-aaaaaaa_1") - head_prefix_c = HOMEBREW_CELLAR.join("testball/HEAD-18a7103") - - setup_tab_for_prefix(outdated_stable_prefix) - tab_a = setup_tab_for_prefix(head_prefix_a, versions: { "stable" => "1.0" }) - setup_tab_for_prefix(head_prefix_b) - - testball_repo = HOMEBREW_PREFIX.join("testball_repo") - testball_repo.mkdir - - @f = formula("testball") do - url "foo" - version "2.10" - head "file://#{testball_repo}", using: :git - end - - testball_repo.cd do - FileUtils.touch "LICENSE" - shutup do - system "git", "init" - system "git", "add", "--all" - system "git", "commit", "-m", "Initial commit" - end - end - - refute_predicate f.outdated_kegs(fetch_head: true), :empty? - - tab_a.source["versions"] = { "stable" => f.version.to_s } - tab_a.write - reset_outdated_kegs - refute_predicate f.outdated_kegs(fetch_head: true), :empty? - - head_prefix_a.rmtree - reset_outdated_kegs - refute_predicate f.outdated_kegs(fetch_head: true), :empty? - - setup_tab_for_prefix(head_prefix_c, source_modified_time: 1) - reset_outdated_kegs - assert_predicate f.outdated_kegs(fetch_head: true), :empty? - ensure - testball_repo.rmtree if testball_repo.exist? - end - - def test_outdated_kegs_version_scheme_changed - @f = formula("testball") do - url "foo" - version "20141010" - version_scheme 1 - end - - prefix = HOMEBREW_CELLAR.join("testball/0.1") - setup_tab_for_prefix(prefix, versions: { "stable" => "0.1" }) - - refute_predicate f.outdated_kegs, :empty? - end - - def test_outdated_kegs_mixed_version_schemes - @f = formula("testball") do - url "foo" - version "20141010" - version_scheme 3 - end - - prefix_a = HOMEBREW_CELLAR.join("testball/20141009") - setup_tab_for_prefix(prefix_a, versions: { "stable" => "20141009", "version_scheme" => 1 }) - - prefix_b = HOMEBREW_CELLAR.join("testball/2.14") - setup_tab_for_prefix(prefix_b, versions: { "stable" => "2.14", "version_scheme" => 2 }) - - refute_predicate f.outdated_kegs, :empty? - reset_outdated_kegs - - prefix_c = HOMEBREW_CELLAR.join("testball/20141009") - setup_tab_for_prefix(prefix_c, versions: { "stable" => "20141009", "version_scheme" => 3 }) - - refute_predicate f.outdated_kegs, :empty? - reset_outdated_kegs - - prefix_d = HOMEBREW_CELLAR.join("testball/20141011") - setup_tab_for_prefix(prefix_d, versions: { "stable" => "20141009", "version_scheme" => 3 }) - assert_predicate f.outdated_kegs, :empty? - end - - def test_outdated_kegs_head_with_version_scheme - @f = formula("testball") do - url "foo" - version "1.0" - version_scheme 2 - end - - head_prefix = HOMEBREW_CELLAR.join("testball/HEAD") - - setup_tab_for_prefix(head_prefix, versions: { "stable" => "1.0", "version_scheme" => 1 }) - refute_predicate f.outdated_kegs, :empty? - - reset_outdated_kegs - head_prefix.rmtree - - setup_tab_for_prefix(head_prefix, versions: { "stable" => "1.0", "version_scheme" => 2 }) - assert_predicate f.outdated_kegs, :empty? - end -end diff --git a/Library/Homebrew/test/formulary_spec.rb b/Library/Homebrew/test/formulary_spec.rb index 8e9d23589..213ad511d 100644 --- a/Library/Homebrew/test/formulary_spec.rb +++ b/Library/Homebrew/test/formulary_spec.rb @@ -216,4 +216,12 @@ describe Formulary do end end end + + describe "::core_path" do + it "returns the path to a Formula in the core tap" do + name = "foo-bar" + expect(subject.core_path(name)) + .to eq(Pathname.new("#{HOMEBREW_LIBRARY}/Taps/homebrew/homebrew-core/Formula/#{name}.rb")) + end + end end diff --git a/Library/Homebrew/test/help_test.rb b/Library/Homebrew/test/help_test.rb deleted file mode 100644 index 92dd99721..000000000 --- a/Library/Homebrew/test/help_test.rb +++ /dev/null @@ -1,21 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestHelp < IntegrationCommandTestCase - def test_help - assert_match "Example usage:\n", - cmd_fail # Generic help (empty argument list). - assert_match "Unknown command: command-that-does-not-exist", - cmd_fail("help", "command-that-does-not-exist") - assert_match(/^brew cat /, - cmd_fail("cat")) # Missing formula argument triggers help. - - assert_match "Example usage:\n", - cmd("help") # Generic help. - assert_match(/^brew cat /, - cmd("help", "cat")) # Internal command (documented, Ruby). - assert_match(/^brew update /, - cmd("help", "update")) # Internal command (documented, Shell). - assert_match(/^brew update-test /, - cmd("help", "update-test")) # Internal developer command (documented, Ruby). - end -end diff --git a/Library/Homebrew/test/home_test.rb b/Library/Homebrew/test/home_test.rb deleted file mode 100644 index ff06b72c1..000000000 --- a/Library/Homebrew/test/home_test.rb +++ /dev/null @@ -1,12 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestHome < IntegrationCommandTestCase - def test_home - setup_test_formula "testball" - - assert_equal HOMEBREW_WWW, - cmd("home", "HOMEBREW_BROWSER" => "echo") - assert_equal Formula["testball"].homepage, - cmd("home", "testball", "HOMEBREW_BROWSER" => "echo") - end -end diff --git a/Library/Homebrew/test/info_test.rb b/Library/Homebrew/test/info_test.rb deleted file mode 100644 index f71044bf0..000000000 --- a/Library/Homebrew/test/info_test.rb +++ /dev/null @@ -1,29 +0,0 @@ -require "testing_env" -require "cmd/info" -require "formula" -require "testing_env" - -class IntegrationCommandTestInfo < IntegrationCommandTestCase - def test_info - setup_test_formula "testball" - - assert_match "testball: stable 0.1", - cmd("info", "testball") - end -end - -class InfoCommandTests < Homebrew::TestCase - def test_github_remote_path - remote = "https://github.com/Homebrew/homebrew-core" - assert_equal "https://github.com/Homebrew/homebrew-core/blob/master/Formula/git.rb", - Homebrew.github_remote_path(remote, "Formula/git.rb") - assert_equal "https://github.com/Homebrew/homebrew-core/blob/master/Formula/git.rb", - Homebrew.github_remote_path("#{remote}.git", "Formula/git.rb") - - assert_equal "https://github.com/user/repo/blob/master/foo.rb", - Homebrew.github_remote_path("git@github.com:user/repo", "foo.rb") - - assert_equal "https://mywebsite.com/foo/bar.rb", - Homebrew.github_remote_path("https://mywebsite.com", "foo/bar.rb") - end -end diff --git a/Library/Homebrew/test/inreplace_spec.rb b/Library/Homebrew/test/inreplace_spec.rb new file mode 100644 index 000000000..5be44f50d --- /dev/null +++ b/Library/Homebrew/test/inreplace_spec.rb @@ -0,0 +1,251 @@ +require "extend/string" +require "tempfile" +require "utils/inreplace" + +describe StringInreplaceExtension do + subject { string.extend(described_class) } + + describe "#change_make_var!" do + context "flag" do + context "with spaces" do + let(:string) do + <<-EOS.undent + OTHER=def + FLAG = abc + FLAG2=abc + EOS + end + + it "is successfully replaced" do + subject.change_make_var! "FLAG", "def" + expect(subject).to eq <<-EOS.undent + OTHER=def + FLAG=def + FLAG2=abc + EOS + end + + it "is successfully appended" do + subject.change_make_var! "FLAG", "\\1 def" + expect(subject).to eq <<-EOS.undent + OTHER=def + FLAG=abc def + FLAG2=abc + EOS + end + end + + context "with tabs" do + let(:string) do + <<-EOS.undent + CFLAGS\t=\t-Wall -O2 + LDFLAGS\t=\t-lcrypto -lssl + EOS + end + + it "is successfully replaced" do + subject.change_make_var! "CFLAGS", "-O3" + expect(subject).to eq <<-EOS.undent + CFLAGS=-O3 + LDFLAGS\t=\t-lcrypto -lssl + EOS + end + end + end + + context "empty flag between other flags" do + let(:string) do + <<-EOS.undent + OTHER=def + FLAG = + FLAG2=abc + EOS + end + + it "is successfully replaced" do + subject.change_make_var! "FLAG", "def" + expect(subject).to eq <<-EOS.undent + OTHER=def + FLAG=def + FLAG2=abc + EOS + end + end + + context "empty flag" do + let(:string) do + <<-EOS.undent + FLAG = + mv file_a file_b + EOS + end + + it "is successfully replaced" do + subject.change_make_var! "FLAG", "def" + expect(subject).to eq <<-EOS.undent + FLAG=def + mv file_a file_b + EOS + end + end + + context "shell-style variable" do + let(:string) do + <<-EOS.undent + OTHER=def + FLAG=abc + FLAG2=abc + EOS + end + + it "is successfully replaced" do + subject.change_make_var! "FLAG", "def" + expect(subject).to eq <<-EOS.undent + OTHER=def + FLAG=def + FLAG2=abc + EOS + end + end + end + + describe "#remove_make_var!" do + context "flag" do + context "with spaces" do + let(:string) do + <<-EOS.undent + OTHER=def + FLAG = abc + FLAG2 = def + EOS + end + + it "is successfully removed" do + subject.remove_make_var! "FLAG" + expect(subject).to eq <<-EOS.undent + OTHER=def + FLAG2 = def + EOS + end + end + + context "with tabs" do + let(:string) do + <<-EOS.undent + CFLAGS\t=\t-Wall -O2 + LDFLAGS\t=\t-lcrypto -lssl + EOS + end + + it "is successfully removed" do + subject.remove_make_var! "LDFLAGS" + expect(subject).to eq <<-EOS.undent + CFLAGS\t=\t-Wall -O2 + EOS + end + end + end + + context "multiple flags" do + let(:string) do + <<-EOS.undent + OTHER=def + FLAG = abc + FLAG2 = def + OTHER2=def + EOS + end + + specify "are be successfully removed" do + subject.remove_make_var! ["FLAG", "FLAG2"] + expect(subject).to eq <<-EOS.undent + OTHER=def + OTHER2=def + EOS + end + end + end + + describe "#get_make_var" do + context "with spaces" do + let(:string) do + <<-EOS.undent + CFLAGS = -Wall -O2 + LDFLAGS = -lcrypto -lssl + EOS + end + + it "extracts the value for a given variable" do + expect(subject.get_make_var("CFLAGS")).to eq("-Wall -O2") + end + end + + context "with tabs" do + let(:string) do + <<-EOS.undent + CFLAGS\t=\t-Wall -O2 + LDFLAGS\t=\t-lcrypto -lssl + EOS + end + + it "extracts the value for a given variable" do + expect(subject.get_make_var("CFLAGS")).to eq("-Wall -O2") + end + end + end + + describe "#sub!" do + let(:string) { "foo" } + + it "replaces the first occurence" do + subject.sub!("o", "e") + expect(subject).to eq("feo") + end + end + + describe "#gsub!" do + let(:string) { "foo" } + + it "replaces the all occurences" do + subject.gsub!("o", "e") # rubocop:disable Performance/StringReplacement + expect(subject).to eq("fee") + end + end +end + +describe Utils::Inreplace do + let(:file) { Tempfile.new("test") } + + before(:each) do + file.write <<-EOS.undent + a + b + c + EOS + end + + after(:each) { file.unlink } + + it "raises error if there is nothing to replace" do + expect { + described_class.inreplace file.path, "d", "f" + }.to raise_error(Utils::InreplaceError) + end + + it "raises error if there is nothing to replace" do + expect { + described_class.inreplace(file.path) do |s| + s.gsub!("d", "f") # rubocop:disable Performance/StringReplacement + end + }.to raise_error(Utils::InreplaceError) + end + + it "raises error if there is nothing to replace" do + expect { + described_class.inreplace(file.path) do |s| + s.change_make_var! "VAR", "value" + s.remove_make_var! "VAR2" + end + }.to raise_error(Utils::InreplaceError) + end +end diff --git a/Library/Homebrew/test/inreplace_test.rb b/Library/Homebrew/test/inreplace_test.rb deleted file mode 100644 index 0e62f9d3f..000000000 --- a/Library/Homebrew/test/inreplace_test.rb +++ /dev/null @@ -1,119 +0,0 @@ -require "testing_env" -require "extend/string" -require "utils/inreplace" - -class InreplaceTest < Homebrew::TestCase - def test_change_make_var - # Replace flag - s1 = "OTHER=def\nFLAG = abc\nFLAG2=abc" - s1.extend(StringInreplaceExtension) - s1.change_make_var! "FLAG", "def" - assert_equal "OTHER=def\nFLAG=def\nFLAG2=abc", s1 - end - - def test_change_make_var_empty - # Replace empty flag - s1 = "OTHER=def\nFLAG = \nFLAG2=abc" - s1.extend(StringInreplaceExtension) - s1.change_make_var! "FLAG", "def" - assert_equal "OTHER=def\nFLAG=def\nFLAG2=abc", s1 - end - - def test_change_make_var_empty_2 - # Replace empty flag - s1 = "FLAG = \nmv file_a file_b" - s1.extend(StringInreplaceExtension) - s1.change_make_var! "FLAG", "def" - assert_equal "FLAG=def\nmv file_a file_b", s1 - end - - def test_change_make_var_append - # Append to flag - s1 = "OTHER=def\nFLAG = abc\nFLAG2=abc" - s1.extend(StringInreplaceExtension) - s1.change_make_var! "FLAG", "\\1 def" - assert_equal "OTHER=def\nFLAG=abc def\nFLAG2=abc", s1 - end - - def test_change_make_var_shell_style - # Shell variables have no spaces around = - s1 = "OTHER=def\nFLAG=abc\nFLAG2=abc" - s1.extend(StringInreplaceExtension) - s1.change_make_var! "FLAG", "def" - assert_equal "OTHER=def\nFLAG=def\nFLAG2=abc", s1 - end - - def test_remove_make_var - # Replace flag - s1 = "OTHER=def\nFLAG = abc\nFLAG2 = def" - s1.extend(StringInreplaceExtension) - s1.remove_make_var! "FLAG" - assert_equal "OTHER=def\nFLAG2 = def", s1 - end - - def test_remove_make_vars - # Replace flag - s1 = "OTHER=def\nFLAG = abc\nFLAG2 = def\nOTHER2=def" - s1.extend(StringInreplaceExtension) - s1.remove_make_var! ["FLAG", "FLAG2"] - assert_equal "OTHER=def\nOTHER2=def", s1 - end - - def test_get_make_var - s = "CFLAGS = -Wall -O2\nLDFLAGS = -lcrypto -lssl" - s.extend(StringInreplaceExtension) - assert_equal "-Wall -O2", s.get_make_var("CFLAGS") - end - - def test_change_make_var_with_tabs - s = "CFLAGS\t=\t-Wall -O2\nLDFLAGS\t=\t-lcrypto -lssl" - s.extend(StringInreplaceExtension) - - assert_equal "-Wall -O2", s.get_make_var("CFLAGS") - - s.change_make_var! "CFLAGS", "-O3" - assert_equal "CFLAGS=-O3\nLDFLAGS\t=\t-lcrypto -lssl", s - - s.remove_make_var! "LDFLAGS" - assert_equal "CFLAGS=-O3\n", s - end - - def test_sub_gsub - s = "foo" - s.extend(StringInreplaceExtension) - - s.sub!("f", "b") - assert_equal "boo", s - - # Under current context, we are testing `String#gsub!`, so let's disable rubocop temporarily. - s.gsub!("o", "e") # rubocop:disable Performance/StringReplacement - assert_equal "bee", s - end - - def test_inreplace_errors - require "tempfile" - extend(Utils::Inreplace) - - file = Tempfile.new("test") - - file.write "a\nb\nc\n" - - assert_raises(Utils::InreplaceError) do - inreplace file.path, "d", "f" - end - - assert_raises(Utils::InreplaceError) do - # Under current context, we are testing `String#gsub!`, so let's disable rubocop temporarily. - inreplace(file.path) { |s| s.gsub!("d", "f") } # rubocop:disable Performance/StringReplacement - end - - assert_raises(Utils::InreplaceError) do - inreplace(file.path) do |s| - s.change_make_var! "VAR", "value" - s.remove_make_var! "VAR2" - end - end - ensure - file.unlink - end -end diff --git a/Library/Homebrew/test/install_test.rb b/Library/Homebrew/test/install_test.rb deleted file mode 100644 index da6c1863f..000000000 --- a/Library/Homebrew/test/install_test.rb +++ /dev/null @@ -1,136 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestInstall < IntegrationCommandTestCase - def test_install - setup_test_formula "testball1" - assert_match "Specify `--HEAD`", cmd_fail("install", "testball1", "--head") - assert_match "No head is defined", cmd_fail("install", "testball1", "--HEAD") - assert_match "No devel block", cmd_fail("install", "testball1", "--devel") - assert_match "#{HOMEBREW_CELLAR}/testball1/0.1", cmd("install", "testball1") - assert_match "testball1-0.1 already installed", cmd("install", "testball1") - assert_match "MacRuby is not packaged", cmd_fail("install", "macruby") - assert_match "No available formula", cmd_fail("install", "formula") - assert_match "This similarly named formula was found", - cmd_fail("install", "testball") - - setup_test_formula "testball2" - assert_match "These similarly named formulae were found", - cmd_fail("install", "testball") - - install_and_rename_coretap_formula "testball1", "testball2" - assert_match "testball1 already installed, it's just not migrated", - cmd("install", "testball2") - end - - def test_install_failures - path = setup_test_formula "testball1", "version \"1.0\"" - devel_content = <<-EOS.undent - version "3.0" - devel do - url "#{Formulary.factory("testball1").stable.url}" - sha256 "#{TESTBALL_SHA256}" - version "2.0" - end - EOS - - assert_match "#{HOMEBREW_CELLAR}/testball1/1.0", cmd("install", "testball1") - - FileUtils.rm path - setup_test_formula "testball1", devel_content - - assert_match "first `brew unlink testball1`", cmd_fail("install", "testball1") - assert_match "#{HOMEBREW_CELLAR}/testball1/1.0", cmd("unlink", "testball1") - assert_match "#{HOMEBREW_CELLAR}/testball1/2.0", cmd("install", "testball1", "--devel") - assert_match "#{HOMEBREW_CELLAR}/testball1/2.0", cmd("unlink", "testball1") - assert_match "#{HOMEBREW_CELLAR}/testball1/3.0", cmd("install", "testball1") - - cmd("switch", "testball1", "2.0") - assert_match "already installed, however linked version is", - cmd("install", "testball1") - assert_match "#{HOMEBREW_CELLAR}/testball1/2.0", cmd("unlink", "testball1") - assert_match "just not linked", cmd("install", "testball1") - end - - def test_install_keg_only_outdated - path_keg_only = setup_test_formula "testball1", <<-EOS.undent - version "1.0" - keg_only "test reason" - EOS - - assert_match "#{HOMEBREW_CELLAR}/testball1/1.0", cmd("install", "testball1") - - FileUtils.rm path_keg_only - setup_test_formula "testball1", <<-EOS.undent - version "2.0" - keg_only "test reason" - EOS - - assert_match "keg-only and another version is linked to opt", - cmd("install", "testball1") - - assert_match "#{HOMEBREW_CELLAR}/testball1/2.0", - cmd("install", "testball1", "--force") - end - - def test_install_head_installed - repo_path = HOMEBREW_CACHE.join("repo") - repo_path.join("bin").mkpath - - repo_path.cd do - shutup do - system "git", "init" - system "git", "remote", "add", "origin", "https://github.com/Homebrew/homebrew-foo" - FileUtils.touch "bin/something.bin" - FileUtils.touch "README" - system "git", "add", "--all" - system "git", "commit", "-m", "Initial repo commit" - end - end - - setup_test_formula "testball1", <<-EOS.undent - version "1.0" - head "file://#{repo_path}", :using => :git - def install - prefix.install Dir["*"] - end - EOS - - # Ignore dependencies, because we'll try to resolve requirements in build.rb - # and there will be the git requirement, but we cannot instantiate git - # formula since we only have testball1 formula. - assert_match "#{HOMEBREW_CELLAR}/testball1/HEAD-d5eb689", cmd("install", "testball1", "--HEAD", "--ignore-dependencies") - assert_match "testball1-HEAD-d5eb689 already installed", - cmd("install", "testball1", "--HEAD", "--ignore-dependencies") - assert_match "#{HOMEBREW_CELLAR}/testball1/HEAD-d5eb689", cmd("unlink", "testball1") - assert_match "#{HOMEBREW_CELLAR}/testball1/1.0", cmd("install", "testball1") - end - - def test_install_with_invalid_option - setup_test_formula "testball1" - assert_match "testball1: this formula has no --with-fo option so it will be ignored!", - cmd("install", "testball1", "--with-fo") - end - - def test_install_with_nonfatal_requirement - setup_test_formula "testball1", <<-EOS.undent - class NonFatalRequirement < Requirement - satisfy { false } - end - depends_on NonFatalRequirement - EOS - message = "NonFatalRequirement unsatisfied!" - assert_equal 1, cmd("install", "testball1").scan(message).size - end - - def test_install_with_fatal_requirement - setup_test_formula "testball1", <<-EOS.undent - class FatalRequirement < Requirement - fatal true - satisfy { false } - end - depends_on FatalRequirement - EOS - message = "FatalRequirement unsatisfied!" - assert_equal 1, cmd_fail("install", "testball1").scan(message).size - end -end diff --git a/Library/Homebrew/test/irb_test.rb b/Library/Homebrew/test/irb_test.rb deleted file mode 100644 index 832ca39a5..000000000 --- a/Library/Homebrew/test/irb_test.rb +++ /dev/null @@ -1,19 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestIrb < IntegrationCommandTestCase - def test_irb - assert_match "'v8'.f # => instance of the v8 formula", - cmd("irb", "--examples") - - setup_test_formula "testball" - - irb_test = HOMEBREW_TEMP/"irb-test.rb" - irb_test.write <<-EOS.undent - "testball".f - :testball.f - exit - EOS - - assert_match "Interactive Homebrew Shell", cmd("irb", irb_test) - end -end diff --git a/Library/Homebrew/test/java_requirement_spec.rb b/Library/Homebrew/test/java_requirement_spec.rb new file mode 100644 index 000000000..5adf64c7c --- /dev/null +++ b/Library/Homebrew/test/java_requirement_spec.rb @@ -0,0 +1,107 @@ +require "requirements/java_requirement" + +describe JavaRequirement do + subject { described_class.new([]) } + + before(:each) do + ENV["JAVA_HOME"] = nil + end + + describe "#message" do + its(:message) { is_expected.to match(/Java is required to install this formula./) } + end + + describe "#inspect" do + subject { described_class.new(%w[1.7+]) } + its(:inspect) { is_expected.to eq('#<JavaRequirement: "java" [] version="1.7+">') } + end + + describe "#display_s" do + context "without specific version" do + its(:display_s) { is_expected.to eq("java") } + end + + context "with version 1.8" do + subject { described_class.new(%w[1.8]) } + its(:display_s) { is_expected.to eq("java = 1.8") } + end + + context "with version 1.8+" do + subject { described_class.new(%w[1.8+]) } + its(:display_s) { is_expected.to eq("java >= 1.8") } + end + end + + describe "#satisfied?" do + subject { described_class.new(%w[1.8]) } + + it "returns false if no `java` executable can be found" do + allow(File).to receive(:executable?).and_return(false) + expect(subject).not_to be_satisfied + end + + it "returns true if #preferred_java returns a path" do + allow(subject).to receive(:preferred_java).and_return(Pathname.new("/usr/bin/java")) + expect(subject).to be_satisfied + end + + context "when #possible_javas contains paths" do + let(:path) { Pathname.new(Dir.mktmpdir) } + let(:java) { path/"java" } + + def setup_java_with_version(version) + IO.write java, <<-EOS.undent + #!/bin/sh + echo 'java version "#{version}"' + EOS + FileUtils.chmod "+x", java + end + + before(:each) do + allow(subject).to receive(:possible_javas).and_return([java]) + end + + after(:each) do + path.rmtree + end + + context "and 1.7 is required" do + subject { described_class.new(%w[1.7]) } + + it "returns false if all are lower" do + setup_java_with_version "1.6.0_5" + expect(subject).not_to be_satisfied + end + + it "returns true if one is equal" do + setup_java_with_version "1.7.0_5" + expect(subject).to be_satisfied + end + + it "returns false if all are higher" do + setup_java_with_version "1.8.0_5" + expect(subject).not_to be_satisfied + end + end + + context "and 1.7+ is required" do + subject { described_class.new(%w[1.7+]) } + + it "returns false if all are lower" do + setup_java_with_version "1.6.0_5" + expect(subject).not_to be_satisfied + end + + it "returns true if one is equal" do + setup_java_with_version "1.7.0_5" + expect(subject).to be_satisfied + end + + it "returns true if one is higher" do + setup_java_with_version "1.8.0_5" + expect(subject).to be_satisfied + end + end + end + end +end diff --git a/Library/Homebrew/test/java_requirement_test.rb b/Library/Homebrew/test/java_requirement_test.rb deleted file mode 100644 index d0b51f92c..000000000 --- a/Library/Homebrew/test/java_requirement_test.rb +++ /dev/null @@ -1,50 +0,0 @@ -require "testing_env" -require "requirements/java_requirement" - -class JavaRequirementTests < Homebrew::TestCase - def setup - super - ENV["JAVA_HOME"] = nil - end - - def test_message - a = JavaRequirement.new([]) - assert_match(/Java is required to install this formula./, a.message) - end - - def test_inspect - a = JavaRequirement.new(%w[1.7+]) - assert_equal a.inspect, '#<JavaRequirement: "java" [] version="1.7+">' - end - - def test_display_s - x = JavaRequirement.new([]) - assert_equal x.display_s, "java" - y = JavaRequirement.new(%w[1.8]) - assert_equal y.display_s, "java = 1.8" - z = JavaRequirement.new(%w[1.8+]) - assert_equal z.display_s, "java >= 1.8" - end - - def test_satisfied? - a = JavaRequirement.new(%w[1.8]) - File.stubs(:executable?).returns(false) - refute_predicate a, :satisfied? - - b = JavaRequirement.new([]) - b.stubs(:preferred_java).returns(Pathname.new("/usr/bin/java")) - assert_predicate b, :satisfied? - - c = JavaRequirement.new(%w[1.7+]) - c.stubs(:possible_javas).returns([Pathname.new("/usr/bin/java")]) - Utils.stubs(:popen_read).returns('java version "1.6.0_5"') - refute_predicate c, :satisfied? - Utils.stubs(:popen_read).returns('java version "1.8.0_5"') - assert_predicate c, :satisfied? - - d = JavaRequirement.new(%w[1.7]) - d.stubs(:possible_javas).returns([Pathname.new("/usr/bin/java")]) - Utils.stubs(:popen_read).returns('java version "1.8.0_5"') - refute_predicate d, :satisfied? - end -end diff --git a/Library/Homebrew/test/keg_spec.rb b/Library/Homebrew/test/keg_spec.rb new file mode 100644 index 000000000..3bf1257e6 --- /dev/null +++ b/Library/Homebrew/test/keg_spec.rb @@ -0,0 +1,490 @@ +require "keg" +require "stringio" + +describe Keg do + include FileUtils + + def setup_test_keg(name, version) + path = HOMEBREW_CELLAR/name/version + (path/"bin").mkpath + + %w[hiworld helloworld goodbye_cruel_world].each do |file| + touch path/"bin"/file + end + + keg = described_class.new(path) + kegs << keg + keg + end + + around(:each) do |example| + begin + @old_stdout = $stdout + $stdout = StringIO.new + + example.run + ensure + $stdout = @old_stdout + end + end + + let(:dst) { HOMEBREW_PREFIX/"bin"/"helloworld" } + let(:nonexistent) { Pathname.new("/some/nonexistent/path") } + let(:mode) { OpenStruct.new } + let!(:keg) { setup_test_keg("foo", "1.0") } + let(:kegs) { [] } + + before(:each) do + (HOMEBREW_PREFIX/"bin").mkpath + (HOMEBREW_PREFIX/"lib").mkpath + end + + after(:each) do + kegs.each(&:unlink) + rmtree HOMEBREW_PREFIX/"lib" + end + + specify "::all" do + Formula.clear_racks_cache + expect(described_class.all).to eq([keg]) + end + + specify "#empty_installation?" do + %w[.DS_Store INSTALL_RECEIPT.json LICENSE.txt].each do |file| + touch keg/file + end + + expect(keg).to exist + expect(keg).to be_a_directory + expect(keg).not_to be_an_empty_installation + + (keg/"bin").rmtree + expect(keg).to be_an_empty_installation + + (keg/"bin").mkpath + touch keg.join("bin", "todo") + expect(keg).not_to be_an_empty_installation + end + + specify "#oldname_opt_record" do + expect(keg.oldname_opt_record).to be nil + oldname_opt_record = HOMEBREW_PREFIX/"opt/oldfoo" + oldname_opt_record.make_relative_symlink(HOMEBREW_CELLAR/"foo/1.0") + expect(keg.oldname_opt_record).to eq(oldname_opt_record) + end + + specify "#remove_oldname_opt_record" do + oldname_opt_record = HOMEBREW_PREFIX/"opt/oldfoo" + oldname_opt_record.make_relative_symlink(HOMEBREW_CELLAR/"foo/2.0") + keg.remove_oldname_opt_record + expect(oldname_opt_record).to be_a_symlink + oldname_opt_record.unlink + oldname_opt_record.make_relative_symlink(HOMEBREW_CELLAR/"foo/1.0") + keg.remove_oldname_opt_record + expect(oldname_opt_record).not_to be_a_symlink + end + + describe "#link" do + it "links a Keg" do + expect(keg.link).to eq(3) + (HOMEBREW_PREFIX/"bin").children.each do |c| + expect(c.readlink).to be_relative + end + end + + context "with dry run set to true" do + it "only prints what would be done" do + mode.dry_run = true + + expect(keg.link(mode)).to eq(0) + expect(keg).not_to be_linked + + ["hiworld", "helloworld", "goodbye_cruel_world"].each do |file| + expect($stdout.string).to match("#{HOMEBREW_PREFIX}/bin/#{file}") + end + expect($stdout.string.lines.count).to eq(3) + end + end + + it "fails when already linked" do + keg.link + + expect { keg.link }.to raise_error(Keg::AlreadyLinkedError) + end + + it "fails when files exist" do + touch dst + + expect { keg.link }.to raise_error(Keg::ConflictError) + end + + it "ignores broken symlinks at target" do + src = keg/"bin"/"helloworld" + dst.make_symlink(nonexistent) + keg.link + expect(dst.readlink).to eq(src.relative_path_from(dst.dirname)) + end + + context "with overwrite set to true" do + it "overwrite existing files" do + touch dst + mode.overwrite = true + expect(keg.link(mode)).to eq(3) + expect(keg).to be_linked + end + + it "overwrites broken symlinks" do + dst.make_symlink "nowhere" + mode.overwrite = true + expect(keg.link(mode)).to eq(3) + expect(keg).to be_linked + end + + it "still supports dryrun" do + touch dst + mode.overwrite = true + mode.dry_run = true + + expect(keg.link(mode)).to eq(0) + expect(keg).not_to be_linked + + expect($stdout.string).to eq("#{dst}\n") + end + end + + it "also creates an opt link" do + expect(keg).not_to be_optlinked + keg.link + expect(keg).to be_optlinked + end + + specify "pkgconfig directory is created" do + link = HOMEBREW_PREFIX/"lib"/"pkgconfig" + (keg/"lib"/"pkgconfig").mkpath + keg.link + expect(link.lstat).to be_a_directory + end + + specify "cmake directory is created" do + link = HOMEBREW_PREFIX/"lib"/"cmake" + (keg/"lib"/"cmake").mkpath + keg.link + expect(link.lstat).to be_a_directory + end + + specify "symlinks are linked directly" do + link = HOMEBREW_PREFIX/"lib"/"pkgconfig" + + (keg/"lib"/"example").mkpath + (keg/"lib"/"pkgconfig").make_symlink "example" + keg.link + + expect(link.resolved_path).to be_a_symlink + expect(link.lstat).to be_a_symlink + end + end + + describe "#unlink" do + it "unlinks a Keg" do + keg.link + expect(dst).to be_a_symlink + expect(keg.unlink).to eq(3) + expect(dst).not_to be_a_symlink + end + + it "prunes empty top-level directories" do + mkpath HOMEBREW_PREFIX/"lib/foo/bar" + mkpath keg/"lib/foo/bar" + touch keg/"lib/foo/bar/file1" + + keg.unlink + + expect(HOMEBREW_PREFIX/"lib/foo").not_to be_a_directory + end + + it "ignores .DS_Store when pruning empty directories" do + mkpath HOMEBREW_PREFIX/"lib/foo/bar" + touch HOMEBREW_PREFIX/"lib/foo/.DS_Store" + mkpath keg/"lib/foo/bar" + touch keg/"lib/foo/bar/file1" + + keg.unlink + + expect(HOMEBREW_PREFIX/"lib/foo").not_to be_a_directory + expect(HOMEBREW_PREFIX/"lib/foo/.DS_Store").not_to exist + end + + it "doesn't remove opt link" do + keg.link + keg.unlink + expect(keg).to be_optlinked + end + + it "preverves broken symlinks pointing outside the Keg" do + keg.link + dst.delete + dst.make_symlink(nonexistent) + keg.unlink + expect(dst).to be_a_symlink + end + + it "preverves broken symlinks pointing into the Keg" do + keg.link + dst.resolved_path.delete + keg.unlink + expect(dst).to be_a_symlink + end + + it "preverves symlinks pointing outside the Keg" do + keg.link + dst.delete + dst.make_symlink(Pathname.new("/bin/sh")) + keg.unlink + expect(dst).to be_a_symlink + end + + it "preserves real files" do + keg.link + dst.delete + touch dst + keg.unlink + expect(dst).to be_a_file + end + + it "ignores nonexistent file" do + keg.link + dst.delete + expect(keg.unlink).to eq(2) + end + + it "doesn't remove links to symlinks" do + a = HOMEBREW_CELLAR/"a"/"1.0" + b = HOMEBREW_CELLAR/"b"/"1.0" + + (a/"lib"/"example").mkpath + (a/"lib"/"example2").make_symlink "example" + (b/"lib"/"example2").mkpath + + a = described_class.new(a) + b = described_class.new(b) + a.link + + lib = HOMEBREW_PREFIX/"lib" + expect(lib.children.length).to eq(2) + expect { b.link }.to raise_error(Keg::ConflictError) + expect(lib.children.length).to eq(2) + end + + it "removes broken symlinks that conflict with directories" do + a = HOMEBREW_CELLAR/"a"/"1.0" + (a/"lib"/"foo").mkpath + + keg = described_class.new(a) + + link = HOMEBREW_PREFIX/"lib"/"foo" + link.parent.mkpath + link.make_symlink(nonexistent) + + keg.link + end + end + + describe "#optlink" do + it "creates an opt link" do + oldname_opt_record = HOMEBREW_PREFIX/"opt/oldfoo" + oldname_opt_record.make_relative_symlink(HOMEBREW_CELLAR/"foo/1.0") + keg_record = HOMEBREW_CELLAR/"foo"/"2.0" + (keg_record/"bin").mkpath + keg = described_class.new(keg_record) + keg.optlink + expect(keg_record).to eq(oldname_opt_record.resolved_path) + keg.uninstall + expect(oldname_opt_record).not_to be_a_symlink + end + + it "doesn't fail if already opt-linked" do + keg.opt_record.make_relative_symlink Pathname.new(keg) + keg.optlink + expect(keg).to be_optlinked + end + + it "replaces an existing directory" do + keg.opt_record.mkpath + keg.optlink + expect(keg).to be_optlinked + end + + it "replaces an existing file" do + keg.opt_record.parent.mkpath + keg.opt_record.write("foo") + keg.optlink + expect(keg).to be_optlinked + end + end + + specify "#link and #unlink" do + expect(keg).not_to be_linked + keg.link + expect(keg).to be_linked + keg.unlink + expect(keg).not_to be_linked + end + + describe "::find_some_installed_dependents" do + def stub_formula_name(name) + f = formula(name) { url "foo-1.0" } + stub_formula_loader f + stub_formula_loader f, "homebrew/core/#{f}" + f + end + + def setup_test_keg(name, version) + f = stub_formula_name(name) + keg = super + Tab.create(f, DevelopmentTools.default_compiler, :libcxx).write + keg + end + + before(:each) do + keg.link + end + + def alter_tab(keg = dependent) + tab = Tab.for_keg(keg) + yield tab + tab.write + end + + # 1.1.6 is the earliest version of Homebrew that generates correct runtime + # dependency lists in Tabs. + def dependencies(deps, homebrew_version: "1.1.6") + alter_tab do |tab| + tab.homebrew_version = homebrew_version + tab.tabfile = dependent/Tab::FILENAME + tab.runtime_dependencies = deps + end + end + + def unreliable_dependencies(deps) + # 1.1.5 is (hopefully!) the last version of Homebrew that generates + # incorrect runtime dependency lists in Tabs. + dependencies(deps, homebrew_version: "1.1.5") + end + + let(:dependent) { setup_test_keg("bar", "1.0") } + + # Test with a keg whose formula isn't known. + # This can happen if e.g. a formula is installed + # from a file path or URL. + specify "unknown Formula" do + allow(Formulary).to receive(:loader_for).and_call_original + alter_tab(keg) do |t| + t.source["tap"] = "some/tap" + t.source["path"] = nil + end + + dependencies [{ "full_name" => "some/tap/foo", "version" => "1.0" }] + expect(keg.installed_dependents).to eq([dependent]) + expect(described_class.find_some_installed_dependents([keg])).to eq([[keg], ["bar 1.0"]]) + + dependencies nil + # It doesn't make sense for a keg with no formula to have any dependents, + # so that can't really be tested. + expect(described_class.find_some_installed_dependents([keg])).to be nil + end + + specify "a dependency with no Tap in Tab" do + tap_dep = setup_test_keg("baz", "1.0") + + alter_tab(keg) { |t| t.source["tap"] = nil } + + dependencies nil + Formula["bar"].class.depends_on "foo" + Formula["bar"].class.depends_on "baz" + + result = described_class.find_some_installed_dependents([keg, tap_dep]) + expect(result).to eq([[keg, tap_dep], ["bar"]]) + end + + specify "no dependencies anywhere" do + dependencies nil + expect(keg.installed_dependents).to be_empty + expect(described_class.find_some_installed_dependents([keg])).to be nil + end + + specify "missing Formula dependency" do + dependencies nil + Formula["bar"].class.depends_on "foo" + expect(keg.installed_dependents).to be_empty + expect(described_class.find_some_installed_dependents([keg])).to eq([[keg], ["bar"]]) + end + + specify "uninstalling dependent and dependency" do + dependencies nil + Formula["bar"].class.depends_on "foo" + expect(keg.installed_dependents).to be_empty + expect(described_class.find_some_installed_dependents([keg, dependent])).to be nil + end + + specify "renamed dependency" do + dependencies nil + + stub_formula_loader Formula["foo"], "homebrew/core/foo-old" + renamed_path = HOMEBREW_CELLAR/"foo-old" + (HOMEBREW_CELLAR/"foo").rename(renamed_path) + renamed_keg = described_class.new(renamed_path/"1.0") + + Formula["bar"].class.depends_on "foo" + + result = described_class.find_some_installed_dependents([renamed_keg]) + expect(result).to eq([[renamed_keg], ["bar"]]) + end + + specify "empty dependencies in Tab" do + dependencies [] + expect(keg.installed_dependents).to be_empty + expect(described_class.find_some_installed_dependents([keg])).to be nil + end + + specify "same name but different version in Tab" do + dependencies [{ "full_name" => "foo", "version" => "1.1" }] + expect(keg.installed_dependents).to eq([dependent]) + expect(described_class.find_some_installed_dependents([keg])).to eq([[keg], ["bar 1.0"]]) + end + + specify "different name and same version in Tab" do + stub_formula_name("baz") + dependencies [{ "full_name" => "baz", "version" => keg.version.to_s }] + expect(keg.installed_dependents).to be_empty + expect(described_class.find_some_installed_dependents([keg])).to be nil + end + + specify "same name and version in Tab" do + dependencies [{ "full_name" => "foo", "version" => "1.0" }] + expect(keg.installed_dependents).to eq([dependent]) + expect(described_class.find_some_installed_dependents([keg])).to eq([[keg], ["bar 1.0"]]) + end + + specify "fallback for old versions" do + unreliable_dependencies [{ "full_name" => "baz", "version" => "1.0" }] + Formula["bar"].class.depends_on "foo" + expect(keg.installed_dependents).to be_empty + expect(described_class.find_some_installed_dependents([keg])).to eq([[keg], ["bar"]]) + end + + specify "non-opt-linked" do + keg.remove_opt_record + dependencies [{ "full_name" => "foo", "version" => "1.0" }] + expect(keg.installed_dependents).to be_empty + expect(described_class.find_some_installed_dependents([keg])).to be nil + end + + specify "keg-only" do + keg.unlink + Formula["foo"].class.keg_only "a good reason" + dependencies [{ "full_name" => "foo", "version" => "1.1" }] # different version + expect(keg.installed_dependents).to eq([dependent]) + expect(described_class.find_some_installed_dependents([keg])).to eq([[keg], ["bar 1.0"]]) + end + end +end diff --git a/Library/Homebrew/test/keg_test.rb b/Library/Homebrew/test/keg_test.rb deleted file mode 100644 index e8f99b777..000000000 --- a/Library/Homebrew/test/keg_test.rb +++ /dev/null @@ -1,479 +0,0 @@ -require "testing_env" -require "keg" -require "stringio" - -class LinkTestCase < Homebrew::TestCase - include FileUtils - - def setup_test_keg(name, version) - path = HOMEBREW_CELLAR.join(name, version) - path.join("bin").mkpath - - %w[hiworld helloworld goodbye_cruel_world].each do |file| - touch path.join("bin", file) - end - - keg = Keg.new(path) - @kegs ||= [] - @kegs << keg - keg - end - - def setup - super - - @keg = setup_test_keg("foo", "1.0") - @dst = HOMEBREW_PREFIX.join("bin", "helloworld") - @nonexistent = Pathname.new("/some/nonexistent/path") - - @mode = OpenStruct.new - - @old_stdout = $stdout - $stdout = StringIO.new - - mkpath HOMEBREW_PREFIX/"bin" - mkpath HOMEBREW_PREFIX/"lib" - end - - def teardown - @kegs.each(&:unlink) - $stdout = @old_stdout - rmtree HOMEBREW_PREFIX/"lib" - super - end -end - -class LinkTests < LinkTestCase - def test_all - Formula.clear_racks_cache - assert_equal [@keg], Keg.all - end - - def test_empty_installation - %w[.DS_Store INSTALL_RECEIPT.json LICENSE.txt].each do |file| - touch @keg/file - end - assert_predicate @keg, :exist? - assert_predicate @keg, :directory? - refute_predicate @keg, :empty_installation? - - (@keg/"bin").rmtree - assert_predicate @keg, :empty_installation? - - (@keg/"bin").mkpath - touch @keg.join("bin", "todo") - refute_predicate @keg, :empty_installation? - end - - def test_linking_keg - assert_equal 3, @keg.link - (HOMEBREW_PREFIX/"bin").children.each { |c| assert_predicate c.readlink, :relative? } - end - - def test_unlinking_keg - @keg.link - assert_predicate @dst, :symlink? - assert_equal 3, @keg.unlink - refute_predicate @dst, :symlink? - end - - def test_oldname_opt_record - assert_nil @keg.oldname_opt_record - oldname_opt_record = HOMEBREW_PREFIX/"opt/oldfoo" - oldname_opt_record.make_relative_symlink(HOMEBREW_CELLAR/"foo/1.0") - assert_equal oldname_opt_record, @keg.oldname_opt_record - end - - def test_optlink_relink - oldname_opt_record = HOMEBREW_PREFIX/"opt/oldfoo" - oldname_opt_record.make_relative_symlink(HOMEBREW_CELLAR/"foo/1.0") - keg_record = HOMEBREW_CELLAR.join("foo", "2.0") - keg_record.join("bin").mkpath - keg = Keg.new(keg_record) - keg.optlink - assert_equal keg_record, oldname_opt_record.resolved_path - keg.uninstall - refute_predicate oldname_opt_record, :symlink? - end - - def test_remove_oldname_opt_record - oldname_opt_record = HOMEBREW_PREFIX/"opt/oldfoo" - oldname_opt_record.make_relative_symlink(HOMEBREW_CELLAR/"foo/2.0") - @keg.remove_oldname_opt_record - assert_predicate oldname_opt_record, :symlink? - oldname_opt_record.unlink - oldname_opt_record.make_relative_symlink(HOMEBREW_CELLAR/"foo/1.0") - @keg.remove_oldname_opt_record - refute_predicate oldname_opt_record, :symlink? - end - - def test_link_dry_run - @mode.dry_run = true - - assert_equal 0, @keg.link(@mode) - refute_predicate @keg, :linked? - - ["hiworld", "helloworld", "goodbye_cruel_world"].each do |file| - assert_match "#{HOMEBREW_PREFIX}/bin/#{file}", $stdout.string - end - assert_equal 3, $stdout.string.lines.count - end - - def test_linking_fails_when_already_linked - @keg.link - assert_raises(Keg::AlreadyLinkedError) { @keg.link } - end - - def test_linking_fails_when_files_exist - touch @dst - assert_raises(Keg::ConflictError) { @keg.link } - end - - def test_link_ignores_broken_symlinks_at_target - src = @keg.join("bin", "helloworld") - @dst.make_symlink(@nonexistent) - @keg.link - assert_equal src.relative_path_from(@dst.dirname), @dst.readlink - end - - def test_link_overwrite - touch @dst - @mode.overwrite = true - assert_equal 3, @keg.link(@mode) - assert_predicate @keg, :linked? - end - - def test_link_overwrite_broken_symlinks - @dst.make_symlink "nowhere" - @mode.overwrite = true - assert_equal 3, @keg.link(@mode) - assert_predicate @keg, :linked? - end - - def test_link_overwrite_dryrun - touch @dst - @mode.overwrite = true - @mode.dry_run = true - - assert_equal 0, @keg.link(@mode) - refute_predicate @keg, :linked? - - assert_equal "#{@dst}\n", $stdout.string - end - - def test_unlink_prunes_empty_toplevel_directories - mkpath HOMEBREW_PREFIX/"lib/foo/bar" - mkpath @keg/"lib/foo/bar" - touch @keg/"lib/foo/bar/file1" - - @keg.unlink - - refute_predicate HOMEBREW_PREFIX/"lib/foo", :directory? - end - - def test_unlink_ignores_ds_store_when_pruning_empty_dirs - mkpath HOMEBREW_PREFIX/"lib/foo/bar" - touch HOMEBREW_PREFIX/"lib/foo/.DS_Store" - mkpath @keg/"lib/foo/bar" - touch @keg/"lib/foo/bar/file1" - - @keg.unlink - - refute_predicate HOMEBREW_PREFIX/"lib/foo", :directory? - refute_predicate HOMEBREW_PREFIX/"lib/foo/.DS_Store", :exist? - end - - def test_linking_creates_opt_link - refute_predicate @keg, :optlinked? - @keg.link - assert_predicate @keg, :optlinked? - end - - def test_unlinking_does_not_remove_opt_link - @keg.link - @keg.unlink - assert_predicate @keg, :optlinked? - end - - def test_existing_opt_link - @keg.opt_record.make_relative_symlink Pathname.new(@keg) - @keg.optlink - assert_predicate @keg, :optlinked? - end - - def test_existing_opt_link_directory - @keg.opt_record.mkpath - @keg.optlink - assert_predicate @keg, :optlinked? - end - - def test_existing_opt_link_file - @keg.opt_record.parent.mkpath - @keg.opt_record.write("foo") - @keg.optlink - assert_predicate @keg, :optlinked? - end - - def test_linked_keg - refute_predicate @keg, :linked? - @keg.link - assert_predicate @keg, :linked? - @keg.unlink - refute_predicate @keg, :linked? - end - - def test_unlink_preserves_broken_symlink_pointing_outside_the_keg - @keg.link - @dst.delete - @dst.make_symlink(@nonexistent) - @keg.unlink - assert_predicate @dst, :symlink? - end - - def test_unlink_preserves_broken_symlink_pointing_into_the_keg - @keg.link - @dst.resolved_path.delete - @keg.unlink - assert_predicate @dst, :symlink? - end - - def test_unlink_preserves_symlink_pointing_outside_of_keg - @keg.link - @dst.delete - @dst.make_symlink(Pathname.new("/bin/sh")) - @keg.unlink - assert_predicate @dst, :symlink? - end - - def test_unlink_preserves_real_file - @keg.link - @dst.delete - touch @dst - @keg.unlink - assert_predicate @dst, :file? - end - - def test_unlink_ignores_nonexistent_file - @keg.link - @dst.delete - assert_equal 2, @keg.unlink - end - - def test_pkgconfig_is_mkpathed - link = HOMEBREW_PREFIX.join("lib", "pkgconfig") - @keg.join("lib", "pkgconfig").mkpath - @keg.link - assert_predicate link.lstat, :directory? - end - - def test_cmake_is_mkpathed - link = HOMEBREW_PREFIX.join("lib", "cmake") - @keg.join("lib", "cmake").mkpath - @keg.link - assert_predicate link.lstat, :directory? - end - - def test_symlinks_are_linked_directly - link = HOMEBREW_PREFIX.join("lib", "pkgconfig") - - @keg.join("lib", "example").mkpath - @keg.join("lib", "pkgconfig").make_symlink "example" - @keg.link - - assert_predicate link.resolved_path, :symlink? - assert_predicate link.lstat, :symlink? - end - - def test_links_to_symlinks_are_not_removed - a = HOMEBREW_CELLAR.join("a", "1.0") - b = HOMEBREW_CELLAR.join("b", "1.0") - - a.join("lib", "example").mkpath - a.join("lib", "example2").make_symlink "example" - b.join("lib", "example2").mkpath - - a = Keg.new(a) - b = Keg.new(b) - a.link - - lib = HOMEBREW_PREFIX.join("lib") - assert_equal 2, lib.children.length - assert_raises(Keg::ConflictError) { b.link } - assert_equal 2, lib.children.length - ensure - a.unlink - end - - def test_removes_broken_symlinks_that_conflict_with_directories - a = HOMEBREW_CELLAR.join("a", "1.0") - a.join("lib", "foo").mkpath - - keg = Keg.new(a) - - link = HOMEBREW_PREFIX.join("lib", "foo") - link.parent.mkpath - link.make_symlink(@nonexistent) - - keg.link - ensure - keg.unlink - end -end - -class InstalledDependantsTests < LinkTestCase - def stub_formula_name(name) - f = formula(name) { url "foo-1.0" } - stub_formula_loader f - stub_formula_loader f, "homebrew/core/#{f}" - f - end - - def setup_test_keg(name, version) - f = stub_formula_name(name) - keg = super - Tab.create(f, DevelopmentTools.default_compiler, :libcxx).write - keg - end - - def setup - super - @dependent = setup_test_keg("bar", "1.0") - @keg.link - end - - def alter_tab(keg = @dependent) - tab = Tab.for_keg(keg) - yield tab - tab.write - end - - # 1.1.6 is the earliest version of Homebrew that generates correct runtime - # dependency lists in tabs. - def dependencies(deps, homebrew_version: "1.1.6") - alter_tab do |tab| - tab.homebrew_version = homebrew_version - tab.tabfile = @dependent.join("INSTALL_RECEIPT.json") - tab.runtime_dependencies = deps - end - end - - def unreliable_dependencies(deps) - # 1.1.5 is (hopefully!) the last version of Homebrew that generates - # incorrect runtime dependency lists in tabs. - dependencies(deps, homebrew_version: "1.1.5") - end - - # Test with a keg whose formula isn't known. - # This can happen if e.g. a formula is installed - # from a file path or URL. - def test_unknown_formula - Formulary.unstub(:loader_for) - alter_tab(@keg) do |t| - t.source["tap"] = "some/tap" - t.source["path"] = nil - end - - dependencies [{ "full_name" => "some/tap/foo", "version" => "1.0" }] - assert_equal [@dependent], @keg.installed_dependents - assert_equal [[@keg], ["bar 1.0"]], Keg.find_some_installed_dependents([@keg]) - - dependencies nil - # It doesn't make sense for a keg with no formula to have any dependents, - # so that can't really be tested. - assert_nil Keg.find_some_installed_dependents([@keg]) - end - - def test_a_dependency_with_no_tap_in_tab - @tap_dep = setup_test_keg("baz", "1.0") - - alter_tab(@keg) { |t| t.source["tap"] = nil } - - dependencies nil - Formula["bar"].class.depends_on "foo" - Formula["bar"].class.depends_on "baz" - - result = Keg.find_some_installed_dependents([@keg, @tap_dep]) - assert_equal [[@keg, @tap_dep], ["bar"]], result - end - - def test_no_dependencies_anywhere - dependencies nil - assert_empty @keg.installed_dependents - assert_nil Keg.find_some_installed_dependents([@keg]) - end - - def test_missing_formula_dependency - dependencies nil - Formula["bar"].class.depends_on "foo" - assert_empty @keg.installed_dependents - assert_equal [[@keg], ["bar"]], Keg.find_some_installed_dependents([@keg]) - end - - def test_uninstalling_dependent_and_dependency - dependencies nil - Formula["bar"].class.depends_on "foo" - assert_empty @keg.installed_dependents - assert_nil Keg.find_some_installed_dependents([@keg, @dependent]) - end - - def test_renamed_dependency - dependencies nil - - stub_formula_loader Formula["foo"], "homebrew/core/foo-old" - renamed_path = HOMEBREW_CELLAR/"foo-old" - (HOMEBREW_CELLAR/"foo").rename(renamed_path) - renamed_keg = Keg.new(renamed_path.join("1.0")) - - Formula["bar"].class.depends_on "foo" - - result = Keg.find_some_installed_dependents([renamed_keg]) - assert_equal [[renamed_keg], ["bar"]], result - end - - def test_empty_dependencies_in_tab - dependencies [] - assert_empty @keg.installed_dependents - assert_nil Keg.find_some_installed_dependents([@keg]) - end - - def test_same_name_different_version_in_tab - dependencies [{ "full_name" => "foo", "version" => "1.1" }] - assert_equal [@dependent], @keg.installed_dependents - assert_equal [[@keg], ["bar 1.0"]], Keg.find_some_installed_dependents([@keg]) - end - - def test_different_name_same_version_in_tab - stub_formula_name("baz") - dependencies [{ "full_name" => "baz", "version" => @keg.version.to_s }] - assert_empty @keg.installed_dependents - assert_nil Keg.find_some_installed_dependents([@keg]) - end - - def test_same_name_and_version_in_tab - dependencies [{ "full_name" => "foo", "version" => "1.0" }] - assert_equal [@dependent], @keg.installed_dependents - assert_equal [[@keg], ["bar 1.0"]], Keg.find_some_installed_dependents([@keg]) - end - - def test_fallback_for_old_versions - unreliable_dependencies [{ "full_name" => "baz", "version" => "1.0" }] - Formula["bar"].class.depends_on "foo" - assert_empty @keg.installed_dependents - assert_equal [[@keg], ["bar"]], Keg.find_some_installed_dependents([@keg]) - end - - def test_nonoptlinked - @keg.remove_opt_record - dependencies [{ "full_name" => "foo", "version" => "1.0" }] - assert_empty @keg.installed_dependents - assert_nil Keg.find_some_installed_dependents([@keg]) - end - - def test_keg_only - @keg.unlink - Formula["foo"].class.keg_only "a good reason" - dependencies [{ "full_name" => "foo", "version" => "1.1" }] # different version - assert_equal [@dependent], @keg.installed_dependents - assert_equal [[@keg], ["bar 1.0"]], Keg.find_some_installed_dependents([@keg]) - end -end diff --git a/Library/Homebrew/test/leaves_test.rb b/Library/Homebrew/test/leaves_test.rb deleted file mode 100644 index f73fba1ea..000000000 --- a/Library/Homebrew/test/leaves_test.rb +++ /dev/null @@ -1,15 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestLeaves < IntegrationCommandTestCase - def test_leaves - setup_test_formula "foo" - setup_test_formula "bar" - assert_equal "", cmd("leaves") - - (HOMEBREW_CELLAR/"foo/0.1/somedir").mkpath - assert_equal "foo", cmd("leaves") - - (HOMEBREW_CELLAR/"bar/0.1/somedir").mkpath - assert_equal "bar", cmd("leaves") - end -end diff --git a/Library/Homebrew/test/link_test.rb b/Library/Homebrew/test/link_test.rb deleted file mode 100644 index 062caa0c0..000000000 --- a/Library/Homebrew/test/link_test.rb +++ /dev/null @@ -1,23 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestLink < IntegrationCommandTestCase - def test_link - assert_match "This command requires a keg argument", cmd_fail("link") - - setup_test_formula "testball1" - cmd("install", "testball1") - cmd("link", "testball1") - - cmd("unlink", "testball1") - assert_match "Would link", cmd("link", "--dry-run", "testball1") - assert_match "Would remove", - cmd("link", "--dry-run", "--overwrite", "testball1") - assert_match "Linking", cmd("link", "testball1") - - setup_test_formula "testball2", <<-EOS.undent - keg_only "just because" - EOS - cmd("install", "testball2") - assert_match "testball2 is keg-only", cmd("link", "testball2") - end -end diff --git a/Library/Homebrew/test/linkapps_test.rb b/Library/Homebrew/test/linkapps_test.rb deleted file mode 100644 index 4c5b8ec13..000000000 --- a/Library/Homebrew/test/linkapps_test.rb +++ /dev/null @@ -1,15 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestLinkapps < IntegrationCommandTestCase - def test_linkapps - home_dir = Pathname.new(mktmpdir) - (home_dir/"Applications").mkpath - - setup_test_formula "testball" - - source_dir = HOMEBREW_CELLAR/"testball/0.1/TestBall.app" - source_dir.mkpath - assert_match "Linking: #{source_dir}", - cmd("linkapps", "--local", "HOME" => home_dir) - end -end diff --git a/Library/Homebrew/test/list_test.rb b/Library/Homebrew/test/list_test.rb deleted file mode 100644 index 3c691e3ad..000000000 --- a/Library/Homebrew/test/list_test.rb +++ /dev/null @@ -1,13 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestList < IntegrationCommandTestCase - def test_list - formulae = %w[bar foo qux] - formulae.each do |f| - (HOMEBREW_CELLAR/"#{f}/1.0/somedir").mkpath - end - - assert_equal formulae.join("\n"), - cmd("list") - end -end diff --git a/Library/Homebrew/test/log_formula_test.rb b/Library/Homebrew/test/log_formula_test.rb deleted file mode 100644 index bb6a1f661..000000000 --- a/Library/Homebrew/test/log_formula_test.rb +++ /dev/null @@ -1,27 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestLogFormula < IntegrationCommandTestCase - def test_log_formula - core_tap = CoreTap.new - setup_test_formula "testball" - - core_tap.path.cd do - shutup do - system "git", "init" - system "git", "add", "--all" - system "git", "commit", "-m", "This is a test commit for Testball" - end - end - - core_tap_url = "file://#{core_tap.path}" - shallow_tap = Tap.fetch("homebrew", "shallow") - shutup do - system "git", "clone", "--depth=1", core_tap_url, shallow_tap.path - end - - assert_match "This is a test commit for Testball", - cmd("log", "#{shallow_tap}/testball") - assert_predicate shallow_tap.path/".git/shallow", :exist?, - "A shallow clone should have been created." - end -end diff --git a/Library/Homebrew/test/log_test.rb b/Library/Homebrew/test/log_test.rb deleted file mode 100644 index b2e150ccd..000000000 --- a/Library/Homebrew/test/log_test.rb +++ /dev/null @@ -1,13 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestLog < IntegrationCommandTestCase - def test_log - FileUtils.cd HOMEBREW_REPOSITORY do - shutup do - system "git", "init" - system "git", "commit", "--allow-empty", "-m", "This is a test commit" - end - end - assert_match "This is a test commit", cmd("log") - end -end diff --git a/Library/Homebrew/test/migrate_test.rb b/Library/Homebrew/test/migrate_test.rb deleted file mode 100644 index 17929d038..000000000 --- a/Library/Homebrew/test/migrate_test.rb +++ /dev/null @@ -1,18 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestMigrate < IntegrationCommandTestCase - def test_migrate - setup_test_formula "testball1" - setup_test_formula "testball2" - assert_match "Invalid usage", cmd_fail("migrate") - assert_match "No available formula with the name \"testball\"", - cmd_fail("migrate", "testball") - assert_match "testball1 doesn't replace any formula", - cmd_fail("migrate", "testball1") - - install_and_rename_coretap_formula "testball1", "testball2" - assert_match "Migrating testball1 to testball2", cmd("migrate", "testball1") - (HOMEBREW_CELLAR/"testball1").unlink - assert_match "Error: No such keg", cmd_fail("migrate", "testball1") - end -end diff --git a/Library/Homebrew/test/migrator_spec.rb b/Library/Homebrew/test/migrator_spec.rb new file mode 100644 index 000000000..90ee9d8ff --- /dev/null +++ b/Library/Homebrew/test/migrator_spec.rb @@ -0,0 +1,264 @@ +require "migrator" +require "test/support/fixtures/testball" +require "tab" +require "keg" + +describe Migrator do + subject { described_class.new(new_formula) } + + let(:new_formula) { Testball.new("newname") } + let(:old_formula) { Testball.new("oldname") } + + let(:new_keg_record) { HOMEBREW_CELLAR/"newname/0.1" } + let(:old_keg_record) { HOMEBREW_CELLAR/"oldname/0.1" } + + let(:old_tab) { Tab.empty } + + let(:keg) { Keg.new(old_keg_record) } + let(:old_pin) { HOMEBREW_PINNED_KEGS/"oldname" } + + before(:each) do |example| + allow(new_formula).to receive(:oldname).and_return("oldname") + + # do not create directories for error tests + next if example.metadata[:description].start_with?("raises an error") + + (old_keg_record/"bin").mkpath + + %w[inside bindir].each do |file| + FileUtils.touch old_keg_record/"bin/#{file}" + end + + old_tab.tabfile = HOMEBREW_CELLAR/"oldname/0.1/INSTALL_RECEIPT.json" + old_tab.source["path"] = "/oldname" + old_tab.write + + keg.link + keg.optlink + + old_pin.make_relative_symlink old_keg_record + + subject # needs to be evaluated eagerly + + (HOMEBREW_PREFIX/"bin").mkpath + end + + after(:each) do + if !old_keg_record.parent.symlink? && old_keg_record.directory? + keg.unlink + end + + if new_keg_record.directory? + new_keg = Keg.new(new_keg_record) + new_keg.unlink + end + end + + describe "::new" do + it "raises an error if there is no old name" do + expect { + described_class.new(old_formula) + }.to raise_error(Migrator::MigratorNoOldnameError) + end + + it "raises an error if there is no old path" do + expect { + described_class.new(new_formula) + }.to raise_error(Migrator::MigratorNoOldpathError) + end + + it "raises an error if the Taps differ" do + keg = HOMEBREW_CELLAR/"oldname/0.1" + keg.mkpath + tab = Tab.empty + tab.tabfile = HOMEBREW_CELLAR/"oldname/0.1/INSTALL_RECEIPT.json" + tab.source["tap"] = "homebrew/core" + tab.write + + expect { + described_class.new(new_formula) + }.to raise_error(Migrator::MigratorDifferentTapsError) + end + end + + specify "#move_to_new_directory" do + keg.unlink + shutup do + subject.move_to_new_directory + end + + expect(new_keg_record).to be_a_directory + expect(new_keg_record/"bin").to be_a_directory + expect(new_keg_record/"bin/inside").to be_a_file + expect(new_keg_record/"bin/bindir").to be_a_file + expect(old_keg_record).not_to be_a_directory + end + + specify "#backup_oldname_cellar" do + old_keg_record.parent.rmtree + (new_keg_record/"bin").mkpath + + subject.backup_oldname_cellar + + expect(old_keg_record/"bin").to be_a_directory + expect(old_keg_record/"bin").to be_a_directory + end + + specify "#repin" do + (new_keg_record/"bin").mkpath + expected_relative = new_keg_record.relative_path_from HOMEBREW_PINNED_KEGS + + subject.repin + + expect(subject.new_pin_record).to be_a_symlink + expect(subject.new_pin_record.readlink).to eq(expected_relative) + expect(subject.old_pin_record).not_to exist + end + + specify "#unlink_oldname" do + expect(HOMEBREW_LINKED_KEGS.children.count).to eq(1) + expect((HOMEBREW_PREFIX/"opt").children.count).to eq(1) + + shutup do + subject.unlink_oldname + end + + expect(HOMEBREW_LINKED_KEGS).not_to exist + expect(HOMEBREW_LIBRARY/"bin").not_to exist + end + + specify "#link_newname" do + keg.unlink + keg.uninstall + + (new_keg_record/"bin").mkpath + %w[inside bindir].each do |file| + FileUtils.touch new_keg_record/"bin"/file + end + + shutup do + subject.link_newname + end + + expect(HOMEBREW_LINKED_KEGS.children.count).to eq(1) + expect((HOMEBREW_PREFIX/"opt").children.count).to eq(1) + end + + specify "#link_oldname_opt" do + new_keg_record.mkpath + subject.link_oldname_opt + expect((HOMEBREW_PREFIX/"opt/oldname").realpath).to eq(new_keg_record.realpath) + end + + specify "#link_oldname_cellar" do + (new_keg_record/"bin").mkpath + keg.unlink + keg.uninstall + subject.link_oldname_cellar + expect((HOMEBREW_CELLAR/"oldname").realpath).to eq(new_keg_record.parent.realpath) + end + + specify "#update_tabs" do + (new_keg_record/"bin").mkpath + tab = Tab.empty + tab.tabfile = HOMEBREW_CELLAR/"newname/0.1/INSTALL_RECEIPT.json" + tab.source["path"] = "/path/that/must/be/changed/by/update_tabs" + tab.write + subject.update_tabs + expect(Tab.for_keg(new_keg_record).source["path"]).to eq(new_formula.path.to_s) + end + + specify "#migrate" do + tab = Tab.empty + tab.tabfile = HOMEBREW_CELLAR/"oldname/0.1/INSTALL_RECEIPT.json" + tab.source["path"] = old_formula.path.to_s + tab.write + + shutup do + subject.migrate + end + + expect(new_keg_record).to exist + expect(old_keg_record.parent).to be_a_symlink + expect(HOMEBREW_LINKED_KEGS/"oldname").not_to exist + expect((HOMEBREW_LINKED_KEGS/"newname").realpath).to eq(new_keg_record.realpath) + expect(old_keg_record.realpath).to eq(new_keg_record.realpath) + expect((HOMEBREW_PREFIX/"opt/oldname").realpath).to eq(new_keg_record.realpath) + expect((HOMEBREW_CELLAR/"oldname").realpath).to eq(new_keg_record.parent.realpath) + expect((HOMEBREW_PINNED_KEGS/"newname").realpath).to eq(new_keg_record.realpath) + expect(Tab.for_keg(new_keg_record).source["path"]).to eq(new_formula.path.to_s) + end + + specify "#unlinik_oldname_opt" do + new_keg_record.mkpath + old_opt_record = HOMEBREW_PREFIX/"opt/oldname" + old_opt_record.unlink if old_opt_record.symlink? + old_opt_record.make_relative_symlink(new_keg_record) + subject.unlink_oldname_opt + expect(old_opt_record).not_to be_a_symlink + end + + specify "#unlink_oldname_cellar" do + new_keg_record.mkpath + keg.unlink + keg.uninstall + old_keg_record.parent.make_relative_symlink(new_keg_record.parent) + subject.unlink_oldname_cellar + expect(old_keg_record.parent).not_to be_a_symlink + end + + specify "#backup_oldname_cellar" do + (new_keg_record/"bin").mkpath + keg.unlink + keg.uninstall + subject.backup_oldname_cellar + expect(old_keg_record.subdirs).not_to be_empty + end + + specify "#backup_old_tabs" do + tab = Tab.empty + tab.tabfile = HOMEBREW_CELLAR/"oldname/0.1/INSTALL_RECEIPT.json" + tab.source["path"] = "/should/be/the/same" + tab.write + migrator = Migrator.new(new_formula) + tab.tabfile.delete + migrator.backup_old_tabs + expect(Tab.for_keg(old_keg_record).source["path"]).to eq("/should/be/the/same") + end + + describe "#backup_oldname" do + after(:each) do + expect(old_keg_record.parent).to be_a_directory + expect(old_keg_record.parent.subdirs).not_to be_empty + expect(HOMEBREW_LINKED_KEGS/"oldname").to exist + expect(HOMEBREW_PREFIX/"opt/oldname").to exist + expect(HOMEBREW_PINNED_KEGS/"oldname").to be_a_symlink + expect(keg).to be_linked + end + + context "when cellar exists" do + it "backs up the old name" do + subject.backup_oldname + end + end + + context "when cellar is removed" do + it "backs up the old name" do + (new_keg_record/"bin").mkpath + keg.unlink + keg.uninstall + subject.backup_oldname + end + end + + context "when cellar is linked" do + it "backs up the old name" do + (new_keg_record/"bin").mkpath + keg.unlink + keg.uninstall + old_keg_record.parent.make_relative_symlink(new_keg_record.parent) + subject.backup_oldname + end + end + end +end diff --git a/Library/Homebrew/test/migrator_test.rb b/Library/Homebrew/test/migrator_test.rb deleted file mode 100644 index 012ea12bb..000000000 --- a/Library/Homebrew/test/migrator_test.rb +++ /dev/null @@ -1,251 +0,0 @@ -require "testing_env" -require "migrator" -require "test/support/fixtures/testball" -require "tab" -require "keg" - -class Formula - attr_writer :oldname -end - -class MigratorErrorsTests < Homebrew::TestCase - def setup - super - @new_f = Testball.new("newname") - @new_f.oldname = "oldname" - @old_f = Testball.new("oldname") - end - - def test_no_oldname - assert_raises(Migrator::MigratorNoOldnameError) { Migrator.new(@old_f) } - end - - def test_no_oldpath - assert_raises(Migrator::MigratorNoOldpathError) { Migrator.new(@new_f) } - end - - def test_different_taps - keg = HOMEBREW_CELLAR/"oldname/0.1" - keg.mkpath - tab = Tab.empty - tab.tabfile = HOMEBREW_CELLAR/"oldname/0.1/INSTALL_RECEIPT.json" - tab.source["tap"] = "homebrew/core" - tab.write - assert_raises(Migrator::MigratorDifferentTapsError) { Migrator.new(@new_f) } - end -end - -class MigratorTests < Homebrew::TestCase - include FileUtils - - def setup - super - - @new_f = Testball.new("newname") - @new_f.oldname = "oldname" - - @old_f = Testball.new("oldname") - - @old_keg_record = HOMEBREW_CELLAR/"oldname/0.1" - @old_keg_record.join("bin").mkpath - @new_keg_record = HOMEBREW_CELLAR/"newname/0.1" - - %w[inside bindir].each { |file| touch @old_keg_record.join("bin", file) } - - @old_tab = Tab.empty - @old_tab.tabfile = HOMEBREW_CELLAR/"oldname/0.1/INSTALL_RECEIPT.json" - @old_tab.source["path"] = "/oldname" - @old_tab.write - - @keg = Keg.new(@old_keg_record) - @keg.link - @keg.optlink - - @old_pin = HOMEBREW_PINNED_KEGS/"oldname" - @old_pin.make_relative_symlink @old_keg_record - - @migrator = Migrator.new(@new_f) - - mkpath HOMEBREW_PREFIX/"bin" - end - - def teardown - if !@old_keg_record.parent.symlink? && @old_keg_record.directory? - @keg.unlink - end - - if @new_keg_record.directory? - new_keg = Keg.new(@new_keg_record) - new_keg.unlink - end - - super - end - - def test_move_cellar - @keg.unlink - shutup { @migrator.move_to_new_directory } - assert_predicate @new_keg_record, :directory? - assert_predicate @new_keg_record/"bin", :directory? - assert_predicate @new_keg_record/"bin/inside", :file? - assert_predicate @new_keg_record/"bin/bindir", :file? - refute_predicate @old_keg_record, :directory? - end - - def test_backup_cellar - @old_keg_record.parent.rmtree - @new_keg_record.join("bin").mkpath - - @migrator.backup_oldname_cellar - - assert_predicate @old_keg_record, :directory? - assert_predicate @old_keg_record/"bin", :directory? - end - - def test_repin - @new_keg_record.join("bin").mkpath - expected_relative = @new_keg_record.relative_path_from HOMEBREW_PINNED_KEGS - - @migrator.repin - - assert_predicate @migrator.new_pin_record, :symlink? - assert_equal expected_relative, @migrator.new_pin_record.readlink - refute_predicate @migrator.old_pin_record, :exist? - end - - def test_unlink_oldname - assert_equal 1, HOMEBREW_LINKED_KEGS.children.size - assert_equal 1, (HOMEBREW_PREFIX/"opt").children.size - - shutup { @migrator.unlink_oldname } - - refute_predicate HOMEBREW_LINKED_KEGS, :exist? - refute_predicate HOMEBREW_LIBRARY/"bin", :exist? - end - - def test_link_newname - @keg.unlink - @keg.uninstall - @new_keg_record.join("bin").mkpath - %w[inside bindir].each { |file| touch @new_keg_record.join("bin", file) } - - shutup { @migrator.link_newname } - - assert_equal 1, HOMEBREW_LINKED_KEGS.children.size - assert_equal 1, (HOMEBREW_PREFIX/"opt").children.size - end - - def test_link_oldname_opt - @new_keg_record.mkpath - @migrator.link_oldname_opt - assert_equal @new_keg_record.realpath, (HOMEBREW_PREFIX/"opt/oldname").realpath - end - - def test_link_oldname_cellar - @new_keg_record.join("bin").mkpath - @keg.unlink - @keg.uninstall - @migrator.link_oldname_cellar - assert_equal @new_keg_record.parent.realpath, (HOMEBREW_CELLAR/"oldname").realpath - end - - def test_update_tabs - @new_keg_record.join("bin").mkpath - tab = Tab.empty - tab.tabfile = HOMEBREW_CELLAR/"newname/0.1/INSTALL_RECEIPT.json" - tab.source["path"] = "/path/that/must/be/changed/by/update_tabs" - tab.write - @migrator.update_tabs - assert_equal @new_f.path.to_s, Tab.for_keg(@new_keg_record).source["path"] - end - - def test_migrate - tab = Tab.empty - tab.tabfile = HOMEBREW_CELLAR/"oldname/0.1/INSTALL_RECEIPT.json" - tab.source["path"] = @old_f.path.to_s - tab.write - - shutup { @migrator.migrate } - - assert_predicate @new_keg_record, :exist? - assert_predicate @old_keg_record.parent, :symlink? - refute_predicate HOMEBREW_LINKED_KEGS/"oldname", :exist? - assert_equal @new_keg_record.realpath, (HOMEBREW_LINKED_KEGS/"newname").realpath - assert_equal @new_keg_record.realpath, @old_keg_record.realpath - assert_equal @new_keg_record.realpath, (HOMEBREW_PREFIX/"opt/oldname").realpath - assert_equal @new_keg_record.parent.realpath, (HOMEBREW_CELLAR/"oldname").realpath - assert_equal @new_keg_record.realpath, (HOMEBREW_PINNED_KEGS/"newname").realpath - assert_equal @new_f.path.to_s, Tab.for_keg(@new_keg_record).source["path"] - end - - def test_unlinik_oldname_opt - @new_keg_record.mkpath - old_opt_record = HOMEBREW_PREFIX/"opt/oldname" - old_opt_record.unlink if old_opt_record.symlink? - old_opt_record.make_relative_symlink(@new_keg_record) - @migrator.unlink_oldname_opt - refute_predicate old_opt_record, :symlink? - end - - def test_unlink_oldname_cellar - @new_keg_record.mkpath - @keg.unlink - @keg.uninstall - @old_keg_record.parent.make_relative_symlink(@new_keg_record.parent) - @migrator.unlink_oldname_cellar - refute_predicate @old_keg_record.parent, :symlink? - end - - def test_backup_oldname_cellar - @new_keg_record.join("bin").mkpath - @keg.unlink - @keg.uninstall - @migrator.backup_oldname_cellar - refute_predicate @old_keg_record.subdirs, :empty? - end - - def test_backup_old_tabs - tab = Tab.empty - tab.tabfile = HOMEBREW_CELLAR/"oldname/0.1/INSTALL_RECEIPT.json" - tab.source["path"] = "/should/be/the/same" - tab.write - migrator = Migrator.new(@new_f) - tab.tabfile.delete - migrator.backup_old_tabs - assert_equal "/should/be/the/same", Tab.for_keg(@old_keg_record).source["path"] - end - - # Backup tests are divided into three groups: when oldname Cellar is deleted - # and when it still exists and when it's a symlink - - def check_after_backup - assert_predicate @old_keg_record.parent, :directory? - refute_predicate @old_keg_record.parent.subdirs, :empty? - assert_predicate HOMEBREW_LINKED_KEGS/"oldname", :exist? - assert_predicate HOMEBREW_PREFIX/"opt/oldname", :exist? - assert_predicate HOMEBREW_PINNED_KEGS/"oldname", :symlink? - assert_predicate @keg, :linked? - end - - def test_backup_cellar_exist - @migrator.backup_oldname - check_after_backup - end - - def test_backup_cellar_removed - @new_keg_record.join("bin").mkpath - @keg.unlink - @keg.uninstall - @migrator.backup_oldname - check_after_backup - end - - def test_backup_cellar_linked - @new_keg_record.join("bin").mkpath - @keg.unlink - @keg.uninstall - @old_keg_record.parent.make_relative_symlink(@new_keg_record.parent) - @migrator.backup_oldname - check_after_backup - end -end diff --git a/Library/Homebrew/test/missing_test.rb b/Library/Homebrew/test/missing_test.rb deleted file mode 100644 index 4f20d8a7a..000000000 --- a/Library/Homebrew/test/missing_test.rb +++ /dev/null @@ -1,34 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestMissing < IntegrationCommandTestCase - def setup - super - - setup_test_formula "foo" - setup_test_formula "bar" - end - - def make_prefix(name) - (HOMEBREW_CELLAR/name/"1.0").mkpath - end - - def test_missing_missing - make_prefix "bar" - - assert_match "foo", cmd("missing") - end - - def test_missing_not_missing - make_prefix "foo" - make_prefix "bar" - - assert_empty cmd("missing") - end - - def test_missing_hide - make_prefix "foo" - make_prefix "bar" - - assert_match "foo", cmd("missing", "--hide=foo") - end -end diff --git a/Library/Homebrew/test/options_spec.rb b/Library/Homebrew/test/options_spec.rb new file mode 100644 index 000000000..a05bb139e --- /dev/null +++ b/Library/Homebrew/test/options_spec.rb @@ -0,0 +1,148 @@ +require "options" + +describe Option do + subject { described_class.new("foo") } + + specify "#to_s" do + expect(subject.to_s).to eq("--foo") + end + + specify "equality" do + foo = Option.new("foo") + bar = Option.new("bar") + expect(subject).to eq(foo) + expect(subject).not_to eq(bar) + expect(subject).to eql(foo) + expect(subject).not_to eql(bar) + end + + specify "#description" do + expect(subject.description).to be_empty + expect(Option.new("foo", "foo").description).to eq("foo") + end + + specify "#inspect" do + expect(subject.inspect).to eq("#<Option: \"--foo\">") + end +end + +describe DeprecatedOption do + subject { described_class.new("foo", "bar") } + + specify "#old" do + expect(subject.old).to eq("foo") + end + + specify "#old_flag" do + expect(subject.old_flag).to eq("--foo") + end + + specify "#current" do + expect(subject.current).to eq("bar") + end + + specify "#current_flag" do + expect(subject.current_flag).to eq("--bar") + end + + specify "equality" do + foobar = DeprecatedOption.new("foo", "bar") + boofar = DeprecatedOption.new("boo", "far") + expect(foobar).to eq(subject) + expect(subject).to eq(foobar) + expect(boofar).not_to eq(subject) + expect(subject).not_to eq(boofar) + end +end + +describe Options do + it "removes duplicate options" do + subject << Option.new("foo") + subject << Option.new("foo") + expect(subject).to include("--foo") + expect(subject.count).to eq(1) + end + + it "preserves existing member when adding a duplicate" do + a = Option.new("foo", "bar") + b = Option.new("foo", "qux") + subject << a << b + expect(subject.count).to eq(1) + expect(subject.first).to be(a) + expect(subject.first.description).to eq(a.description) + end + + specify "#include?" do + subject << Option.new("foo") + expect(subject).to include("--foo") + expect(subject).to include("foo") + expect(subject).to include(Option.new("foo")) + end + + describe "#+" do + it "returns options" do + expect(subject + Options.new).to be_an_instance_of(Options) + end + end + + describe "#-" do + it "returns options" do + expect(subject - Options.new).to be_an_instance_of(Options) + end + end + + specify "#&" do + foo, bar, baz = %w[foo bar baz].map { |o| Option.new(o) } + options = Options.new << foo << bar + subject << foo << baz + expect((subject & options).to_a).to eq([foo]) + end + + specify "#|" do + foo, bar, baz = %w[foo bar baz].map { |o| Option.new(o) } + options = Options.new << foo << bar + subject << foo << baz + expect((subject | options).sort).to eq([foo, bar, baz].sort) + end + + specify "#*" do + subject << Option.new("aa") << Option.new("bb") << Option.new("cc") + expect((subject * "XX").split("XX").sort).to eq(%w[--aa --bb --cc]) + end + + describe "<<" do + it "returns itself" do + expect(subject << Option.new("foo")).to be subject + end + end + + specify "#as_flags" do + subject << Option.new("foo") + expect(subject.as_flags).to eq(%w[--foo]) + end + + specify "#to_a" do + option = Option.new("foo") + subject << option + expect(subject.to_a).to eq([option]) + end + + specify "#to_ary" do + option = Option.new("foo") + subject << option + expect(subject.to_ary).to eq([option]) + end + + specify "::create_with_array" do + array = %w[--foo --bar] + option1 = Option.new("foo") + option2 = Option.new("bar") + expect(Options.create(array).sort).to eq([option1, option2].sort) + end + + specify "#inspect" do + expect(subject.inspect).to eq("#<Options: []>") + subject << Option.new("foo") + expect(subject.inspect).to eq("#<Options: [#<Option: \"--foo\">]>") + end +end diff --git a/Library/Homebrew/test/options_test.rb b/Library/Homebrew/test/options_test.rb deleted file mode 100644 index 09ea14180..000000000 --- a/Library/Homebrew/test/options_test.rb +++ /dev/null @@ -1,160 +0,0 @@ -require "testing_env" -require "options" -require "testing_env" - -class IntegrationCommandTestOptions < IntegrationCommandTestCase - def test_options - setup_test_formula "testball", <<-EOS.undent - depends_on "bar" => :recommended - EOS - - assert_equal "--with-foo\n\tBuild with foo\n--without-bar\n\tBuild without bar support", - cmd("options", "testball").chomp - end -end - -class OptionTests < Homebrew::TestCase - def setup - super - @option = Option.new("foo") - end - - def test_to_s - assert_equal "--foo", @option.to_s - end - - def test_equality - foo = Option.new("foo") - bar = Option.new("bar") - assert_equal foo, @option - refute_equal bar, @option - assert_eql @option, foo - refute_eql @option, bar - end - - def test_description - assert_empty @option.description - assert_equal "foo", Option.new("foo", "foo").description - end - - def test_inspect - assert_equal "#<Option: \"--foo\">", @option.inspect - end -end - -class DeprecatedOptionTests < Homebrew::TestCase - def setup - super - @deprecated_option = DeprecatedOption.new("foo", "bar") - end - - def test_old - assert_equal "foo", @deprecated_option.old - assert_equal "--foo", @deprecated_option.old_flag - end - - def test_current - assert_equal "bar", @deprecated_option.current - assert_equal "--bar", @deprecated_option.current_flag - end - - def test_equality - foobar = DeprecatedOption.new("foo", "bar") - boofar = DeprecatedOption.new("boo", "far") - assert_equal foobar, @deprecated_option - refute_equal boofar, @deprecated_option - assert_eql @deprecated_option, foobar - refute_eql @deprecated_option, boofar - end -end - -class OptionsTests < Homebrew::TestCase - def setup - super - @options = Options.new - end - - def test_no_duplicate_options - @options << Option.new("foo") - @options << Option.new("foo") - assert_includes @options, "--foo" - assert_equal 1, @options.count - end - - def test_preserves_existing_member_when_pushing_duplicate - a = Option.new("foo", "bar") - b = Option.new("foo", "qux") - @options << a << b - assert_equal 1, @options.count - assert_same a, @options.first - assert_equal a.description, @options.first.description - end - - def test_include - @options << Option.new("foo") - assert_includes @options, "--foo" - assert_includes @options, "foo" - assert_includes @options, Option.new("foo") - end - - def test_union_returns_options - assert_instance_of Options, @options + Options.new - end - - def test_difference_returns_options - assert_instance_of Options, @options - Options.new - end - - def test_shovel_returns_self - assert_same @options, @options << Option.new("foo") - end - - def test_as_flags - @options << Option.new("foo") - assert_equal %w[--foo], @options.as_flags - end - - def test_to_a - option = Option.new("foo") - @options << option - assert_equal [option], @options.to_a - end - - def test_to_ary - option = Option.new("foo") - @options << option - assert_equal [option], @options.to_ary - end - - def test_intersection - foo, bar, baz = %w[foo bar baz].map { |o| Option.new(o) } - options = Options.new << foo << bar - @options << foo << baz - assert_equal [foo], (@options & options).to_a - end - - def test_set_union - foo, bar, baz = %w[foo bar baz].map { |o| Option.new(o) } - options = Options.new << foo << bar - @options << foo << baz - assert_equal [foo, bar, baz].sort, (@options | options).sort - end - - def test_times - @options << Option.new("aa") << Option.new("bb") << Option.new("cc") - assert_equal %w[--aa --bb --cc], (@options * "XX").split("XX").sort - end - - def test_create_with_array - array = %w[--foo --bar] - option1 = Option.new("foo") - option2 = Option.new("bar") - assert_equal [option1, option2].sort, Options.create(array).sort - end - - def test_inspect - assert_equal "#<Options: []>", @options.inspect - @options << Option.new("foo") - assert_equal "#<Options: [#<Option: \"--foo\">]>", @options.inspect - end -end diff --git a/Library/Homebrew/test/os/mac/bottle_tag_test.rb b/Library/Homebrew/test/os/mac/bottle_tag_test.rb deleted file mode 100644 index 996bd4d53..000000000 --- a/Library/Homebrew/test/os/mac/bottle_tag_test.rb +++ /dev/null @@ -1,79 +0,0 @@ -require "testing_env" -require "utils/bottles" - -class OSMacBottleTagTests < Homebrew::TestCase - def test_tag_tiger_ppc - MacOS.stubs(:version).returns(MacOS::Version.new("10.4")) - Hardware::CPU.stubs(:type).returns(:ppc) - Hardware::CPU.stubs(:family).returns(:foo) - MacOS.stubs(:prefer_64_bit?).returns(false) - assert_equal :tiger_foo, Utils::Bottles.tag - end - - def test_tag_tiger_intel - MacOS.stubs(:version).returns(MacOS::Version.new("10.4")) - Hardware::CPU.stubs(:type).returns(:intel) - MacOS.stubs(:prefer_64_bit?).returns(false) - assert_equal :tiger, Utils::Bottles.tag - end - - def test_tag_tiger_ppc_64 - MacOS.stubs(:version).returns(MacOS::Version.new("10.4")) - Hardware::CPU.stubs(:type).returns(:ppc) - Hardware::CPU.stubs(:family).returns(:g5) - MacOS.stubs(:prefer_64_bit?).returns(true) - assert_equal :tiger_g5_64, Utils::Bottles.tag - end - - # Note that this will probably never be used - def test_tag_tiger_intel_64 - MacOS.stubs(:version).returns(MacOS::Version.new("10.4")) - Hardware::CPU.stubs(:type).returns(:intel) - MacOS.stubs(:prefer_64_bit?).returns(true) - assert_equal :tiger_64, Utils::Bottles.tag - end - - def test_tag_leopard_intel - MacOS.stubs(:version).returns(MacOS::Version.new("10.5")) - Hardware::CPU.stubs(:type).returns(:intel) - MacOS.stubs(:prefer_64_bit?).returns(false) - assert_equal :leopard, Utils::Bottles.tag - end - - def test_tag_leopard_ppc_64 - MacOS.stubs(:version).returns(MacOS::Version.new("10.5")) - Hardware::CPU.stubs(:type).returns(:ppc) - Hardware::CPU.stubs(:family).returns(:g5) - MacOS.stubs(:prefer_64_bit?).returns(true) - assert_equal :leopard_g5_64, Utils::Bottles.tag - end - - def test_tag_leopard_intel_64 - MacOS.stubs(:version).returns(MacOS::Version.new("10.5")) - Hardware::CPU.stubs(:type).returns(:intel) - MacOS.stubs(:prefer_64_bit?).returns(true) - assert_equal :leopard_64, Utils::Bottles.tag - end - - def test_tag_snow_leopard_32 - MacOS.stubs(:version).returns(MacOS::Version.new("10.6")) - Hardware::CPU.stubs(:is_64_bit?).returns(false) - assert_equal :snow_leopard_32, Utils::Bottles.tag - end - - def test_tag_snow_leopard_64 - MacOS.stubs(:version).returns(MacOS::Version.new("10.6")) - Hardware::CPU.stubs(:is_64_bit?).returns(true) - assert_equal :snow_leopard, Utils::Bottles.tag - end - - def test_tag_lion - MacOS.stubs(:version).returns(MacOS::Version.new("10.7")) - assert_equal :lion, Utils::Bottles.tag - end - - def test_tag_mountain_lion - MacOS.stubs(:version).returns(MacOS::Version.new("10.8")) - assert_equal :mountain_lion, Utils::Bottles.tag - end -end diff --git a/Library/Homebrew/test/os/mac/dependency_collector_spec.rb b/Library/Homebrew/test/os/mac/dependency_collector_spec.rb new file mode 100644 index 000000000..21b15cd99 --- /dev/null +++ b/Library/Homebrew/test/os/mac/dependency_collector_spec.rb @@ -0,0 +1,50 @@ +require "dependency_collector" + +RSpec::Matchers.alias_matcher :need_tar_xz_dependency, :be_tar_needs_xz_dependency + +describe DependencyCollector do + after(:each) do + described_class.clear_cache + end + + specify "#tar_needs_xz_dependency?" do + allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.9")) + expect(described_class).not_to need_tar_xz_dependency + end + + specify "LD64 pre-Leopard dependency" do + allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.4")) + expect(subject.build(:ld64)).to eq(LD64Dependency.new) + end + + specify "LD64 Leopard or newer dependency" do + allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.5")) + expect(subject.build(:ld64)).to be nil + end + + specify "ant Mavericks or newer dependency" do + allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.9")) + subject.add ant: :build + expect(subject.deps.find { |dep| dep.name == "ant" }).to eq(Dependency.new("ant", [:build])) + end + + specify "ant pre-Mavericks dependency" do + allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.7")) + subject.add ant: :build + expect(subject.deps.find { |dep| dep.name == "ant" }).to be nil + end + + specify "Resource xz pre-Mavericks dependency" do + allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.8")) + resource = Resource.new + resource.url("http://example.com/foo.tar.xz") + expect(subject.add(resource)).to eq(Dependency.new("xz", [:build])) + end + + specify "Resource xz Mavericks or newer dependency" do + allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.9")) + resource = Resource.new + resource.url("http://example.com/foo.tar.xz") + expect(subject.add(resource)).to be nil + end +end diff --git a/Library/Homebrew/test/os/mac/dependency_collector_test.rb b/Library/Homebrew/test/os/mac/dependency_collector_test.rb deleted file mode 100644 index 1033df9ab..000000000 --- a/Library/Homebrew/test/os/mac/dependency_collector_test.rb +++ /dev/null @@ -1,59 +0,0 @@ -require "testing_env" -require "dependency_collector" - -class OSMacDependencyCollectorTests < Homebrew::TestCase - def find_dependency(name) - @d.deps.find { |dep| dep.name == name } - end - - def setup - super - @d = DependencyCollector.new - end - - def teardown - DependencyCollector.clear_cache - super - end - - def test_tar_needs_xz_dependency - MacOS.stubs(:version).returns(MacOS::Version.new("10.9")) - refute DependencyCollector.tar_needs_xz_dependency? - end - - def test_ld64_dep_pre_leopard - MacOS.stubs(:version).returns(MacOS::Version.new("10.4")) - assert_equal LD64Dependency.new, @d.build(:ld64) - end - - def test_ld64_dep_leopard_or_newer - MacOS.stubs(:version).returns(MacOS::Version.new("10.5")) - assert_nil @d.build(:ld64) - end - - def test_ant_dep_mavericks_or_newer - MacOS.stubs(:version).returns(MacOS::Version.new("10.9")) - @d.add ant: :build - assert_equal find_dependency("ant"), Dependency.new("ant", [:build]) - end - - def test_ant_dep_pre_mavericks - MacOS.stubs(:version).returns(MacOS::Version.new("10.7")) - @d.add ant: :build - assert_nil find_dependency("ant") - end - - def test_resource_dep_xz_pre_mavericks - MacOS.stubs(:version).returns(MacOS::Version.new("10.8")) - resource = Resource.new - resource.url("http://example.com/foo.tar.xz") - assert_equal Dependency.new("xz", [:build]), @d.add(resource) - end - - def test_resource_dep_xz_mavericks_or_newer - MacOS.stubs(:version).returns(MacOS::Version.new("10.9")) - resource = Resource.new - resource.url("http://example.com/foo.tar.xz") - assert_nil @d.add(resource) - end -end diff --git a/Library/Homebrew/test/os/mac/diagnostic_spec.rb b/Library/Homebrew/test/os/mac/diagnostic_spec.rb new file mode 100644 index 000000000..d2b38a332 --- /dev/null +++ b/Library/Homebrew/test/os/mac/diagnostic_spec.rb @@ -0,0 +1,42 @@ +require "diagnostic" + +describe Homebrew::Diagnostic::Checks do + specify "#check_for_other_package_managers" do + allow(MacOS).to receive(:macports_or_fink).and_return(["fink"]) + expect(subject.check_for_other_package_managers) + .to match("You have MacPorts or Fink installed:") + end + + specify "#check_for_unsupported_macos" do + ENV.delete("HOMEBREW_DEVELOPER") + allow(OS::Mac).to receive(:prerelease?).and_return(true) + + expect(subject.check_for_unsupported_macos) + .to match("We do not provide support for this pre-release version.") + end + + specify "#check_for_unsupported_curl_vars" do + allow(MacOS).to receive(:version).and_return(OS::Mac::Version.new("10.10")) + ENV["SSL_CERT_DIR"] = "/some/path" + + expect(subject.check_for_unsupported_curl_vars) + .to match("SSL_CERT_DIR support was removed from Apple's curl.") + end + + specify "#check_for_beta_xquartz" do + allow(MacOS::XQuartz).to receive(:version).and_return("2.7.10_beta2") + + expect(subject.check_for_beta_xquartz) + .to match("The following beta release of XQuartz is installed: 2.7.10_beta2") + end + + specify "#check_xcode_8_without_clt_on_el_capitan" do + allow(MacOS).to receive(:version).and_return(OS::Mac::Version.new("10.11")) + allow(MacOS::Xcode).to receive(:installed?).and_return(true) + allow(MacOS::Xcode).to receive(:version).and_return("8.0") + allow(MacOS::Xcode).to receive(:without_clt?).and_return(true) + + expect(subject.check_xcode_8_without_clt_on_el_capitan) + .to match("You have Xcode 8 installed without the CLT") + end +end diff --git a/Library/Homebrew/test/os/mac/diagnostic_test.rb b/Library/Homebrew/test/os/mac/diagnostic_test.rb deleted file mode 100644 index 704235b01..000000000 --- a/Library/Homebrew/test/os/mac/diagnostic_test.rb +++ /dev/null @@ -1,45 +0,0 @@ -require "testing_env" -require "fileutils" -require "pathname" -require "diagnostic" - -class OSMacDiagnosticChecksTest < Homebrew::TestCase - def setup - super - @checks = Homebrew::Diagnostic::Checks.new - end - - def test_check_for_other_package_managers - MacOS.stubs(:macports_or_fink).returns ["fink"] - assert_match "You have MacPorts or Fink installed:", - @checks.check_for_other_package_managers - end - - def test_check_for_unsupported_macos - ENV.delete("HOMEBREW_DEVELOPER") - OS::Mac.stubs(:prerelease?).returns true - assert_match "We do not provide support for this pre-release version.", - @checks.check_for_unsupported_macos - end - - def test_check_for_unsupported_curl_vars - MacOS.stubs(:version).returns OS::Mac::Version.new("10.10") - ENV["SSL_CERT_DIR"] = "/some/path" - - assert_match "SSL_CERT_DIR support was removed from Apple's curl.", - @checks.check_for_unsupported_curl_vars - end - - def test_check_for_beta_xquartz - MacOS::XQuartz.stubs(:version).returns("2.7.10_beta2") - assert_match "The following beta release of XQuartz is installed: 2.7.10_beta2", @checks.check_for_beta_xquartz - end - - def test_check_xcode_8_without_clt_on_el_capitan - MacOS.stubs(:version).returns OS::Mac::Version.new("10.11") - MacOS::Xcode.stubs(:installed?).returns true - MacOS::Xcode.stubs(:version).returns "8.0" - MacOS::Xcode.stubs(:without_clt?).returns true - assert_match "You have Xcode 8 installed without the CLT", @checks.check_xcode_8_without_clt_on_el_capitan - end -end diff --git a/Library/Homebrew/test/outdated_test.rb b/Library/Homebrew/test/outdated_test.rb deleted file mode 100644 index 3e7148ded..000000000 --- a/Library/Homebrew/test/outdated_test.rb +++ /dev/null @@ -1,10 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestOutdated < IntegrationCommandTestCase - def test_outdated - setup_test_formula "testball" - (HOMEBREW_CELLAR/"testball/0.0.1/foo").mkpath - - assert_equal "testball", cmd("outdated") - end -end diff --git a/Library/Homebrew/test/patching_spec.rb b/Library/Homebrew/test/patching_spec.rb new file mode 100644 index 000000000..dd849ca92 --- /dev/null +++ b/Library/Homebrew/test/patching_spec.rb @@ -0,0 +1,289 @@ +require "formula" + +describe "patching" do + TESTBALL_URL = "file://#{TEST_FIXTURE_DIR}/tarballs/testball-0.1.tbz".freeze + TESTBALL_PATCHES_URL = "file://#{TEST_FIXTURE_DIR}/tarballs/testball-0.1-patches.tgz".freeze + PATCH_URL_A = "file://#{TEST_FIXTURE_DIR}/patches/noop-a.diff".freeze + PATCH_URL_B = "file://#{TEST_FIXTURE_DIR}/patches/noop-b.diff".freeze + PATCH_A_CONTENTS = File.read "#{TEST_FIXTURE_DIR}/patches/noop-a.diff" + PATCH_B_CONTENTS = File.read "#{TEST_FIXTURE_DIR}/patches/noop-b.diff" + APPLY_A = "noop-a.diff".freeze + APPLY_B = "noop-b.diff".freeze + APPLY_C = "noop-c.diff".freeze + + def formula(name = "formula_name", path: Formulary.core_path(name), spec: :stable, alias_path: nil, &block) + Class.new(Formula) { + url TESTBALL_URL + sha256 TESTBALL_SHA256 + class_eval(&block) + }.new(name, path, spec, alias_path: alias_path) + end + + matcher :be_patched do + match do |formula| + shutup do + formula.brew do + formula.patch + s = File.read("libexec/NOOP") + expect(s).not_to include("NOOP"), "libexec/NOOP was not patched as expected" + expect(s).to include("ABCD"), "libexec/NOOP was not patched as expected" + end + end + end + end + + matcher :be_sequentially_patched do + match do |formula| + shutup do + formula.brew do + formula.patch + s = File.read("libexec/NOOP") + expect(s).not_to include("NOOP"), "libexec/NOOP was not patched as expected" + expect(s).not_to include("ABCD"), "libexec/NOOP was not patched as expected" + expect(s).to include("1234"), "libexec/NOOP was not patched as expected" + end + end + end + end + + matcher :miss_apply do + match do |formula| + expect { + shutup do + formula.brew do + formula.patch + end + end + }.to raise_error(MissingApplyError) + end + end + + specify "single_patch" do + expect( + formula do + def patches + PATCH_URL_A + end + end, + ).to be_patched + end + + specify "single_patch_dsl" do + expect( + formula do + patch do + url PATCH_URL_A + sha256 PATCH_A_SHA256 + end + end, + ).to be_patched + end + + specify "single_patch_dsl_with_apply" do + expect( + formula do + patch do + url TESTBALL_PATCHES_URL + sha256 TESTBALL_PATCHES_SHA256 + apply APPLY_A + end + end, + ).to be_patched + end + + specify "single_patch_dsl_with_sequential_apply" do + expect( + formula do + patch do + url TESTBALL_PATCHES_URL + sha256 TESTBALL_PATCHES_SHA256 + apply APPLY_A, APPLY_C + end + end, + ).to be_sequentially_patched + end + + specify "single_patch_dsl_with_strip" do + expect( + formula do + patch :p1 do + url PATCH_URL_A + sha256 PATCH_A_SHA256 + end + end, + ).to be_patched + end + + specify "single_patch_dsl_with_strip_with_apply" do + expect( + formula do + patch :p1 do + url TESTBALL_PATCHES_URL + sha256 TESTBALL_PATCHES_SHA256 + apply APPLY_A + end + end, + ).to be_patched + end + + specify "single_patch_dsl_with_incorrect_strip" do + expect { + shutup do + f = formula do + patch :p0 do + url PATCH_URL_A + sha256 PATCH_A_SHA256 + end + end + + f.brew { |formula, _staging| formula.patch } + end + }.to raise_error(ErrorDuringExecution) + end + + specify "single_patch_dsl_with_incorrect_strip_with_apply" do + expect { + shutup do + f = formula do + patch :p0 do + url TESTBALL_PATCHES_URL + sha256 TESTBALL_PATCHES_SHA256 + apply APPLY_A + end + end + + f.brew { |formula, _staging| formula.patch } + end + }.to raise_error(ErrorDuringExecution) + end + + specify "patch_p0_dsl" do + expect( + formula do + patch :p0 do + url PATCH_URL_B + sha256 PATCH_B_SHA256 + end + end, + ).to be_patched + end + + specify "patch_p0_dsl_with_apply" do + expect( + formula do + patch :p0 do + url TESTBALL_PATCHES_URL + sha256 TESTBALL_PATCHES_SHA256 + apply APPLY_B + end + end, + ).to be_patched + end + + specify "patch_p0" do + expect( + formula do + def patches + { p0: PATCH_URL_B } + end + end, + ).to be_patched + end + + specify "patch_array" do + expect( + formula do + def patches + [PATCH_URL_A] + end + end, + ).to be_patched + end + + specify "patch_hash" do + expect( + formula do + def patches + { p1: PATCH_URL_A } + end + end, + ).to be_patched + end + + specify "patch_hash_array" do + expect( + formula do + def patches + { p1: [PATCH_URL_A] } + end + end, + ).to be_patched + end + + specify "patch_string" do + expect(formula { patch PATCH_A_CONTENTS }).to be_patched + end + + specify "patch_string_with_strip" do + expect(formula { patch :p0, PATCH_B_CONTENTS }).to be_patched + end + + specify "patch_data_constant" do + expect( + formula("test", path: Pathname.new(__FILE__).expand_path) do + def patches + :DATA + end + end, + ).to be_patched + end + + specify "single_patch_missing_apply_fail" do + expect( + formula do + def patches + TESTBALL_PATCHES_URL + end + end, + ).to miss_apply + end + + specify "single_patch_dsl_missing_apply_fail" do + expect( + formula do + patch do + url TESTBALL_PATCHES_URL + sha256 TESTBALL_PATCHES_SHA256 + end + end, + ).to miss_apply + end + + specify "single_patch_dsl_with_apply_enoent_fail" do + expect { + shutup do + f = formula do + patch do + url TESTBALL_PATCHES_URL + sha256 TESTBALL_PATCHES_SHA256 + apply "patches/#{APPLY_A}" + end + end + + f.brew { |formula, _staging| formula.patch } + end + }.to raise_error(ErrorDuringExecution) + end +end + +__END__ +diff --git a/libexec/NOOP b/libexec/NOOP +index bfdda4c..e08d8f4 100755 +--- a/libexec/NOOP ++++ b/libexec/NOOP +@@ -1,2 +1,2 @@ + #!/bin/bash +-echo NOOP +\ No newline at end of file ++echo ABCD +\ No newline at end of file diff --git a/Library/Homebrew/test/patching_test.rb b/Library/Homebrew/test/patching_test.rb deleted file mode 100644 index 3dacc0818..000000000 --- a/Library/Homebrew/test/patching_test.rb +++ /dev/null @@ -1,248 +0,0 @@ -require "testing_env" -require "formula" - -class PatchingTests < Homebrew::TestCase - TESTBALL_URL = "file://#{TEST_FIXTURE_DIR}/tarballs/testball-0.1.tbz".freeze - TESTBALL_PATCHES_URL = "file://#{TEST_FIXTURE_DIR}/tarballs/testball-0.1-patches.tgz".freeze - PATCH_URL_A = "file://#{TEST_FIXTURE_DIR}/patches/noop-a.diff".freeze - PATCH_URL_B = "file://#{TEST_FIXTURE_DIR}/patches/noop-b.diff".freeze - PATCH_A_CONTENTS = File.read "#{TEST_FIXTURE_DIR}/patches/noop-a.diff" - PATCH_B_CONTENTS = File.read "#{TEST_FIXTURE_DIR}/patches/noop-b.diff" - APPLY_A = "noop-a.diff".freeze - APPLY_B = "noop-b.diff".freeze - APPLY_C = "noop-c.diff".freeze - - def formula(*args, &block) - super do - url TESTBALL_URL - sha256 TESTBALL_SHA256 - class_eval(&block) - end - end - - def assert_patched(formula) - shutup do - formula.brew do - formula.patch - s = File.read("libexec/NOOP") - refute_includes s, "NOOP", "libexec/NOOP was not patched as expected" - assert_includes s, "ABCD", "libexec/NOOP was not patched as expected" - end - end - end - - def assert_sequentially_patched(formula) - shutup do - formula.brew do - formula.patch - s = File.read("libexec/NOOP") - refute_includes s, "NOOP", "libexec/NOOP was not patched as expected" - refute_includes s, "ABCD", "libexec/NOOP was not patched as expected" - assert_includes s, "1234", "libexec/NOOP was not patched as expected" - end - end - end - - def assert_missing_apply_fail(formula) - assert_raises(MissingApplyError) do - shutup do - formula.brew do - formula.patch - end - end - end - end - - def test_single_patch - assert_patched formula { - def patches - PATCH_URL_A - end - } - end - - def test_single_patch_dsl - assert_patched formula { - patch do - url PATCH_URL_A - sha256 PATCH_A_SHA256 - end - } - end - - def test_single_patch_dsl_with_apply - assert_patched formula { - patch do - url TESTBALL_PATCHES_URL - sha256 TESTBALL_PATCHES_SHA256 - apply APPLY_A - end - } - end - - def test_single_patch_dsl_with_sequential_apply - assert_sequentially_patched formula { - patch do - url TESTBALL_PATCHES_URL - sha256 TESTBALL_PATCHES_SHA256 - apply APPLY_A, APPLY_C - end - } - end - - def test_single_patch_dsl_with_strip - assert_patched formula { - patch :p1 do - url PATCH_URL_A - sha256 PATCH_A_SHA256 - end - } - end - - def test_single_patch_dsl_with_strip_with_apply - assert_patched formula { - patch :p1 do - url TESTBALL_PATCHES_URL - sha256 TESTBALL_PATCHES_SHA256 - apply APPLY_A - end - } - end - - def test_single_patch_dsl_with_incorrect_strip - assert_raises(ErrorDuringExecution) do - shutup do - formula do - patch :p0 do - url PATCH_URL_A - sha256 PATCH_A_SHA256 - end - end.brew { |f, _staging| f.patch } - end - end - end - - def test_single_patch_dsl_with_incorrect_strip_with_apply - assert_raises(ErrorDuringExecution) do - shutup do - formula do - patch :p0 do - url TESTBALL_PATCHES_URL - sha256 TESTBALL_PATCHES_SHA256 - apply APPLY_A - end - end.brew { |f, _staging| f.patch } - end - end - end - - def test_patch_p0_dsl - assert_patched formula { - patch :p0 do - url PATCH_URL_B - sha256 PATCH_B_SHA256 - end - } - end - - def test_patch_p0_dsl_with_apply - assert_patched formula { - patch :p0 do - url TESTBALL_PATCHES_URL - sha256 TESTBALL_PATCHES_SHA256 - apply APPLY_B - end - } - end - - def test_patch_p0 - assert_patched formula { - def patches - { p0: PATCH_URL_B } - end - } - end - - def test_patch_array - assert_patched formula { - def patches - [PATCH_URL_A] - end - } - end - - def test_patch_hash - assert_patched formula { - def patches - { p1: PATCH_URL_A } - end - } - end - - def test_patch_hash_array - assert_patched formula { - def patches - { p1: [PATCH_URL_A] } - end - } - end - - def test_patch_string - assert_patched formula { patch PATCH_A_CONTENTS } - end - - def test_patch_string_with_strip - assert_patched formula { patch :p0, PATCH_B_CONTENTS } - end - - def test_patch_data_constant - assert_patched formula("test", Pathname.new(__FILE__).expand_path) { - def patches - :DATA - end - } - end - - def test_single_patch_missing_apply_fail - assert_missing_apply_fail formula { - def patches - TESTBALL_PATCHES_URL - end - } - end - - def test_single_patch_dsl_missing_apply_fail - assert_missing_apply_fail formula { - patch do - url TESTBALL_PATCHES_URL - sha256 TESTBALL_PATCHES_SHA256 - end - } - end - - def test_single_patch_dsl_with_apply_enoent_fail - assert_raises(ErrorDuringExecution) do - shutup do - formula do - patch do - url TESTBALL_PATCHES_URL - sha256 TESTBALL_PATCHES_SHA256 - apply "patches/#{APPLY_A}" - end - end.brew { |f, _staging| f.patch } - end - end - end -end - -__END__ -diff --git a/libexec/NOOP b/libexec/NOOP -index bfdda4c..e08d8f4 100755 ---- a/libexec/NOOP -+++ b/libexec/NOOP -@@ -1,2 +1,2 @@ - #!/bin/bash --echo NOOP -\ No newline at end of file -+echo ABCD -\ No newline at end of file diff --git a/Library/Homebrew/test/pathname_spec.rb b/Library/Homebrew/test/pathname_spec.rb new file mode 100644 index 000000000..21e14479f --- /dev/null +++ b/Library/Homebrew/test/pathname_spec.rb @@ -0,0 +1,307 @@ +require "tmpdir" +require "extend/pathname" +require "install_renamed" + +describe Pathname do + include FileUtils + + let(:src) { Pathname.new(Dir.mktmpdir) } + let(:dst) { Pathname.new(Dir.mktmpdir) } + let(:file) { src/"foo" } + let(:dir) { src/"bar" } + + after(:each) { rm_rf [src, dst] } + + describe DiskUsageExtension do + before(:each) do + mkdir_p dir/"a-directory" + touch [dir/".DS_Store", dir/"a-file"] + File.truncate(dir/"a-file", 1_048_576) + ln_s dir/"a-file", dir/"a-symlink" + ln dir/"a-file", dir/"a-hardlink" + end + + describe "#file_count" do + it "returns the number of files in a directory" do + expect(dir.file_count).to eq(3) + end + end + + describe "#abv" do + context "when called on a directory" do + it "returns a string with the file count and disk usage" do + expect(dir.abv).to eq("3 files, 1MB") + end + end + + context "when called on a file" do + it "returns the disk usage" do + expect((dir/"a-file").abv).to eq("1MB") + end + end + end + end + + describe "#rmdir_if_possible" do + before(:each) { mkdir_p dir } + + it "returns true and removes a directory if it doesn't contain files" do + expect(dir.rmdir_if_possible).to be true + expect(dir).not_to exist + end + + it "returns false and doesn't delete a directory if it contains files" do + touch dir/"foo" + expect(dir.rmdir_if_possible).to be false + expect(dir).to be_a_directory + end + + it "ignores .DS_Store files" do + touch dir/".DS_Store" + expect(dir.rmdir_if_possible).to be true + expect(dir).not_to exist + end + end + + describe "#write" do + it "creates a file and writes to it" do + expect(file).not_to exist + file.write("CONTENT") + expect(File.read(file)).to eq("CONTENT") + end + + it "raises an error if the file already exists" do + touch file + expect { file.write("CONTENT") }.to raise_error(RuntimeError) + end + end + + describe "#append_lines" do + it "appends lines to a file" do + touch file + + file.append_lines("CONTENT") + expect(File.read(file)).to eq <<-EOS.undent + CONTENT + EOS + + file.append_lines("CONTENTS") + expect(File.read(file)).to eq <<-EOS.undent + CONTENT + CONTENTS + EOS + end + + it "raises an error if the file does not exist" do + expect(file).not_to exist + expect { file.append_lines("CONTENT") }.to raise_error(RuntimeError) + end + end + + describe "#atomic_write" do + it "atomically replaces a file" do + touch file + file.atomic_write("CONTENT") + expect(File.read(file)).to eq("CONTENT") + end + + it "preserves permissions" do + File.open(file, "w", 0100777).close + file.atomic_write("CONTENT") + expect(file.stat.mode).to eq(0100777 & ~File.umask) + end + + it "preserves default permissions" do + file.atomic_write("CONTENT") + sentinel = file.parent.join("sentinel") + touch sentinel + expect(file.stat.mode).to eq(sentinel.stat.mode) + end + end + + describe "#ensure_writable" do + it "makes a file writable and restores permissions afterwards" do + touch file + chmod 0555, file + expect(file).not_to be_writable + file.ensure_writable do + expect(file).to be_writable + end + expect(file).not_to be_writable + end + end + + describe "#extname" do + it "supports common multi-level archives" do + expect(Pathname.new("foo-0.1.tar.gz").extname).to eq(".tar.gz") + expect(Pathname.new("foo-0.1.cpio.gz").extname).to eq(".cpio.gz") + end + end + + describe "#stem" do + it "returns the basename without double extensions" do + expect(Pathname("foo-0.1.tar.gz").stem).to eq("foo-0.1") + expect(Pathname("foo-0.1.cpio.gz").stem).to eq("foo-0.1") + end + end + + describe "#install" do + before(:each) do + (src/"a.txt").write "This is sample file a." + (src/"b.txt").write "This is sample file b." + end + + it "raises an error if the file doesn't exist" do + expect { dst.install "non_existent_file" }.to raise_error(Errno::ENOENT) + end + + it "installs a file to a directory with its basename" do + touch file + dst.install(file) + expect(dst/file.basename).to exist + expect(file).not_to exist + end + + it "creates intermediate directories" do + touch file + expect(dir).not_to be_a_directory + dir.install(file) + expect(dir).to be_a_directory + end + + it "can install a file" do + dst.install src/"a.txt" + expect(dst/"a.txt").to exist, "a.txt was not installed" + expect(dst/"b.txt").not_to exist, "b.txt was installed." + end + + it "can install an array of files" do + dst.install [src/"a.txt", src/"b.txt"] + + expect(dst/"a.txt").to exist, "a.txt was not installed" + expect(dst/"b.txt").to exist, "b.txt was not installed" + end + + it "can install a directory" do + bin = src/"bin" + bin.mkpath + mv Dir[src/"*.txt"], bin + dst.install bin + + expect(dst/"bin/a.txt").to exist, "a.txt was not installed" + expect(dst/"bin/b.txt").to exist, "b.txt was not installed" + end + + it "supports renaming files" do + dst.install src/"a.txt" => "c.txt" + + expect(dst/"c.txt").to exist, "c.txt was not installed" + expect(dst/"a.txt").not_to exist, "a.txt was installed but not renamed" + expect(dst/"b.txt").not_to exist, "b.txt was installed" + end + + it "supports renaming multiple files" do + dst.install(src/"a.txt" => "c.txt", src/"b.txt" => "d.txt") + + expect(dst/"c.txt").to exist, "c.txt was not installed" + expect(dst/"d.txt").to exist, "d.txt was not installed" + expect(dst/"a.txt").not_to exist, "a.txt was installed but not renamed" + expect(dst/"b.txt").not_to exist, "b.txt was installed but not renamed" + end + + it "supports renaming directories" do + bin = src/"bin" + bin.mkpath + mv Dir[src/"*.txt"], bin + dst.install bin => "libexec" + + expect(dst/"bin").not_to exist, "bin was installed but not renamed" + expect(dst/"libexec/a.txt").to exist, "a.txt was not installed" + expect(dst/"libexec/b.txt").to exist, "b.txt was not installed" + end + + it "can install directories as relative symlinks" do + bin = src/"bin" + bin.mkpath + mv Dir[src/"*.txt"], bin + dst.install_symlink bin + + expect(dst/"bin").to be_a_symlink + expect(dst/"bin").to be_a_directory + expect(dst/"bin/a.txt").to exist + expect(dst/"bin/b.txt").to exist + expect((dst/"bin").readlink).to be_relative + end + + it "can install relative paths as symlinks" do + dst.install_symlink "foo" => "bar" + expect((dst/"bar").readlink).to eq(Pathname.new("foo")) + end + end + + describe InstallRenamed do + before(:each) do + dst.extend(InstallRenamed) + end + + it "renames the installed file if it already exists" do + file.write "a" + dst.install file + + file.write "b" + dst.install file + + expect(File.read(dst/file.basename)).to eq("a") + expect(File.read(dst/"#{file.basename}.default")).to eq("b") + end + + it "renames the installed directory" do + file.write "a" + dst.install src + expect(File.read(dst/src.basename/file.basename)).to eq("a") + end + + it "recursively renames directories" do + (dst/dir.basename).mkpath + (dst/dir.basename/"another_file").write "a" + dir.mkpath + (dir/"another_file").write "b" + dst.install dir + expect(File.read(dst/dir.basename/"another_file.default")).to eq("b") + end + end + + describe "#cp_path_sub" do + it "copies a file and replaces the given pattern" do + file.write "a" + file.cp_path_sub src, dst + expect(File.read(dst/file.basename)).to eq("a") + end + + it "copies a directory and replaces the given pattern" do + dir.mkpath + dir.cp_path_sub src, dst + expect(dst/dir.basename).to be_a_directory + end + end + + describe "#ds_store?" do + it "returns whether a file is .DS_Store or not" do + expect(file).not_to be_ds_store + expect(file/".DS_Store").to be_ds_store + end + end +end + +describe FileUtils do + let(:dst) { Pathname.new(Dir.mktmpdir) } + + describe "#mkdir" do + it "creates indermediate directories" do + described_class.mkdir dst/"foo/bar/baz" do + expect(dst/"foo/bar/baz").to exist, "foo/bar/baz was not created" + expect(dst/"foo/bar/baz").to be_a_directory, "foo/bar/baz was not a directory structure" + end + end + end +end diff --git a/Library/Homebrew/test/pathname_test.rb b/Library/Homebrew/test/pathname_test.rb deleted file mode 100644 index 0107c8675..000000000 --- a/Library/Homebrew/test/pathname_test.rb +++ /dev/null @@ -1,268 +0,0 @@ -require "testing_env" -require "tmpdir" -require "extend/pathname" -require "install_renamed" - -module PathnameTestExtension - include FileUtils - - def setup - super - @src = Pathname.new(mktmpdir) - @dst = Pathname.new(mktmpdir) - @file = @src/"foo" - @dir = @src/"bar" - end -end - -class PathnameTests < Homebrew::TestCase - include PathnameTestExtension - - def test_disk_usage_extension - mkdir_p @dir/"a-directory" - touch @dir/".DS_Store" - touch @dir/"a-file" - File.truncate(@dir/"a-file", 1_048_576) - ln_s @dir/"a-file", @dir/"a-symlink" - ln @dir/"a-file", @dir/"a-hardlink" - assert_equal 3, @dir.file_count - assert_equal "3 files, 1M", @dir.abv - assert_equal "1M", (@dir/"a-file").abv - end - - def test_rmdir_if_possible - mkdir_p @dir - touch @dir/"foo" - - assert !@dir.rmdir_if_possible - assert_predicate @dir, :directory? - - rm_f @dir/"foo" - assert @dir.rmdir_if_possible - refute_predicate @dir, :exist? - end - - def test_rmdir_if_possible_ignore_ds_store - mkdir_p @dir - touch @dir/".DS_Store" - assert @dir.rmdir_if_possible - refute_predicate @dir, :exist? - end - - def test_write - @file.write("CONTENT") - assert_equal "CONTENT", File.read(@file) - end - - def test_write_does_not_overwrite - touch @file - assert_raises(RuntimeError) { @file.write("CONTENT") } - end - - def test_append_lines - touch @file - @file.append_lines("CONTENT") - assert_equal "CONTENT\n", File.read(@file) - @file.append_lines("CONTENTS") - assert_equal "CONTENT\nCONTENTS\n", File.read(@file) - end - - def test_append_lines_does_not_create - assert_raises(RuntimeError) { @file.append_lines("CONTENT") } - end - - def test_atomic_write - touch @file - @file.atomic_write("CONTENT") - assert_equal "CONTENT", File.read(@file) - end - - def test_atomic_write_preserves_permissions - File.open(@file, "w", 0100777) {} - @file.atomic_write("CONTENT") - assert_equal 0100777 & ~File.umask, @file.stat.mode - end - - def test_atomic_write_preserves_default_permissions - @file.atomic_write("CONTENT") - sentinel = @file.parent.join("sentinel") - touch sentinel - assert_equal sentinel.stat.mode, @file.stat.mode - end - - def test_ensure_writable - touch @file - chmod 0555, @file - @file.ensure_writable { assert_predicate @file, :writable? } - refute_predicate @file, :writable? - end - - def test_extname - assert_equal ".tar.gz", Pathname("foo-0.1.tar.gz").extname - assert_equal ".cpio.gz", Pathname("foo-0.1.cpio.gz").extname - end - - def test_stem - assert_equal "foo-0.1", Pathname("foo-0.1.tar.gz").stem - assert_equal "foo-0.1", Pathname("foo-0.1.cpio.gz").stem - end - - def test_install_missing_file - assert_raises(Errno::ENOENT) { @dst.install "non_existent_file" } - end - - def test_install_removes_original - touch @file - @dst.install(@file) - - assert_predicate @dst/@file.basename, :exist? - refute_predicate @file, :exist? - end - - def test_install_creates_intermediate_directories - touch @file - refute_predicate @dir, :directory? - @dir.install(@file) - assert_predicate @dir, :directory? - end - - def test_install_renamed - @dst.extend(InstallRenamed) - - @file.write "a" - @dst.install @file - @file.write "b" - @dst.install @file - - assert_equal "a", File.read(@dst/@file.basename) - assert_equal "b", File.read(@dst/"#{@file.basename}.default") - end - - def test_install_renamed_directory - @dst.extend(InstallRenamed) - @file.write "a" - @dst.install @src - assert_equal "a", File.read(@dst/@src.basename/@file.basename) - end - - def test_install_renamed_directory_recursive - @dst.extend(InstallRenamed) - (@dst/@dir.basename).mkpath - (@dst/@dir.basename/"another_file").write "a" - @dir.mkpath - (@dir/"another_file").write "b" - @dst.install @dir - assert_equal "b", File.read(@dst/@dir.basename/"another_file.default") - end - - def test_cp_path_sub_file - @file.write "a" - @file.cp_path_sub @src, @dst - assert_equal "a", File.read(@dst/"foo") - end - - def test_cp_path_sub_directory - @dir.mkpath - @dir.cp_path_sub @src, @dst - assert_predicate @dst/@dir.basename, :directory? - end - - def test_ds_store - refute_predicate @file, :ds_store? - assert_predicate @src/".DS_Store", :ds_store? - end -end - -class PathnameInstallTests < Homebrew::TestCase - include PathnameTestExtension - - def setup - super - (@src/"a.txt").write "This is sample file a." - (@src/"b.txt").write "This is sample file b." - end - - def test_install - @dst.install @src/"a.txt" - - assert_predicate @dst/"a.txt", :exist?, "a.txt was not installed" - refute_predicate @dst/"b.txt", :exist?, "b.txt was installed." - end - - def test_install_list - @dst.install [@src/"a.txt", @src/"b.txt"] - - assert_predicate @dst/"a.txt", :exist?, "a.txt was not installed" - assert_predicate @dst/"b.txt", :exist?, "b.txt was not installed" - end - - def test_install_glob - @dst.install Dir[@src/"*.txt"] - - assert_predicate @dst/"a.txt", :exist?, "a.txt was not installed" - assert_predicate @dst/"b.txt", :exist?, "b.txt was not installed" - end - - def test_install_directory - bin = @src/"bin" - bin.mkpath - mv Dir[@src/"*.txt"], bin - @dst.install bin - - assert_predicate @dst/"bin/a.txt", :exist?, "a.txt was not installed" - assert_predicate @dst/"bin/b.txt", :exist?, "b.txt was not installed" - end - - def test_install_rename - @dst.install @src/"a.txt" => "c.txt" - - assert_predicate @dst/"c.txt", :exist?, "c.txt was not installed" - refute_predicate @dst/"a.txt", :exist?, "a.txt was installed but not renamed" - refute_predicate @dst/"b.txt", :exist?, "b.txt was installed" - end - - def test_install_rename_more - @dst.install(@src/"a.txt" => "c.txt", @src/"b.txt" => "d.txt") - - assert_predicate @dst/"c.txt", :exist?, "c.txt was not installed" - assert_predicate @dst/"d.txt", :exist?, "d.txt was not installed" - refute_predicate @dst/"a.txt", :exist?, "a.txt was installed but not renamed" - refute_predicate @dst/"b.txt", :exist?, "b.txt was installed but not renamed" - end - - def test_install_rename_directory - bin = @src/"bin" - bin.mkpath - mv Dir[@src/"*.txt"], bin - @dst.install bin => "libexec" - - refute_predicate @dst/"bin", :exist?, "bin was installed but not renamed" - assert_predicate @dst/"libexec/a.txt", :exist?, "a.txt was not installed" - assert_predicate @dst/"libexec/b.txt", :exist?, "b.txt was not installed" - end - - def test_install_symlink - bin = @src/"bin" - bin.mkpath - mv Dir[@src/"*.txt"], bin - @dst.install_symlink bin - - assert_predicate @dst/"bin", :symlink? - assert_predicate @dst/"bin", :directory? - assert_predicate @dst/"bin/a.txt", :exist? - assert_predicate @dst/"bin/b.txt", :exist? - assert_predicate((@dst/"bin").readlink, :relative?) - end - - def test_install_relative_symlink - @dst.install_symlink "foo" => "bar" - assert_equal Pathname.new("foo"), (@dst/"bar").readlink - end - - def test_mkdir_creates_intermediate_directories - mkdir @dst/"foo/bar/baz" do - assert_predicate @dst/"foo/bar/baz", :exist?, "foo/bar/baz was not created" - assert_predicate @dst/"foo/bar/baz", :directory?, "foo/bar/baz was not a directory structure" - end - end -end diff --git a/Library/Homebrew/test/pin_unpin_test.rb b/Library/Homebrew/test/pin_unpin_test.rb deleted file mode 100644 index 65fb9e4da..000000000 --- a/Library/Homebrew/test/pin_unpin_test.rb +++ /dev/null @@ -1,18 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestPinUnpin < IntegrationCommandTestCase - def test_pin_unpin - setup_test_formula "testball" - (HOMEBREW_CELLAR/"testball/0.0.1/foo").mkpath - - cmd("pin", "testball") - cmd("upgrade") - refute((HOMEBREW_CELLAR/"testball/0.1").directory?, - "The latest version directory should NOT be created") - - cmd("unpin", "testball") - cmd("upgrade") - assert((HOMEBREW_CELLAR/"testball/0.1").directory?, - "The latest version directory should be created") - end -end diff --git a/Library/Homebrew/test/prefix_formula_test.rb b/Library/Homebrew/test/prefix_formula_test.rb deleted file mode 100644 index eb5970d3e..000000000 --- a/Library/Homebrew/test/prefix_formula_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestPrefixFormula < IntegrationCommandTestCase - def test_prefix_formula - assert_match "#{HOMEBREW_CELLAR}/testball", - cmd("--prefix", testball) - end -end diff --git a/Library/Homebrew/test/prefix_test.rb b/Library/Homebrew/test/prefix_test.rb deleted file mode 100644 index a3ae75542..000000000 --- a/Library/Homebrew/test/prefix_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestPrefix < IntegrationCommandTestCase - def test_prefix - assert_equal HOMEBREW_PREFIX.to_s, - cmd("--prefix") - end -end diff --git a/Library/Homebrew/test/prune_test.rb b/Library/Homebrew/test/prune_test.rb deleted file mode 100644 index 8fa5df7b7..000000000 --- a/Library/Homebrew/test/prune_test.rb +++ /dev/null @@ -1,21 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestPrune < IntegrationCommandTestCase - def test_prune - share = (HOMEBREW_PREFIX/"share") - - (share/"pruneable/directory/here").mkpath - (share/"notpruneable/file").write "I'm here" - FileUtils.ln_s "/i/dont/exist/no/really/i/dont", share/"pruneable_symlink" - - assert_match %r{Would remove \(empty directory\): .*/pruneable/directory/here}, - cmd("prune", "--dry-run") - assert_match "Pruned 1 symbolic links and 3 directories", - cmd("prune") - refute((share/"pruneable").directory?) - assert((share/"notpruneable").directory?) - refute((share/"pruneable_symlink").symlink?) - - assert_match "Nothing pruned", cmd("prune", "--verbose") - end -end diff --git a/Library/Homebrew/test/pull_offline_test.rb b/Library/Homebrew/test/pull_offline_test.rb deleted file mode 100644 index c9d46cd74..000000000 --- a/Library/Homebrew/test/pull_offline_test.rb +++ /dev/null @@ -1,10 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestPullOffline < IntegrationCommandTestCase - def test_pull_offline - assert_match "You meant `git pull --rebase`.", cmd_fail("pull", "--rebase") - assert_match "This command requires at least one argument", cmd_fail("pull") - assert_match "Not a GitHub pull request or commit", - cmd_fail("pull", "0") - end -end diff --git a/Library/Homebrew/test/pull_test.rb b/Library/Homebrew/test/pull_test.rb deleted file mode 100644 index 445d73cb1..000000000 --- a/Library/Homebrew/test/pull_test.rb +++ /dev/null @@ -1,27 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestPull < IntegrationCommandTestCase - def test_pull - skip "Requires network connection" if ENV["HOMEBREW_NO_GITHUB_API"] - - core_tap = CoreTap.new - core_tap.path.cd do - shutup do - system "git", "init" - system "git", "checkout", "-b", "new-branch" - end - end - - assert_match "Testing URLs require `--bottle`!", - cmd_fail("pull", "https://bot.brew.sh/job/Homebrew\%20Testing/1028/") - assert_match "Current branch is new-branch", - cmd_fail("pull", "1") - assert_match "No changed formulae found to bump", - cmd_fail("pull", "--bump", "8") - assert_match "Can only bump one changed formula", - cmd_fail("pull", "--bump", - "https://api.github.com/repos/Homebrew/homebrew-core/pulls/122") - assert_match "Patch failed to apply", - cmd_fail("pull", "https://github.com/Homebrew/homebrew-core/pull/1") - end -end diff --git a/Library/Homebrew/test/readall_test.rb b/Library/Homebrew/test/readall_test.rb deleted file mode 100644 index 3eec79dd8..000000000 --- a/Library/Homebrew/test/readall_test.rb +++ /dev/null @@ -1,12 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestReadall < IntegrationCommandTestCase - def test_readall - formula_file = setup_test_formula "testball" - alias_file = CoreTap.new.alias_dir/"foobar" - alias_file.parent.mkpath - FileUtils.ln_s formula_file, alias_file - cmd("readall", "--aliases", "--syntax") - cmd("readall", "homebrew/core") - end -end diff --git a/Library/Homebrew/test/reinstall_pinned_test.rb b/Library/Homebrew/test/reinstall_pinned_test.rb deleted file mode 100644 index 80f5518ea..000000000 --- a/Library/Homebrew/test/reinstall_pinned_test.rb +++ /dev/null @@ -1,15 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestReinstallPinned < IntegrationCommandTestCase - def test_reinstall_pinned - setup_test_formula "testball" - - HOMEBREW_CELLAR.join("testball/0.1").mkpath - HOMEBREW_PINNED_KEGS.mkpath - FileUtils.ln_s HOMEBREW_CELLAR.join("testball/0.1"), HOMEBREW_PINNED_KEGS/"testball" - - assert_match "testball is pinned. You must unpin it to reinstall.", cmd("reinstall", "testball") - - HOMEBREW_PINNED_KEGS.rmtree - end -end diff --git a/Library/Homebrew/test/reinstall_test.rb b/Library/Homebrew/test/reinstall_test.rb deleted file mode 100644 index 2906983c3..000000000 --- a/Library/Homebrew/test/reinstall_test.rb +++ /dev/null @@ -1,24 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestReinstall < IntegrationCommandTestCase - def test_reinstall - setup_test_formula "testball" - - cmd("install", "testball", "--with-foo") - foo_dir = HOMEBREW_CELLAR/"testball/0.1/foo" - assert foo_dir.exist? - foo_dir.rmtree - assert_match "Reinstalling testball --with-foo", - cmd("reinstall", "testball") - assert foo_dir.exist? - end - - def test_reinstall_with_invalid_option - setup_test_formula "testball" - - cmd("install", "testball", "--with-foo") - - assert_match "testball: this formula has no --with-fo option so it will be ignored!", - cmd("reinstall", "testball", "--with-fo") - end -end diff --git a/Library/Homebrew/test/repository_test.rb b/Library/Homebrew/test/repository_test.rb deleted file mode 100644 index 77967a58d..000000000 --- a/Library/Homebrew/test/repository_test.rb +++ /dev/null @@ -1,10 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestRepository < IntegrationCommandTestCase - def test_repository - assert_match HOMEBREW_REPOSITORY.to_s, - cmd("--repository") - assert_match "#{HOMEBREW_LIBRARY}/Taps/foo/homebrew-bar", - cmd("--repository", "foo/bar") - end -end diff --git a/Library/Homebrew/test/resource_spec.rb b/Library/Homebrew/test/resource_spec.rb new file mode 100644 index 000000000..6a0419538 --- /dev/null +++ b/Library/Homebrew/test/resource_spec.rb @@ -0,0 +1,147 @@ +require "resource" + +describe Resource do + subject { described_class.new("test") } + + describe "#url" do + it "sets the URL" do + subject.url("foo") + expect(subject.url).to eq("foo") + end + + it "can set the URL with specifications" do + subject.url("foo", branch: "master") + expect(subject.url).to eq("foo") + expect(subject.specs).to eq(branch: "master") + end + + it "can set the URL with a custom download strategy class" do + strategy = Class.new(AbstractDownloadStrategy) + subject.url("foo", using: strategy) + expect(subject.url).to eq("foo") + expect(subject.download_strategy).to eq(strategy) + end + + it "can set the URL with specifications and a custom download strategy class" do + strategy = Class.new(AbstractDownloadStrategy) + subject.url("foo", using: strategy, branch: "master") + expect(subject.url).to eq("foo") + expect(subject.specs).to eq(branch: "master") + expect(subject.download_strategy).to eq(strategy) + end + + it "can set the URL with a custom download strategy symbol" do + subject.url("foo", using: :git) + expect(subject.url).to eq("foo") + expect(subject.download_strategy).to eq(GitDownloadStrategy) + end + + it "raises an error if the download strategy class is unkown" do + expect { subject.url("foo", using: Class.new) }.to raise_error(TypeError) + end + + it "does not mutate the specifications hash" do + specs = { using: :git, branch: "master" } + subject.url("foo", specs) + expect(subject.specs).to eq(branch: "master") + expect(subject.using).to eq(:git) + expect(specs).to eq(using: :git, branch: "master") + end + end + + describe "#version" do + it "sets the version" do + subject.version("1.0") + expect(subject.version).to eq(Version.parse("1.0")) + expect(subject.version).not_to be_detected_from_url + end + + it "can detect the version from a URL" do + subject.url("http://example.com/foo-1.0.tar.gz") + expect(subject.version).to eq(Version.parse("1.0")) + expect(subject.version).to be_detected_from_url + end + + it "can set the version with a scheme" do + klass = Class.new(Version) + subject.version klass.new("1.0") + expect(subject.version).to eq(Version.parse("1.0")) + expect(subject.version).to be_a(klass) + end + + it "can set the version from a tag" do + subject.url("http://example.com/foo-1.0.tar.gz", tag: "v1.0.2") + expect(subject.version).to eq(Version.parse("1.0.2")) + expect(subject.version).to be_detected_from_url + end + + it "rejects non-string versions" do + expect { subject.version(1) }.to raise_error(TypeError) + expect { subject.version(2.0) }.to raise_error(TypeError) + expect { subject.version(Object.new) }.to raise_error(TypeError) + end + + it "returns nil if unset" do + expect(subject.version).to be nil + end + end + + describe "#mirrors" do + it "is empty by defaults" do + expect(subject.mirrors).to be_empty + end + + it "returns an array of mirrors added with #mirror" do + subject.mirror("foo") + subject.mirror("bar") + expect(subject.mirrors).to eq(%w[foo bar]) + end + end + + describe "#checksum" do + it "returns nil if unset" do + expect(subject.checksum).to be nil + end + + it "returns the checksum set with #sha256" do + subject.sha256(TEST_SHA256) + expect(subject.checksum).to eq(Checksum.new(:sha256, TEST_SHA256)) + end + end + + describe "#download_strategy" do + it "returns the download strategy" do + strategy = Object.new + expect(DownloadStrategyDetector) + .to receive(:detect).with("foo", nil).and_return(strategy) + subject.url("foo") + expect(subject.download_strategy).to eq(strategy) + end + end + + specify "#verify_download_integrity_missing" do + fn = Pathname.new("test") + + allow(fn).to receive(:file?).and_return(true) + expect(fn).to receive(:verify_checksum).and_raise(ChecksumMissingError) + expect(fn).to receive(:sha256) + + shutup do + subject.verify_download_integrity(fn) + end + end + + specify "#verify_download_integrity_mismatch" do + fn = double(file?: true) + checksum = subject.sha256(TEST_SHA256) + + expect(fn).to receive(:verify_checksum).with(checksum) + .and_raise(ChecksumMismatchError.new(fn, checksum, Object.new)) + + shutup do + expect { + subject.verify_download_integrity(fn) + }.to raise_error(ChecksumMismatchError) + end + end +end diff --git a/Library/Homebrew/test/resource_test.rb b/Library/Homebrew/test/resource_test.rb deleted file mode 100644 index d982a7c33..000000000 --- a/Library/Homebrew/test/resource_test.rb +++ /dev/null @@ -1,133 +0,0 @@ -require "testing_env" -require "resource" - -class ResourceTests < Homebrew::TestCase - def setup - super - @resource = Resource.new("test") - end - - def test_url - @resource.url("foo") - assert_equal "foo", @resource.url - end - - def test_url_with_specs - @resource.url("foo", branch: "master") - assert_equal "foo", @resource.url - assert_equal({ branch: "master" }, @resource.specs) - end - - def test_url_with_custom_download_strategy_class - strategy = Class.new(AbstractDownloadStrategy) - @resource.url("foo", using: strategy) - assert_equal "foo", @resource.url - assert_equal strategy, @resource.download_strategy - end - - def test_url_with_specs_and_download_strategy - strategy = Class.new(AbstractDownloadStrategy) - @resource.url("foo", using: strategy, branch: "master") - assert_equal "foo", @resource.url - assert_equal({ branch: "master" }, @resource.specs) - assert_equal strategy, @resource.download_strategy - end - - def test_url_with_custom_download_strategy_symbol - @resource.url("foo", using: :git) - assert_equal "foo", @resource.url - assert_equal GitDownloadStrategy, @resource.download_strategy - end - - def test_raises_for_unknown_download_strategy_class - assert_raises(TypeError) { @resource.url("foo", using: Class.new) } - end - - def test_does_not_mutate_specs_hash - specs = { using: :git, branch: "master" } - @resource.url("foo", specs) - assert_equal({ branch: "master" }, @resource.specs) - assert_equal(:git, @resource.using) - assert_equal({ using: :git, branch: "master" }, specs) - end - - def test_version - @resource.version("1.0") - assert_version_equal "1.0", @resource.version - refute_predicate @resource.version, :detected_from_url? - end - - def test_version_from_url - @resource.url("http://example.com/foo-1.0.tar.gz") - assert_version_equal "1.0", @resource.version - assert_predicate @resource.version, :detected_from_url? - end - - def test_version_with_scheme - klass = Class.new(Version) - @resource.version klass.new("1.0") - assert_version_equal "1.0", @resource.version - assert_instance_of klass, @resource.version - end - - def test_version_from_tag - @resource.url("http://example.com/foo-1.0.tar.gz", tag: "v1.0.2") - assert_version_equal "1.0.2", @resource.version - assert_predicate @resource.version, :detected_from_url? - end - - def test_rejects_non_string_versions - assert_raises(TypeError) { @resource.version(1) } - assert_raises(TypeError) { @resource.version(2.0) } - assert_raises(TypeError) { @resource.version(Object.new) } - end - - def test_version_when_url_is_not_set - assert_nil @resource.version - end - - def test_mirrors - assert_empty @resource.mirrors - @resource.mirror("foo") - @resource.mirror("bar") - assert_equal %w[foo bar], @resource.mirrors - end - - def test_checksum_setters - assert_nil @resource.checksum - @resource.sha256(TEST_SHA256) - assert_equal Checksum.new(:sha256, TEST_SHA256), @resource.checksum - end - - def test_download_strategy - strategy = Object.new - DownloadStrategyDetector - .expects(:detect).with("foo", nil).returns(strategy) - @resource.url("foo") - assert_equal strategy, @resource.download_strategy - end - - def test_verify_download_integrity_missing - fn = Pathname.new("test") - - fn.stubs(file?: true) - fn.expects(:verify_checksum).raises(ChecksumMissingError) - fn.expects(:sha256) - - shutup { @resource.verify_download_integrity(fn) } - end - - def test_verify_download_integrity_mismatch - fn = stub(file?: true) - checksum = @resource.sha256(TEST_SHA256) - - fn.expects(:verify_checksum).with(checksum) - .raises(ChecksumMismatchError.new(fn, checksum, Object.new)) - - shutup do - assert_raises(ChecksumMismatchError) do - @resource.verify_download_integrity(fn) - end - end - end -end diff --git a/Library/Homebrew/test/search_test.rb b/Library/Homebrew/test/search_test.rb deleted file mode 100644 index 70b6f01fb..000000000 --- a/Library/Homebrew/test/search_test.rb +++ /dev/null @@ -1,30 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestSearch < IntegrationCommandTestCase - def test_search - setup_test_formula "testball" - desc_cache = HOMEBREW_CACHE/"desc_cache.json" - refute_predicate desc_cache, :exist?, "Cached file should not exist" - - assert_match "testball", cmd("search") - assert_match "testball", cmd("search", "testball") - assert_match "testball", cmd("search", "homebrew/homebrew-core/testball") - assert_match "testball", cmd("search", "--desc", "Some test") - - flags = { - "macports" => "https://www.macports.org/ports.php?by=name&substr=testball", - "fink" => "http://pdb.finkproject.org/pdb/browse.php?summary=testball", - "debian" => "https://packages.debian.org/search?keywords=testball&searchon=names&suite=all§ion=all", - "opensuse" => "https://software.opensuse.org/search?q=testball", - "fedora" => "https://admin.fedoraproject.org/pkgdb/packages/%2Atestball%2A/", - "ubuntu" => "http://packages.ubuntu.com/search?keywords=testball&searchon=names&suite=all§ion=all", - } - - flags.each do |flag, url| - assert_equal url, cmd("search", "--#{flag}", - "testball", "HOMEBREW_BROWSER" => "echo") - end - - assert_predicate desc_cache, :exist?, "Cached file should exist" - end -end diff --git a/Library/Homebrew/test/services_test.rb b/Library/Homebrew/test/services_test.rb deleted file mode 100644 index 280aeb9f4..000000000 --- a/Library/Homebrew/test/services_test.rb +++ /dev/null @@ -1,11 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestServices < IntegrationCommandTestCase - def test_services - needs_test_cmd_taps - needs_macos - setup_remote_tap("homebrew/services") - assert_equal "Warning: No services available to control with `brew services`", - cmd("services", "list") - end -end diff --git a/Library/Homebrew/test/sh_test.rb b/Library/Homebrew/test/sh_test.rb deleted file mode 100644 index 48fcdc54a..000000000 --- a/Library/Homebrew/test/sh_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestSh < IntegrationCommandTestCase - def test_sh - assert_match "Your shell has been configured", - cmd("sh", "SHELL" => which("true")) - end -end diff --git a/Library/Homebrew/test/spec_helper.rb b/Library/Homebrew/test/spec_helper.rb index 547ec3f7b..9a4dbe026 100644 --- a/Library/Homebrew/test/spec_helper.rb +++ b/Library/Homebrew/test/spec_helper.rb @@ -16,6 +16,7 @@ require "tap" require "test/support/helper/shutup" require "test/support/helper/fixtures" +require "test/support/helper/formula" require "test/support/helper/spec/shared_context/integration_test" TEST_DIRECTORIES = [ @@ -32,9 +33,14 @@ RSpec.configure do |config| config.order = :random config.include(Test::Helper::Shutup) config.include(Test::Helper::Fixtures) + config.include(Test::Helper::Formula) config.before(:each) do |example| if example.metadata[:needs_macos] - skip "not on macOS" unless OS.mac? + skip "Not on macOS." unless OS.mac? + end + + if example.metadata[:needs_official_cmd_taps] + skip "Needs official command Taps." unless ENV["HOMEBREW_TEST_OFFICIAL_CMD_TAPS"] end if example.metadata[:needs_python] diff --git a/Library/Homebrew/test/support/helper/formula.rb b/Library/Homebrew/test/support/helper/formula.rb new file mode 100644 index 000000000..7f55f4b66 --- /dev/null +++ b/Library/Homebrew/test/support/helper/formula.rb @@ -0,0 +1,19 @@ +require "formulary" + +module Test + module Helper + module Formula + def formula(name = "formula_name", path: Formulary.core_path(name), spec: :stable, alias_path: nil, &block) + Class.new(::Formula, &block).new(name, path, spec, alias_path: alias_path) + end + + # Use a stubbed {Formulary::FormulaLoader} to make a given formula be found + # when loading from {Formulary} with `ref`. + def stub_formula_loader(formula, ref = formula.full_name) + loader = double(get_formula: formula) + allow(Formulary).to receive(:loader_for).with(ref, from: :keg).and_return(loader) + allow(Formulary).to receive(:loader_for).with(ref, from: nil).and_return(loader) + end + end + end +end diff --git a/Library/Homebrew/test/support/helper/spec/shared_context/integration_test.rb b/Library/Homebrew/test/support/helper/spec/shared_context/integration_test.rb index dd2271a3a..2eb98826a 100644 --- a/Library/Homebrew/test/support/helper/spec/shared_context/integration_test.rb +++ b/Library/Homebrew/test/support/helper/spec/shared_context/integration_test.rb @@ -63,7 +63,15 @@ RSpec.shared_context "integration test" do def brew(*args) env = args.last.is_a?(Hash) ? args.pop : {} + # Avoid warnings when HOMEBREW_PREFIX/bin is not in PATH. + path = [ + env["PATH"], + (HOMEBREW_PREFIX/"bin").realpath.to_s, + ENV["PATH"], + ].compact.join(File::PATH_SEPARATOR) + env.merge!( + "PATH" => path, "HOMEBREW_BREW_FILE" => HOMEBREW_PREFIX/"bin/brew", "HOMEBREW_INTEGRATION_TEST" => command_id_from_args(args), "HOMEBREW_TEST_TMPDIR" => TEST_TMPDIR, @@ -87,6 +95,80 @@ RSpec.shared_context "integration test" do status end end + + def setup_test_formula(name, content = nil) + case name + when /^testball/ + content = <<-EOS.undent + desc "Some test" + homepage "https://example.com/#{name}" + url "file://#{TEST_FIXTURE_DIR}/tarballs/testball-0.1.tbz" + sha256 "#{TESTBALL_SHA256}" + + option "with-foo", "Build with foo" + + def install + (prefix/"foo"/"test").write("test") if build.with? "foo" + prefix.install Dir["*"] + (buildpath/"test.c").write \ + "#include <stdio.h>\\nint main(){return printf(\\"test\\");}" + bin.mkpath + system ENV.cc, "test.c", "-o", bin/"test" + end + + #{content} + + # something here + EOS + when "foo" + content = <<-EOS.undent + url "https://example.com/#{name}-1.0" + EOS + when "bar" + content = <<-EOS.undent + url "https://example.com/#{name}-1.0" + depends_on "foo" + EOS + end + + Formulary.core_path(name).tap do |formula_path| + formula_path.write <<-EOS.undent + class #{Formulary.class_s(name)} < Formula + #{content} + end + EOS + end + end + + def setup_remote_tap(name) + Tap.fetch(name).tap do |tap| + tap.install(full_clone: false, quiet: true) unless tap.installed? + end + end + + def install_and_rename_coretap_formula(old_name, new_name) + shutup do + CoreTap.instance.path.cd do |tap_path| + system "git", "init" + system "git", "add", "--all" + system "git", "commit", "-m", + "#{old_name.capitalize} has not yet been renamed" + + brew "install", old_name + + (tap_path/"Formula/#{old_name}.rb").unlink + (tap_path/"formula_renames.json").write JSON.generate(old_name => new_name) + + system "git", "add", "--all" + system "git", "commit", "-m", + "#{old_name.capitalize} has been renamed to #{new_name.capitalize}" + end + end + end + + def testball + "#{TEST_FIXTURE_DIR}/testball.rb" + end end RSpec.configure do |config| diff --git a/Library/Homebrew/test/switch_test.rb b/Library/Homebrew/test/switch_test.rb deleted file mode 100644 index af1926c39..000000000 --- a/Library/Homebrew/test/switch_test.rb +++ /dev/null @@ -1,20 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestSwitch < IntegrationCommandTestCase - def test_switch - assert_match "Usage: brew switch <name> <version>", cmd_fail("switch") - assert_match "testball not found", cmd_fail("switch", "testball", "0.1") - - setup_test_formula "testball", <<-EOS.undent - keg_only "just because" - EOS - - cmd("install", "testball") - testball_rack = HOMEBREW_CELLAR/"testball" - FileUtils.cp_r testball_rack/"0.1", testball_rack/"0.2" - - cmd("switch", "testball", "0.2") - assert_match "testball does not have a version \"0.3\"", - cmd_fail("switch", "testball", "0.3") - end -end diff --git a/Library/Homebrew/test/tab_spec.rb b/Library/Homebrew/test/tab_spec.rb new file mode 100644 index 000000000..01dbeb67c --- /dev/null +++ b/Library/Homebrew/test/tab_spec.rb @@ -0,0 +1,341 @@ +require "tab" +require "formula" + +RSpec::Matchers.alias_matcher :be_built_with, :be_with + +describe Tab do + matcher :be_poured_from_bottle do + match do |actual| + actual.poured_from_bottle == true + end + end + + matcher :be_built_as_bottle do + match do |actual| + actual.built_as_bottle == true + end + end + + subject { + described_class.new( + "homebrew_version" => HOMEBREW_VERSION, + "used_options" => used_options.as_flags, + "unused_options" => unused_options.as_flags, + "built_as_bottle" => false, + "poured_from_bottle" => true, + "changed_files" => [], + "time" => time, + "source_modified_time" => 0, + "HEAD" => TEST_SHA1, + "compiler" => "clang", + "stdlib" => "libcxx", + "runtime_dependencies" => [], + "source" => { + "tap" => CoreTap.instance.to_s, + "path" => CoreTap.instance.path.to_s, + "spec" => "stable", + "versions" => { + "stable" => "0.10", + "devel" => "0.14", + "head" => "HEAD-1111111", + }, + }, + ) + } + let(:time) { Time.now.to_i } + let(:unused_options) { Options.create(%w[--with-baz --without-qux]) } + let(:used_options) { Options.create(%w[--with-foo --without-bar]) } + + let(:f) { formula { url "foo-1.0" } } + let(:f_tab_path) { f.prefix/"INSTALL_RECEIPT.json" } + let(:f_tab_content) { (TEST_FIXTURE_DIR/"receipt.json").read } + + specify "defaults" do + tab = described_class.empty + + expect(tab.homebrew_version).to eq(HOMEBREW_VERSION) + expect(tab.unused_options).to be_empty + expect(tab.used_options).to be_empty + expect(tab.changed_files).to be nil + expect(tab).not_to be_built_as_bottle + expect(tab).not_to be_poured_from_bottle + expect(tab).to be_stable + expect(tab).not_to be_devel + expect(tab).not_to be_head + expect(tab.tap).to be nil + expect(tab.time).to be nil + expect(tab.HEAD).to be nil + expect(tab.runtime_dependencies).to be_empty + expect(tab.stable_version).to be nil + expect(tab.devel_version).to be nil + expect(tab.head_version).to be nil + expect(tab.cxxstdlib.compiler).to eq(DevelopmentTools.default_compiler) + expect(tab.cxxstdlib.type).to be nil + expect(tab.source["path"]).to be nil + end + + specify "#include?" do + expect(subject).to include("with-foo") + expect(subject).to include("without-bar") + end + + specify "#with?" do + expect(subject).to be_built_with("foo") + expect(subject).to be_built_with("qux") + expect(subject).not_to be_built_with("bar") + expect(subject).not_to be_built_with("baz") + end + + specify "#universal?" do + tab = described_class.new(used_options: %w[--universal]) + expect(tab).to be_universal + end + + specify "#parsed_homebrew_version" do + tab = described_class.new + expect(tab.parsed_homebrew_version).to be Version::NULL + + tab = described_class.new(homebrew_version: "1.2.3") + expect(tab.parsed_homebrew_version).to eq("1.2.3") + expect(tab.parsed_homebrew_version).to be < "1.2.3-1-g12789abdf" + expect(tab.parsed_homebrew_version).to be_kind_of(Version) + + tab.homebrew_version = "1.2.4-567-g12789abdf" + expect(tab.parsed_homebrew_version).to be > "1.2.4" + expect(tab.parsed_homebrew_version).to be > "1.2.4-566-g21789abdf" + expect(tab.parsed_homebrew_version).to be < "1.2.4-568-g01789abdf" + + tab = described_class.new(homebrew_version: "2.0.0-134-gabcdefabc-dirty") + expect(tab.parsed_homebrew_version).to be > "2.0.0" + expect(tab.parsed_homebrew_version).to be > "2.0.0-133-g21789abdf" + expect(tab.parsed_homebrew_version).to be < "2.0.0-135-g01789abdf" + end + + specify "#runtime_dependencies" do + tab = described_class.new + expect(tab.runtime_dependencies).to be nil + + tab.homebrew_version = "1.1.6" + expect(tab.runtime_dependencies).to be nil + + tab.runtime_dependencies = [] + expect(tab.runtime_dependencies).not_to be nil + + tab.homebrew_version = "1.1.5" + expect(tab.runtime_dependencies).to be nil + + tab.homebrew_version = "1.1.7" + expect(tab.runtime_dependencies).not_to be nil + + tab.homebrew_version = "1.1.10" + expect(tab.runtime_dependencies).not_to be nil + + tab.runtime_dependencies = [{ "full_name" => "foo", "version" => "1.0" }] + expect(tab.runtime_dependencies).not_to be nil + end + + specify "#cxxstdlib" do + expect(subject.cxxstdlib.compiler).to eq(:clang) + expect(subject.cxxstdlib.type).to eq(:libcxx) + end + + specify "other attributes" do + expect(subject.HEAD).to eq(TEST_SHA1) + expect(subject.tap.name).to eq("homebrew/core") + expect(subject.time).to eq(time) + expect(subject).not_to be_built_as_bottle + expect(subject).to be_poured_from_bottle + end + + describe "::from_file" do + it "parses a Tab from a file" do + path = Pathname.new("#{TEST_FIXTURE_DIR}/receipt.json") + tab = described_class.from_file(path) + source_path = "/usr/local/Library/Taps/homebrew/homebrew-core/Formula/foo.rb" + runtime_dependencies = [{ "full_name" => "foo", "version" => "1.0" }] + changed_files = %w[INSTALL_RECEIPT.json bin/foo] + + expect(tab.used_options.sort).to eq(used_options.sort) + expect(tab.unused_options.sort).to eq(unused_options.sort) + expect(tab.changed_files).to eq(changed_files) + expect(tab).not_to be_built_as_bottle + expect(tab).to be_poured_from_bottle + expect(tab).to be_stable + expect(tab).not_to be_devel + expect(tab).not_to be_head + expect(tab.tap.name).to eq("homebrew/core") + expect(tab.spec).to eq(:stable) + expect(tab.time).to eq(Time.at(1_403_827_774).to_i) + expect(tab.HEAD).to eq(TEST_SHA1) + expect(tab.cxxstdlib.compiler).to eq(:clang) + expect(tab.cxxstdlib.type).to eq(:libcxx) + expect(tab.runtime_dependencies).to eq(runtime_dependencies) + expect(tab.stable_version.to_s).to eq("2.14") + expect(tab.devel_version.to_s).to eq("2.15") + expect(tab.head_version.to_s).to eq("HEAD-0000000") + expect(tab.source["path"]).to eq(source_path) + end + + it "can parse an old Tab file" do + path = Pathname.new("#{TEST_FIXTURE_DIR}/receipt_old.json") + tab = described_class.from_file(path) + + expect(tab.used_options.sort).to eq(used_options.sort) + expect(tab.unused_options.sort).to eq(unused_options.sort) + expect(tab).not_to be_built_as_bottle + expect(tab).to be_poured_from_bottle + expect(tab).to be_stable + expect(tab).not_to be_devel + expect(tab).not_to be_head + expect(tab.tap.name).to eq("homebrew/core") + expect(tab.spec).to eq(:stable) + expect(tab.time).to eq(Time.at(1_403_827_774).to_i) + expect(tab.HEAD).to eq(TEST_SHA1) + expect(tab.cxxstdlib.compiler).to eq(:clang) + expect(tab.cxxstdlib.type).to eq(:libcxx) + expect(tab.runtime_dependencies).to be nil + end + end + + describe "::create" do + it "creates a Tab" do + f = formula do + url "foo-1.0" + depends_on "bar" + depends_on "user/repo/from_tap" + depends_on "baz" => :build + end + + tap = Tap.new("user", "repo") + from_tap = formula("from_tap", path: tap.path/"Formula/from_tap.rb") do + url "from_tap-1.0" + end + stub_formula_loader from_tap + + stub_formula_loader formula("bar") { url "bar-2.0" } + stub_formula_loader formula("baz") { url "baz-3.0" } + + compiler = DevelopmentTools.default_compiler + stdlib = :libcxx + tab = described_class.create(f, compiler, stdlib) + + runtime_dependencies = [ + { "full_name" => "bar", "version" => "2.0" }, + { "full_name" => "user/repo/from_tap", "version" => "1.0" }, + ] + + expect(tab.runtime_dependencies).to eq(runtime_dependencies) + expect(tab.source["path"]).to eq(f.path.to_s) + end + + it "can create a Tab from an alias" do + alias_path = CoreTap.instance.alias_dir/"bar" + f = formula(alias_path: alias_path) { url "foo-1.0" } + compiler = DevelopmentTools.default_compiler + stdlib = :libcxx + tab = described_class.create(f, compiler, stdlib) + + expect(tab.source["path"]).to eq(f.alias_path.to_s) + end + end + + describe "::for_keg" do + subject { described_class.for_keg(f.prefix) } + + it "creates a Tab for a given Keg" do + f.prefix.mkpath + f_tab_path.write f_tab_content + + expect(subject.tabfile).to eq(f_tab_path) + end + + it "can create a Tab for a non-existant Keg" do + f.prefix.mkpath + + expect(subject.tabfile).to be nil + end + end + + describe "::for_formula" do + it "creates a Tab for a given Formula" do + tab = described_class.for_formula(f) + expect(tab.source["path"]).to eq(f.path.to_s) + end + + it "can create a Tab for for a Formula from an alias" do + alias_path = CoreTap.instance.alias_dir/"bar" + f = formula(alias_path: alias_path) { url "foo-1.0" } + + tab = described_class.for_formula(f) + expect(tab.source["path"]).to eq(alias_path.to_s) + end + + it "creates a Tab for a given Formula" do + f.prefix.mkpath + f_tab_path.write f_tab_content + + tab = described_class.for_formula(f) + expect(tab.tabfile).to eq(f_tab_path) + end + + it "can create a Tab for a non-existant Formula" do + f.prefix.mkpath + + tab = described_class.for_formula(f) + expect(tab.tabfile).to be nil + end + + it "can create a Tab for a Formula with multiple Kegs" do + f.prefix.mkpath + f_tab_path.write f_tab_content + + f2 = formula { url "foo-2.0" } + f2.prefix.mkpath + + expect(f2.rack).to eq(f.rack) + expect(f.installed_prefixes.length).to eq(2) + + tab = described_class.for_formula(f) + expect(tab.tabfile).to eq(f_tab_path) + end + + it "can create a Tab for a Formula with an outdated Kegs" do + f_tab_path.write f_tab_content + + f2 = formula { url "foo-2.0" } + + expect(f2.rack).to eq(f.rack) + expect(f.installed_prefixes.length).to eq(1) + + tab = described_class.for_formula(f) + expect(tab.tabfile).to eq(f_tab_path) + end + end + + specify "#to_json" do + tab = described_class.new(JSON.parse(subject.to_json)) + expect(tab.used_options.sort).to eq(subject.used_options.sort) + expect(tab.unused_options.sort).to eq(subject.unused_options.sort) + expect(tab.built_as_bottle).to eq(subject.built_as_bottle) + expect(tab.poured_from_bottle).to eq(subject.poured_from_bottle) + expect(tab.changed_files).to eq(subject.changed_files) + expect(tab.tap).to eq(subject.tap) + expect(tab.spec).to eq(subject.spec) + expect(tab.time).to eq(subject.time) + expect(tab.HEAD).to eq(subject.HEAD) + expect(tab.compiler).to eq(subject.compiler) + expect(tab.stdlib).to eq(subject.stdlib) + expect(tab.runtime_dependencies).to eq(subject.runtime_dependencies) + expect(tab.stable_version).to eq(subject.stable_version) + expect(tab.devel_version).to eq(subject.devel_version) + expect(tab.head_version).to eq(subject.head_version) + expect(tab.source["path"]).to eq(subject.source["path"]) + end + + specify "::remap_deprecated_options" do + deprecated_options = [DeprecatedOption.new("with-foo", "with-foo-new")] + remapped_options = described_class.remap_deprecated_options(deprecated_options, subject.used_options) + expect(remapped_options).to include(Option.new("without-bar")) + expect(remapped_options).to include(Option.new("with-foo-new")) + end +end diff --git a/Library/Homebrew/test/tab_test.rb b/Library/Homebrew/test/tab_test.rb deleted file mode 100644 index 08d45ee90..000000000 --- a/Library/Homebrew/test/tab_test.rb +++ /dev/null @@ -1,318 +0,0 @@ -require "testing_env" -require "tab" -require "formula" - -class TabTests < Homebrew::TestCase - def setup - super - - @time = Time.now.to_i - @used = Options.create(%w[--with-foo --without-bar]) - @unused = Options.create(%w[--with-baz --without-qux]) - - @tab = Tab.new( - "homebrew_version" => HOMEBREW_VERSION, - "used_options" => @used.as_flags, - "unused_options" => @unused.as_flags, - "built_as_bottle" => false, - "poured_from_bottle" => true, - "changed_files" => [], - "time" => @time, - "source_modified_time" => 0, - "HEAD" => TEST_SHA1, - "compiler" => "clang", - "stdlib" => "libcxx", - "runtime_dependencies" => [], - "source" => { - "tap" => CoreTap.instance.to_s, - "path" => CoreTap.instance.path.to_s, - "spec" => "stable", - "versions" => { - "stable" => "0.10", - "devel" => "0.14", - "head" => "HEAD-1111111", - }, - }, - ) - end - - def test_defaults - tab = Tab.empty - - assert_equal HOMEBREW_VERSION, tab.homebrew_version - assert_empty tab.unused_options - assert_empty tab.used_options - assert_nil tab.changed_files - refute_predicate tab, :built_as_bottle - refute_predicate tab, :poured_from_bottle - assert_predicate tab, :stable? - refute_predicate tab, :devel? - refute_predicate tab, :head? - assert_nil tab.tap - assert_nil tab.time - assert_nil tab.HEAD - assert_empty tab.runtime_dependencies - assert_nil tab.stable_version - assert_nil tab.devel_version - assert_nil tab.head_version - assert_equal DevelopmentTools.default_compiler, tab.cxxstdlib.compiler - assert_nil tab.cxxstdlib.type - assert_nil tab.source["path"] - end - - def test_include? - assert_includes @tab, "with-foo" - assert_includes @tab, "without-bar" - end - - def test_with? - assert @tab.with?("foo") - assert @tab.with?("qux") - refute @tab.with?("bar") - refute @tab.with?("baz") - end - - def test_universal? - tab = Tab.new(used_options: %w[--universal]) - assert_predicate tab, :universal? - end - - def test_parsed_homebrew_version - tab = Tab.new - assert_same Version::NULL, tab.parsed_homebrew_version - - tab = Tab.new(homebrew_version: "1.2.3") - assert_equal "1.2.3", tab.parsed_homebrew_version - assert tab.parsed_homebrew_version < "1.2.3-1-g12789abdf" - assert_kind_of Version, tab.parsed_homebrew_version - - tab.homebrew_version = "1.2.4-567-g12789abdf" - assert tab.parsed_homebrew_version > "1.2.4" - assert tab.parsed_homebrew_version > "1.2.4-566-g21789abdf" - assert tab.parsed_homebrew_version < "1.2.4-568-g01789abdf" - - tab = Tab.new(homebrew_version: "2.0.0-134-gabcdefabc-dirty") - assert tab.parsed_homebrew_version > "2.0.0" - assert tab.parsed_homebrew_version > "2.0.0-133-g21789abdf" - assert tab.parsed_homebrew_version < "2.0.0-135-g01789abdf" - end - - def test_runtime_dependencies - tab = Tab.new - assert_nil tab.runtime_dependencies - - tab.homebrew_version = "1.1.6" - assert_nil tab.runtime_dependencies - - tab.runtime_dependencies = [] - refute_nil tab.runtime_dependencies - - tab.homebrew_version = "1.1.5" - assert_nil tab.runtime_dependencies - - tab.homebrew_version = "1.1.7" - refute_nil tab.runtime_dependencies - - tab.homebrew_version = "1.1.10" - refute_nil tab.runtime_dependencies - - tab.runtime_dependencies = [{ "full_name" => "foo", "version" => "1.0" }] - refute_nil tab.runtime_dependencies - end - - def test_cxxstdlib - assert_equal :clang, @tab.cxxstdlib.compiler - assert_equal :libcxx, @tab.cxxstdlib.type - end - - def test_other_attributes - assert_equal TEST_SHA1, @tab.HEAD - assert_equal "homebrew/core", @tab.tap.name - assert_equal @time, @tab.time - refute_predicate @tab, :built_as_bottle - assert_predicate @tab, :poured_from_bottle - end - - def test_from_old_version_file - path = Pathname.new("#{TEST_FIXTURE_DIR}/receipt_old.json") - tab = Tab.from_file(path) - - assert_equal @used.sort, tab.used_options.sort - assert_equal @unused.sort, tab.unused_options.sort - refute_predicate tab, :built_as_bottle - assert_predicate tab, :poured_from_bottle - assert_predicate tab, :stable? - refute_predicate tab, :devel? - refute_predicate tab, :head? - assert_equal "homebrew/core", tab.tap.name - assert_equal :stable, tab.spec - refute_nil tab.time - assert_equal TEST_SHA1, tab.HEAD - assert_equal :clang, tab.cxxstdlib.compiler - assert_equal :libcxx, tab.cxxstdlib.type - assert_nil tab.runtime_dependencies - end - - def test_from_file - path = Pathname.new("#{TEST_FIXTURE_DIR}/receipt.json") - tab = Tab.from_file(path) - source_path = "/usr/local/Library/Taps/homebrew/homebrew-core/Formula/foo.rb" - runtime_dependencies = [{ "full_name" => "foo", "version" => "1.0" }] - changed_files = %w[INSTALL_RECEIPT.json bin/foo] - - assert_equal @used.sort, tab.used_options.sort - assert_equal @unused.sort, tab.unused_options.sort - assert_equal changed_files, tab.changed_files - refute_predicate tab, :built_as_bottle - assert_predicate tab, :poured_from_bottle - assert_predicate tab, :stable? - refute_predicate tab, :devel? - refute_predicate tab, :head? - assert_equal "homebrew/core", tab.tap.name - assert_equal :stable, tab.spec - refute_nil tab.time - assert_equal TEST_SHA1, tab.HEAD - assert_equal :clang, tab.cxxstdlib.compiler - assert_equal :libcxx, tab.cxxstdlib.type - assert_equal runtime_dependencies, tab.runtime_dependencies - assert_equal "2.14", tab.stable_version.to_s - assert_equal "2.15", tab.devel_version.to_s - assert_equal "HEAD-0000000", tab.head_version.to_s - assert_equal source_path, tab.source["path"] - end - - def test_create - f = formula do - url "foo-1.0" - depends_on "bar" - depends_on "user/repo/from_tap" - depends_on "baz" => :build - end - - tap = Tap.new("user", "repo") - from_tap = formula("from_tap", tap.path/"Formula/from_tap.rb") do - url "from_tap-1.0" - end - stub_formula_loader from_tap - - stub_formula_loader formula("bar") { url "bar-2.0" } - stub_formula_loader formula("baz") { url "baz-3.0" } - - compiler = DevelopmentTools.default_compiler - stdlib = :libcxx - tab = Tab.create(f, compiler, stdlib) - - runtime_dependencies = [ - { "full_name" => "bar", "version" => "2.0" }, - { "full_name" => "user/repo/from_tap", "version" => "1.0" }, - ] - - assert_equal runtime_dependencies, tab.runtime_dependencies - assert_equal f.path.to_s, tab.source["path"] - end - - def test_create_from_alias - alias_path = CoreTap.instance.alias_dir/"bar" - f = formula(alias_path: alias_path) { url "foo-1.0" } - compiler = DevelopmentTools.default_compiler - stdlib = :libcxx - tab = Tab.create(f, compiler, stdlib) - - assert_equal f.alias_path.to_s, tab.source["path"] - end - - def test_for_formula - f = formula { url "foo-1.0" } - tab = Tab.for_formula(f) - - assert_equal f.path.to_s, tab.source["path"] - end - - def test_for_formula_from_alias - alias_path = CoreTap.instance.alias_dir/"bar" - f = formula(alias_path: alias_path) { url "foo-1.0" } - tab = Tab.for_formula(f) - - assert_equal alias_path.to_s, tab.source["path"] - end - - def test_to_json - tab = Tab.new(JSON.parse(@tab.to_json)) - assert_equal @tab.used_options.sort, tab.used_options.sort - assert_equal @tab.unused_options.sort, tab.unused_options.sort - assert_equal @tab.built_as_bottle, tab.built_as_bottle - assert_equal @tab.poured_from_bottle, tab.poured_from_bottle - assert_equal @tab.changed_files, tab.changed_files - assert_equal @tab.tap, tab.tap - assert_equal @tab.spec, tab.spec - assert_equal @tab.time, tab.time - assert_equal @tab.HEAD, tab.HEAD - assert_equal @tab.compiler, tab.compiler - assert_equal @tab.stdlib, tab.stdlib - assert_equal @tab.runtime_dependencies, tab.runtime_dependencies - assert_equal @tab.stable_version, tab.stable_version - assert_equal @tab.devel_version, tab.devel_version - assert_equal @tab.head_version, tab.head_version - assert_equal @tab.source["path"], tab.source["path"] - end - - def test_remap_deprecated_options - deprecated_options = [DeprecatedOption.new("with-foo", "with-foo-new")] - remapped_options = Tab.remap_deprecated_options(deprecated_options, @tab.used_options) - assert_includes remapped_options, Option.new("without-bar") - assert_includes remapped_options, Option.new("with-foo-new") - end -end - -class TabLoadingTests < Homebrew::TestCase - def setup - super - @f = formula { url "foo-1.0" } - @f.prefix.mkpath - @path = @f.prefix.join(Tab::FILENAME) - @path.write TEST_FIXTURE_DIR.join("receipt.json").read - end - - def test_for_keg - tab = Tab.for_keg(@f.prefix) - assert_equal @path, tab.tabfile - end - - def test_for_keg_nonexistent_path - @path.unlink - tab = Tab.for_keg(@f.prefix) - assert_nil tab.tabfile - end - - def test_for_formula - tab = Tab.for_formula(@f) - assert_equal @path, tab.tabfile - end - - def test_for_formula_nonexistent_path - @path.unlink - tab = Tab.for_formula(@f) - assert_nil tab.tabfile - end - - def test_for_formula_multiple_kegs - f2 = formula { url "foo-2.0" } - f2.prefix.mkpath - - assert_equal @f.rack, f2.rack - assert_equal 2, @f.installed_prefixes.length - - tab = Tab.for_formula(@f) - assert_equal @path, tab.tabfile - end - - def test_for_formula_outdated_keg - f2 = formula { url "foo-2.0" } - - assert_equal @f.rack, f2.rack - assert_equal 1, @f.installed_prefixes.length - - tab = Tab.for_formula(f2) - assert_equal @path, tab.tabfile - end -end diff --git a/Library/Homebrew/test/tap_new_test.rb b/Library/Homebrew/test/tap_new_test.rb deleted file mode 100644 index 261a334f0..000000000 --- a/Library/Homebrew/test/tap_new_test.rb +++ /dev/null @@ -1,9 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestTapNew < IntegrationCommandTestCase - def test_tap_readme - assert_equal "", cmd("tap-new", "homebrew/foo", "--verbose") - readme = HOMEBREW_LIBRARY/"Taps/homebrew/homebrew-foo/README.md" - assert readme.exist?, "The README should be created" - end -end diff --git a/Library/Homebrew/test/tap_test.rb b/Library/Homebrew/test/tap_test.rb index 578326cea..729fc8198 100644 --- a/Library/Homebrew/test/tap_test.rb +++ b/Library/Homebrew/test/tap_test.rb @@ -1,34 +1,4 @@ require "testing_env" -require "testing_env" - -class IntegrationCommandTestTap < IntegrationCommandTestCase - def test_tap - path = Tap::TAP_DIRECTORY/"homebrew/homebrew-foo" - path.mkpath - path.cd do - shutup do - system "git", "init" - system "git", "remote", "add", "origin", "https://github.com/Homebrew/homebrew-foo" - FileUtils.touch "readme" - system "git", "add", "--all" - system "git", "commit", "-m", "init" - end - end - - assert_match "homebrew/foo", cmd("tap") - assert_match "homebrew/science", cmd("tap", "--list-official") - assert_match "2 taps", cmd("tap-info") - assert_match "https://github.com/Homebrew/homebrew-foo", cmd("tap-info", "homebrew/foo") - assert_match "https://github.com/Homebrew/homebrew-foo", cmd("tap-info", "--json=v1", "--installed") - assert_match "Pinned homebrew/foo", cmd("tap-pin", "homebrew/foo") - assert_match "homebrew/foo", cmd("tap", "--list-pinned") - assert_match "Unpinned homebrew/foo", cmd("tap-unpin", "homebrew/foo") - assert_match "Tapped", cmd("tap", "homebrew/bar", path/".git") - assert_match "Untapped", cmd("untap", "homebrew/bar") - assert_equal "", cmd("tap", "homebrew/bar", path/".git", "-q", "--full") - assert_match "Untapped", cmd("untap", "homebrew/bar") - end -end class TapTest < Homebrew::TestCase include FileUtils diff --git a/Library/Homebrew/test/test_formula_test.rb b/Library/Homebrew/test/test_formula_test.rb deleted file mode 100644 index 5ad2db9e9..000000000 --- a/Library/Homebrew/test/test_formula_test.rb +++ /dev/null @@ -1,30 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestTestFormula < IntegrationCommandTestCase - def test_test_formula - assert_match "This command requires a formula argument", cmd_fail("test") - assert_match "Testing requires the latest version of testball", - cmd_fail("test", testball) - - cmd("install", testball) - assert_match "testball defines no test", cmd_fail("test", testball) - - setup_test_formula "testball_copy", <<-EOS.undent - head "https://github.com/example/testball2.git" - - devel do - url "file://#{TEST_FIXTURE_DIR}/tarballs/testball-0.1.tbz" - sha256 "#{TESTBALL_SHA256}" - end - - keg_only "just because" - - test do - end - EOS - - cmd("install", "testball_copy") - assert_match "Testing testball_copy", cmd("test", "--HEAD", "testball_copy") - assert_match "Testing testball_copy", cmd("test", "--devel", "testball_copy") - end -end diff --git a/Library/Homebrew/test/uninstall_test.rb b/Library/Homebrew/test/uninstall_test.rb index 2f8bf4fff..a9230ffac 100644 --- a/Library/Homebrew/test/uninstall_test.rb +++ b/Library/Homebrew/test/uninstall_test.rb @@ -60,10 +60,3 @@ class UninstallTests < Homebrew::TestCase end end end - -class IntegrationCommandTestUninstall < IntegrationCommandTestCase - def test_uninstall - cmd("install", testball) - assert_match "Uninstalling testball", cmd("uninstall", "--force", testball) - end -end diff --git a/Library/Homebrew/test/unlink_test.rb b/Library/Homebrew/test/unlink_test.rb deleted file mode 100644 index 6d5cefc67..000000000 --- a/Library/Homebrew/test/unlink_test.rb +++ /dev/null @@ -1,10 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestUnlink < IntegrationCommandTestCase - def test_unlink - setup_test_formula "testball" - - cmd("install", "testball") - assert_match "Would remove", cmd("unlink", "--dry-run", "testball") - end -end diff --git a/Library/Homebrew/test/unlinkapps_test.rb b/Library/Homebrew/test/unlinkapps_test.rb deleted file mode 100644 index 9d9672199..000000000 --- a/Library/Homebrew/test/unlinkapps_test.rb +++ /dev/null @@ -1,19 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestUnlinkapps < IntegrationCommandTestCase - def test_unlinkapps - home_dir = Pathname.new(mktmpdir) - apps_dir = home_dir/"Applications" - apps_dir.mkpath - - setup_test_formula "testball" - - source_app = (HOMEBREW_CELLAR/"testball/0.1/TestBall.app") - source_app.mkpath - - FileUtils.ln_s source_app, "#{apps_dir}/TestBall.app" - - assert_match "Unlinking: #{apps_dir}/TestBall.app", - cmd("unlinkapps", "--local", "HOME" => home_dir) - end -end diff --git a/Library/Homebrew/test/unpack_test.rb b/Library/Homebrew/test/unpack_test.rb deleted file mode 100644 index bbff6ad1c..000000000 --- a/Library/Homebrew/test/unpack_test.rb +++ /dev/null @@ -1,13 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestUnpack < IntegrationCommandTestCase - def test_unpack - setup_test_formula "testball" - - mktmpdir do |path| - cmd "unpack", "testball", "--destdir=#{path}" - assert File.directory?("#{path}/testball-0.1"), - "The tarball should be unpacked" - end - end -end diff --git a/Library/Homebrew/test/update_report_test.rb b/Library/Homebrew/test/update_report_test.rb deleted file mode 100644 index 32c3e36d0..000000000 --- a/Library/Homebrew/test/update_report_test.rb +++ /dev/null @@ -1,135 +0,0 @@ -require "testing_env" -require "cmd/update-report" -require "formula_versions" -require "yaml" - -class ReportTests < Homebrew::TestCase - class ReporterMock < ::Reporter - attr_accessor :diff - - def initialize(tap) - @tap = tap - ENV["HOMEBREW_UPDATE_BEFORE#{repo_var}"] = "12345678" - ENV["HOMEBREW_UPDATE_AFTER#{repo_var}"] = "abcdef12" - super(tap) - end - end - - def fixture(name) - self.class.fixture_data[name] || "" - end - - def self.fixture_data - @fixture_data ||= YAML.load_file("#{TEST_FIXTURE_DIR}/updater_fixture.yaml") - end - - def setup - super - @tap = CoreTap.new - @reporter = ReporterMock.new(@tap) - @hub = ReporterHub.new - end - - def perform_update(fixture_name = "") - Formulary.stubs(:factory).returns(stub(pkg_version: "1.0")) - FormulaVersions.stubs(:new).returns(stub(formula_at_revision: "2.0")) - @reporter.diff = fixture(fixture_name) - @hub.add(@reporter) if @reporter.updated? - end - - def test_update_report_without_revision_var - ENV.delete_if { |k, _v| k.start_with? "HOMEBREW_UPDATE" } - assert_raises(Reporter::ReporterRevisionUnsetError) { Reporter.new(@tap) } - end - - def test_update_homebrew_without_any_changes - perform_update - assert_empty @hub - end - - def test_update_homebrew_without_formulae_changes - perform_update("update_git_diff_output_without_formulae_changes") - assert_empty @hub.select_formula(:M) - assert_empty @hub.select_formula(:A) - assert_empty @hub.select_formula(:D) - end - - def test_update_homebrew_with_formulae_changes - perform_update("update_git_diff_output_with_formulae_changes") - assert_equal %w[xar yajl], @hub.select_formula(:M) - assert_equal %w[antiword bash-completion ddrescue dict lua], @hub.select_formula(:A) - end - - def test_update_homebrew_with_removed_formulae - perform_update("update_git_diff_output_with_removed_formulae") - assert_equal %w[libgsasl], @hub.select_formula(:D) - end - - def test_update_homebrew_with_changed_filetype - perform_update("update_git_diff_output_with_changed_filetype") - assert_equal %w[elixir], @hub.select_formula(:M) - assert_equal %w[libbson], @hub.select_formula(:A) - assert_equal %w[libgsasl], @hub.select_formula(:D) - end - - def test_update_homebrew_with_formula_rename - @tap.stubs(:formula_renames).returns("cv" => "progress") - perform_update("update_git_diff_output_with_formula_rename") - assert_empty @hub.select_formula(:A) - assert_empty @hub.select_formula(:D) - assert_equal [["cv", "progress"]], @hub.select_formula(:R) - end - - def test_update_homebrew_with_restructured_tap - tap = Tap.new("foo", "bar") - @reporter = ReporterMock.new(tap) - tap.path.join("Formula").mkpath - - perform_update("update_git_diff_output_with_restructured_tap") - assert_empty @hub.select_formula(:A) - assert_empty @hub.select_formula(:D) - assert_empty @hub.select_formula(:R) - ensure - tap.path.parent.rmtree - end - - def test_update_homebrew_with_formula_rename_and_restructuring - tap = Tap.new("foo", "bar") - @reporter = ReporterMock.new(tap) - tap.path.join("Formula").mkpath - tap.stubs(:formula_renames).returns("xchat" => "xchat2") - - perform_update("update_git_diff_output_with_formula_rename_and_restructuring") - assert_empty @hub.select_formula(:A) - assert_empty @hub.select_formula(:D) - assert_equal [%w[foo/bar/xchat foo/bar/xchat2]], @hub.select_formula(:R) - ensure - tap.path.parent.rmtree - end - - def test_update_homebrew_simulate_homebrew_php_restructuring - tap = Tap.new("foo", "bar") - @reporter = ReporterMock.new(tap) - tap.path.join("Formula").mkpath - - perform_update("update_git_diff_simulate_homebrew_php_restructuring") - assert_empty @hub.select_formula(:A) - assert_empty @hub.select_formula(:D) - assert_empty @hub.select_formula(:R) - ensure - tap.path.parent.rmtree - end - - def test_update_homebrew_with_tap_formulae_changes - tap = Tap.new("foo", "bar") - @reporter = ReporterMock.new(tap) - tap.path.join("Formula").mkpath - - perform_update("update_git_diff_output_with_tap_formulae_changes") - assert_equal %w[foo/bar/lua], @hub.select_formula(:A) - assert_equal %w[foo/bar/git], @hub.select_formula(:M) - assert_empty @hub.select_formula(:D) - ensure - tap.path.parent.rmtree - end -end diff --git a/Library/Homebrew/test/upgrade_test.rb b/Library/Homebrew/test/upgrade_test.rb deleted file mode 100644 index f3f5dccc7..000000000 --- a/Library/Homebrew/test/upgrade_test.rb +++ /dev/null @@ -1,12 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestUpgrade < IntegrationCommandTestCase - def test_upgrade - setup_test_formula "testball" - (HOMEBREW_CELLAR/"testball/0.0.1/foo").mkpath - - cmd("upgrade") - assert((HOMEBREW_CELLAR/"testball/0.1").directory?, - "The latest version directory should be created") - end -end diff --git a/Library/Homebrew/test/uses_test.rb b/Library/Homebrew/test/uses_test.rb deleted file mode 100644 index 1fad0da28..000000000 --- a/Library/Homebrew/test/uses_test.rb +++ /dev/null @@ -1,16 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestUses < IntegrationCommandTestCase - def test_uses - setup_test_formula "foo" - setup_test_formula "bar" - setup_test_formula "baz", <<-EOS.undent - url "https://example.com/baz-1.0" - depends_on "bar" - EOS - - assert_equal "", cmd("uses", "baz") - assert_equal "baz", cmd("uses", "bar") - assert_match(/(bar\nbaz|baz\nbar)/, cmd("uses", "--recursive", "foo")) - end -end diff --git a/Library/Homebrew/test/utils/bottles/bottles_spec.rb b/Library/Homebrew/test/utils/bottles/bottles_spec.rb new file mode 100644 index 000000000..8b54b0b34 --- /dev/null +++ b/Library/Homebrew/test/utils/bottles/bottles_spec.rb @@ -0,0 +1,80 @@ +require "utils/bottles" + +describe Utils::Bottles do + describe "#tag", :needs_macos do + it "returns :tiger_foo on Tiger PowerPC" do + allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.4")) + allow(Hardware::CPU).to receive(:type).and_return(:ppc) + allow(Hardware::CPU).to receive(:family).and_return(:foo) + allow(MacOS).to receive(:prefer_64_bit?).and_return(false) + expect(described_class.tag).to eq(:tiger_foo) + end + + it "returns :tiger on Tiger Intel" do + allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.4")) + allow(Hardware::CPU).to receive(:type).and_return(:intel) + allow(MacOS).to receive(:prefer_64_bit?).and_return(false) + expect(described_class.tag).to eq(:tiger) + end + + it "returns :tiger_g5_64 on Tiger PowerPC 64-bit" do + allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.4")) + allow(Hardware::CPU).to receive(:type).and_return(:ppc) + allow(Hardware::CPU).to receive(:family).and_return(:g5) + allow(MacOS).to receive(:prefer_64_bit?).and_return(true) + expect(described_class.tag).to eq(:tiger_g5_64) + end + + # Note that this will probably never be used + it "returns :tiger_64 on Tiger Intel 64-bit" do + allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.4")) + allow(Hardware::CPU).to receive(:type).and_return(:intel) + allow(MacOS).to receive(:prefer_64_bit?).and_return(true) + expect(described_class.tag).to eq(:tiger_64) + end + + it "returns :leopard on Leopard Intel" do + allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.5")) + allow(Hardware::CPU).to receive(:type).and_return(:intel) + allow(MacOS).to receive(:prefer_64_bit?).and_return(false) + expect(described_class.tag).to eq(:leopard) + end + + it "returns :leopard_g5_64 on Leopard PowerPC 64-bit" do + allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.5")) + allow(Hardware::CPU).to receive(:type).and_return(:ppc) + allow(Hardware::CPU).to receive(:family).and_return(:g5) + allow(MacOS).to receive(:prefer_64_bit?).and_return(true) + expect(described_class.tag).to eq(:leopard_g5_64) + end + + it "returns :leopard_64 on Leopard Intel 64-bit" do + allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.5")) + allow(Hardware::CPU).to receive(:type).and_return(:intel) + allow(MacOS).to receive(:prefer_64_bit?).and_return(true) + expect(described_class.tag).to eq(:leopard_64) + end + + it "returns :snow_leopard_32 on Snow Leopard 32-bit" do + allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.6")) + allow(Hardware::CPU).to receive(:is_64_bit?).and_return(false) + expect(described_class.tag).to eq(:snow_leopard_32) + end + + it "returns :snow_leopard on Snow Leopard 64-bit" do + allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.6")) + allow(Hardware::CPU).to receive(:is_64_bit?).and_return(true) + expect(described_class.tag).to eq(:snow_leopard) + end + + it "returns :lion on Lion" do + allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.7")) + expect(described_class.tag).to eq(:lion) + end + + it "returns :mountain_lion on Mountain Lion" do + allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.8")) + expect(described_class.tag).to eq(:mountain_lion) + end + end +end diff --git a/Library/Homebrew/test/utils_spec.rb b/Library/Homebrew/test/utils_spec.rb index 040ad630b..b3fdedcb9 100644 --- a/Library/Homebrew/test/utils_spec.rb +++ b/Library/Homebrew/test/utils_spec.rb @@ -232,10 +232,10 @@ describe "globally-scoped helper methods" do specify "#disk_usage_readable" do expect(disk_usage_readable(1)).to eq("1B") expect(disk_usage_readable(1000)).to eq("1000B") - expect(disk_usage_readable(1024)).to eq("1K") - expect(disk_usage_readable(1025)).to eq("1K") - expect(disk_usage_readable(4_404_020)).to eq("4.2M") - expect(disk_usage_readable(4_509_715_660)).to eq("4.2G") + expect(disk_usage_readable(1024)).to eq("1KB") + expect(disk_usage_readable(1025)).to eq("1KB") + expect(disk_usage_readable(4_404_020)).to eq("4.2MB") + expect(disk_usage_readable(4_509_715_660)).to eq("4.2GB") end describe "#number_readable" do diff --git a/Library/Homebrew/test/version_test.rb b/Library/Homebrew/test/version_test.rb deleted file mode 100644 index e7ffbc4f6..000000000 --- a/Library/Homebrew/test/version_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -require "testing_env" - -class IntegrationCommandTestVersion < IntegrationCommandTestCase - def test_version - assert_match HOMEBREW_VERSION.to_s, - cmd("--version") - end -end |
