diff --git a/Gemfile b/Gemfile index 7ff0da1e8..25de561c6 100644 --- a/Gemfile +++ b/Gemfile @@ -3,5 +3,4 @@ source :rubygems group :test do gem 'rake' gem 'purdytest' - gem 'mocha' end diff --git a/Gemfile.lock b/Gemfile.lock index 1a45d8e60..fb1a25d37 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,10 +1,7 @@ GEM remote: http://rubygems.org/ specs: - metaclass (0.0.1) minitest (2.12.1) - mocha (0.12.7) - metaclass (~> 0.0.1) purdytest (1.0.0) minitest (~> 2.2) rake (10.0.1) @@ -13,6 +10,5 @@ PLATFORMS ruby DEPENDENCIES - mocha purdytest rake diff --git a/lib/cask.rb b/lib/cask.rb index 55e685a83..8219358fb 100644 --- a/lib/cask.rb +++ b/lib/cask.rb @@ -25,6 +25,10 @@ class Cask def self.appdir @appdir ||= Pathname.new(File.expand_path("~/Applications")) end + + def self.set_appdir(canned_appdir) + @appdir = canned_appdir + end def self.init HOMEBREW_CACHE.mkpath unless HOMEBREW_CACHE.exist? diff --git a/lib/cask/actions.rb b/lib/cask/actions.rb index 9d1be8213..1de53bad8 100644 --- a/lib/cask/actions.rb +++ b/lib/cask/actions.rb @@ -5,13 +5,13 @@ module Cask::Actions target = destination_path.join(app) if destination.symlink? # destination exists but is symlink; removing and relinking - puts "[#{self}] linking #{File.basename(destination)}" + ohai "[#{self}] linking #{File.basename(destination)}" destination.delete destination.make_symlink(target) elsif destination.directory? || destination.file? - puts "[#{self}] NOT linking #{File.basename(destination)} - already exists" + ohai "[#{self}] NOT linking #{File.basename(destination)} - already exists" else - puts "[#{self}] linking #{File.basename(destination)}" + ohai "[#{self}] linking #{File.basename(destination)}" destination.make_symlink(target) end end diff --git a/lib/cask/audit.rb b/lib/cask/audit.rb index 185f8be13..f961c7e5e 100644 --- a/lib/cask/audit.rb +++ b/lib/cask/audit.rb @@ -1,11 +1,12 @@ class Cask::Audit attr_reader :cask, :errors, :warnings, :headers, :response_status - def initialize(cask) + def initialize(cask, fetcher=Cask::Fetcher) @cask = cask @errors = [] @warnings = [] @headers = {} + @fetcher = fetcher end def run! @@ -94,7 +95,7 @@ class Cask::Audit end def _get_data_from_request - response = _curl(cask.url) + response = @fetcher.head(cask.url) if response.empty? add_error "timeout while requesting #{cask.url}" @@ -122,7 +123,4 @@ class Cask::Audit end end - def _curl(url) - `curl --max-time 5 --silent --location --head '#{url}'` - end end diff --git a/lib/cask/dsl.rb b/lib/cask/dsl.rb index cfa4c3c3a..d19ff7c78 100644 --- a/lib/cask/dsl.rb +++ b/lib/cask/dsl.rb @@ -21,7 +21,7 @@ module Cask::DSL end def url(url=nil) - @url ||= URI.parse(url) + @url ||= (url && URI.parse(url)) end def version(version=nil) diff --git a/lib/cask/fetcher.rb b/lib/cask/fetcher.rb new file mode 100644 index 000000000..11ae67f3d --- /dev/null +++ b/lib/cask/fetcher.rb @@ -0,0 +1,5 @@ +class Cask::Fetcher + def self.head(url) + `curl --max-time 5 --silent --location --head '#{url}'` + end +end diff --git a/test/cask/actions_test.rb b/test/cask/actions_test.rb index eb30d36ea..3c4a84996 100644 --- a/test/cask/actions_test.rb +++ b/test/cask/actions_test.rb @@ -1,17 +1,11 @@ require 'test_helper' -require 'cmd/uninstall' describe Cask::Actions do describe 'linkapps' do before do - fake_appdir = HOMEBREW_PREFIX/"Applications" - fake_appdir.mkpath - Cask.stubs(:appdir).returns(fake_appdir) - @caffeine = Cask.load('local-caffeine') shutup { Cask::Installer.install(@caffeine) } - @appdir = HOMEBREW_CELLAR/'local-caffeine'/@caffeine.version - @app = @appdir/'Caffeine.app' + @app = @caffeine.destination_path/'Caffeine.app' end after do @@ -30,7 +24,7 @@ describe Cask::Actions do end it "works with an application in a subdir" do - appsubdir = @appdir/'subdir' + appsubdir = @caffeine.destination_path/'subdir' appsubdir.mkpath FileUtils.mv @app, appsubdir appinsubdir = appsubdir/'Caffeine.app' diff --git a/test/cask/audit_test.rb b/test/cask/audit_test.rb index 36d132cd7..d9d44b889 100644 --- a/test/cask/audit_test.rb +++ b/test/cask/audit_test.rb @@ -1,22 +1,37 @@ require 'test_helper' +class CaskMissingUrl < Cask + version '1.2.3' + homepage 'http://example.com' +end + +class CaskMissingVersion < Cask + url 'http://localhost/something.dmg' + homepage 'http://example.com' +end + +class CaskMissingHomepage < Cask + url 'http://localhost/something.dmg' + version '1.2.3' +end + describe Cask::Audit do describe "result" do it "is 'failed' if there are have been any errors added" do - audit = Cask::Audit.new(mock()) + audit = Cask::Audit.new(TestHelper.test_cask) audit.add_error 'bad' audit.add_warning 'eh' audit.result.must_match /failed/ end it "is 'warning' if there are no errors, but there are warnings" do - audit = Cask::Audit.new(mock()) + audit = Cask::Audit.new(TestHelper.test_cask) audit.add_warning 'eh' audit.result.must_match /warning/ end it "is 'passed' if there are no errors or warning" do - audit = Cask::Audit.new(mock()) + audit = Cask::Audit.new(TestHelper.test_cask) audit.result.must_match /passed/ end end @@ -24,19 +39,19 @@ describe Cask::Audit do describe "run!" do describe "required fields" do it "adds an error if url is missing" do - audit = Cask::Audit.new(stub(:url => nil, :version => 'something', :homepage => 'something')) + audit = Cask::Audit.new(CaskMissingUrl.new) audit.run! audit.errors.must_include 'url is required' end it "adds an error if version is missing" do - audit = Cask::Audit.new(stub(:url => 'something', :version => nil, :homepage => 'something')) + audit = Cask::Audit.new(CaskMissingVersion.new) audit.run! audit.errors.must_include 'version is required' end it "adds an error if homepage is missing" do - audit = Cask::Audit.new(stub(:url => 'something', :version => 'something', :homepage => nil)) + audit = Cask::Audit.new(CaskMissingHomepage.new) audit.run! audit.errors.must_include 'homepage is required' end @@ -44,26 +59,23 @@ describe Cask::Audit do describe "request processing" do it "adds an error if response is empty" do - audit = Cask::Audit.new(stub(:url => 'something', :version => 'something', :homepage => 'something')) - audit.stubs(:_curl).returns('') + cask = TestHelper.test_cask + TestHelper.fake_response_for(cask.url, "") + audit = Cask::Audit.new(cask, TestHelper.fake_fetcher) audit.run! - audit.errors.must_include 'timeout while requesting something' + audit.errors.must_include "timeout while requesting #{cask.url}" end it "properly populates the response code and headers from an http response" do - audit = Cask::Audit.new(stub( - :url => URI('http://something/file.zip'), - :version => 'something', - :homepage => 'something', - :content_length => '123' - )) - audit.stubs(:_curl).returns(<<-RESPONSE.gsub(/^ /, '')) + TestHelper.fake_response_for(TestHelper.test_cask.url, <<-RESPONSE.gsub(/^ /, '')) HTTP/1.1 200 OK Content-Type: application/x-apple-diskimage ETag: "b4208f3e84967be4b078ecaa03fba941" Content-Length: 23726161 Last-Modified: Sun, 12 Aug 2012 21:17:21 GMT RESPONSE + + audit = Cask::Audit.new(TestHelper.test_cask, TestHelper.fake_fetcher) audit.run! audit.response_status.must_equal 'HTTP/1.1 200 OK' audit.headers.must_equal({ diff --git a/test/cask_test.rb b/test/cask_test.rb index f97f629ca..a0e54e526 100644 --- a/test/cask_test.rb +++ b/test/cask_test.rb @@ -22,14 +22,4 @@ describe Cask do all_casks.each { |cask| cask.must_be_kind_of String } end end - - describe "init" do - it "sets up dependent directories required for us to properly function" do - HOMEBREW_CACHE.stubs(:exist?).returns(false) - Cask.appdir.stubs(:exist?).returns(false) - HOMEBREW_CACHE.expects :mkpath - Cask.appdir.expects :mkpath - Cask.init - end - end end diff --git a/test/cli/install_test.rb b/test/cli/install_test.rb index 1e3a7d96e..949d8f97f 100644 --- a/test/cli/install_test.rb +++ b/test/cli/install_test.rb @@ -2,19 +2,17 @@ require 'test_helper' describe Cask::CLI::Install do it "allows install of multiple casks at once" do - Cask::Installer.stubs(:install) - Cask.expects(:load).with('adium') - Cask.expects(:load).with('google-chrome') - Cask::CLI::Install.run('adium', 'google-chrome') + shutup do + Cask::CLI::Install.run('local-transmission', 'local-caffeine') + end + + Cask.load('local-transmission').must_be :installed? + Cask.load('local-caffeine').must_be :installed? end it "properly handles casks that are not present" do - Cask::Installer.stubs(:install) - Cask.expects(:load).with('adium') - Cask.expects(:load).with('what-the-balls').raises(CaskUnavailableError.new('what-the-balls')) - Cask.expects(:load).with('google-chrome') lambda { - Cask::CLI::Install.run('adium', 'what-the-balls', 'google-chrome') + Cask::CLI::Install.run('what-the-balls') }.must_output <<-OUTPUT.gsub(/^ */, '') Error: No available cask for what-the-balls OUTPUT diff --git a/test/cli/linkapps_test.rb b/test/cli/linkapps_test.rb index e8b07e6eb..adcea0855 100644 --- a/test/cli/linkapps_test.rb +++ b/test/cli/linkapps_test.rb @@ -1,21 +1,33 @@ require 'test_helper' describe Cask::CLI::Linkapps do - it "only links casks provided in arguments" do - mock_cask = mock() - mock_cask.expects(:linkapps).twice - Cask.expects(:load).with('adium').returns(mock_cask) - Cask.expects(:load).with('google-chrome').returns(mock_cask) - Cask::CLI::Linkapps.run('adium', 'google-chrome') + it "only links casks mentioned when arguments are provided" do + caffeine = Cask.load('local-caffeine') + transmission = Cask.load('local-transmission') + + shutup do + Cask::Installer.install caffeine + Cask::Installer.install transmission + + Cask::CLI::Linkapps.run('local-transmission') + end + + (Cask.appdir/"Transmission.app").must_be :symlink? + (Cask.appdir/"Caffeine.app").wont_be :symlink? end it "links all installed casks when no arguments supplied" do - mock_cask = mock() - mock_cask.expects(:linkapps).times(3) - Cask.expects(:load).times(3).returns(mock_cask) + caffeine = Cask.load('local-caffeine') + transmission = Cask.load('local-transmission') + + shutup do + Cask::Installer.install caffeine + Cask::Installer.install transmission - Cask.expects(:installed).returns(['mock1', 'mock2', 'mock3']) + Cask::CLI::Linkapps.run + end - Cask::CLI::Linkapps.run + (Cask.appdir/"Transmission.app").must_be :symlink? + (Cask.appdir/"Caffeine.app").must_be :symlink? end end diff --git a/test/cli/list_test.rb b/test/cli/list_test.rb index cc87d46c6..ad51b9118 100644 --- a/test/cli/list_test.rb +++ b/test/cli/list_test.rb @@ -2,19 +2,20 @@ require 'test_helper' describe Cask::CLI::List do it "lists the installed casks in a pretty fashion" do - Cask.stubs(:installed).returns(%w[ - phinze-cask/adium - phinze-cask/google-chrome - ]) + shutup do + Cask::CLI::Install.run('local-transmission', 'local-caffeine') + end + lambda { Cask::CLI::List.run }.must_output <<-OUTPUT.gsub(/^ */, '') - adium - google-chrome + local-caffeine + local-transmission OUTPUT end - it "lists the taps for casks that show up in two" do + it "lists the taps for casks that show up in two taps" do + skip("need to move this implementation to an easier to test location") Cask.stubs(:installed).returns(%w[ phinze-cask/adium phinze-cask/google-chrome diff --git a/test/cli/search_test.rb b/test/cli/search_test.rb index f4b72a1b7..02721b297 100644 --- a/test/cli/search_test.rb +++ b/test/cli/search_test.rb @@ -2,16 +2,11 @@ require 'test_helper' describe Cask::CLI::Search do it "lists the available casks that match the search term" do - Cask.stubs(:all_titles).returns(%w[ - phinze-cask/foo - phinze-cask/bar - phinze-cask/baz - ]) lambda { - Cask::CLI::Search.run('ba') + Cask::CLI::Search.run('intellij') }.must_output <<-OUTPUT.gsub(/^ */, '') - bar - baz + intellij-community + intellij-ultimate OUTPUT end end diff --git a/test/cli/uninstall_test.rb b/test/cli/uninstall_test.rb index d620b28ce..b7adae7f1 100644 --- a/test/cli/uninstall_test.rb +++ b/test/cli/uninstall_test.rb @@ -17,21 +17,21 @@ describe Cask::CLI::Uninstall do OUTPUT end - it "delegates to the installer to properly uninstall" do - fake_cask = stub('fake-cask') - Cask.stubs(:load).with('fake-cask').returns(fake_cask) - Cask::Installer.expects(:uninstall).with(fake_cask) - Cask::CLI::Uninstall.run('fake-cask') - end - it "can uninstall multiple casks at once" do - Cask::Installer.expects(:uninstall).with do |cask| - cask.title == 'caffeine' - end - Cask::Installer.expects(:uninstall).with do |cask| - cask.title == 'anvil' + caffeine = Cask.load('local-caffeine') + transmission = Cask.load('local-transmission') + + shutup do + Cask::Installer.install caffeine + Cask::Installer.install transmission end - Cask::CLI::Uninstall.run('caffeine', 'anvil') + caffeine.must_be :installed? + transmission.must_be :installed? + + Cask::CLI::Uninstall.run('local-caffeine', 'local-transmission') + + caffeine.wont_be :installed? + transmission.wont_be :installed? end end diff --git a/test/support/fake_appdir.rb b/test/support/fake_appdir.rb new file mode 100644 index 000000000..46001dca6 --- /dev/null +++ b/test/support/fake_appdir.rb @@ -0,0 +1,19 @@ +# wire in a fake appdir for linkapps +CANNED_APPDIR = (HOMEBREW_REPOSITORY/"Applications") +Cask.set_appdir(CANNED_APPDIR) + +module FakeAppdirHooks + def before_setup + super + CANNED_APPDIR.mkdir + end + + def after_teardown + super + FileUtils.rm_rf(CANNED_APPDIR) + end +end + +class MiniTest::Spec + include FakeAppdirHooks +end diff --git a/test/support/fake_fetcher.rb b/test/support/fake_fetcher.rb new file mode 100644 index 000000000..a81b41f36 --- /dev/null +++ b/test/support/fake_fetcher.rb @@ -0,0 +1,37 @@ +class Cask::FakeFetcher + def self.fake_response_for(url, response) + @responses[url] = response + end + + def self.head(url) + @responses ||= {} + unless @responses.key?(url) + fail("no response faked for #{url.inspect}") + end + @responses[url] + end + + def self.init + @responses = {} + end + + def self.clear + @responses = {} + end +end + +module FakeFetcherHooks + def before_setup + super + Cask::FakeFetcher.init + end + + def after_teardown + super + Cask::FakeFetcher.clear + end +end + +class MiniTest::Spec + include FakeFetcherHooks +end diff --git a/test/test_helper.rb b/test/test_helper.rb index 30a408fcc..10e686c82 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -21,15 +21,11 @@ HOMEBREW_LIBRARY = HOMEBREW_REPOSITORY/"Library" # making homebrew's cache dir allows us to actually download casks in tests HOMEBREW_CACHE.mkpath - # must be called after testing_env so at_exit hooks are in proper order require 'minitest/spec' require 'minitest/autorun' require 'purdytest' -# sometimes you need to mock -require 'mocha' - # our baby require 'cask' @@ -39,8 +35,22 @@ class TestHelper path = File.join(File.dirname(__FILE__), 'support', 'binaries', name) "file://#{path}" end + + def self.test_cask + Cask.load('test-cask') + end + + def self.fake_fetcher + Cask::FakeFetcher + end + + def self.fake_response_for(*args) + Cask::FakeFetcher.fake_response_for(*args) + end end +require 'support/fake_fetcher' +require 'support/fake_appdir' # pretend like we installed the cask tap project_root = Pathname.new(File.expand_path("#{File.dirname(__FILE__)}/../"))