aboutsummaryrefslogtreecommitdiffstats
path: root/Library/Homebrew/test/compiler_selector_spec.rb
blob: 18efbfd424e79053fb3d0e733ecca9ebdf1b15c8 (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
require "compilers"
require "software_spec"

describe CompilerSelector do
  subject { described_class.new(software_spec, versions, compilers) }
  let(:compilers) { [:clang, :gcc, :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(: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 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)
      expect(subject.compiler).to eq(:gcc)
    end

    it "returns clang if it fails with gcc and llvm" do
      software_spec.fails_with(:gcc)
      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(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(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