aboutsummaryrefslogtreecommitdiffstats
path: root/Library/Homebrew/test/formula_installer_spec.rb
blob: efe2bf5a251eb5685766a52481303f8e18c04c97 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
require "formula"
require "formula_installer"
require "keg"
require "tab"
require "test/support/fixtures/testball"
require "test/support/fixtures/testball_bottle"

RSpec::Matchers.define_negated_matcher :need_bottle, :be_bottle_unneeded
RSpec::Matchers.alias_matcher :have_disabled_bottle, :be_bottle_disabled

describe FormulaInstaller do
  matcher :be_poured_from_bottle do
    match(&:poured_from_bottle)
  end

  def temporary_install(formula)
    expect(formula).not_to be_installed

    installer = described_class.new(formula)

    shutup do
      installer.install
    end

    keg = Keg.new(formula.prefix)

    expect(formula).to be_installed

    begin
      Tab.clear_cache
      expect(Tab.for_keg(keg)).not_to be_poured_from_bottle

      yield formula
    ensure
      Tab.clear_cache
      keg.unlink
      keg.uninstall
      formula.clear_cache
      # there will be log files when sandbox is enable.
      formula.logs.rmtree if formula.logs.directory?
    end

    expect(keg).not_to exist
    expect(formula).not_to be_installed
  end

  specify "basic installation" do
    ARGV << "--with-invalid_flag" # added to ensure it doesn't fail install

    temporary_install(Testball.new) do |f|
      # Test that things made it into the Keg
      expect(f.prefix/"readme").to exist

      expect(f.bin).to be_a_directory
      expect(f.bin.children.count).to eq(3)

      expect(f.libexec).to be_a_directory
      expect(f.libexec.children.count).to eq(1)

      expect(f.prefix/"main.c").not_to exist
      expect(f.prefix/"license").not_to exist

      # Test that things make it into the Cellar
      keg = Keg.new f.prefix
      keg.link

      bin = HOMEBREW_PREFIX/"bin"
      expect(bin).to be_a_directory
      expect(bin.children.count).to eq(3)
      expect(f.prefix/".brew/testball.rb").to be_readable
    end
  end

  specify "Formula installation with unneeded bottle" do
    allow(DevelopmentTools).to receive(:installed?).and_return(false)

    formula = Testball.new
    allow(formula).to receive(:bottle_unneeded?).and_return(true)
    allow(formula).to receive(:bottle_disabled?).and_return(true)

    expect(formula).not_to be_bottled
    expect(formula).not_to need_bottle
    expect(formula).to have_disabled_bottle

    temporary_install(formula) do |f|
      expect(f).to be_installed
    end
  end

  specify "Formula is not poured from bottle when compiler specified" do
    expect(ARGV.cc).to be nil

    cc_arg = "--cc=clang"
    ARGV << cc_arg

    temporary_install(TestballBottle.new) do |f|
      tab = Tab.for_formula(f)
      expect(tab.compiler).to eq("clang")
    end
  end

  specify "check installation sanity pinned dependency" do
    dep_name = "dependency"
    dep_path = CoreTap.new.formula_dir/"#{dep_name}.rb"
    dep_path.write <<-EOS.undent
      class #{Formulary.class_s(dep_name)} < Formula
        url "foo"
        version "0.2"
      end
    EOS

    Formulary::FORMULAE.delete(dep_path)
    dependency = Formulary.factory(dep_name)

    dependent = formula do
      url "foo"
      version "0.5"
      depends_on dependency.name.to_s
    end

    (dependency.prefix("0.1")/"bin"/"a").mkpath
    HOMEBREW_PINNED_KEGS.mkpath
    FileUtils.ln_s dependency.prefix("0.1"), HOMEBREW_PINNED_KEGS/dep_name

    dependency_keg = Keg.new(dependency.prefix("0.1"))
    dependency_keg.link

    expect(dependency_keg).to be_linked
    expect(dependency).to be_pinned

    fi = FormulaInstaller.new(dependent)

    expect {
      fi.check_install_sanity
    }.to raise_error(CannotInstallFormulaError)
  end

  describe "#install_requirement_formula?" do
    before do
      @requirement = Python3Requirement.new
      allow(@requirement).to receive(:satisfied?).and_return(satisfied?)
      allow(@requirement).to receive(:satisfied_by_formula?).and_return(satisfied_by_formula?)
      allow_any_instance_of(Dependency).to receive(:installed?).and_return(installed?)
      @dependent = formula do
        url "foo"
        version "0.1"
        depends_on :python3
      end
      @build = BuildOptions.new [], []
      @fi = FormulaInstaller.new(@dependent)
    end

    subject { @fi.install_requirement_formula?(@requirement, @dependent, @build) }

    context "it returns false when requirement is satisfied" do
      let(:satisfied?) { true }
      let(:satisfied_by_formula?) { false }
      let(:installed?) { false }
      it { is_expected.to be false }
    end

    context "it returns false when requirement is satisfied but default formula is installed" do
      let(:satisfied?) { true }
      let(:satisfied_by_formula?) { false }
      let(:installed?) { true }
      it { is_expected.to be false }
    end

    context "it returns true when requirement isn't satisfied" do
      let(:satisfied?) { false }
      let(:satisfied_by_formula?) { false }
      let(:installed?) { false }
      it { is_expected.to be true }
    end

    context "it returns true when requirement is satisfied by a formula" do
      let(:satisfied?) { true }
      let(:satisfied_by_formula?) { true }
      let(:installed?) { false }
      it { is_expected.to be true }
    end
  end
end