aboutsummaryrefslogtreecommitdiffstats
path: root/Library/Homebrew/test/cask/cli
diff options
context:
space:
mode:
authorMarkus Reiter2017-03-05 06:31:36 +0100
committerMarkus Reiter2017-03-05 23:08:14 +0100
commit9fc6c7b2be300ff35dc52d80f4dc38d36d52ddc2 (patch)
tree43e99a683329471c1dc965dcc92daccb57df7e8d /Library/Homebrew/test/cask/cli
parent67ec76d1492fbb03959a782a85c4fb985d6a5884 (diff)
downloadbrew-9fc6c7b2be300ff35dc52d80f4dc38d36d52ddc2.tar.bz2
Move Cask specs into `brew tests`.
Diffstat (limited to 'Library/Homebrew/test/cask/cli')
-rw-r--r--Library/Homebrew/test/cask/cli/audit_spec.rb59
-rw-r--r--Library/Homebrew/test/cask/cli/cat_spec.rb57
-rw-r--r--Library/Homebrew/test/cask/cli/cleanup_spec.rb93
-rw-r--r--Library/Homebrew/test/cask/cli/create_spec.rb98
-rw-r--r--Library/Homebrew/test/cask/cli/doctor_spec.rb15
-rw-r--r--Library/Homebrew/test/cask/cli/edit_spec.rb60
-rw-r--r--Library/Homebrew/test/cask/cli/fetch_spec.rb75
-rw-r--r--Library/Homebrew/test/cask/cli/home_spec.rb46
-rw-r--r--Library/Homebrew/test/cask/cli/info_spec.rb108
-rw-r--r--Library/Homebrew/test/cask/cli/install_spec.rb107
-rw-r--r--Library/Homebrew/test/cask/cli/list_spec.rb82
-rw-r--r--Library/Homebrew/test/cask/cli/options_spec.rb138
-rw-r--r--Library/Homebrew/test/cask/cli/reinstall_spec.rb22
-rw-r--r--Library/Homebrew/test/cask/cli/search_spec.rb59
-rw-r--r--Library/Homebrew/test/cask/cli/style_spec.rb235
-rw-r--r--Library/Homebrew/test/cask/cli/uninstall_spec.rb189
-rw-r--r--Library/Homebrew/test/cask/cli/version_spec.rb9
-rw-r--r--Library/Homebrew/test/cask/cli/zap_spec.rb73
18 files changed, 1525 insertions, 0 deletions
diff --git a/Library/Homebrew/test/cask/cli/audit_spec.rb b/Library/Homebrew/test/cask/cli/audit_spec.rb
new file mode 100644
index 000000000..2736e60c1
--- /dev/null
+++ b/Library/Homebrew/test/cask/cli/audit_spec.rb
@@ -0,0 +1,59 @@
+describe Hbc::CLI::Audit, :cask do
+ let(:auditor) { double }
+ let(:cask) { double }
+
+ describe "selection of Casks to audit" do
+ it "audits all Casks if no tokens are given" do
+ allow(Hbc).to receive(:all).and_return([cask, cask])
+
+ expect(auditor).to receive(:audit).twice
+
+ run_audit([], auditor)
+ end
+
+ it "audits specified Casks if tokens are given" do
+ cask_token = "nice-app"
+ expect(Hbc).to receive(:load).with(cask_token).and_return(cask)
+
+ expect(auditor).to receive(:audit).with(cask, audit_download: false, check_token_conflicts: false)
+
+ run_audit([cask_token], auditor)
+ end
+ end
+
+ describe "rules for downloading a Cask" do
+ it "does not download the Cask per default" do
+ allow(Hbc).to receive(:load).and_return(cask)
+ expect(auditor).to receive(:audit).with(cask, audit_download: false, check_token_conflicts: false)
+
+ run_audit(["casktoken"], auditor)
+ end
+
+ it "download a Cask if --download flag is set" do
+ allow(Hbc).to receive(:load).and_return(cask)
+ expect(auditor).to receive(:audit).with(cask, audit_download: true, check_token_conflicts: false)
+
+ run_audit(["casktoken", "--download"], auditor)
+ end
+ end
+
+ describe "rules for checking token conflicts" do
+ it "does not check for token conflicts per default" do
+ allow(Hbc).to receive(:load).and_return(cask)
+ expect(auditor).to receive(:audit).with(cask, audit_download: false, check_token_conflicts: false)
+
+ run_audit(["casktoken"], auditor)
+ end
+
+ it "checks for token conflicts if --token-conflicts flag is set" do
+ allow(Hbc).to receive(:load).and_return(cask)
+ expect(auditor).to receive(:audit).with(cask, audit_download: false, check_token_conflicts: true)
+
+ run_audit(["casktoken", "--token-conflicts"], auditor)
+ end
+ end
+
+ def run_audit(args, auditor)
+ Hbc::CLI::Audit.new(args, auditor).run
+ end
+end
diff --git a/Library/Homebrew/test/cask/cli/cat_spec.rb b/Library/Homebrew/test/cask/cli/cat_spec.rb
new file mode 100644
index 000000000..daf6fb960
--- /dev/null
+++ b/Library/Homebrew/test/cask/cli/cat_spec.rb
@@ -0,0 +1,57 @@
+describe Hbc::CLI::Cat, :cask do
+ describe "given a basic Cask" do
+ let(:expected_output) {
+ <<-EOS.undent
+ cask 'basic-cask' do
+ version '1.2.3'
+ sha256 '8c62a2b791cf5f0da6066a0a4b6e85f62949cd60975da062df44adf887f4370b'
+
+ url 'http://example.com/TestCask.dmg'
+ homepage 'http://example.com/'
+
+ app 'TestCask.app'
+ end
+ EOS
+ }
+
+ it "displays the Cask file content about the specified Cask" do
+ expect {
+ Hbc::CLI::Cat.run("basic-cask")
+ }.to output(expected_output).to_stdout
+ end
+
+ it "throws away additional Cask arguments and uses the first" do
+ expect {
+ Hbc::CLI::Cat.run("basic-cask", "local-caffeine")
+ }.to output(expected_output).to_stdout
+ end
+
+ it "throws away stray options" do
+ expect {
+ Hbc::CLI::Cat.run("--notavalidoption", "basic-cask")
+ }.to output(expected_output).to_stdout
+ end
+ end
+
+ it "raises an exception when the Cask does not exist" do
+ expect {
+ Hbc::CLI::Cat.run("notacask")
+ }.to raise_error(Hbc::CaskUnavailableError)
+ end
+
+ describe "when no Cask is specified" do
+ it "raises an exception" do
+ expect {
+ Hbc::CLI::Cat.run
+ }.to raise_error(Hbc::CaskUnspecifiedError)
+ end
+ end
+
+ describe "when no Cask is specified, but an invalid option" do
+ it "raises an exception" do
+ expect {
+ Hbc::CLI::Cat.run("--notavalidoption")
+ }.to raise_error(Hbc::CaskUnspecifiedError)
+ end
+ end
+end
diff --git a/Library/Homebrew/test/cask/cli/cleanup_spec.rb b/Library/Homebrew/test/cask/cli/cleanup_spec.rb
new file mode 100644
index 000000000..f8578e80d
--- /dev/null
+++ b/Library/Homebrew/test/cask/cli/cleanup_spec.rb
@@ -0,0 +1,93 @@
+describe Hbc::CLI::Cleanup, :cask do
+ let(:cache_location) { Pathname.new(Dir.mktmpdir).realpath }
+ let(:cleanup_outdated) { false }
+
+ subject { described_class.new(cache_location, cleanup_outdated) }
+
+ after do
+ cache_location.rmtree
+ end
+
+ describe "cleanup" do
+ it "removes cached downloads of given casks" do
+ cleaned_up_cached_download = "caffeine"
+
+ cached_downloads = [
+ cache_location.join("#{cleaned_up_cached_download}--latest.zip"),
+ cache_location.join("transmission--2.61.dmg"),
+ ]
+
+ cached_downloads.each(&FileUtils.method(:touch))
+
+ cleanup_size = Hbc::Utils.size_in_bytes(cached_downloads[0])
+
+ expect {
+ subject.cleanup(cleaned_up_cached_download)
+ }.to output(<<-EOS.undent).to_stdout
+ ==> Removing cached downloads for #{cleaned_up_cached_download}
+ #{cached_downloads[0]}
+ ==> This operation has freed approximately #{disk_usage_readable(cleanup_size)} of disk space.
+ EOS
+
+ expect(cached_downloads[0].exist?).to eq(false)
+ expect(cached_downloads[1].exist?).to eq(true)
+ end
+ end
+
+ describe "cleanup!" do
+ it "removes cached downloads" do
+ cached_download = cache_location.join("SomeDownload.dmg")
+ FileUtils.touch(cached_download)
+ cleanup_size = subject.disk_cleanup_size
+
+ expect {
+ subject.cleanup!
+ }.to output(<<-EOS.undent).to_stdout
+ ==> Removing cached downloads
+ #{cached_download}
+ ==> This operation has freed approximately #{disk_usage_readable(cleanup_size)} of disk space.
+ EOS
+
+ expect(cached_download.exist?).to eq(false)
+ end
+
+ # TODO: uncomment when unflaky.
+ # it "does not removed locked files" do
+ # cached_download = cache_location.join("SomeDownload.dmg")
+ # FileUtils.touch(cached_download)
+ # cleanup_size = subject.disk_cleanup_size
+ #
+ # File.new(cached_download).flock(File::LOCK_EX)
+ #
+ # expect(Hbc::Utils).to be_file_locked(cached_download)
+ #
+ # expect {
+ # subject.cleanup!
+ # }.to output(<<-EOS.undent).to_stdout
+ # ==> Removing cached downloads
+ # skipping: #{cached_download} is locked
+ # ==> This operation has freed approximately #{disk_usage_readable(cleanup_size)} of disk space.
+ # EOS
+ #
+ # expect(cached_download.exist?).to eq(true)
+ # end
+
+ context "when cleanup_outdated is specified" do
+ let(:cleanup_outdated) { true }
+
+ it "does not remove cache files newer than 10 days old" do
+ cached_download = cache_location.join("SomeNewDownload.dmg")
+ FileUtils.touch(cached_download)
+
+ expect {
+ subject.cleanup!
+ }.to output(<<-EOS.undent).to_stdout
+ ==> Removing cached downloads older than 10 days old
+ Nothing to do
+ EOS
+
+ expect(cached_download.exist?).to eq(true)
+ end
+ end
+ end
+end
diff --git a/Library/Homebrew/test/cask/cli/create_spec.rb b/Library/Homebrew/test/cask/cli/create_spec.rb
new file mode 100644
index 000000000..21eaeb656
--- /dev/null
+++ b/Library/Homebrew/test/cask/cli/create_spec.rb
@@ -0,0 +1,98 @@
+# monkeypatch for testing
+module Hbc
+ class CLI
+ class Create
+ def self.exec_editor(*command)
+ editor_commands << command
+ end
+
+ def self.reset!
+ @editor_commands = []
+ end
+
+ def self.editor_commands
+ @editor_commands ||= []
+ end
+ end
+ end
+end
+
+describe Hbc::CLI::Create, :cask do
+ before(:each) do
+ Hbc::CLI::Create.reset!
+ end
+
+ after(:each) do
+ %w[new-cask additional-cask another-cask yet-another-cask local-caff].each do |cask|
+ path = Hbc.path(cask)
+ path.delete if path.exist?
+ end
+ end
+
+ it "opens the editor for the specified Cask" do
+ Hbc::CLI::Create.run("new-cask")
+ expect(Hbc::CLI::Create.editor_commands).to eq [
+ [Hbc.path("new-cask")],
+ ]
+ end
+
+ it "drops a template down for the specified Cask" do
+ Hbc::CLI::Create.run("new-cask")
+ template = File.read(Hbc.path("new-cask"))
+ expect(template).to eq <<-EOS.undent
+ cask 'new-cask' do
+ version ''
+ sha256 ''
+
+ url 'https://'
+ name ''
+ homepage ''
+
+ app ''
+ end
+ EOS
+ end
+
+ it "throws away additional Cask arguments and uses the first" do
+ Hbc::CLI::Create.run("additional-cask", "another-cask")
+ expect(Hbc::CLI::Create.editor_commands).to eq [
+ [Hbc.path("additional-cask")],
+ ]
+ end
+
+ it "throws away stray options" do
+ Hbc::CLI::Create.run("--notavalidoption", "yet-another-cask")
+ expect(Hbc::CLI::Create.editor_commands).to eq [
+ [Hbc.path("yet-another-cask")],
+ ]
+ end
+
+ it "raises an exception when the Cask already exists" do
+ expect {
+ Hbc::CLI::Create.run("basic-cask")
+ }.to raise_error(Hbc::CaskAlreadyCreatedError)
+ end
+
+ it "allows creating Casks that are substrings of existing Casks" do
+ Hbc::CLI::Create.run("local-caff")
+ expect(Hbc::CLI::Create.editor_commands).to eq [
+ [Hbc.path("local-caff")],
+ ]
+ end
+
+ describe "when no Cask is specified" do
+ it "raises an exception" do
+ expect {
+ Hbc::CLI::Create.run
+ }.to raise_error(Hbc::CaskUnspecifiedError)
+ end
+ end
+
+ describe "when no Cask is specified, but an invalid option" do
+ it "raises an exception" do
+ expect {
+ Hbc::CLI::Create.run("--notavalidoption")
+ }.to raise_error(Hbc::CaskUnspecifiedError)
+ end
+ end
+end
diff --git a/Library/Homebrew/test/cask/cli/doctor_spec.rb b/Library/Homebrew/test/cask/cli/doctor_spec.rb
new file mode 100644
index 000000000..ff1cf5706
--- /dev/null
+++ b/Library/Homebrew/test/cask/cli/doctor_spec.rb
@@ -0,0 +1,15 @@
+require "hbc/version"
+
+describe Hbc::CLI::Doctor do
+ it "displays some nice info about the environment" do
+ expect {
+ Hbc::CLI::Doctor.run
+ }.to output(/\A==> Homebrew-Cask Version/).to_stdout
+ end
+
+ it "raises an exception when arguments are given" do
+ expect {
+ Hbc::CLI::Doctor.run("argument")
+ }.to raise_error(ArgumentError)
+ end
+end
diff --git a/Library/Homebrew/test/cask/cli/edit_spec.rb b/Library/Homebrew/test/cask/cli/edit_spec.rb
new file mode 100644
index 000000000..61970290b
--- /dev/null
+++ b/Library/Homebrew/test/cask/cli/edit_spec.rb
@@ -0,0 +1,60 @@
+# monkeypatch for testing
+module Hbc
+ class CLI
+ class Edit
+ def self.exec_editor(*command)
+ editor_commands << command
+ end
+
+ def self.reset!
+ @editor_commands = []
+ end
+
+ def self.editor_commands
+ @editor_commands ||= []
+ end
+ end
+ end
+end
+
+describe Hbc::CLI::Edit, :cask do
+ before(:each) do
+ Hbc::CLI::Edit.reset!
+ end
+
+ it "opens the editor for the specified Cask" do
+ Hbc::CLI::Edit.run("local-caffeine")
+ expect(Hbc::CLI::Edit.editor_commands).to eq [
+ [Hbc.path("local-caffeine")],
+ ]
+ end
+
+ it "throws away additional arguments and uses the first" do
+ Hbc::CLI::Edit.run("local-caffeine", "local-transmission")
+ expect(Hbc::CLI::Edit.editor_commands).to eq [
+ [Hbc.path("local-caffeine")],
+ ]
+ end
+
+ it "raises an exception when the Cask doesnt exist" do
+ expect {
+ Hbc::CLI::Edit.run("notacask")
+ }.to raise_error(Hbc::CaskUnavailableError)
+ end
+
+ describe "when no Cask is specified" do
+ it "raises an exception" do
+ expect {
+ Hbc::CLI::Edit.run
+ }.to raise_error(Hbc::CaskUnspecifiedError)
+ end
+ end
+
+ describe "when no Cask is specified, but an invalid option" do
+ it "raises an exception" do
+ expect {
+ Hbc::CLI::Edit.run("--notavalidoption")
+ }.to raise_error(Hbc::CaskUnspecifiedError)
+ end
+ end
+end
diff --git a/Library/Homebrew/test/cask/cli/fetch_spec.rb b/Library/Homebrew/test/cask/cli/fetch_spec.rb
new file mode 100644
index 000000000..1571c2a70
--- /dev/null
+++ b/Library/Homebrew/test/cask/cli/fetch_spec.rb
@@ -0,0 +1,75 @@
+describe Hbc::CLI::Fetch, :cask do
+ let(:local_transmission) {
+ Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-transmission.rb")
+ }
+
+ let(:local_caffeine) {
+ Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-caffeine.rb")
+ }
+
+ it "allows download the installer of a Cask" do
+ shutup do
+ Hbc::CLI::Fetch.run("local-transmission", "local-caffeine")
+ end
+ expect(Hbc::CurlDownloadStrategy.new(local_transmission).cached_location).to exist
+ expect(Hbc::CurlDownloadStrategy.new(local_caffeine).cached_location).to exist
+ end
+
+ it "prevents double fetch (without nuking existing installation)" do
+ download_stategy = Hbc::CurlDownloadStrategy.new(local_transmission)
+
+ shutup do
+ Hbc::Download.new(local_transmission).perform
+ end
+ old_ctime = File.stat(download_stategy.cached_location).ctime
+
+ shutup do
+ Hbc::CLI::Fetch.run("local-transmission")
+ end
+ new_ctime = File.stat(download_stategy.cached_location).ctime
+
+ expect(old_ctime.to_i).to eq(new_ctime.to_i)
+ end
+
+ it "allows double fetch with --force" do
+ shutup do
+ Hbc::Download.new(local_transmission).perform
+ end
+
+ download_stategy = Hbc::CurlDownloadStrategy.new(local_transmission)
+ old_ctime = File.stat(download_stategy.cached_location).ctime
+ sleep(1)
+
+ shutup do
+ Hbc::CLI::Fetch.run("local-transmission", "--force")
+ end
+ download_stategy = Hbc::CurlDownloadStrategy.new(local_transmission)
+ new_ctime = File.stat(download_stategy.cached_location).ctime
+
+ expect(new_ctime.to_i).to be > old_ctime.to_i
+ end
+
+ it "properly handles Casks that are not present" do
+ expect {
+ shutup do
+ Hbc::CLI::Fetch.run("notacask")
+ end
+ }.to raise_error(Hbc::CaskUnavailableError)
+ end
+
+ describe "when no Cask is specified" do
+ it "raises an exception" do
+ expect {
+ Hbc::CLI::Fetch.run
+ }.to raise_error(Hbc::CaskUnspecifiedError)
+ end
+ end
+
+ describe "when no Cask is specified, but an invalid option" do
+ it "raises an exception" do
+ expect {
+ Hbc::CLI::Fetch.run("--notavalidoption")
+ }.to raise_error(Hbc::CaskUnspecifiedError)
+ end
+ end
+end
diff --git a/Library/Homebrew/test/cask/cli/home_spec.rb b/Library/Homebrew/test/cask/cli/home_spec.rb
new file mode 100644
index 000000000..a5359f24f
--- /dev/null
+++ b/Library/Homebrew/test/cask/cli/home_spec.rb
@@ -0,0 +1,46 @@
+# monkeypatch for testing
+module Hbc
+ class CLI
+ class Home
+ def self.system(*command)
+ system_commands << command
+ end
+
+ def self.reset!
+ @system_commands = []
+ end
+
+ def self.system_commands
+ @system_commands ||= []
+ end
+ end
+ end
+end
+
+describe Hbc::CLI::Home, :cask do
+ before do
+ Hbc::CLI::Home.reset!
+ end
+
+ it "opens the homepage for the specified Cask" do
+ Hbc::CLI::Home.run("local-caffeine")
+ expect(Hbc::CLI::Home.system_commands).to eq [
+ ["/usr/bin/open", "--", "http://example.com/local-caffeine"],
+ ]
+ end
+
+ it "works for multiple Casks" do
+ Hbc::CLI::Home.run("local-caffeine", "local-transmission")
+ expect(Hbc::CLI::Home.system_commands).to eq [
+ ["/usr/bin/open", "--", "http://example.com/local-caffeine"],
+ ["/usr/bin/open", "--", "http://example.com/local-transmission"],
+ ]
+ end
+
+ it "opens the project page when no Cask is specified" do
+ Hbc::CLI::Home.run
+ expect(Hbc::CLI::Home.system_commands).to eq [
+ ["/usr/bin/open", "--", "http://caskroom.io/"],
+ ]
+ end
+end
diff --git a/Library/Homebrew/test/cask/cli/info_spec.rb b/Library/Homebrew/test/cask/cli/info_spec.rb
new file mode 100644
index 000000000..2f70a0b96
--- /dev/null
+++ b/Library/Homebrew/test/cask/cli/info_spec.rb
@@ -0,0 +1,108 @@
+describe Hbc::CLI::Info, :cask do
+ it "displays some nice info about the specified Cask" do
+ expect {
+ Hbc::CLI::Info.run("local-caffeine")
+ }.to output(<<-EOS.undent).to_stdout
+ local-caffeine: 1.2.3
+ http://example.com/local-caffeine
+ Not installed
+ From: https://github.com/caskroom/homebrew-spec/blob/master/Casks/local-caffeine.rb
+ ==> Name
+ None
+ ==> Artifacts
+ Caffeine.app (app)
+ EOS
+ end
+
+ describe "given multiple Casks" do
+ let(:expected_output) {
+ <<-EOS.undent
+ local-caffeine: 1.2.3
+ http://example.com/local-caffeine
+ Not installed
+ From: https://github.com/caskroom/homebrew-spec/blob/master/Casks/local-caffeine.rb
+ ==> Name
+ None
+ ==> Artifacts
+ Caffeine.app (app)
+ local-transmission: 2.61
+ http://example.com/local-transmission
+ Not installed
+ From: https://github.com/caskroom/homebrew-spec/blob/master/Casks/local-transmission.rb
+ ==> Name
+ None
+ ==> Artifacts
+ Transmission.app (app)
+ EOS
+ }
+
+ it "displays the info" do
+ expect {
+ Hbc::CLI::Info.run("local-caffeine", "local-transmission")
+ }.to output(expected_output).to_stdout
+ end
+
+ it "throws away stray options" do
+ expect {
+ Hbc::CLI::Info.run("--notavalidoption", "local-caffeine", "local-transmission")
+ }.to output(expected_output).to_stdout
+ end
+ end
+
+ it "should print caveats if the Cask provided one" do
+ expect {
+ Hbc::CLI::Info.run("with-caveats")
+ }.to output(<<-EOS.undent).to_stdout
+ with-caveats: 1.2.3
+ http://example.com/local-caffeine
+ Not installed
+ From: https://github.com/caskroom/homebrew-spec/blob/master/Casks/with-caveats.rb
+ ==> Name
+ None
+ ==> Artifacts
+ Caffeine.app (app)
+ ==> Caveats
+ Here are some things you might want to know.
+
+ Cask token: with-caveats
+
+ Custom text via puts followed by DSL-generated text:
+ To use with-caveats, you may need to add the /custom/path/bin directory
+ to your PATH environment variable, eg (for bash shell):
+
+ export PATH=/custom/path/bin:"$PATH"
+
+ EOS
+ end
+
+ it 'should not print "Caveats" section divider if the caveats block has no output' do
+ expect {
+ Hbc::CLI::Info.run("with-conditional-caveats")
+ }.to output(<<-EOS.undent).to_stdout
+ with-conditional-caveats: 1.2.3
+ http://example.com/local-caffeine
+ Not installed
+ From: https://github.com/caskroom/homebrew-spec/blob/master/Casks/with-conditional-caveats.rb
+ ==> Name
+ None
+ ==> Artifacts
+ Caffeine.app (app)
+ EOS
+ end
+
+ describe "when no Cask is specified" do
+ it "raises an exception" do
+ expect {
+ Hbc::CLI::Info.run
+ }.to raise_error(Hbc::CaskUnspecifiedError)
+ end
+ end
+
+ describe "when no Cask is specified, but an invalid option" do
+ it "raises an exception" do
+ expect {
+ Hbc::CLI::Info.run("--notavalidoption")
+ }.to raise_error(Hbc::CaskUnspecifiedError)
+ end
+ end
+end
diff --git a/Library/Homebrew/test/cask/cli/install_spec.rb b/Library/Homebrew/test/cask/cli/install_spec.rb
new file mode 100644
index 000000000..5a40017e8
--- /dev/null
+++ b/Library/Homebrew/test/cask/cli/install_spec.rb
@@ -0,0 +1,107 @@
+describe Hbc::CLI::Install, :cask do
+ it "allows staging and activation of multiple Casks at once" do
+ shutup do
+ Hbc::CLI::Install.run("local-transmission", "local-caffeine")
+ end
+
+ expect(Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-transmission.rb")).to be_installed
+ expect(Hbc.appdir.join("Transmission.app")).to be_a_directory
+ expect(Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-caffeine.rb")).to be_installed
+ expect(Hbc.appdir.join("Caffeine.app")).to be_a_directory
+ end
+
+ it "skips double install (without nuking existing installation)" do
+ shutup do
+ Hbc::CLI::Install.run("local-transmission")
+ end
+ shutup do
+ Hbc::CLI::Install.run("local-transmission")
+ end
+ expect(Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-transmission.rb")).to be_installed
+ end
+
+ it "prints a warning message on double install" do
+ shutup do
+ Hbc::CLI::Install.run("local-transmission")
+ end
+
+ expect {
+ Hbc::CLI::Install.run("local-transmission", "")
+ }.to output(/Warning: A Cask for local-transmission is already installed./).to_stderr
+ end
+
+ it "allows double install with --force" do
+ shutup do
+ Hbc::CLI::Install.run("local-transmission")
+ end
+
+ expect {
+ expect {
+ Hbc::CLI::Install.run("local-transmission", "--force")
+ }.to output(/It seems there is already an App at.*overwriting\./).to_stderr
+ }.to output(/local-transmission was successfully installed!/).to_stdout
+ end
+
+ it "skips dependencies with --skip-cask-deps" do
+ shutup do
+ Hbc::CLI::Install.run("with-depends-on-cask-multiple", "--skip-cask-deps")
+ end
+ expect(Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-depends-on-cask-multiple.rb")).to be_installed
+ expect(Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-caffeine.rb")).not_to be_installed
+ expect(Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-transmission.rb")).not_to be_installed
+ end
+
+ it "properly handles Casks that are not present" do
+ expect {
+ shutup do
+ Hbc::CLI::Install.run("notacask")
+ end
+ }.to raise_error(Hbc::CaskError)
+ end
+
+ it "returns a suggestion for a misspelled Cask" do
+ expect {
+ begin
+ Hbc::CLI::Install.run("localcaffeine")
+ rescue Hbc::CaskError
+ nil
+ end
+ }.to output(/No available Cask for localcaffeine\. Did you mean:\nlocal-caffeine/).to_stderr
+ end
+
+ it "returns multiple suggestions for a Cask fragment" do
+ expect {
+ begin
+ Hbc::CLI::Install.run("local-caf")
+ rescue Hbc::CaskError
+ nil
+ end
+ }.to output(/No available Cask for local-caf\. Did you mean one of:\nlocal-caffeine/).to_stderr
+ end
+
+ describe "when no Cask is specified" do
+ with_options = lambda do |options|
+ it "raises an exception" do
+ expect {
+ Hbc::CLI::Install.run(*options)
+ }.to raise_error(Hbc::CaskUnspecifiedError)
+ end
+ end
+
+ describe "without options" do
+ with_options.call([])
+ end
+
+ describe "with --force" do
+ with_options.call(["--force"])
+ end
+
+ describe "with --skip-cask-deps" do
+ with_options.call(["--skip-cask-deps"])
+ end
+
+ describe "with an invalid option" do
+ with_options.call(["--notavalidoption"])
+ end
+ end
+end
diff --git a/Library/Homebrew/test/cask/cli/list_spec.rb b/Library/Homebrew/test/cask/cli/list_spec.rb
new file mode 100644
index 000000000..e367e9588
--- /dev/null
+++ b/Library/Homebrew/test/cask/cli/list_spec.rb
@@ -0,0 +1,82 @@
+describe Hbc::CLI::List, :cask do
+ it "lists the installed Casks in a pretty fashion" do
+ casks = %w[local-caffeine local-transmission].map { |c| Hbc.load(c) }
+
+ casks.each do |c|
+ InstallHelper.install_with_caskfile(c)
+ end
+
+ expect {
+ Hbc::CLI::List.run
+ }.to output(<<-EOS.undent).to_stdout
+ local-caffeine
+ local-transmission
+ EOS
+ end
+
+ describe "lists versions" do
+ let(:casks) { ["local-caffeine", "local-transmission"] }
+ let(:expected_output) {
+ <<-EOS.undent
+ local-caffeine 1.2.3
+ local-transmission 2.61
+ EOS
+ }
+
+ before(:each) do
+ casks.map(&Hbc.method(:load)).each(&InstallHelper.method(:install_with_caskfile))
+ end
+
+ it "of all installed Casks" do
+ expect {
+ Hbc::CLI::List.run("--versions")
+ }.to output(expected_output).to_stdout
+ end
+
+ it "of given Casks" do
+ expect {
+ Hbc::CLI::List.run("--versions", "local-caffeine", "local-transmission")
+ }.to output(expected_output).to_stdout
+ end
+ end
+
+ describe "when Casks have been renamed" do
+ let(:caskroom_path) { Hbc.caskroom.join("ive-been-renamed") }
+ let(:staged_path) { caskroom_path.join("latest") }
+
+ before do
+ staged_path.mkpath
+ end
+
+ it "lists installed Casks without backing ruby files (due to renames or otherwise)" do
+ expect {
+ Hbc::CLI::List.run
+ }.to output(<<-EOS.undent).to_stdout
+ ive-been-renamed (!)
+ EOS
+ end
+ end
+
+ describe "given a set of installed Casks" do
+ let(:caffeine) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-caffeine.rb") }
+ let(:transmission) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-transmission.rb") }
+ let(:casks) { [caffeine, transmission] }
+
+ it "lists the installed files for those Casks" do
+ casks.each(&InstallHelper.method(:install_without_artifacts_with_caskfile))
+
+ shutup do
+ Hbc::Artifact::App.new(transmission).install_phase
+ end
+
+ expect {
+ Hbc::CLI::List.run("local-transmission", "local-caffeine")
+ }.to output(<<-EOS.undent).to_stdout
+ ==> Apps
+ #{Hbc.appdir.join("Transmission.app")} (#{Hbc.appdir.join("Transmission.app").abv})
+ ==> Apps
+ Missing App: #{Hbc.appdir.join("Caffeine.app")}
+ EOS
+ end
+ end
+end
diff --git a/Library/Homebrew/test/cask/cli/options_spec.rb b/Library/Homebrew/test/cask/cli/options_spec.rb
new file mode 100644
index 000000000..86933e27e
--- /dev/null
+++ b/Library/Homebrew/test/cask/cli/options_spec.rb
@@ -0,0 +1,138 @@
+describe Hbc::CLI, :cask do
+ it "supports setting the appdir" do
+ Hbc::CLI.process_options %w[help --appdir=/some/path/foo]
+
+ expect(Hbc.appdir).to eq(Pathname.new("/some/path/foo"))
+ end
+
+ it "supports setting the appdir from ENV" do
+ ENV["HOMEBREW_CASK_OPTS"] = "--appdir=/some/path/bar"
+
+ Hbc::CLI.process_options %w[help]
+
+ expect(Hbc.appdir).to eq(Pathname.new("/some/path/bar"))
+ end
+
+ it "supports setting the prefpanedir" do
+ Hbc::CLI.process_options %w[help --prefpanedir=/some/path/foo]
+
+ expect(Hbc.prefpanedir).to eq(Pathname.new("/some/path/foo"))
+ end
+
+ it "supports setting the prefpanedir from ENV" do
+ ENV["HOMEBREW_CASK_OPTS"] = "--prefpanedir=/some/path/bar"
+
+ Hbc::CLI.process_options %w[help]
+
+ expect(Hbc.prefpanedir).to eq(Pathname.new("/some/path/bar"))
+ end
+
+ it "supports setting the qlplugindir" do
+ Hbc::CLI.process_options %w[help --qlplugindir=/some/path/foo]
+
+ expect(Hbc.qlplugindir).to eq(Pathname.new("/some/path/foo"))
+ end
+
+ it "supports setting the qlplugindir from ENV" do
+ ENV["HOMEBREW_CASK_OPTS"] = "--qlplugindir=/some/path/bar"
+
+ Hbc::CLI.process_options %w[help]
+
+ expect(Hbc.qlplugindir).to eq(Pathname.new("/some/path/bar"))
+ end
+
+ it "supports setting the colorpickerdir" do
+ Hbc::CLI.process_options %w[help --colorpickerdir=/some/path/foo]
+
+ expect(Hbc.colorpickerdir).to eq(Pathname.new("/some/path/foo"))
+ end
+
+ it "supports setting the colorpickerdir from ENV" do
+ ENV["HOMEBREW_CASK_OPTS"] = "--colorpickerdir=/some/path/bar"
+
+ Hbc::CLI.process_options %w[help]
+
+ expect(Hbc.colorpickerdir).to eq(Pathname.new("/some/path/bar"))
+ end
+
+ it "supports setting the dictionarydir" do
+ Hbc::CLI.process_options %w[help --dictionarydir=/some/path/foo]
+
+ expect(Hbc.dictionarydir).to eq(Pathname.new("/some/path/foo"))
+ end
+
+ it "supports setting the dictionarydir from ENV" do
+ ENV["HOMEBREW_CASK_OPTS"] = "--dictionarydir=/some/path/bar"
+
+ Hbc::CLI.process_options %w[help]
+
+ expect(Hbc.dictionarydir).to eq(Pathname.new("/some/path/bar"))
+ end
+
+ it "supports setting the fontdir" do
+ Hbc::CLI.process_options %w[help --fontdir=/some/path/foo]
+
+ expect(Hbc.fontdir).to eq(Pathname.new("/some/path/foo"))
+ end
+
+ it "supports setting the fontdir from ENV" do
+ ENV["HOMEBREW_CASK_OPTS"] = "--fontdir=/some/path/bar"
+
+ Hbc::CLI.process_options %w[help]
+
+ expect(Hbc.fontdir).to eq(Pathname.new("/some/path/bar"))
+ end
+
+ it "supports setting the servicedir" do
+ Hbc::CLI.process_options %w[help --servicedir=/some/path/foo]
+
+ expect(Hbc.servicedir).to eq(Pathname.new("/some/path/foo"))
+ end
+
+ it "supports setting the servicedir from ENV" do
+ ENV["HOMEBREW_CASK_OPTS"] = "--servicedir=/some/path/bar"
+
+ Hbc::CLI.process_options %w[help]
+
+ expect(Hbc.servicedir).to eq(Pathname.new("/some/path/bar"))
+ end
+
+ it "allows additional options to be passed through" do
+ rest = Hbc::CLI.process_options %w[edit foo --create --appdir=/some/path/qux]
+
+ expect(Hbc.appdir).to eq(Pathname.new("/some/path/qux"))
+ expect(rest).to eq(%w[edit foo --create])
+ end
+
+ describe "when a mandatory argument is missing" do
+ it "shows a user-friendly error message" do
+ expect {
+ Hbc::CLI.process_options %w[install -f]
+ }.to raise_error(Hbc::CaskError)
+ end
+ end
+
+ describe "given an ambiguous option" do
+ it "shows a user-friendly error message" do
+ expect {
+ Hbc::CLI.process_options %w[edit -c]
+ }.to raise_error(Hbc::CaskError)
+ end
+ end
+
+ describe "--debug" do
+ it "sets the Cask debug method to true" do
+ Hbc::CLI.process_options %w[help --debug]
+ expect(Hbc.debug).to be true
+ Hbc.debug = false
+ end
+ end
+
+ describe "--help" do
+ it "sets the Cask help method to true" do
+ Hbc::CLI.process_options %w[foo --help]
+ expect(Hbc.help).to be true
+ Hbc.help = false
+ end
+ end
+end
diff --git a/Library/Homebrew/test/cask/cli/reinstall_spec.rb b/Library/Homebrew/test/cask/cli/reinstall_spec.rb
new file mode 100644
index 000000000..e573a3470
--- /dev/null
+++ b/Library/Homebrew/test/cask/cli/reinstall_spec.rb
@@ -0,0 +1,22 @@
+describe Hbc::CLI::Reinstall, :cask do
+ it "allows reinstalling a Cask" do
+ shutup do
+ Hbc::CLI::Install.run("local-transmission")
+ end
+ expect(Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-transmission.rb")).to be_installed
+
+ shutup do
+ Hbc::CLI::Reinstall.run("local-transmission")
+ end
+ expect(Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-transmission.rb")).to be_installed
+ end
+
+ it "allows reinstalling a non installed Cask" do
+ expect(Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-transmission.rb")).not_to be_installed
+
+ shutup do
+ Hbc::CLI::Reinstall.run("local-transmission")
+ end
+ expect(Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-transmission.rb")).to be_installed
+ end
+end
diff --git a/Library/Homebrew/test/cask/cli/search_spec.rb b/Library/Homebrew/test/cask/cli/search_spec.rb
new file mode 100644
index 000000000..0bcff809a
--- /dev/null
+++ b/Library/Homebrew/test/cask/cli/search_spec.rb
@@ -0,0 +1,59 @@
+describe Hbc::CLI::Search, :cask do
+ it "lists the available Casks that match the search term" do
+ expect {
+ Hbc::CLI::Search.run("local")
+ }.to output(<<-EOS.undent).to_stdout
+ ==> Partial matches
+ local-caffeine
+ local-transmission
+ EOS
+ end
+
+ it "shows that there are no Casks matching a search term that did not result in anything" do
+ expect {
+ Hbc::CLI::Search.run("foo-bar-baz")
+ }.to output("No Cask found for \"foo-bar-baz\".\n").to_stdout
+ end
+
+ it "lists all available Casks with no search term" do
+ expect {
+ Hbc::CLI::Search.run
+ }.to output(/local-caffeine/).to_stdout
+ end
+
+ it "ignores hyphens in search terms" do
+ expect {
+ Hbc::CLI::Search.run("lo-cal-caffeine")
+ }.to output(/local-caffeine/).to_stdout
+ end
+
+ it "ignores hyphens in Cask tokens" do
+ expect {
+ Hbc::CLI::Search.run("localcaffeine")
+ }.to output(/local-caffeine/).to_stdout
+ end
+
+ it "accepts multiple arguments" do
+ expect {
+ Hbc::CLI::Search.run("local caffeine")
+ }.to output(/local-caffeine/).to_stdout
+ end
+
+ it "accepts a regexp argument" do
+ expect {
+ Hbc::CLI::Search.run("/^local-c[a-z]ffeine$/")
+ }.to output("==> Regexp matches\nlocal-caffeine\n").to_stdout
+ end
+
+ it "Returns both exact and partial matches" do
+ expect {
+ Hbc::CLI::Search.run("test-opera")
+ }.to output(/^==> Exact match\ntest-opera\n==> Partial matches\ntest-opera-mail/).to_stdout
+ end
+
+ it "does not search the Tap name" do
+ expect {
+ Hbc::CLI::Search.run("caskroom")
+ }.to output(/^No Cask found for "caskroom"\.\n/).to_stdout
+ end
+end
diff --git a/Library/Homebrew/test/cask/cli/style_spec.rb b/Library/Homebrew/test/cask/cli/style_spec.rb
new file mode 100644
index 000000000..106bfbb44
--- /dev/null
+++ b/Library/Homebrew/test/cask/cli/style_spec.rb
@@ -0,0 +1,235 @@
+require "English"
+require "open3"
+require "rubygems"
+
+describe Hbc::CLI::Style do
+ let(:args) { [] }
+ let(:cli) { described_class.new(args) }
+
+ around do |example|
+ shutup { example.run }
+ end
+
+ describe ".run" do
+ subject { described_class.run(args) }
+
+ before do
+ allow(described_class).to receive(:new).and_return(cli)
+ allow(cli).to receive(:run).and_return(retval)
+ end
+
+ context "when rubocop succeeds" do
+ let(:retval) { true }
+
+ it "exits successfully" do
+ subject
+ end
+ end
+
+ context "when rubocop fails" do
+ let(:retval) { false }
+
+ it "raises an exception" do
+ expect { subject }.to raise_error(Hbc::CaskError)
+ end
+ end
+ end
+
+ describe "#run" do
+ subject { cli.run }
+
+ before do
+ allow(cli).to receive_messages(install_rubocop: nil,
+ system: nil,
+ rubocop_args: nil,
+ cask_paths: nil)
+ allow($CHILD_STATUS).to receive(:success?).and_return(success)
+ end
+
+ context "when rubocop succeeds" do
+ let(:success) { true }
+ it { is_expected.to be_truthy }
+ end
+
+ context "when rubocop fails" do
+ let(:success) { false }
+ it { is_expected.to be_falsey }
+ end
+ end
+
+ describe "#install_rubocop" do
+ subject { cli.install_rubocop }
+
+ context "when installation succeeds" do
+ before do
+ allow(Homebrew).to receive(:install_gem_setup_path!)
+ end
+
+ it "exits successfully" do
+ expect { subject }.not_to raise_error
+ end
+ end
+
+ context "when installation fails" do
+ before do
+ allow(Homebrew).to receive(:install_gem_setup_path!).and_raise(SystemExit)
+ end
+
+ it "raises an error" do
+ expect { subject }.to raise_error(Hbc::CaskError)
+ end
+ end
+
+ context "version" do
+ it "matches `HOMEBREW_RUBOCOP_VERSION`" do
+ stdout, status = Open3.capture2("gem", "dependency", "rubocop-cask", "--version", HOMEBREW_RUBOCOP_CASK_VERSION, "--pipe", "--remote")
+
+ expect(status).to be_a_success
+
+ requirement = Gem::Requirement.new(stdout.scan(/rubocop --version '(.*)'/).flatten.first)
+ version = Gem::Version.new(HOMEBREW_RUBOCOP_VERSION)
+
+ expect(requirement).not_to be_none
+ expect(requirement).to be_satisfied_by(version)
+ end
+ end
+ end
+
+ describe "#cask_paths" do
+ subject { cli.cask_paths }
+
+ before do
+ allow(cli).to receive(:cask_tokens).and_return(tokens)
+ end
+
+ context "when no cask tokens are given" do
+ let(:tokens) { [] }
+
+ before do
+ allow(Hbc).to receive(:all_tapped_cask_dirs).and_return(%w[Casks MoreCasks])
+ end
+
+ it { is_expected.to eq(%w[Casks MoreCasks]) }
+ end
+
+ context "when at least one cask token is a path that exists" do
+ let(:tokens) { ["adium", "Casks/dropbox.rb"] }
+ before do
+ allow(File).to receive(:exist?).and_return(false, true)
+ end
+
+ it "treats all tokens as paths" do
+ expect(subject).to eq(tokens)
+ end
+ end
+
+ context "when no cask tokens are paths that exist" do
+ let(:tokens) { %w[adium dropbox] }
+ before do
+ allow(File).to receive(:exist?).and_return(false)
+ end
+
+ it "tries to find paths for all tokens" do
+ expect(Hbc).to receive(:path).twice
+ subject
+ end
+ end
+ end
+
+ describe "#cask_tokens" do
+ subject { cli.cask_tokens }
+
+ context "when no args are given" do
+ let(:args) { [] }
+ it { is_expected.to be_empty }
+ end
+
+ context "when only flags are given" do
+ let(:args) { ["--fix"] }
+ it { is_expected.to be_empty }
+ end
+
+ context "when only empty args are given" do
+ let(:args) { ["", ""] }
+ it { is_expected.to be_empty }
+ end
+
+ context "when a cask token is given" do
+ let(:args) { ["adium"] }
+ it { is_expected.to eq(["adium"]) }
+ end
+
+ context "when multiple cask tokens are given" do
+ let(:args) { %w[adium dropbox] }
+ it { is_expected.to eq(%w[adium dropbox]) }
+ end
+
+ context "when cask tokens are given with flags" do
+ let(:args) { ["adium", "dropbox", "--fix"] }
+ it { is_expected.to eq(%w[adium dropbox]) }
+ end
+ end
+
+ describe "#rubocop_args" do
+ subject { cli.rubocop_args }
+
+ before do
+ allow(cli).to receive(:fix?).and_return(fix)
+ end
+
+ context "when fix? is true" do
+ let(:fix) { true }
+ it { is_expected.to include("--auto-correct") }
+ end
+
+ context "when fix? is false" do
+ let(:fix) { false }
+ it { is_expected.not_to include("--auto-correct") }
+ end
+ end
+
+ describe "#default_args" do
+ subject { cli.default_args }
+
+ it { is_expected.to include("--require", "rubocop-cask", "--format", "simple", "--force-exclusion") }
+ end
+
+ describe "#autocorrect_args" do
+ subject { cli.autocorrect_args }
+ let(:default_args) { ["--format", "simple"] }
+
+ it "should add --auto-correct to default args" do
+ allow(cli).to receive(:default_args).and_return(default_args)
+ expect(subject).to include("--auto-correct", *default_args)
+ end
+ end
+
+ describe "#fix?" do
+ subject { cli.fix? }
+
+ context "when --fix is passed as an argument" do
+ let(:args) { ["adium", "--fix"] }
+ it { is_expected.to be_truthy }
+ end
+
+ context "when --correct is passed as an argument" do
+ let(:args) { ["adium", "--correct"] }
+ it { is_expected.to be_truthy }
+ end
+
+ context "when --auto-correct is passed as an argument" do
+ let(:args) { ["adium", "--auto-correct"] }
+ it { is_expected.to be_truthy }
+ end
+
+ context "when --auto-correct is misspelled as --autocorrect" do
+ let(:args) { ["adium", "--autocorrect"] }
+ it { is_expected.to be_truthy }
+ end
+
+ context "when no flag equivalent to --fix is passed as an argument" do
+ let(:args) { ["adium"] }
+ it { is_expected.to be_falsey }
+ end
+ end
+end
diff --git a/Library/Homebrew/test/cask/cli/uninstall_spec.rb b/Library/Homebrew/test/cask/cli/uninstall_spec.rb
new file mode 100644
index 000000000..cbfb3e237
--- /dev/null
+++ b/Library/Homebrew/test/cask/cli/uninstall_spec.rb
@@ -0,0 +1,189 @@
+describe Hbc::CLI::Uninstall, :cask do
+ it "shows an error when a bad Cask is provided" do
+ expect {
+ Hbc::CLI::Uninstall.run("notacask")
+ }.to raise_error(Hbc::CaskUnavailableError)
+ end
+
+ it "shows an error when a Cask is provided that's not installed" do
+ expect {
+ Hbc::CLI::Uninstall.run("local-caffeine")
+ }.to raise_error(Hbc::CaskNotInstalledError)
+ end
+
+ it "tries anyway on a non-present Cask when --force is given" do
+ expect {
+ Hbc::CLI::Uninstall.run("local-caffeine", "--force")
+ }.not_to raise_error
+ end
+
+ it "can uninstall and unlink multiple Casks at once" do
+ caffeine = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-caffeine.rb")
+ transmission = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-transmission.rb")
+
+ shutup do
+ Hbc::Installer.new(caffeine).install
+ Hbc::Installer.new(transmission).install
+ end
+
+ expect(caffeine).to be_installed
+ expect(transmission).to be_installed
+
+ shutup do
+ Hbc::CLI::Uninstall.run("local-caffeine", "local-transmission")
+ end
+
+ expect(caffeine).not_to be_installed
+ expect(Hbc.appdir.join("Transmission.app")).not_to exist
+ expect(transmission).not_to be_installed
+ expect(Hbc.appdir.join("Caffeine.app")).not_to exist
+ end
+
+ it "calls `uninstall` before removing artifacts" do
+ cask = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-uninstall-script-app.rb")
+
+ shutup do
+ Hbc::Installer.new(cask).install
+ end
+
+ expect(cask).to be_installed
+
+ expect {
+ shutup do
+ Hbc::CLI::Uninstall.run("with-uninstall-script-app")
+ end
+ }.not_to raise_error
+
+ expect(cask).not_to be_installed
+ expect(Hbc.appdir.join("MyFancyApp.app")).not_to exist
+ end
+
+ it "can uninstall Casks when the uninstall script is missing, but only when using `--force`" do
+ cask = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-uninstall-script-app.rb")
+
+ shutup do
+ Hbc::Installer.new(cask).install
+ end
+
+ expect(cask).to be_installed
+
+ Hbc.appdir.join("MyFancyApp.app").rmtree
+
+ expect {
+ shutup do
+ Hbc::CLI::Uninstall.run("with-uninstall-script-app")
+ end
+ }.to raise_error(Hbc::CaskError, /does not exist/)
+
+ expect(cask).to be_installed
+
+ expect {
+ shutup do
+ Hbc::CLI::Uninstall.run("with-uninstall-script-app", "--force")
+ end
+ }.not_to raise_error
+
+ expect(cask).not_to be_installed
+ end
+
+ describe "when multiple versions of a cask are installed" do
+ let(:token) { "versioned-cask" }
+ let(:first_installed_version) { "1.2.3" }
+ let(:last_installed_version) { "4.5.6" }
+ let(:timestamped_versions) {
+ [
+ [first_installed_version, "123000"],
+ [last_installed_version, "456000"],
+ ]
+ }
+ let(:caskroom_path) { Hbc.caskroom.join(token).tap(&:mkpath) }
+
+ before(:each) do
+ timestamped_versions.each do |timestamped_version|
+ caskroom_path.join(".metadata", *timestamped_version, "Casks").tap(&:mkpath)
+ .join("#{token}.rb").open("w") do |caskfile|
+ caskfile.puts <<-EOS.undent
+ cask '#{token}' do
+ version '#{timestamped_version[0]}'
+ end
+ EOS
+ end
+ caskroom_path.join(timestamped_version[0]).mkpath
+ end
+ end
+
+ it "uninstalls one version at a time" do
+ shutup do
+ Hbc::CLI::Uninstall.run("versioned-cask")
+ end
+
+ expect(caskroom_path.join(first_installed_version)).to exist
+ expect(caskroom_path.join(last_installed_version)).not_to exist
+ expect(caskroom_path).to exist
+
+ shutup do
+ Hbc::CLI::Uninstall.run("versioned-cask")
+ end
+
+ expect(caskroom_path.join(first_installed_version)).not_to exist
+ expect(caskroom_path).not_to exist
+ end
+
+ it "displays a message when versions remain installed" do
+ expect {
+ expect {
+ Hbc::CLI::Uninstall.run("versioned-cask")
+ }.not_to output.to_stderr
+ }.to output(/#{token} #{first_installed_version} is still installed./).to_stdout
+ end
+ end
+
+ describe "when Casks in Taps have been renamed or removed" do
+ let(:app) { Hbc.appdir.join("ive-been-renamed.app") }
+ let(:caskroom_path) { Hbc.caskroom.join("ive-been-renamed").tap(&:mkpath) }
+ let(:saved_caskfile) { caskroom_path.join(".metadata", "latest", "timestamp", "Casks").join("ive-been-renamed.rb") }
+
+ before do
+ app.tap(&:mkpath)
+ .join("Contents").tap(&:mkpath)
+ .join("Info.plist").tap(&FileUtils.method(:touch))
+
+ caskroom_path.mkpath
+
+ saved_caskfile.dirname.mkpath
+
+ IO.write saved_caskfile, <<-EOS.undent
+ cask 'ive-been-renamed' do
+ version :latest
+
+ app 'ive-been-renamed.app'
+ end
+ EOS
+ end
+
+ it "can still uninstall those Casks" do
+ shutup do
+ Hbc::CLI::Uninstall.run("ive-been-renamed")
+ end
+
+ expect(app).not_to exist
+ expect(caskroom_path).not_to exist
+ end
+ end
+
+ describe "when no Cask is specified" do
+ it "raises an exception" do
+ expect {
+ Hbc::CLI::Uninstall.run
+ }.to raise_error(Hbc::CaskUnspecifiedError)
+ end
+ end
+
+ describe "when no Cask is specified, but an invalid option" do
+ it "raises an exception" do
+ expect {
+ Hbc::CLI::Uninstall.run("--notavalidoption")
+ }.to raise_error(Hbc::CaskUnspecifiedError)
+ end
+ end
+end
diff --git a/Library/Homebrew/test/cask/cli/version_spec.rb b/Library/Homebrew/test/cask/cli/version_spec.rb
new file mode 100644
index 000000000..2091496fc
--- /dev/null
+++ b/Library/Homebrew/test/cask/cli/version_spec.rb
@@ -0,0 +1,9 @@
+describe "brew cask --version", :cask do
+ it "respects the --version argument" do
+ expect {
+ expect {
+ Hbc::CLI::NullCommand.new("--version").run
+ }.not_to output.to_stderr
+ }.to output(Hbc.full_version).to_stdout
+ end
+end
diff --git a/Library/Homebrew/test/cask/cli/zap_spec.rb b/Library/Homebrew/test/cask/cli/zap_spec.rb
new file mode 100644
index 000000000..0f3d024b5
--- /dev/null
+++ b/Library/Homebrew/test/cask/cli/zap_spec.rb
@@ -0,0 +1,73 @@
+describe Hbc::CLI::Zap, :cask do
+ it "shows an error when a bad Cask is provided" do
+ expect {
+ Hbc::CLI::Zap.run("notacask")
+ }.to raise_error(Hbc::CaskUnavailableError)
+ end
+
+ it "can zap and unlink multiple Casks at once" do
+ caffeine = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-caffeine.rb")
+ transmission = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-transmission.rb")
+
+ shutup do
+ Hbc::Installer.new(caffeine).install
+ Hbc::Installer.new(transmission).install
+ end
+
+ expect(caffeine).to be_installed
+ expect(transmission).to be_installed
+
+ shutup do
+ Hbc::CLI::Zap.run("--notavalidoption",
+ "local-caffeine", "local-transmission")
+ end
+
+ expect(caffeine).not_to be_installed
+ expect(Hbc.appdir.join("Caffeine.app")).not_to be_a_symlink
+ expect(transmission).not_to be_installed
+ expect(Hbc.appdir.join("Transmission.app")).not_to be_a_symlink
+ end
+
+ # TODO: Explicit test that both zap and uninstall directives get dispatched.
+ # The above tests that implicitly.
+ #
+ # it "dispatches both uninstall and zap stanzas" do
+ # with_zap = Hbc.load('with-zap')
+ #
+ # shutup do
+ # Hbc::Installer.new(with_zap).install
+ # end
+ #
+ # with_zap.must_be :installed?
+ #
+ # Hbc::FakeSystemCommand.stubs_command(['/usr/bin/sudo', '-E', '--', '/usr/bin/osascript', '-e', 'tell application "System Events" to count processes whose bundle identifier is "my.fancy.package.app"'], '1')
+ # Hbc::FakeSystemCommand.stubs_command(['/usr/bin/sudo', '-E', '--', '/usr/bin/osascript', '-e', 'tell application id "my.fancy.package.app" to quit'])
+ # Hbc::FakeSystemCommand.stubs_command(['/usr/bin/sudo', '-E', '--', '/usr/bin/osascript', '-e', 'tell application "System Events" to count processes whose bundle identifier is "my.fancy.package.app.from.uninstall"'], '1')
+ # Hbc::FakeSystemCommand.stubs_command(['/usr/bin/sudo', '-E', '--', '/usr/bin/osascript', '-e', 'tell application id "my.fancy.package.app.from.uninstall" to quit'])
+ #
+ # Hbc::FakeSystemCommand.expects_command(['/usr/bin/sudo', '-E', '--', with_zap.staged_path.join('MyFancyPkg','FancyUninstaller.tool'), '--please'])
+ # Hbc::FakeSystemCommand.expects_command(['/usr/bin/sudo', '-E', '--', '/bin/rm', '-rf', '--',
+ # Pathname.new('~/Library/Preferences/my.fancy.app.plist').expand_path])
+ #
+ # shutup do
+ # Hbc::CLI::Zap.run('with-zap')
+ # end
+ # with_zap.wont_be :installed?
+ # end
+
+ describe "when no Cask is specified" do
+ it "raises an exception" do
+ expect {
+ Hbc::CLI::Zap.run
+ }.to raise_error(Hbc::CaskUnspecifiedError)
+ end
+ end
+
+ describe "when no Cask is specified, but an invalid option" do
+ it "raises an exception" do
+ expect {
+ Hbc::CLI::Zap.run("--notavalidoption")
+ }.to raise_error(Hbc::CaskUnspecifiedError)
+ end
+ end
+end