spec/unit/builder_spec.rb (321 lines of code) (raw):
require "spec_helper"
module Omnibus
describe Builder do
let(:software) do
double(Software,
name: "chefdk",
install_dir: project_dir,
project_dir: project_dir)
end
let(:project_dir) { on_windows ? "C:/opscode/chefdk" : "/opt/chefdk" }
let(:on_windows) { false }
let(:msys_bash) { "C:\\opscode\\chefdk\\embedded\\msys\\1.0\\bin\\bash.exe" }
def run_build_command
subject.send(:build_commands)[0].run(subject)
end
subject { described_class.new(software) }
before do
allow(subject).to receive(:windows?).and_return(on_windows)
allow(subject).to receive(:windows_safe_path) do |*args|
path = File.join(*args)
path.gsub!(File::SEPARATOR, '\\') if on_windows # rubocop:disable Style/StringLiterals
end
end
describe "#command" do
it "is a DSL method" do
expect(subject).to have_exposed_method(:command)
end
end
describe "#workers" do
it "is a DSL method" do
expect(subject).to have_exposed_method(:workers)
end
end
describe "#go" do
it "is a DSL method" do
expect(subject).to have_exposed_method(:go)
end
end
describe "#ruby" do
it "is a DSL method" do
expect(subject).to have_exposed_method(:ruby)
end
end
describe "#gem" do
it "is a DSL method" do
expect(subject).to have_exposed_method(:gem)
end
end
describe "#bundle" do
it "is a DSL method" do
expect(subject).to have_exposed_method(:bundle)
end
end
describe "#appbundle" do
it "is a DSL method" do
expect(subject).to have_exposed_method(:appbundle)
end
end
describe "#block" do
it "is a DSL method" do
expect(subject).to have_exposed_method(:block)
end
end
describe "#erb" do
it "is a DSL method" do
expect(subject).to have_exposed_method(:erb)
end
end
describe "#mkdir" do
it "is a DSL method" do
expect(subject).to have_exposed_method(:mkdir)
end
end
describe "#touch" do
it "is a DSL method" do
expect(subject).to have_exposed_method(:touch)
end
end
describe "#delete" do
it "is a DSL method" do
expect(subject).to have_exposed_method(:delete)
end
end
describe "#strip" do
it "is a DSL method" do
expect(subject).to have_exposed_method(:strip)
end
end
describe "#copy" do
it "is a DSL method" do
expect(subject).to have_exposed_method(:copy)
end
end
describe "#move" do
it "is a DSL method" do
expect(subject).to have_exposed_method(:move)
end
end
describe "#link" do
it "is a DSL method" do
expect(subject).to have_exposed_method(:link)
end
end
describe "#sync" do
it "is a DSL method" do
expect(subject).to have_exposed_method(:sync)
end
end
describe "#update_config_guess" do
it "is a DSL method" do
expect(subject).to have_exposed_method(:update_config_guess)
end
end
describe "#windows_safe_path" do
it "is a DSL method" do
expect(subject).to have_exposed_method(:windows_safe_path)
end
end
describe "#project_dir" do
it "is a DSL method" do
expect(subject).to have_exposed_method(:project_dir)
end
end
describe "#install_dir" do
it "is a DSL method" do
expect(subject).to have_exposed_method(:install_dir)
end
end
describe "#overrides" do
it "is a DSL method" do
expect(subject).to have_exposed_method(:overrides)
end
end
describe "#make" do
before do
allow(subject).to receive(:command)
end
it "is a DSL method" do
expect(subject).to have_exposed_method(:make)
end
context "when :bin is present" do
it "uses the custom bin" do
expect(subject).to receive(:command)
.with("/path/to/make", { in_msys_bash: true })
subject.make(bin: "/path/to/make")
end
end
context "when gmake is present" do
before do
allow(Omnibus).to receive(:which)
.with("gmake")
.and_return("/bin/gmake")
end
it "uses gmake and sets MAKE=gmake" do
expect(subject).to receive(:command)
.with("gmake", { env: { "MAKE" => "gmake" }, in_msys_bash: true } )
subject.make
end
end
context "when gmake is not present" do
before do
allow(Omnibus).to receive(:which)
.and_return(nil)
end
it "uses make" do
expect(subject).to receive(:command)
.with("make", { in_msys_bash: true } )
subject.make
end
end
it "accepts 0 options" do
expect(subject).to receive(:command)
.with("make", { in_msys_bash: true } )
expect { subject.make }.to_not raise_error
end
it "accepts an additional command string" do
expect(subject).to receive(:command)
.with("make install", { in_msys_bash: true } )
expect { subject.make("install") }.to_not raise_error
end
it "persists given options" do
expect(subject).to receive(:command)
.with("make", { timeout: 3600, in_msys_bash: true } )
subject.make(timeout: 3600)
end
end
describe "#configure" do
before do
allow(subject).to receive(:command)
end
it "is a DSL method" do
expect(subject).to have_exposed_method(:configure)
end
context "on 64-bit windows" do
let(:on_windows) { true }
let(:windows_i386) { false }
before do
allow(subject).to receive(:windows_arch_i386?)
.and_return(windows_i386)
end
it "appends platform host to the options" do
expect(subject).to receive(:command)
.with("./configure --build=x86_64-w64-mingw32 --prefix=#{project_dir}/embedded", { in_msys_bash: true } )
subject.configure
end
end
context "on 32-bit windows" do
let(:on_windows) { true }
let(:windows_i386) { true }
before do
allow(subject).to receive(:windows_arch_i386?)
.and_return(windows_i386)
end
it "appends platform host to the options" do
expect(subject).to receive(:command)
.with("./configure --build=i686-w64-mingw32 --prefix=#{project_dir}/embedded", { in_msys_bash: true } )
subject.configure
end
end
context "when :bin is present" do
it "uses the custom bin" do
expect(subject).to receive(:command)
.with("/path/to/configure --prefix=#{project_dir}/embedded", { in_msys_bash: true } )
subject.configure(bin: "/path/to/configure")
end
end
context "when :prefix is present" do
it "emits non-empty prefix" do
expect(subject).to receive(:command)
.with("./configure --prefix=/some/prefix", { in_msys_bash: true } )
subject.configure(prefix: "/some/prefix")
end
it "omits prefix if empty" do
expect(subject).to receive(:command)
.with("./configure", { in_msys_bash: true } )
subject.configure(prefix: "")
end
end
it "accepts 0 options" do
expect(subject).to receive(:command)
.with("./configure --prefix=#{project_dir}/embedded", { in_msys_bash: true } )
expect { subject.configure }.to_not raise_error
end
it "accepts an additional command string" do
expect(subject).to receive(:command)
.with("./configure --prefix=#{project_dir}/embedded --myopt", { in_msys_bash: true } )
expect { subject.configure("--myopt") }.to_not raise_error
end
it "persists given options" do
expect(subject).to receive(:command)
.with("./configure --prefix=#{project_dir}/embedded", { timeout: 3600, in_msys_bash: true } )
subject.configure(timeout: 3600)
end
end
describe "#patch" do
before do
allow(subject).to receive(:find_file)
.with("config/patches", "good_patch")
.and_return(
[ ["#{project_dir}/patch_location1/good_patch", "#{project_dir}/patch_location2/good_patch"],
"#{project_dir}/patch_location2/good_patch" ]
)
end
it "is a DSL method" do
expect(subject).to have_exposed_method(:patch)
end
it "invokes patch with patch level 1 unless specified" do
expect { subject.patch(source: "good_patch") }.to_not raise_error
expect(subject).to receive(:shellout!)
.with("patch -p1 -i #{project_dir}/patch_location2/good_patch", { in_msys_bash: true } )
run_build_command
end
it "invokes patch with patch level provided" do
expect { subject.patch(source: "good_patch", plevel: 0) }.to_not raise_error
expect(subject).to receive(:shellout!)
.with("patch -p0 -i #{project_dir}/patch_location2/good_patch", { in_msys_bash: true } )
run_build_command
end
it "invokes patch differently if target is provided" do
expect { subject.patch(source: "good_patch", target: "target/path") }.to_not raise_error
expect(subject).to receive(:shellout!)
.with("cat #{project_dir}/patch_location2/good_patch | patch -p1 target/path", { in_msys_bash: true } )
run_build_command
end
it "persists other options" do
expect { subject.patch(source: "good_patch", timeout: 3600) }.to_not raise_error
expect(subject).to receive(:shellout!)
.with("patch -p1 -i #{project_dir}/patch_location2/good_patch", { timeout: 3600, in_msys_bash: true } )
run_build_command
end
end
describe "#shasum" do
let(:build_step) do
Proc.new do
block do
command("true")
end
end
end
let(:tmp_dir) { Dir.mktmpdir }
after { FileUtils.rmdir(tmp_dir) }
let(:software) do
double(Software,
name: "chefdk",
install_dir: tmp_dir,
project_dir: tmp_dir,
overridden?: false)
end
let(:before_build_shasum) do
b = described_class.new(software)
b.evaluate(&build_step)
b.shasum
end
it "returns the same value when called before or after the build" do
subject.evaluate(&build_step)
subject.build
expect(subject.shasum).to eq(before_build_shasum)
end
end
end
end