diff --git a/.travis.yml b/.travis.yml index 635721991..4e70d1565 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,22 +1,24 @@ +language: ruby +rvm: + - 1.8.7 + - 1.9.2 + - 1.9.3 + - 2.0.0 + - 2.1.2 +cache: bundler + before_script: - git config --global user.email "bot@heroku.com" - git config --global user.name "Heroku Bot (Travis CI)" -bundler_args: --without development - -language: ruby +script: bundle exec rspec spec --color --format documentation notifications: email: false - webhooks: - on_success: always - on_failure: always - urls: - - http://dx-helper.herokuapp.com/travis - -rvm: - - 1.8.7 - - 1.9.2 - - 1.9.3 -script: bundle exec rspec -bfs spec +deploy: + provider: rubygems + on: + tags: true + api_key: + secure: ALsBCGGvdAiIEJR9zTzxumcgCaS5eqOs7Oee7e4SiDgHrT/DRSsFJBtNp9mJvQvHzW3FqSFZU7NO6tSRkwHGdGGw7pf/emjZ2ua0exuyCQ3LaCJBdwSQXl0GTMhhaMCCd2NYWJ+Fa3Q9jWWAdCfV8rqz5AX4ZG6fi3C2uubppVs= diff --git a/CHANGELOG b/CHANGELOG index 50c19b84b..4fa2b1878 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,46 @@ +3.11.1 2014-09-12 +================= +Attempt to push ~/.ssh/id_rsa SSH key instead of any one key +Always prompt for uploading SSH keys + +3.10.6 2014-09-04 +================= +Added ssh-keygen shim for Windows + +3.10.5 2014-08-27 +================= +Ocra support for building standalone heroku-ocra.exe + +3.10.4 2014-08-22 +================= +Upgraded excon to 0.39.5 + +3.10.3 2014-08-21 +================= +Fixed minor issue with recording fork source + +3.10.2 2014-08-21 +================= +Removed lazy-loading of heroku-api and rest_client (was swallowing errors) +Fail fast for issue with pgbackups:transfer +Removed price tier from info +Help info for two factor topic +Send deploy type and source metadata for forks + +3.10.1 2014-08-14 +================= +No changes, just verifying new release code is in order + +3.10.0 2014-08-14 +================= +Fixed beta releases +Upgrade heroku-api and excon + +3.9.7 2014-08-12 +================ +Bring 2fa:disable back +Several pg and pgbackups command improvements + 3.9.4 2014-07-21 ================ Actually fix a bug where setting HEROKU_API_KEY would cause failures diff --git a/Gemfile b/Gemfile index 77d3fd114..e016c9c38 100644 --- a/Gemfile +++ b/Gemfile @@ -3,21 +3,14 @@ source "https://rubygems.org" gemspec group :development, :test do - gem "rake", ">= 0.8.7" - gem "rr", "~> 1.0.2" -end - -group :development do + gem "rake" + gem "rr" gem "aws-s3" - gem "fpm" - gem "rubyzip" -end - -group :test do + gem "mime-types", "< 2.0" gem "fakefs" - gem "jruby-openssl", :platform => :jruby gem "json" - gem "rspec", ">= 2.0" - gem "sqlite3" + gem "rspec" gem "webmock" + gem "coveralls", :require => false + gem "ocra", :require => false end diff --git a/Gemfile.lock b/Gemfile.lock index c41b2a239..a99e8008d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,69 +1,75 @@ PATH remote: . specs: - heroku (3.9.4) - heroku-api (= 0.3.17) + heroku (3.11.1) + heroku-api (~> 0.3.19) launchy (>= 0.3.2) netrc (~> 0.7.7) - rest-client (~> 1.6.1) - rubyzip + rest-client (= 1.6.7) + rubyzip (= 0.9.9) GEM remote: https://rubygems.org/ specs: - addressable (2.3.2) - arr-pm (0.0.7) - cabin (> 0) + addressable (2.3.6) aws-s3 (0.6.3) builder mime-types xml-simple - backports (2.3.0) - builder (3.1.4) - cabin (0.4.4) - json - clamp (0.5.0) - crack (0.3.2) - diff-lcs (1.1.3) - excon (0.38.0) - fakefs (0.4.2) - fpm (0.4.6) - arr-pm (~> 0.0.7) - backports (= 2.3.0) - cabin (~> 0.4.3) - clamp - json - heroku-api (0.3.17) - excon (~> 0.27) - multi_json (~> 1.8.2) - json (1.7.7) + builder (3.2.2) + coveralls (0.7.1) + multi_json (~> 1.3) + rest-client + simplecov (>= 0.7) + term-ansicolor + thor + crack (0.4.2) + safe_yaml (~> 1.0.0) + diff-lcs (1.2.5) + docile (1.1.5) + excon (0.39.5) + fakefs (0.5.2) + heroku-api (0.3.19) + excon (~> 0.38) + multi_json (~> 1.8) + json (1.8.1) launchy (2.4.2) addressable (~> 2.3) - mime-types (1.21) - multi_json (1.8.4) + mime-types (1.25.1) + multi_json (1.10.1) netrc (0.7.7) - rake (10.0.3) - rdoc (4.1.1) - json (~> 1.4) - rest-client (1.6.8) - mime-types (~> 1.16) - rdoc (>= 2.4.2) - rr (1.0.4) - rspec (2.12.0) - rspec-core (~> 2.12.0) - rspec-expectations (~> 2.12.0) - rspec-mocks (~> 2.12.0) - rspec-core (2.12.2) - rspec-expectations (2.12.1) - diff-lcs (~> 1.1.3) - rspec-mocks (2.12.2) + ocra (1.3.2) + rake (10.3.2) + rest-client (1.6.7) + mime-types (>= 1.16) + rr (1.1.2) + rspec (3.0.0) + rspec-core (~> 3.0.0) + rspec-expectations (~> 3.0.0) + rspec-mocks (~> 3.0.0) + rspec-core (3.0.4) + rspec-support (~> 3.0.0) + rspec-expectations (3.0.4) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.0.0) + rspec-mocks (3.0.4) + rspec-support (~> 3.0.0) + rspec-support (3.0.4) rubyzip (0.9.9) - sqlite3 (1.3.7) - sqlite3 (1.3.7-x86-mingw32) - webmock (1.9.0) - addressable (>= 2.2.7) - crack (>= 0.1.7) - xml-simple (1.1.2) + safe_yaml (1.0.3) + simplecov (0.9.0) + docile (~> 1.1.0) + multi_json + simplecov-html (~> 0.8.0) + simplecov-html (0.8.0) + term-ansicolor (1.3.0) + tins (~> 1.0) + thor (0.19.1) + tins (1.3.2) + webmock (1.18.0) + addressable (>= 2.3.6) + crack (>= 0.3.2) + xml-simple (1.1.4) PLATFORMS ruby @@ -71,14 +77,13 @@ PLATFORMS DEPENDENCIES aws-s3 + coveralls fakefs - fpm heroku! - jruby-openssl json - rake (>= 0.8.7) - rr (~> 1.0.2) - rspec (>= 2.0) - rubyzip - sqlite3 + mime-types (< 2.0) + ocra + rake + rr + rspec webmock diff --git a/README.md b/README.md index 775604fc3..10bd0ba75 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,10 @@ For more about Heroku see . To get started see -[![Build Status](https://secure.travis-ci.org/heroku/heroku.png)](http://travis-ci.org/heroku/heroku) -[![Dependency Status](https://gemnasium.com/heroku/heroku.png)](https://gemnasium.com/heroku/heroku) +[![Build Status](https://travis-ci.org/heroku/heroku.svg?branch=master)](https://travis-ci.org/heroku/heroku) +[![Build status](https://ci.appveyor.com/api/projects/status/kv0r2s5eyckpanhr/branch/master)](https://ci.appveyor.com/project/dickeyxxx/heroku/branch/master) +[![Coverage Status](https://img.shields.io/coveralls/heroku/heroku.svg)](https://coveralls.io/r/heroku/heroku?branch=master) +[![Dependency Status](https://gemnasium.com/heroku/heroku.svg)](https://gemnasium.com/heroku/heroku) Setup ----- diff --git a/Rakefile b/Rakefile index c381f9c28..df648ff65 100644 --- a/Rakefile +++ b/Rakefile @@ -172,7 +172,7 @@ CHANGELOG end desc("Release the latest version") -task "release" => ["gem:release", "tgz:release", "zip:release", "manifest:update"] do +task "release" => ["tgz:release", "zip:release", "manifest:update"] do puts("Released v#{version}") end diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 000000000..7cd92d822 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,16 @@ +version: "{build}" +branches: + only: + - master +clone_depth: 1 +install: + - ruby --version + - bundle install -j4 +build_script: + - ocra bin\heroku-ocra data\cacert.pem +test_script: + - heroku-ocra.exe help + - heroku-ocra.exe status +artifacts: + - path: heroku-ocra.exe + name: heroku-ocra.exe diff --git a/bin/heroku b/bin/heroku index 75ec5149f..2cfd27fb5 100755 --- a/bin/heroku +++ b/bin/heroku @@ -1,4 +1,4 @@ -#!/usr/bin/env ruby +#!/usr/bin/ruby # encoding: UTF-8 # resolve bin path, ignoring symlinks diff --git a/bin/heroku-ocra b/bin/heroku-ocra new file mode 100644 index 000000000..d464fa12a --- /dev/null +++ b/bin/heroku-ocra @@ -0,0 +1,21 @@ +#!/usr/bin/env ruby +# encoding: UTF-8 + +# resolve bin path, ignoring symlinks +require "pathname" +bin_file = Pathname.new(__FILE__).realpath + +# add self to libpath +$:.unshift File.expand_path("../../lib", bin_file) + +require "heroku/updater" +Heroku::Updater.disable("`heroku update` is only available from Heroku Toolbelt.\nDownload and install from https://toolbelt.heroku.com") + +# start up the CLI +require "heroku/cli" +Heroku.user_agent = "heroku-ocra/#{Heroku::VERSION} (#{RUBY_PLATFORM}) ruby/#{RUBY_VERSION}" +Heroku::CLI.start(*ARGV) + +# require other dependencies ocra needs to include +require 'Win32API' +MultiJson.load('{"foo": "bar"}') # preps multi_json diff --git a/dist/manifest.rake b/dist/manifest.rake index 0d3b46e0e..adaf03b04 100644 --- a/dist/manifest.rake +++ b/dist/manifest.rake @@ -1,4 +1,6 @@ task "manifest:update" do + abort "Manifest should never contain betas." if beta? + tempdir do |dir| File.open("VERSION", "w") do |file| file.puts version diff --git a/dist/zip.rake b/dist/zip.rake index 9f7252c23..bc3a98af2 100644 --- a/dist/zip.rake +++ b/dist/zip.rake @@ -36,5 +36,5 @@ task "zip:release" => %w( zip:build zip:sign ) do |t| store pkg("heroku-#{version}.zip"), "heroku-client/heroku-client-beta.zip" if beta? store pkg("heroku-#{version}.zip"), "heroku-client/heroku-client.zip" unless beta? - sh "heroku config:add UPDATE_HASH=#{zip_signature} -a toolbelt" + sh "heroku config:add UPDATE_HASH=#{zip_signature} -a toolbelt" unless beta? end diff --git a/heroku.gemspec b/heroku.gemspec index 650db705e..668e83b04 100644 --- a/heroku.gemspec +++ b/heroku.gemspec @@ -20,9 +20,9 @@ Gem::Specification.new do |gem| gem.files = %x{ git ls-files }.split("\n").select { |d| d =~ %r{^(License|README|bin/|data/|ext/|lib/|spec/|test/)} } - gem.add_dependency "heroku-api", "= 0.3.17" + gem.add_dependency "heroku-api", "~> 0.3.19" gem.add_dependency "launchy", ">= 0.3.2" gem.add_dependency "netrc", "~> 0.7.7" - gem.add_dependency "rest-client", "~> 1.6.1" - gem.add_dependency "rubyzip" + gem.add_dependency "rest-client", "= 1.6.7" + gem.add_dependency "rubyzip", "= 0.9.9" end diff --git a/lib/heroku/api/releases_v3.rb b/lib/heroku/api/releases_v3.rb index 41a4d0815..632f168f7 100644 --- a/lib/heroku/api/releases_v3.rb +++ b/lib/heroku/api/releases_v3.rb @@ -11,15 +11,20 @@ def get_releases_v3(app, range=nil) ) end - def post_release_v3(app, slug_id, description=nil) + def post_release_v3(app, slug_id, opts={}) + headers = { + 'Accept' => 'application/vnd.heroku+json; version=3', + 'Content-Type' => 'application/json' + } + headers.merge!('Heroku-Deploy-Type' => opts[:deploy_type]) if opts[:deploy_type] + headers.merge!('Heroku-Deploy-Source' => opts[:deploy_source]) if opts[:deploy_source] + body = { 'slug' => slug_id } - body.merge!('description' => description) if description + body.merge!('description' => opts[:description]) if opts[:description] + request( :expects => 201, - :headers => { - 'Accept' => 'application/vnd.heroku+json; version=3', - 'Content-Type' => 'application/json' - }, + :headers => headers, :method => :post, :path => "/apps/#{app}/releases", :body => Heroku::Helpers.json_encode(body) diff --git a/lib/heroku/auth.rb b/lib/heroku/auth.rb index d759a9188..5387a5d22 100644 --- a/lib/heroku/auth.rb +++ b/lib/heroku/auth.rb @@ -13,7 +13,6 @@ class << self def api @api ||= begin - require("heroku-api") api = Heroku::API.new(default_params.merge(:api_key => password)) def api.request(params, &block) @@ -75,7 +74,6 @@ def password # :nodoc: end def api_key(user = get_credentials[0], password = get_credentials[1]) - require("heroku-api") api = Heroku::API.new(default_params) api.post_login(user, password).body["api_key"] rescue Heroku::API::Errors::Unauthorized => e @@ -240,45 +238,54 @@ def ask_for_password end def ask_for_and_save_credentials - require("heroku-api") # for the errors - begin - @credentials = ask_for_credentials - write_credentials - check - rescue Heroku::API::Errors::NotFound, Heroku::API::Errors::Unauthorized => e - delete_credentials - display "Authentication failed." - retry if retry_login? - exit 1 - rescue Exception => e - delete_credentials - raise e - end + @credentials = ask_for_credentials + write_credentials + check check_for_associated_ssh_key unless Heroku::Command.current_command == "keys:add" @credentials + rescue Heroku::API::Errors::NotFound, Heroku::API::Errors::Unauthorized => e + delete_credentials + display "Authentication failed." + retry if retry_login? + exit 1 + rescue Exception => e + delete_credentials + raise e end def check_for_associated_ssh_key if api.get_keys.body.empty? + display "Your Heroku account does not have a public ssh key uploaded." associate_or_generate_ssh_key end end def associate_or_generate_ssh_key - public_keys = Dir.glob("#{home_directory}/.ssh/*.pub").sort - - case public_keys.length - when 0 then - display "Could not find an existing public key." + unless File.exists?("#{home_directory}/.ssh/id_rsa.pub") + display "Could not find an existing public key at ~/.ssh/id_rsa.pub" display "Would you like to generate one? [Yn] ", false - unless ask.strip.downcase == "n" + unless ask.strip.downcase =~ /^n/ display "Generating new SSH public key." - generate_ssh_key("id_rsa") + generate_ssh_key("#{home_directory}/.ssh/id_rsa") associate_key("#{home_directory}/.ssh/id_rsa.pub") + return end - when 1 then - display "Found existing public key: #{public_keys.first}" - associate_key(public_keys.first) + end + + chosen = ssh_prompt + associate_key(chosen) if chosen + end + + def ssh_prompt + public_keys = Dir.glob("#{home_directory}/.ssh/*.pub").sort + case public_keys.length + when 0 + error("No SSH keys found") + return nil + when 1 + display "Found an SSH public key at #{public_keys.first}" + display "Would you like to upload it to Heroku? [Yn] ", false + return ask.strip.downcase =~ /^n/ ? nil : public_keys.first else display "Found the following SSH public keys:" public_keys.each_with_index do |key, index| @@ -290,19 +297,14 @@ def associate_or_generate_ssh_key if choice == -1 || chosen.nil? error("Invalid choice") end - associate_key(chosen) + return chosen end end def generate_ssh_key(keyfile) - ssh_dir = File.join(home_directory, ".ssh") - unless File.exists?(ssh_dir) - FileUtils.mkdir_p ssh_dir - unless running_on_windows? - File.chmod(0700, ssh_dir) - end - end - output = `ssh-keygen -t rsa -N "" -f \"#{home_directory}/.ssh/#{keyfile}\" 2>&1` + ssh_dir = File.dirname(keyfile) + FileUtils.mkdir_p ssh_dir, :mode => 0700 + output = `ssh-keygen -t rsa -N "" -f \"#{keyfile}\" 2>&1` if ! $?.success? error("Could not generate key: #{output}") end diff --git a/lib/heroku/cli.rb b/lib/heroku/cli.rb index cb0a734d8..36389c756 100644 --- a/lib/heroku/cli.rb +++ b/lib/heroku/cli.rb @@ -4,12 +4,8 @@ require "heroku" require "heroku/command" require "heroku/helpers" - -# workaround for rescue/reraise to define errors in command.rb failing in 1.8.6 -if RUBY_VERSION =~ /^1.8.6/ - require('heroku-api') - require('rest_client') -end +require 'rest_client' +require 'heroku-api' begin # attempt to load the JSON parser bundled with ruby for multi_json diff --git a/lib/heroku/client.rb b/lib/heroku/client.rb index 18594ac0a..7286713ad 100644 --- a/lib/heroku/client.rb +++ b/lib/heroku/client.rb @@ -6,6 +6,7 @@ require 'heroku/helpers' require 'heroku/version' require 'heroku/client/ssl_endpoint' +require 'rest_client' # A Ruby class to call the Heroku REST API. You might use this if you want to # manage your Heroku apps from within a Ruby program, such as Capistrano. @@ -32,7 +33,6 @@ def self.gem_version_string attr_accessor :host, :user, :password def initialize(user, password, host=Heroku::Auth.host) - require 'rest_client' @user = user @password = password @host = host @@ -349,7 +349,6 @@ class Service attr_accessor :attached def initialize(client, app) - require 'rest_client' @client = client @app = app end @@ -435,7 +434,6 @@ class AppCrashed < RuntimeError; end # support for console sessions class ConsoleSession def initialize(id, app, client) - require 'rest_client' @id = id; @app = app; @client = client end def run(cmd) @@ -616,6 +614,10 @@ def process(method, uri, extra_headers={}, payload=nil) headers = heroku_headers.merge(extra_headers) args = [method, payload, headers].compact + if Heroku::Auth.two_factor_code + headers.merge!("Heroku-Two-Factor-Code" => Heroku::Auth.two_factor_code) + end + resource_options = default_resource_options_for_uri(uri) begin diff --git a/lib/heroku/client/heroku_postgresql.rb b/lib/heroku/client/heroku_postgresql.rb index 07038e70d..4f1957be6 100644 --- a/lib/heroku/client/heroku_postgresql.rb +++ b/lib/heroku/client/heroku_postgresql.rb @@ -18,7 +18,6 @@ def self.headers attr_reader :attachment def initialize(attachment) @attachment = attachment - require 'rest_client' end def heroku_postgresql_host @@ -58,6 +57,10 @@ def reset http_put "#{resource_name}/reset" end + def connection_reset + http_post "#{resource_name}/connection_reset" + end + def rotate_credentials http_post "#{resource_name}/credentials_rotation" end diff --git a/lib/heroku/client/organizations.rb b/lib/heroku/client/organizations.rb index 819ca9c3e..dea83814d 100644 --- a/lib/heroku/client/organizations.rb +++ b/lib/heroku/client/organizations.rb @@ -1,4 +1,3 @@ -require 'heroku-api' require "heroku/client" class Heroku::Client::Organizations @@ -231,7 +230,7 @@ def decompress_response!(response) end def manager_url - ENV['HEROKU_MANAGER_URL'] || "https://manager-api.heroku.com" + ENV['HEROKU_MANAGER_URL'] || "https://api.heroku.com" end end diff --git a/lib/heroku/client/pgbackups.rb b/lib/heroku/client/pgbackups.rb index be129f531..a031daa9d 100644 --- a/lib/heroku/client/pgbackups.rb +++ b/lib/heroku/client/pgbackups.rb @@ -5,7 +5,6 @@ class Heroku::Client::Pgbackups include Heroku::Helpers def initialize(uri) - require 'rest_client' @uri = URI.parse(uri) end diff --git a/lib/heroku/command.rb b/lib/heroku/command.rb index f944955e9..e9e6ede75 100644 --- a/lib/heroku/command.rb +++ b/lib/heroku/command.rb @@ -213,15 +213,8 @@ def self.prepare_run(cmd, args=[]) end def self.run(cmd, arguments=[]) - begin - object, method = prepare_run(cmd, arguments.dup) - object.send(method) - rescue Interrupt, StandardError, SystemExit => error - # load likely error classes, as they may not be loaded yet due to defered loads - require 'heroku-api' - require 'rest_client' - raise(error) - end + object, method = prepare_run(cmd, arguments.dup) + object.send(method) rescue Heroku::API::Errors::Unauthorized, RestClient::Unauthorized => e retry_login = handle_auth_error(e) retry if retry_login @@ -259,7 +252,12 @@ def self.run(cmd, arguments=[]) rescue Heroku::API::Errors::ErrorWithResponse => e error extract_error(e.response.body) rescue RestClient::RequestFailed => e - error extract_error(e.http_body) + if e.response.code == 403 && e.response.headers.has_key?(:heroku_two_factor_required) + Heroku::Auth.ask_for_second_factor + retry + else + error extract_error(e.http_body) + end rescue CommandFailed => e error e.message rescue OptionParser::ParseError diff --git a/lib/heroku/command/apps.rb b/lib/heroku/command/apps.rb index 6f10db1e2..6e5ce8deb 100644 --- a/lib/heroku/command/apps.rb +++ b/lib/heroku/command/apps.rb @@ -178,10 +178,6 @@ def info data["Web URL"] = app_data["web_url"] - if app_data["tier"] - data["Tier"] = app_data["tier"].capitalize - end - styled_hash(data) end end diff --git a/lib/heroku/command/fork.rb b/lib/heroku/command/fork.rb index f92bb2d29..b38d2161e 100644 --- a/lib/heroku/command/fork.rb +++ b/lib/heroku/command/fork.rb @@ -42,7 +42,7 @@ def index end action("Copying slug") do - copy_slug(from, to) + copy_slug(from_info, to_info) end from_config = api.get_config_vars(from).body @@ -108,12 +108,18 @@ def index private - def copy_slug(from, to) + def copy_slug(from_info, to_info) + from = from_info["name"] + to = to_info["name"] from_releases = api.get_releases_v3(from, 'version ..; order=desc,max=1;').body raise Heroku::Command::CommandFailed.new("No releases on #{from}") if from_releases.empty? from_slug = from_releases.first.fetch('slug', {}) raise Heroku::Command::CommandFailed.new("No slug on #{from}") unless from_slug - api.post_release_v3(to, from_slug["id"], "Forked from #{from}") + api.post_release_v3(to, + from_slug["id"], + :description => "Forked from #{from}", + :deploy_type => "fork", + :deploy_source => from_info["id"]) end def check_for_pgbackups!(app) diff --git a/lib/heroku/command/pg.rb b/lib/heroku/command/pg.rb index ce46abee7..1f9246980 100644 --- a/lib/heroku/command/pg.rb +++ b/lib/heroku/command/pg.rb @@ -268,6 +268,14 @@ def kill # terminates ALL connections # def killall + db = args.first + attachment = generate_resolver.resolve(db, "DATABASE_URL") + client = hpg_client(attachment) + client.connection_reset + display "Connections terminated" + rescue StandardError + # fall back to original mechanism if calling the reset endpoint + # fails sql = %Q( SELECT pg_terminate_backend(#{pid_column}) FROM pg_stat_activity @@ -341,7 +349,7 @@ def pull def maintenance mode_with_argument = shift_argument || '' mode, mode_argument = mode_with_argument.split('=') - p [mode, mode_argument] + db = shift_argument no_maintenance = options[:force] if mode.nil? || db.nil? || !(%w[info run window].include? mode) @@ -530,7 +538,9 @@ def find_uri def version return @version if defined? @version - @version = exec_sql("select version();").match(/PostgreSQL (\d+\.\d+\.\d+) on/)[1] + result = exec_sql("select version();").match(/PostgreSQL (\d+\.\d+\.\d+) on/) + fail("Unable to determine Postgres version") unless result + @version = result[1] end def nine_two? @@ -564,7 +574,11 @@ def exec_sql_on_uri(sql,uri) ENV["PGPASSWORD"] = uri.password ENV["PGSSLMODE"] = (uri.host == 'localhost' ? 'prefer' : 'require' ) user_part = uri.user ? "-U #{uri.user}" : "" - `psql -c "#{sql}" #{user_part} -h #{uri.host} -p #{uri.port || 5432} #{uri.path[1..-1]}` + output = `#{psql_cmd} -c "#{sql}" #{user_part} -h #{uri.host} -p #{uri.port || 5432} #{uri.path[1..-1]}` + if (! $?.success?) || output.nil? || output.empty? + raise "psql failed. exit status #{$?.to_i}, output: #{output.inspect}" + end + output rescue Errno::ENOENT output_with_bang "The local psql command could not be located" output_with_bang "For help installing psql, see https://devcenter.heroku.com/articles/heroku-postgresql#local-setup" @@ -572,4 +586,9 @@ def exec_sql_on_uri(sql,uri) end end + def psql_cmd + # some people alais psql, so we need to find the real psql + # but windows doesn't have the command command + running_on_windows? ? 'psql' : 'command psql' + end end diff --git a/lib/heroku/command/pgbackups.rb b/lib/heroku/command/pgbackups.rb index 9754d7ac5..839e235d2 100644 --- a/lib/heroku/command/pgbackups.rb +++ b/lib/heroku/command/pgbackups.rb @@ -219,6 +219,10 @@ def transfer validate_arguments! + if from.url == to.url + error("source and target database are the same") + end + opts = {} verify_app = to.app || app if confirm_command(verify_app, "WARNING: Destructive Action\nTransfering data from #{from.name} to #{to.name}") diff --git a/lib/heroku/command/two_factor.rb b/lib/heroku/command/two_factor.rb index c2c1a6efd..447c89dcb 100644 --- a/lib/heroku/command/two_factor.rb +++ b/lib/heroku/command/two_factor.rb @@ -1,5 +1,7 @@ require "heroku/command/base" +# manage two factor settings for account +# module Heroku::Command class TwoFactor < BaseWithApp # 2fa diff --git a/lib/heroku/command/update.rb b/lib/heroku/command/update.rb index 67b977a15..5a7ca34ba 100644 --- a/lib/heroku/command/update.rb +++ b/lib/heroku/command/update.rb @@ -16,7 +16,7 @@ class Heroku::Command::Update < Heroku::Command::Base # def index validate_arguments! - update_from_url("https://toolbelt.heroku.com/download/zip") + update_from_url(false) end # update:beta @@ -28,15 +28,15 @@ def index # def beta validate_arguments! - update_from_url("https://toolbelt.heroku.com/download/beta-zip") + update_from_url(true) end private - def update_from_url(url) + def update_from_url(prerelease) Heroku::Updater.check_disabled! action("Updating from #{Heroku::VERSION}") do - if new_version = Heroku::Updater.update(url) + if new_version = Heroku::Updater.update(prerelease) status("updated to #{new_version}") else status("nothing to update") diff --git a/lib/heroku/updater.rb b/lib/heroku/updater.rb index 87540aa8c..5ff50f675 100644 --- a/lib/heroku/updater.rb +++ b/lib/heroku/updater.rb @@ -21,6 +21,20 @@ def self.updated_client_path File.join(Heroku::Helpers.home_directory, ".heroku", "client") end + def self.latest_version + http_get('http://assets.heroku.com/heroku-client/VERSION').chomp + end + + def self.official_zip_hash + http_get('https://toolbelt.heroku.com/update/hash').chomp + end + + def self.http_get(url) + require 'excon' + require 'heroku/excon' + Excon.get_with_redirect(url, :nonblock => false).body + end + def self.latest_local_version installed_version = client_version_from_path(installed_client_path) updated_version = client_version_from_path(updated_client_path) @@ -31,6 +45,10 @@ def self.latest_local_version end end + def self.needs_update? + compare_versions(latest_version, latest_local_version) > 0 + end + def self.client_version_from_path(path) version_file = File.join(path, "lib/heroku/version.rb") if File.exists?(version_file) @@ -51,7 +69,8 @@ def self.check_disabled! end end - def self.wait_for_lock(path, wait_for=5, check_every=0.5) + def self.wait_for_lock(wait_for=5, check_every=0.5) + path = updating_lock_path start = Time.now.to_i while File.exists?(path) sleep check_every @@ -59,69 +78,66 @@ def self.wait_for_lock(path, wait_for=5, check_every=0.5) Heroku::Helpers.error "Unable to acquire update lock" end end - begin - FileUtils.touch path - ret = yield - ensure - FileUtils.rm_f path - end - ret - end - - def self.autoupdate? - true + FileUtils.mkdir_p File.dirname(path) + FileUtils.touch path + yield + ensure + FileUtils.rm_f path end - def self.update(url, autoupdate=false) - wait_for_lock(updating_lock_path, 5) do - require "excon" + def self.update(prerelease) + wait_for_lock do require "heroku" - require "heroku/excon" require "tmpdir" require "zip/zip" - latest_version = Excon.get_with_redirect("http://assets.heroku.com/heroku-client/VERSION", :nonblock => false).body.chomp + return unless prerelease || needs_update? - if compare_versions(latest_version, latest_local_version) > 0 - Dir.mktmpdir do |download_dir| - File.open("#{download_dir}/heroku.zip", "wb") do |file| - file.print Excon.get_with_redirect(url, :nonblock => false).body - end + Dir.mktmpdir do |download_dir| + zip_filename = "#{download_dir}/heroku.zip" + if prerelease + url = "https://toolbelt.heroku.com/download/beta-zip" + else + url = "https://toolbelt.heroku.com/download/zip" + end - hash = Digest::SHA256.file("#{download_dir}/heroku.zip").hexdigest - official_hash = Excon.get_with_redirect("https://toolbelt.heroku.com/update/hash", :nonblock => false).body.chomp + download_file(url, zip_filename) + unless prerelease + hash = Digest::SHA256.file(zip_filename).hexdigest + error "Update hash signature mismatch" unless hash == official_zip_hash + end - error "Update hash signature mismatch" unless hash == official_hash + extract_zip(zip_filename, download_dir) + FileUtils.rm_f zip_filename - Zip::ZipFile.open("#{download_dir}/heroku.zip") do |zip| - zip.each do |entry| - target = File.join(download_dir, entry.to_s) - FileUtils.mkdir_p File.dirname(target) - zip.extract(entry, target) { true } - end - end + version = client_version_from_path(download_dir) - FileUtils.rm "#{download_dir}/heroku.zip" + # do not replace beta version if it is old + return if version < latest_local_version - old_version = latest_local_version - new_version = client_version_from_path(download_dir) + FileUtils.rm_rf updated_client_path + FileUtils.mkdir_p File.dirname(updated_client_path) + FileUtils.cp_r download_dir, updated_client_path - if compare_versions(new_version, old_version) < 0 && !autoupdate - Heroku::Helpers.error("Installed version (#{old_version}) is newer than the latest available update (#{new_version})") - end + version + end + end + end - FileUtils.rm_rf updated_client_path - FileUtils.mkdir_p File.dirname(updated_client_path) - FileUtils.cp_r download_dir, updated_client_path + def self.download_file(from_url, to_filename) + File.open(to_filename, "wb") do |file| + file.print http_get(from_url) + end + end - new_version - end - else - false # already up to date + def self.extract_zip(filename, dir) + Zip::ZipFile.open(filename) do |zip| + zip.each do |entry| + target = File.join(dir, entry.to_s) + FileUtils.mkdir_p File.dirname(target) + zip.extract(entry, target) { true } end end - ensure - FileUtils.rm_f(updating_lock_path) end def self.compare_versions(first_version, second_version) diff --git a/lib/heroku/version.rb b/lib/heroku/version.rb index 43b86f551..11eca788e 100644 --- a/lib/heroku/version.rb +++ b/lib/heroku/version.rb @@ -1,3 +1,3 @@ module Heroku - VERSION = "3.9.4" + VERSION = "3.11.1" end diff --git a/spec/fixtures/heroku-client-3.9.7.zip b/spec/fixtures/heroku-client-3.9.7.zip new file mode 100644 index 000000000..c109fdcf8 Binary files /dev/null and b/spec/fixtures/heroku-client-3.9.7.zip differ diff --git a/spec/helper/pg_dump_restore_spec.rb b/spec/helper/pg_dump_restore_spec.rb index f99020783..761c51063 100644 --- a/spec/helper/pg_dump_restore_spec.rb +++ b/spec/helper/pg_dump_restore_spec.rb @@ -7,35 +7,35 @@ end it 'requires uris for from and to arguments' do - expect { PgDumpRestore.new(nil , @localdb, mock) }.to raise_error - expect { PgDumpRestore.new(@remotedb, nil , mock) }.to raise_error - expect { PgDumpRestore.new(@remotedb, @localdb, mock) }.to_not raise_error + expect { PgDumpRestore.new(nil , @localdb, double) }.to raise_error + expect { PgDumpRestore.new(@remotedb, nil , double) }.to raise_error + expect { PgDumpRestore.new(@remotedb, @localdb, double) }.to_not raise_error end it 'uses PGPORT from ENV to set local port' do ENV['PGPORT'] = '15432' - expect(PgDumpRestore.new(@remotedb, @localdb, mock).instance_variable_get('@target').port).to eq 15432 + expect(PgDumpRestore.new(@remotedb, @localdb, double).instance_variable_get('@target').port).to eq 15432 end it 'on pulls, prepare requires the local database to not exist' do - mock_command = mock - mock_command.should_receive(:error).once + mock_command = double + expect(mock_command).to receive(:error).once pgdr = PgDumpRestore.new(@remotedb, @localdb, mock_command) - pgdr.should_receive(:`).once.and_return(`false`) + expect(pgdr).to receive(:`).once.and_return(`false`) pgdr.prepare end it 'on pushes, prepare requires the remote database to be empty' do - mock_command = mock - mock_command.should_receive(:error).once + mock_command = double + expect(mock_command).to receive(:error).once pgdr = PgDumpRestore.new(@localdb, @remotedb, mock_command) - mock_command.should_receive(:exec_sql_on_uri).once.and_return("something that isn't a true") + expect(mock_command).to receive(:exec_sql_on_uri).once.and_return("something that isn't a true") pgdr.prepare end it 'executes a proper dump/restore command' do - pgdr = PgDumpRestore.new(@remotedb, @localdb, mock) + pgdr = PgDumpRestore.new(@remotedb, @localdb, double) expect(pgdr.dump_restore_cmd).to match(/ pg_dump .* remotehost .* @@ -49,18 +49,18 @@ describe 'verification' do it 'errors when the extensions do not match' do - mock_command = mock - mock_command.should_receive(:error).once + mock_command = double + expect(mock_command).to receive(:error).once pgdr = PgDumpRestore.new(@localdb, @remotedb, mock_command) - mock_command.should_receive(:exec_sql_on_uri).twice.and_return("these", "don't match") + expect(mock_command).to receive(:exec_sql_on_uri).twice.and_return("these", "don't match") pgdr.verify end it 'is fine when the extensions match' do - mock_command = mock - mock_command.should_not_receive(:error) + mock_command = double + expect(mock_command).not_to receive(:error) pgdr = PgDumpRestore.new(@localdb, @remotedb, mock_command) - mock_command.should_receive(:exec_sql_on_uri).twice.and_return("these match", "these match") + expect(mock_command).to receive(:exec_sql_on_uri).twice.and_return("these match", "these match") pgdr.verify end end diff --git a/spec/heroku/auth_spec.rb b/spec/heroku/auth_spec.rb index ee9a04da9..5e50b1614 100644 --- a/spec/heroku/auth_spec.rb +++ b/spec/heroku/auth_spec.rb @@ -10,16 +10,16 @@ module Heroku ENV['HEROKU_API_KEY'] = nil @cli = Heroku::Auth - @cli.stub!(:check) - @cli.stub!(:display) - @cli.stub!(:running_on_a_mac?).and_return(false) + allow(@cli).to receive(:check) + allow(@cli).to receive(:display) + allow(@cli).to receive(:running_on_a_mac?).and_return(false) @cli.credentials = nil FakeFS.activate! - FakeFS::File.stub!(:stat).and_return(double('stat', :mode => "0600".to_i(8))) - FakeFS::FileUtils.stub!(:chmod) - FakeFS::File.stub!(:readlines) do |path| + allow(FakeFS::File).to receive(:stat).and_return(double('stat', :mode => "0600".to_i(8))) + allow(FakeFS::FileUtils).to receive(:chmod) + allow(FakeFS::File).to receive(:readlines) do |path| File.read(path).split("\n").map {|line| "#{line}\n"} end @@ -48,16 +48,16 @@ module Heroku it "should translate to netrc and cleanup" do # preconditions - File.exist?(@cli.legacy_credentials_path).should == true - File.exist?(@cli.netrc_path).should == false + expect(File.exist?(@cli.legacy_credentials_path)).to eq(true) + expect(File.exist?(@cli.netrc_path)).to eq(false) # transition - @cli.get_credentials.should == ['legacy_user', 'legacy_pass'] + expect(@cli.get_credentials).to eq(['legacy_user', 'legacy_pass']) # postconditions - File.exist?(@cli.legacy_credentials_path).should == false - File.exist?(@cli.netrc_path).should == true - Netrc.read(@cli.netrc_path)["api.#{@cli.host}"].should == ['legacy_user', 'legacy_pass'] + expect(File.exist?(@cli.legacy_credentials_path)).to eq(false) + expect(File.exist?(@cli.netrc_path)).to eq(true) + expect(Netrc.read(@cli.netrc_path)["api.#{@cli.host}"]).to eq(['legacy_user', 'legacy_pass']) end end @@ -67,34 +67,34 @@ module Heroku end it "gets credentials from environment variables in preference to credentials file" do - @cli.read_credentials.should == ['', ENV['HEROKU_API_KEY']] + expect(@cli.read_credentials).to eq(['', ENV['HEROKU_API_KEY']]) end it "returns a blank username" do - @cli.user.should be_empty + expect(@cli.user).to be_empty end it "returns the api key as the password" do - @cli.password.should == ENV['HEROKU_API_KEY'] + expect(@cli.password).to eq(ENV['HEROKU_API_KEY']) end it "does not overwrite credentials file with environment variable credentials" do - @cli.should_not_receive(:write_credentials) + expect(@cli).not_to receive(:write_credentials) @cli.read_credentials end context "reauthenticating" do before do - @cli.stub!(:ask_for_credentials).and_return(['new_user', 'new_password']) - @cli.stub!(:check) - @cli.should_receive(:check_for_associated_ssh_key) + allow(@cli).to receive(:ask_for_credentials).and_return(['new_user', 'new_password']) + allow(@cli).to receive(:check) + expect(@cli).to receive(:check_for_associated_ssh_key) @cli.reauthorize end it "updates saved credentials" do - Netrc.read(@cli.netrc_path)["api.#{@cli.host}"].should == ['new_user', 'new_password'] + expect(Netrc.read(@cli.netrc_path)["api.#{@cli.host}"]).to eq(['new_user', 'new_password']) end it "returns environment variable credentials" do - @cli.read_credentials.should == ['', ENV['HEROKU_API_KEY']] + expect(@cli.read_credentials).to eq(['', ENV['HEROKU_API_KEY']]) end end @@ -103,56 +103,56 @@ module Heroku @cli.logout end it "should delete saved credentials" do - File.exists?(@cli.legacy_credentials_path).should be_false - Netrc.read(@cli.netrc_path)["api.#{@cli.host}"].should be_nil + expect(File.exists?(@cli.legacy_credentials_path)).to be_falsey + expect(Netrc.read(@cli.netrc_path)["api.#{@cli.host}"]).to be_nil end end end describe "#base_host" do it "returns the host without the first part" do - @cli.base_host("http://foo.bar.com").should == "bar.com" + expect(@cli.base_host("http://foo.bar.com")).to eq("bar.com") end it "works with localhost" do - @cli.base_host("http://localhost:3000").should == "localhost" + expect(@cli.base_host("http://localhost:3000")).to eq("localhost") end end it "asks for credentials when the file doesn't exist" do @cli.delete_credentials - @cli.should_receive(:ask_for_credentials).and_return(["u", "p"]) - @cli.should_receive(:check_for_associated_ssh_key) - @cli.user.should == 'u' - @cli.password.should == 'p' + expect(@cli).to receive(:ask_for_credentials).and_return(["u", "p"]) + expect(@cli).to receive(:check_for_associated_ssh_key) + expect(@cli.user).to eq('u') + expect(@cli.password).to eq('p') end it "writes credentials and uploads authkey when credentials are saved" do - @cli.stub!(:credentials) - @cli.stub!(:check) - @cli.stub!(:ask_for_credentials).and_return("username", "apikey") - @cli.should_receive(:write_credentials) - @cli.should_receive(:check_for_associated_ssh_key) + allow(@cli).to receive(:credentials) + allow(@cli).to receive(:check) + allow(@cli).to receive(:ask_for_credentials).and_return("username", "apikey") + expect(@cli).to receive(:write_credentials) + expect(@cli).to receive(:check_for_associated_ssh_key) @cli.ask_for_and_save_credentials end it "save_credentials deletes the credentials when the upload authkey is unauthorized" do - @cli.stub!(:write_credentials) - @cli.stub!(:retry_login?).and_return(false) - @cli.stub!(:ask_for_credentials).and_return("username", "apikey") - @cli.stub!(:check) { raise Heroku::API::Errors::Unauthorized.new("Login Failed", Excon::Response.new) } - @cli.should_receive(:delete_credentials) - lambda { @cli.ask_for_and_save_credentials }.should raise_error(SystemExit) + allow(@cli).to receive(:write_credentials) + allow(@cli).to receive(:retry_login?).and_return(false) + allow(@cli).to receive(:ask_for_credentials).and_return("username", "apikey") + allow(@cli).to receive(:check) { raise Heroku::API::Errors::Unauthorized.new("Login Failed", Excon::Response.new) } + expect(@cli).to receive(:delete_credentials) + expect { @cli.ask_for_and_save_credentials }.to raise_error(SystemExit) end it "asks for login again when not authorized, for three times" do - @cli.stub!(:read_credentials) - @cli.stub!(:write_credentials) - @cli.stub!(:delete_credentials) - @cli.stub!(:ask_for_credentials).and_return("username", "apikey") - @cli.stub!(:check) { raise Heroku::API::Errors::Unauthorized.new("Login Failed", Excon::Response.new) } - @cli.should_receive(:ask_for_credentials).exactly(3).times - lambda { @cli.ask_for_and_save_credentials }.should raise_error(SystemExit) + allow(@cli).to receive(:read_credentials) + allow(@cli).to receive(:write_credentials) + allow(@cli).to receive(:delete_credentials) + allow(@cli).to receive(:ask_for_credentials).and_return("username", "apikey") + allow(@cli).to receive(:check) { raise Heroku::API::Errors::Unauthorized.new("Login Failed", Excon::Response.new) } + expect(@cli).to receive(:ask_for_credentials).exactly(3).times + expect { @cli.ask_for_and_save_credentials }.to raise_error(SystemExit) end it "deletes the credentials file" do @@ -160,16 +160,16 @@ module Heroku File.open(@cli.legacy_credentials_path, "w") do |file| file.puts "legacy_user\nlegacy_pass" end - FileUtils.should_receive(:rm_f).with(@cli.legacy_credentials_path) + expect(FileUtils).to receive(:rm_f).with(@cli.legacy_credentials_path) @cli.delete_credentials end it "writes the login information to the credentials file for the 'heroku login' command" do - @cli.stub!(:ask_for_credentials).and_return(['one', 'two']) - @cli.stub!(:check) - @cli.should_receive(:check_for_associated_ssh_key) + allow(@cli).to receive(:ask_for_credentials).and_return(['one', 'two']) + allow(@cli).to receive(:check) + expect(@cli).to receive(:check_for_associated_ssh_key) @cli.reauthorize - Netrc.read(@cli.netrc_path)["api.#{@cli.host}"].should == (['one', 'two']) + expect(Netrc.read(@cli.netrc_path)["api.#{@cli.host}"]).to eq(['one', 'two']) end it "migrates long api keys to short api keys" do @@ -177,76 +177,66 @@ module Heroku api_key = "7e262de8cac430d8a250793ce8d5b334ae56b4ff15767385121145198a2b4d2e195905ef8bf7cfc5" @cli.netrc["api.#{@cli.host}"] = ["user", api_key] - @cli.get_credentials.should == ["user", api_key[0,40]] + expect(@cli.get_credentials).to eq(["user", api_key[0,40]]) %w{api code}.each do |section| - Netrc.read(@cli.netrc_path)["#{section}.#{@cli.host}"].should == ["user", api_key[0,40]] + expect(Netrc.read(@cli.netrc_path)["#{section}.#{@cli.host}"]).to eq(["user", api_key[0,40]]) end end describe "automatic key uploading" do before(:each) do + allow(@cli).to receive(:home_directory).and_return(Heroku::Helpers.home_directory) FileUtils.mkdir_p("#{@cli.home_directory}/.ssh") - @cli.stub!(:ask_for_credentials).and_return("username", "apikey") + allow(@cli).to receive(:ask_for_credentials).and_return("username", "apikey") end describe "an account with existing keys" do before :each do - @api = mock(Object) - @response = mock(Object) - @response.should_receive(:body).and_return(['existingkeys']) - @api.should_receive(:get_keys).and_return(@response) - @cli.should_receive(:api).and_return(@api) + @api = double(Object) + @response = double(Object) + expect(@response).to receive(:body).and_return(['existingkeys']) + expect(@api).to receive(:get_keys).and_return(@response) + expect(@cli).to receive(:api).and_return(@api) end it "should not do anything if the account already has keys" do - @cli.should_not_receive(:associate_key) + expect(@cli).not_to receive(:associate_key) @cli.check_for_associated_ssh_key end end describe "an account with no keys" do before :each do - @api = mock(Object) - @response = mock(Object) - @response.should_receive(:body).and_return([]) - @api.should_receive(:get_keys).and_return(@response) - @cli.should_receive(:api).and_return(@api) + @api = double(Object) + @response = double(Object) + expect(@response).to receive(:body).and_return([]) + expect(@api).to receive(:get_keys).and_return(@response) + expect(@cli).to receive(:api).and_return(@api) end describe "with zero public keys" do it "should ask to generate a key" do - @cli.should_receive(:ask).and_return("y") - @cli.should_receive(:generate_ssh_key).with("id_rsa") - @cli.should_receive(:associate_key).with("#{@cli.home_directory}/.ssh/id_rsa.pub") - @cli.check_for_associated_ssh_key - end - end - - describe "with one public key" do - before(:each) { FileUtils.touch("#{@cli.home_directory}/.ssh/id_rsa.pub") } - after(:each) { FileUtils.rm("#{@cli.home_directory}/.ssh/id_rsa.pub") } - - it "should upload the key" do - @cli.should_receive(:associate_key).with("#{@cli.home_directory}/.ssh/id_rsa.pub") + expect(@cli).to receive(:ask).and_return("y") + expect(@cli).to receive(:generate_ssh_key).with("#{@cli.home_directory}/.ssh/id_rsa") + expect(@cli).to receive(:associate_key).with("#{@cli.home_directory}/.ssh/id_rsa.pub") @cli.check_for_associated_ssh_key end end describe "with many public keys" do - before(:each) do + before :each do FileUtils.touch("#{@cli.home_directory}/.ssh/id_rsa.pub") FileUtils.touch("#{@cli.home_directory}/.ssh/id_rsa2.pub") end - after(:each) do - FileUtils.rm("#{@cli.home_directory}/.ssh/id_rsa.pub") - FileUtils.rm("#{@cli.home_directory}/.ssh/id_rsa2.pub") + after :each do + FileUtils.rm_rf(@cli.home_directory) end it "should ask which key to upload" do File.open("#{@cli.home_directory}/.ssh/id_rsa.pub", "w") { |f| f.puts } - @cli.should_receive(:associate_key).with("#{@cli.home_directory}/.ssh/id_rsa2.pub") - @cli.should_receive(:ask).and_return("2") + expect(@cli).to receive(:associate_key).with("#{@cli.home_directory}/.ssh/id_rsa2.pub") + expect(@cli).to receive(:ask).and_return("2") @cli.check_for_associated_ssh_key end end diff --git a/spec/heroku/client/heroku_postgresql_spec.rb b/spec/heroku/client/heroku_postgresql_spec.rb index 840e24a79..94b575c5c 100644 --- a/spec/heroku/client/heroku_postgresql_spec.rb +++ b/spec/heroku/client/heroku_postgresql_spec.rb @@ -6,7 +6,8 @@ include Heroku::Helpers before do - Heroku::Auth.stub :user => 'user@example.com', :password => 'apitoken' + allow(Heroku::Auth).to receive(:user).and_return('user@example.com') + allow(Heroku::Auth).to receive(:password).and_return('apitoken') end let(:attachment) { double('attachment', :resource_name => 'something-something-42', :starter_plan? => false) } @@ -14,7 +15,7 @@ describe 'api choosing' do it "sends an ingress request to the client for production plans" do - attachment.stub! :starter_plan? => false + expect(attachment).to receive(:starter_plan?).and_return(false) host = 'postgres-api.heroku.com' url = "https://user@example.com:apitoken@#{host}/client/v11/databases/#{attachment.resource_name}/ingress" @@ -25,11 +26,11 @@ client.ingress - a_request(:put, url).should have_been_made.once + expect(a_request(:put, url)).to have_been_made.once end it "sends an ingress request to the client for production plans" do - attachment.stub! :starter_plan? => true + allow(attachment).to receive_messages :starter_plan? => true host = 'postgres-starter-api.heroku.com' url = "https://user@example.com:apitoken@#{host}/client/v11/databases/#{attachment.resource_name}/ingress" @@ -40,7 +41,7 @@ client.ingress - a_request(:put, url).should have_been_made.once + expect(a_request(:put, url)).to have_been_made.once end end @@ -50,21 +51,21 @@ it 'works without the extended option' do stub_request(:get, url).to_return :body => '{}' client.get_database - a_request(:get, url).should have_been_made.once + expect(a_request(:get, url)).to have_been_made.once end it 'works with the extended option' do url2 = url + '?extended=true' stub_request(:get, url2).to_return :body => '{}' client.get_database(true) - a_request(:get, url2).should have_been_made.once + expect(a_request(:get, url2)).to have_been_made.once end it "retries on error, then raises" do stub_request(:get, url).to_return(:body => "error", :status => 500) - client.stub(:sleep) - lambda { client.get_database }.should raise_error RestClient::InternalServerError - a_request(:get, url).should have_been_made.times(4) + allow(client).to receive(:sleep) + expect { client.get_database }.to raise_error RestClient::InternalServerError + expect(a_request(:get, url)).to have_been_made.times(4) end end diff --git a/spec/heroku/client/pgbackups_spec.rb b/spec/heroku/client/pgbackups_spec.rb index b6b7cdfb2..e4fa794cf 100644 --- a/spec/heroku/client/pgbackups_spec.rb +++ b/spec/heroku/client/pgbackups_spec.rb @@ -14,16 +14,16 @@ let(:version) { Heroku::Client.version } it 'still has a heroku gem version' do - version.should be - version.split(/\./).first.to_i.should >= 2 + expect(version).to be + expect(version.split(/\./).first.to_i).to be >= 2 end it 'includes the heroku gem version' do stub_request(:get, transfer_path) client.get_transfers - a_request(:get, transfer_path).with( + expect(a_request(:get, transfer_path).with( :headers => {'X-Heroku-Gem-Version' => version} - ).should have_been_made.once + )).to have_been_made.once end end @@ -36,7 +36,7 @@ client.create_transfer("postgres://from", "postgres://to", "FROMNAME", "TO_NAME") - a_request(:post, transfer_path).should have_been_made.once + expect(a_request(:post, transfer_path)).to have_been_made.once end end diff --git a/spec/heroku/client/rendezvous_spec.rb b/spec/heroku/client/rendezvous_spec.rb index f450ec98a..1cc73f7b8 100644 --- a/spec/heroku/client/rendezvous_spec.rb +++ b/spec/heroku/client/rendezvous_spec.rb @@ -12,51 +12,51 @@ end context "fixup" do it "null" do - @rendezvous.send(:fixup, nil).should be_nil + expect(@rendezvous.send(:fixup, nil)).to be_nil end it "an empty string" do - @rendezvous.send(:fixup, "").should eq "" + expect(@rendezvous.send(:fixup, "")).to eq "" end it "hash" do - @rendezvous.send(:fixup, { :x => :y }).should eq({ :x => :y }) + expect(@rendezvous.send(:fixup, { :x => :y })).to eq({ :x => :y }) end it "default English UTF-8 data" do - @rendezvous.send(:fixup, "heroku").should eq "heroku" + expect(@rendezvous.send(:fixup, "heroku")).to eq "heroku" end it "default Japanese UTF-8 encoded data" do - @rendezvous.send(:fixup, "愛しています").should eq "愛しています" + expect(@rendezvous.send(:fixup, "愛しています")).to eq "愛しています" end if RUBY_VERSION >= "1.9" it "ISO-8859-1 force-encoded data" do - @rendezvous.send(:fixup, "Хероку".force_encoding("ISO-8859-1")).should eq "Хероку".force_encoding("UTF-8") + expect(@rendezvous.send(:fixup, "Хероку".force_encoding("ISO-8859-1"))).to eq "Хероку".force_encoding("UTF-8") end end end context "with mock ssl" do before :each do mock_openssl - @ssl_socket_mock.should_receive(:puts).with("secret") - @ssl_socket_mock.should_receive(:readline).and_return(nil) + expect(@ssl_socket_mock).to receive(:puts).with("secret") + expect(@ssl_socket_mock).to receive(:readline).and_return(nil) end it "should connect to host:post" do - TCPSocket.should_receive(:open).with("heroku.local", 1234).and_return(@tcp_socket_mock) - IO.stub(:select).and_return(nil) - @ssl_socket_mock.stub(:write) - @ssl_socket_mock.stub(:flush) { raise Timeout::Error } - lambda { @rendezvous.start }.should raise_error(Timeout::Error) + expect(TCPSocket).to receive(:open).with("heroku.local", 1234).and_return(@tcp_socket_mock) + allow(IO).to receive(:select).and_return(nil) + allow(@ssl_socket_mock).to receive(:write) + allow(@ssl_socket_mock).to receive(:flush) { raise Timeout::Error } + expect { @rendezvous.start }.to raise_error(Timeout::Error) end it "should callback on_connect" do @rendezvous.on_connect do raise "on_connect" end - TCPSocket.should_receive(:open).and_return(@tcp_socket_mock) - lambda { @rendezvous.start }.should raise_error("on_connect") + expect(TCPSocket).to receive(:open).and_return(@tcp_socket_mock) + expect { @rendezvous.start }.to raise_error("on_connect") end it "should fixup received data" do - TCPSocket.should_receive(:open).and_return(@tcp_socket_mock) - @ssl_socket_mock.should_receive(:readpartial).and_return("The quick brown fox jumps over the lazy dog") - @rendezvous.stub(:fixup) { |data| raise "received: #{data}" } - lambda { @rendezvous.start }.should raise_error("received: The quick brown fox jumps over the lazy dog") + expect(TCPSocket).to receive(:open).and_return(@tcp_socket_mock) + expect(@ssl_socket_mock).to receive(:readpartial).and_return("The quick brown fox jumps over the lazy dog") + allow(@rendezvous).to receive(:fixup) { |data| raise "received: #{data}" } + expect { @rendezvous.start }.to raise_error("received: The quick brown fox jumps over the lazy dog") end end end diff --git a/spec/heroku/client/ssl_endpoint_spec.rb b/spec/heroku/client/ssl_endpoint_spec.rb index d58f1e1cb..a78abf49d 100644 --- a/spec/heroku/client/ssl_endpoint_spec.rb +++ b/spec/heroku/client/ssl_endpoint_spec.rb @@ -10,22 +10,22 @@ stub_request(:post, "https://api.heroku.com/apps/example/ssl-endpoints"). with(:body => { :accept => "json", :pem => "pem content", :key => "key content" }). to_return(:body => %{ {"cname": "tokyo-1050" } }) - @client.ssl_endpoint_add("example", "pem content", "key content").should == { "cname" => "tokyo-1050" } + expect(@client.ssl_endpoint_add("example", "pem content", "key content")).to eq({ "cname" => "tokyo-1050" }) end it "gets info on an ssl endpoint" do stub_request(:get, "https://api.heroku.com/apps/example/ssl-endpoints/tokyo-1050"). to_return(:body => %{ {"cname": "tokyo-1050" } }) - @client.ssl_endpoint_info("example", "tokyo-1050").should == { "cname" => "tokyo-1050" } + expect(@client.ssl_endpoint_info("example", "tokyo-1050")).to eq({ "cname" => "tokyo-1050" }) end it "lists ssl endpoints for an app" do stub_request(:get, "https://api.heroku.com/apps/example/ssl-endpoints"). to_return(:body => %{ [{"cname": "tokyo-1050" }, {"cname": "tokyo-1051" }] }) - @client.ssl_endpoint_list("example").should == [ + expect(@client.ssl_endpoint_list("example")).to eq([ { "cname" => "tokyo-1050" }, { "cname" => "tokyo-1051" }, - ] + ]) end it "removes an ssl endpoint" do @@ -36,13 +36,13 @@ it "rolls back an ssl endpoint" do stub_request(:post, "https://api.heroku.com/apps/example/ssl-endpoints/tokyo-1050/rollback"). to_return(:body => %{ {"cname": "tokyo-1050" } }) - @client.ssl_endpoint_rollback("example", "tokyo-1050").should == { "cname" => "tokyo-1050" } + expect(@client.ssl_endpoint_rollback("example", "tokyo-1050")).to eq({ "cname" => "tokyo-1050" }) end it "updates an ssl endpoint" do stub_request(:put, "https://api.heroku.com/apps/example/ssl-endpoints/tokyo-1050"). with(:body => { :accept => "json", :pem => "pem content", :key => "key content" }). to_return(:body => %{ {"cname": "tokyo-1050" } }) - @client.ssl_endpoint_update("example", "tokyo-1050", "pem content", "key content").should == { "cname" => "tokyo-1050" } + expect(@client.ssl_endpoint_update("example", "tokyo-1050", "pem content", "key content")).to eq({ "cname" => "tokyo-1050" }) end end diff --git a/spec/heroku/client_spec.rb b/spec/heroku/client_spec.rb index 56c2cceac..d9a8826a9 100644 --- a/spec/heroku/client_spec.rb +++ b/spec/heroku/client_spec.rb @@ -8,15 +8,15 @@ before do @client = Heroku::Client.new(nil, nil) - @resource = mock('heroku rest resource') - @client.stub!(:extract_warning) + @resource = double('heroku rest resource') + allow(@client).to receive(:extract_warning) end it "Client.auth -> get user details" do user_info = { "api_key" => "abc" } stub_request(:post, "https://foo:bar@api.heroku.com/login").to_return(:body => json_encode(user_info)) capture_stderr do # capture deprecation message - Heroku::Client.auth("foo", "bar").should == user_info + expect(Heroku::Client.auth("foo", "bar")).to eq(user_info) end end @@ -29,10 +29,10 @@ EOXML capture_stderr do # capture deprecation message - @client.list.should == [ + expect(@client.list).to eq([ ["example", "test@heroku.com"], ["example2", "test@heroku.com"] - ] + ]) end end @@ -49,10 +49,10 @@ EOXML - @client.stub!(:list_collaborators).and_return([:jon, :mike]) - @client.stub!(:installed_addons).and_return([:addon1]) + allow(@client).to receive(:list_collaborators).and_return([:jon, :mike]) + allow(@client).to receive(:installed_addons).and_return([:addon1]) capture_stderr do # capture deprecation message - @client.info('example').should == { :blessed => 'true', :created_at => '2008-07-08T17:21:50-07:00', :id => '49134', :name => 'example', :production => 'true', :share_public => 'true', :domain_name => nil, :collaborators => [:jon, :mike], :addons => [:addon1] } + expect(@client.info('example')).to eq({ :blessed => 'true', :created_at => '2008-07-08T17:21:50-07:00', :id => '49134', :name => 'example', :production => 'true', :share_public => 'true', :domain_name => nil, :collaborators => [:jon, :mike], :addons => [:addon1] }) end end @@ -62,7 +62,7 @@ untitled-123 EOXML capture_stderr do # capture deprecation message - @client.create_request.should == "untitled-123" + expect(@client.create_request).to eq("untitled-123") end end @@ -72,17 +72,17 @@ newapp EOXML capture_stderr do # capture deprecation message - @client.create_request("newapp").should == "newapp" + expect(@client.create_request("newapp")).to eq("newapp") end end it "create_complete?(name) -> checks if a create request is complete" do - @response = mock('response') - @response.should_receive(:code).and_return(202) - @client.should_receive(:resource).and_return(@resource) - @resource.should_receive(:put).with({}, @client.heroku_headers).and_return(@response) + @response = double('response') + expect(@response).to receive(:code).and_return(202) + expect(@client).to receive(:resource).and_return(@resource) + expect(@resource).to receive(:put).with({}, @client.heroku_headers).and_return(@response) capture_stderr do # capture deprecation message - @client.create_complete?('example').should be_false + expect(@client.create_complete?('example')).to be_falsey end end @@ -119,7 +119,7 @@ stub_api_request(:delete, "/apps/example/consoles/consolename") @client.console('example') do |c| - c.run("1+1").should == '=> 2' + expect(c.run("1+1")).to eq('=> 2') end end @@ -127,7 +127,7 @@ stub_request(:post, %r{.*/apps/example/console}).to_return({ :body => "ERRMSG", :status => 502 }) - lambda { @client.console('example') }.should raise_error(Heroku::Client::AppCrashed, /Your application may have crashed/) + expect { @client.console('example') }.to raise_error(Heroku::Client::AppCrashed, /Your application may have crashed/) end it "restart(app_name) -> restarts the app servers" do @@ -145,7 +145,7 @@ end it "can read old style logs" do - @client.should_receive(:puts).with("oldlogs") + expect(@client).to receive(:puts).with("oldlogs") @client.read_logs("example") end end @@ -158,7 +158,7 @@ it "can read new style logs" do @client.read_logs("example") do |logs| - logs.should == "newlogs" + expect(logs).to eq("newlogs") end end end @@ -167,7 +167,7 @@ it "logs(app_name) -> returns recent output of the app logs" do stub_api_request(:get, "/apps/example/logs").to_return(:body => "log") capture_stderr do # capture deprecation message - @client.logs('example').should == 'log' + expect(@client.logs('example')).to eq('log') end end @@ -179,7 +179,7 @@ EOXML capture_stderr do # capture deprecation message - @client.dynos('example').should == 5 + expect(@client.dynos('example')).to eq(5) end end @@ -191,7 +191,7 @@ EOXML capture_stderr do # capture deprecation message - @client.workers('example').should == 5 + expect(@client.workers('example')).to eq(5) end end @@ -204,21 +204,21 @@ it "rake catches 502s and shows the app crashlog" do e = RestClient::RequestFailed.new - e.stub!(:http_code).and_return(502) - e.stub!(:http_body).and_return('the crashlog') - @client.should_receive(:post).and_raise(e) + allow(e).to receive(:http_code).and_return(502) + allow(e).to receive(:http_body).and_return('the crashlog') + expect(@client).to receive(:post).and_raise(e) capture_stderr do # capture deprecation message - lambda { @client.rake('example', '') }.should raise_error(Heroku::Client::AppCrashed) + expect { @client.rake('example', '') }.to raise_error(Heroku::Client::AppCrashed) end end it "rake passes other status codes (i.e., 500) as standard restclient exceptions" do e = RestClient::RequestFailed.new - e.stub!(:http_code).and_return(500) - e.stub!(:http_body).and_return('not a crashlog') - @client.should_receive(:post).and_raise(e) + allow(e).to receive(:http_code).and_return(500) + allow(e).to receive(:http_body).and_return('not a crashlog') + expect(@client).to receive(:post).and_raise(e) capture_stderr do # capture deprecation message - lambda { @client.rake('example', '') }.should raise_error(RestClient::RequestFailed) + expect { @client.rake('example', '') }.to raise_error(RestClient::RequestFailed) end end @@ -226,7 +226,7 @@ it "scales a process and returns the new count" do stub_api_request(:post, "/apps/example/ps/scale").with(:body => { :type => "web", :qty => "5" }).to_return(:body => "5") capture_stderr do # capture deprecation message - @client.ps_scale("example", :type => "web", :qty => "5").should == 5 + expect(@client.ps_scale("example", :type => "web", :qty => "5")).to eq(5) end end end @@ -241,10 +241,10 @@ EOXML capture_stderr do # capture deprecation message - @client.list_collaborators('example').should == [ + expect(@client.list_collaborators('example')).to eq([ { :email => 'joe@example.com' }, { :email => 'jon@example.com' } - ] + ]) end end @@ -273,7 +273,7 @@ EOXML capture_stderr do # capture deprecation message - @client.list_domains('example').should == [{:domain => 'example1.com'}, {:domain => 'example2.com'}] + expect(@client.list_domains('example')).to eq([{:domain => 'example1.com'}, {:domain => 'example2.com'}]) end end @@ -292,11 +292,11 @@ end it "remove_domain(app_name, domain) -> makes sure a domain is set" do - lambda do + expect do capture_stderr do # capture deprecation message @client.remove_domain('example', '') end - end.should raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "remove_domains(app_name) -> removes all domain names from app" do @@ -309,8 +309,8 @@ it "add_ssl(app_name, pem, key) -> adds a ssl cert to the domain" do stub_api_request(:post, "/apps/example/ssl").with do |request| body = CGI::parse(request.body) - body["key"].first.should == "thekey" - body["pem"].first.should == "thepem" + expect(body["key"].first).to eq("thekey") + expect(body["pem"].first).to eq("thepem") end.to_return(:body => "{}") @client.add_ssl('example', 'thepem', 'thekey') end @@ -332,7 +332,7 @@ EOXML capture_stderr do # capture deprecation message - @client.keys.should == [ "ssh-dss thekey== joe@workstation" ] + expect(@client.keys).to eq([ "ssh-dss thekey== joe@workstation" ]) end end @@ -376,7 +376,7 @@ it "config_vars(app_name) -> json hash of config vars for the app" do stub_api_request(:get, "/apps/example/config_vars").to_return(:body => '{"A":"one", "B":"two"}') capture_stderr do # capture deprecation message - @client.config_vars('example').should == { 'A' => 'one', 'B' => 'two'} + expect(@client.config_vars('example')).to eq({ 'A' => 'one', 'B' => 'two'}) end end @@ -404,7 +404,7 @@ it "can handle config vars with special characters" do stub_api_request(:delete, "/apps/example/config_vars/foo%5Bbar%5D") capture_stderr do # capture deprecation message - lambda { @client.remove_config_var('example', 'foo[bar]') }.should_not raise_error + expect { @client.remove_config_var('example', 'foo[bar]') }.not_to raise_error end end end @@ -412,73 +412,73 @@ describe "addons" do it "addons -> array with addons available for installation" do stub_api_request(:get, "/addons").to_return(:body => '[{"name":"addon1"}, {"name":"addon2"}]') - @client.addons.should == [{'name' => 'addon1'}, {'name' => 'addon2'}] + expect(@client.addons).to eq([{'name' => 'addon1'}, {'name' => 'addon2'}]) end it "installed_addons(app_name) -> array of installed addons" do stub_api_request(:get, "/apps/example/addons").to_return(:body => '[{"name":"addon1"}]') - @client.installed_addons('example').should == [{'name' => 'addon1'}] + expect(@client.installed_addons('example')).to eq([{'name' => 'addon1'}]) end it "install_addon(app_name, addon_name)" do stub_api_request(:post, "/apps/example/addons/addon1") - @client.install_addon('example', 'addon1').should be_nil + expect(@client.install_addon('example', 'addon1')).to be_nil end it "upgrade_addon(app_name, addon_name)" do stub_api_request(:put, "/apps/example/addons/addon1") - @client.upgrade_addon('example', 'addon1').should be_nil + expect(@client.upgrade_addon('example', 'addon1')).to be_nil end it "downgrade_addon(app_name, addon_name)" do stub_api_request(:put, "/apps/example/addons/addon1") - @client.downgrade_addon('example', 'addon1').should be_nil + expect(@client.downgrade_addon('example', 'addon1')).to be_nil end it "uninstall_addon(app_name, addon_name)" do stub_api_request(:delete, "/apps/example/addons/addon1?"). to_return(:body => json_encode({"message" => nil, "price" => "free", "status" => "uninstalled"})) - @client.uninstall_addon('example', 'addon1').should be_true + expect(@client.uninstall_addon('example', 'addon1')).to be_truthy end it "uninstall_addon(app_name, addon_name) with confirmation" do stub_api_request(:delete, "/apps/example/addons/addon1?confirm=example"). to_return(:body => json_encode({"message" => nil, "price" => "free", "status" => "uninstalled"})) - @client.uninstall_addon('example', 'addon1', :confirm => "example").should be_true + expect(@client.uninstall_addon('example', 'addon1', :confirm => "example")).to be_truthy end it "install_addon(app_name, addon_name) with response" do stub_request(:post, "https://api.heroku.com/apps/example/addons/addon1"). to_return(:body => json_encode({'price' => 'free', 'message' => "Don't Panic"})) - @client.install_addon('example', 'addon1'). - should == { 'price' => 'free', 'message' => "Don't Panic" } + expect(@client.install_addon('example', 'addon1')). + to eq({ 'price' => 'free', 'message' => "Don't Panic" }) end it "upgrade_addon(app_name, addon_name) with response" do stub_request(:put, "https://api.heroku.com/apps/example/addons/addon1"). to_return(:body => json_encode('price' => 'free', 'message' => "Don't Panic")) - @client.upgrade_addon('example', 'addon1'). - should == { 'price' => 'free', 'message' => "Don't Panic" } + expect(@client.upgrade_addon('example', 'addon1')). + to eq({ 'price' => 'free', 'message' => "Don't Panic" }) end it "downgrade_addon(app_name, addon_name) with response" do stub_request(:put, "https://api.heroku.com/apps/example/addons/addon1"). to_return(:body => json_encode('price' => 'free', 'message' => "Don't Panic")) - @client.downgrade_addon('example', 'addon1'). - should == { 'price' => 'free', 'message' => "Don't Panic" } + expect(@client.downgrade_addon('example', 'addon1')). + to eq({ 'price' => 'free', 'message' => "Don't Panic" }) end it "uninstall_addon(app_name, addon_name) with response" do stub_api_request(:delete, "/apps/example/addons/addon1?"). to_return(:body => json_encode('price'=> 'free', 'message'=> "Don't Panic")) - @client.uninstall_addon('example', 'addon1'). - should == { 'price' => 'free', 'message' => "Don't Panic" } + expect(@client.uninstall_addon('example', 'addon1')). + to eq({ 'price' => 'free', 'message' => "Don't Panic" }) end end @@ -488,45 +488,45 @@ end it "creates a RestClient resource for making calls" do - @client.stub!(:host).and_return('heroku.com') - @client.stub!(:user).and_return('joe@example.com') - @client.stub!(:password).and_return('secret') + allow(@client).to receive(:host).and_return('heroku.com') + allow(@client).to receive(:user).and_return('joe@example.com') + allow(@client).to receive(:password).and_return('secret') res = @client.resource('/xyz') - res.url.should == 'https://api.heroku.com/xyz' - res.user.should == 'joe@example.com' - res.password.should == 'secret' + expect(res.url).to eq('https://api.heroku.com/xyz') + expect(res.user).to eq('joe@example.com') + expect(res.password).to eq('secret') end it "appends the api. prefix to the host" do @client.host = "heroku.com" - @client.resource('/xyz').url.should == 'https://api.heroku.com/xyz' + expect(@client.resource('/xyz').url).to eq('https://api.heroku.com/xyz') end it "doesn't add the api. prefix to full hosts" do @client.host = 'http://resource' res = @client.resource('/xyz') - res.url.should == 'http://resource/xyz' + expect(res.url).to eq('http://resource/xyz') end it "runs a callback when the API sets a warning header" do - response = mock('rest client response', :headers => { :x_heroku_warning => 'Warning' }) - @client.should_receive(:resource).and_return(@resource) - @resource.should_receive(:get).and_return(response) + response = double('rest client response', :headers => { :x_heroku_warning => 'Warning' }) + expect(@client).to receive(:resource).and_return(@resource) + expect(@resource).to receive(:get).and_return(response) @client.on_warning { |msg| @callback = msg } @client.get('test') - @callback.should == 'Warning' + expect(@callback).to eq('Warning') end it "doesn't run the callback twice for the same warning" do - response = mock('rest client response', :headers => { :x_heroku_warning => 'Warning' }) - @client.stub!(:resource).and_return(@resource) - @resource.stub!(:get).and_return(response) + response = double('rest client response', :headers => { :x_heroku_warning => 'Warning' }) + allow(@client).to receive(:resource).and_return(@resource) + allow(@resource).to receive(:get).and_return(response) @client.on_warning { |msg| @callback_called ||= 0; @callback_called += 1 } @client.get('test1') @client.get('test2') - @callback_called.should == 1 + expect(@callback_called).to eq(1) end end @@ -534,14 +534,14 @@ it "list_stacks(app_name) -> json hash of available stacks" do stub_api_request(:get, "/apps/example/stack?include_deprecated=false").to_return(:body => '{"stack":"one"}') capture_stderr do # capture deprecation message - @client.list_stacks("example").should == { 'stack' => 'one' } + expect(@client.list_stacks("example")).to eq({ 'stack' => 'one' }) end end it "list_stacks(app_name, include_deprecated=true) passes the deprecated option" do stub_api_request(:get, "/apps/example/stack?include_deprecated=true").to_return(:body => '{"stack":"one"}') capture_stderr do # capture deprecation message - @client.list_stacks("example", :include_deprecated => true).should == { 'stack' => 'one' } + expect(@client.list_stacks("example", :include_deprecated => true)).to eq({ 'stack' => 'one' }) end end end diff --git a/spec/heroku/command/addons_spec.rb b/spec/heroku/command/addons_spec.rb index 56dddb35f..ab59a054f 100644 --- a/spec/heroku/command/addons_spec.rb +++ b/spec/heroku/command/addons_spec.rb @@ -21,8 +21,8 @@ module Heroku::Command it "should display no addons when none are configured" do stderr, stdout = execute("addons") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT example has no add-ons. STDOUT end @@ -44,8 +44,8 @@ module Heroku::Command } ) stderr, stdout = execute("addons") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT === example Configured Add-ons deployhooks:http heroku-postgresql:ronin HEROKU_POSTGRESQL_RED @@ -76,8 +76,8 @@ module Heroku::Command { "name" => "cloudcounter:platinum", "state" => "beta" } ]) stderr, stdout = execute("addons:list") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT === alpha cloudcounter:basic @@ -96,8 +96,8 @@ module Heroku::Command describe 'v1-style command line params' do it "understands foo=baz" do - @addons.stub!(:args).and_return(%w(my_addon foo=baz)) - @addons.heroku.should_receive(:install_addon).with('example', 'my_addon', { 'foo' => 'baz' }) + allow(@addons).to receive(:args).and_return(%w(my_addon foo=baz)) + expect(@addons.heroku).to receive(:install_addon).with('example', 'my_addon', { 'foo' => 'baz' }) @addons.add end @@ -117,8 +117,8 @@ module Heroku::Command } ) stderr, stdout = execute("addons:add my_addon --foo=bar extra=XXX") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Warning: non-unix style params have been deprecated, use --extra=XXX instead Adding my_addon on example... done, v99 (free) Use `heroku addons:docs my_addon` to view documentation. @@ -129,32 +129,32 @@ module Heroku::Command describe 'unix-style command line params' do it "understands --foo=baz" do - @addons.stub!(:args).and_return(%w(my_addon --foo=baz)) - @addons.heroku.should_receive(:install_addon).with('example', 'my_addon', { 'foo' => 'baz' }) + allow(@addons).to receive(:args).and_return(%w(my_addon --foo=baz)) + expect(@addons.heroku).to receive(:install_addon).with('example', 'my_addon', { 'foo' => 'baz' }) @addons.add end it "understands --foo baz" do - @addons.stub!(:args).and_return(%w(my_addon --foo baz)) - @addons.heroku.should_receive(:install_addon).with('example', 'my_addon', { 'foo' => 'baz' }) + allow(@addons).to receive(:args).and_return(%w(my_addon --foo baz)) + expect(@addons.heroku).to receive(:install_addon).with('example', 'my_addon', { 'foo' => 'baz' }) @addons.add end it "treats lone switches as true" do - @addons.stub!(:args).and_return(%w(my_addon --foo)) - @addons.heroku.should_receive(:install_addon).with('example', 'my_addon', { 'foo' => true }) + allow(@addons).to receive(:args).and_return(%w(my_addon --foo)) + expect(@addons.heroku).to receive(:install_addon).with('example', 'my_addon', { 'foo' => true }) @addons.add end it "converts 'true' to boolean" do - @addons.stub!(:args).and_return(%w(my_addon --foo=true)) - @addons.heroku.should_receive(:install_addon).with('example', 'my_addon', { 'foo' => true }) + allow(@addons).to receive(:args).and_return(%w(my_addon --foo=true)) + expect(@addons.heroku).to receive(:install_addon).with('example', 'my_addon', { 'foo' => true }) @addons.add end it "works with many config vars" do - @addons.stub!(:args).and_return(%w(my_addon --foo baz --bar yes --baz=foo --bab --bob=true)) - @addons.heroku.should_receive(:install_addon).with('example', 'my_addon', { 'foo' => 'baz', 'bar' => 'yes', 'baz' => 'foo', 'bab' => true, 'bob' => true }) + allow(@addons).to receive(:args).and_return(%w(my_addon --foo baz --bar yes --baz=foo --bab --bob=true)) + expect(@addons.heroku).to receive(:install_addon).with('example', 'my_addon', { 'foo' => 'baz', 'bar' => 'yes', 'baz' => 'foo', 'bab' => true, 'bob' => true }) @addons.add end @@ -162,19 +162,19 @@ module Heroku::Command stub_request(:post, %r{apps/example/addons/my_addon$}). with(:body => {:config => { 'foo' => 'baz', 'bar' => 'yes', 'baz' => 'foo', 'bab' => 'true', 'bob' => 'true' }}) stderr, stdout = execute("addons:add my_addon --foo baz --bar yes --baz=foo --bab --bob=true") - stderr.should == "" + expect(stderr).to eq("") end it "raises an error for spurious arguments" do - @addons.stub!(:args).and_return(%w(my_addon spurious)) - lambda { @addons.add }.should raise_error(CommandFailed) + allow(@addons).to receive(:args).and_return(%w(my_addon spurious)) + expect { @addons.add }.to raise_error(CommandFailed) end end describe "mixed options" do it "understands foo=bar and --baz=bar on the same line" do - @addons.stub!(:args).and_return(%w(my_addon foo=baz --baz=bar bob=true --bar)) - @addons.heroku.should_receive(:install_addon).with('example', 'my_addon', { 'foo' => 'baz', 'baz' => 'bar', 'bar' => true, 'bob' => true }) + allow(@addons).to receive(:args).and_return(%w(my_addon foo=baz --baz=bar bob=true --bar)) + expect(@addons.heroku).to receive(:install_addon).with('example', 'my_addon', { 'foo' => 'baz', 'baz' => 'bar', 'bar' => true, 'bob' => true }) @addons.add end @@ -182,16 +182,16 @@ module Heroku::Command stub_request(:post, %r{apps/example/addons/my_addon$}). with(:body => {:config => { 'foo' => 'baz', 'baz' => 'bar', 'bar' => 'true', 'bob' => 'true' }}) stderr, stdout = execute("addons:add my_addon foo=baz --baz=bar bob=true --bar") - stderr.should == "" - stdout.should include("Warning: non-unix style params have been deprecated, use --foo=baz --bob=true instead") + expect(stderr).to eq("") + expect(stdout).to include("Warning: non-unix style params have been deprecated, use --foo=baz --bob=true instead") end end describe "fork, follow, and rollback switches" do it "should only resolve for heroku-postgresql addon" do %w{fork follow rollback}.each do |switch| - @addons.stub!(:args).and_return("addon --#{switch} HEROKU_POSTGRESQL_RED".split) - @addons.heroku.should_receive(:install_addon). + allow(@addons).to receive(:args).and_return("addon --#{switch} HEROKU_POSTGRESQL_RED".split) + expect(@addons.heroku).to receive(:install_addon). with('example', 'addon', {switch => 'HEROKU_POSTGRESQL_RED'}) @addons.add end @@ -199,8 +199,8 @@ module Heroku::Command it "should translate --fork, --follow, and --rollback" do %w{fork follow rollback}.each do |switch| - Heroku::Helpers::HerokuPostgresql::Resolver.any_instance.stub(:app_config_vars).and_return({}) - Heroku::Helpers::HerokuPostgresql::Resolver.any_instance.stub(:app_attachments).and_return([Heroku::Helpers::HerokuPostgresql::Attachment.new({ + allow_any_instance_of(Heroku::Helpers::HerokuPostgresql::Resolver).to receive(:app_config_vars).and_return({}) + allow_any_instance_of(Heroku::Helpers::HerokuPostgresql::Resolver).to receive(:app_attachments).and_return([Heroku::Helpers::HerokuPostgresql::Attachment.new({ 'app' => {'name' => 'sushi'}, 'name' => 'HEROKU_POSTGRESQL_RED', 'config_var' => 'HEROKU_POSTGRESQL_RED_URL', @@ -208,35 +208,35 @@ module Heroku::Command 'value' => 'postgres://red_url', 'type' => 'heroku-postgresql:ronin' }}) ]) - @addons.stub!(:args).and_return("heroku-postgresql --#{switch} HEROKU_POSTGRESQL_RED".split) - @addons.heroku.should_receive(:install_addon).with('example', 'heroku-postgresql:ronin', {switch => 'postgres://red_url'}) + allow(@addons).to receive(:args).and_return("heroku-postgresql --#{switch} HEROKU_POSTGRESQL_RED".split) + expect(@addons.heroku).to receive(:install_addon).with('example', 'heroku-postgresql:ronin', {switch => 'postgres://red_url'}) @addons.add end end it "should NOT translate --fork and --follow if passed in a full postgres url even if there are no databases" do %w{fork follow}.each do |switch| - @addons.stub!(:app_config_vars).and_return({}) - @addons.stub!(:app_attachments).and_return([]) - @addons.stub!(:args).and_return("heroku-postgresql:ronin --#{switch} postgres://foo:yeah@awesome.com:234/bestdb".split) - @addons.heroku.should_receive(:install_addon).with('example', 'heroku-postgresql:ronin', {switch => 'postgres://foo:yeah@awesome.com:234/bestdb'}) + allow(@addons).to receive(:app_config_vars).and_return({}) + allow(@addons).to receive(:app_attachments).and_return([]) + allow(@addons).to receive(:args).and_return("heroku-postgresql:ronin --#{switch} postgres://foo:yeah@awesome.com:234/bestdb".split) + expect(@addons.heroku).to receive(:install_addon).with('example', 'heroku-postgresql:ronin', {switch => 'postgres://foo:yeah@awesome.com:234/bestdb'}) @addons.add end end it "should fail if fork / follow across applications and no plan is specified" do %w{fork follow}.each do |switch| - @addons.stub!(:app_config_vars).and_return({}) - @addons.stub!(:app_attachments).and_return([]) - @addons.stub!(:args).and_return("heroku-postgresql --#{switch} postgres://foo:yeah@awesome.com:234/bestdb".split) - lambda { @addons.add }.should raise_error(CommandFailed) + allow(@addons).to receive(:app_config_vars).and_return({}) + allow(@addons).to receive(:app_attachments).and_return([]) + allow(@addons).to receive(:args).and_return("heroku-postgresql --#{switch} postgres://foo:yeah@awesome.com:234/bestdb".split) + expect { @addons.add }.to raise_error(CommandFailed) end end end describe 'adding' do before do - @addons.stub!(:args).and_return(%w(my_addon)) + allow(@addons).to receive(:args).and_return(%w(my_addon)) Excon.stub( { :expects => 200, @@ -255,28 +255,28 @@ module Heroku::Command it "requires an addon name" do - @addons.stub!(:args).and_return([]) - lambda { @addons.add }.should raise_error(CommandFailed) + allow(@addons).to receive(:args).and_return([]) + expect { @addons.add }.to raise_error(CommandFailed) end it "adds an addon" do - @addons.stub!(:args).and_return(%w(my_addon)) - @addons.heroku.should_receive(:install_addon).with('example', 'my_addon', {}) + allow(@addons).to receive(:args).and_return(%w(my_addon)) + expect(@addons.heroku).to receive(:install_addon).with('example', 'my_addon', {}) @addons.add end it "adds an addon with a price" do stub_core.install_addon("example", "my_addon", {}).returns({ "price" => "free" }) stderr, stdout = execute("addons:add my_addon") - stderr.should == "" - stdout.should =~ /\(free\)/ + expect(stderr).to eq("") + expect(stdout).to match(/\(free\)/) end it "adds an addon with a price and message" do stub_core.install_addon("example", "my_addon", {}).returns({ "price" => "free", "message" => "foo" }) stderr, stdout = execute("addons:add my_addon") - stderr.should == "" - stdout.should == <<-OUTPUT + expect(stderr).to eq("") + expect(stdout).to eq <<-OUTPUT Adding my_addon on example... done, v99 (free) foo Use `heroku addons:docs my_addon` to view documentation. @@ -286,8 +286,8 @@ module Heroku::Command it "excludes addon plan from docs message" do stub_core.install_addon("example", "my_addon:test", {}).returns({ "price" => "free", "message" => "foo" }) stderr, stdout = execute("addons:add my_addon:test") - stderr.should == "" - stdout.should == <<-OUTPUT + expect(stderr).to eq("") + expect(stdout).to eq <<-OUTPUT Adding my_addon:test on example... done, v99 (free) foo Use `heroku addons:docs my_addon` to view documentation. @@ -297,8 +297,8 @@ module Heroku::Command it "adds an addon with a price and multiline message" do stub_core.install_addon("example", "my_addon", {}).returns({ "price" => "$200/mo", "message" => "foo\nbar" }) stderr, stdout = execute("addons:add my_addon") - stderr.should == "" - stdout.should == <<-OUTPUT + expect(stderr).to eq("") + expect(stdout).to eq <<-OUTPUT Adding my_addon on example... done, v99 ($200/mo) foo bar @@ -307,14 +307,14 @@ module Heroku::Command end it "displays an error with unexpected options" do - Heroku::Command.should_receive(:error).with("Unexpected arguments: bar") + expect(Heroku::Command).to receive(:error).with("Unexpected arguments: bar") run("addons:add redistogo -a foo bar") end end describe 'upgrading' do before do - @addons.stub!(:args).and_return(%w(my_addon)) + allow(@addons).to receive(:args).and_return(%w(my_addon)) Excon.stub( { :expects => 200, @@ -332,27 +332,27 @@ module Heroku::Command end it "requires an addon name" do - @addons.stub!(:args).and_return([]) - lambda { @addons.upgrade }.should raise_error(CommandFailed) + allow(@addons).to receive(:args).and_return([]) + expect { @addons.upgrade }.to raise_error(CommandFailed) end it "upgrades an addon" do - @addons.stub!(:args).and_return(%w(my_addon)) - @addons.heroku.should_receive(:upgrade_addon).with('example', 'my_addon', {}) + allow(@addons).to receive(:args).and_return(%w(my_addon)) + expect(@addons.heroku).to receive(:upgrade_addon).with('example', 'my_addon', {}) @addons.upgrade end it "upgrade an addon with config vars" do - @addons.stub!(:args).and_return(%w(my_addon --foo=baz)) - @addons.heroku.should_receive(:upgrade_addon).with('example', 'my_addon', { 'foo' => 'baz' }) + allow(@addons).to receive(:args).and_return(%w(my_addon --foo=baz)) + expect(@addons.heroku).to receive(:upgrade_addon).with('example', 'my_addon', { 'foo' => 'baz' }) @addons.upgrade end it "adds an addon with a price" do stub_core.upgrade_addon("example", "my_addon", {}).returns({ "price" => "free" }) stderr, stdout = execute("addons:upgrade my_addon") - stderr.should == "" - stdout.should == <<-OUTPUT + expect(stderr).to eq("") + expect(stdout).to eq <<-OUTPUT Upgrading to my_addon on example... done, v99 (free) Use `heroku addons:docs my_addon` to view documentation. OUTPUT @@ -361,8 +361,8 @@ module Heroku::Command it "adds an addon with a price and message" do stub_core.upgrade_addon("example", "my_addon", {}).returns({ "price" => "free", "message" => "Don't Panic" }) stderr, stdout = execute("addons:upgrade my_addon") - stderr.should == "" - stdout.should == <<-OUTPUT + expect(stderr).to eq("") + expect(stdout).to eq <<-OUTPUT Upgrading to my_addon on example... done, v99 (free) Don't Panic Use `heroku addons:docs my_addon` to view documentation. @@ -372,7 +372,7 @@ module Heroku::Command describe 'downgrading' do before do - @addons.stub!(:args).and_return(%w(my_addon)) + allow(@addons).to receive(:args).and_return(%w(my_addon)) Excon.stub( { :expects => 200, @@ -390,27 +390,27 @@ module Heroku::Command end it "requires an addon name" do - @addons.stub!(:args).and_return([]) - lambda { @addons.downgrade }.should raise_error(CommandFailed) + allow(@addons).to receive(:args).and_return([]) + expect { @addons.downgrade }.to raise_error(CommandFailed) end it "downgrades an addon" do - @addons.stub!(:args).and_return(%w(my_addon)) - @addons.heroku.should_receive(:upgrade_addon).with('example', 'my_addon', {}) + allow(@addons).to receive(:args).and_return(%w(my_addon)) + expect(@addons.heroku).to receive(:upgrade_addon).with('example', 'my_addon', {}) @addons.downgrade end it "downgrade an addon with config vars" do - @addons.stub!(:args).and_return(%w(my_addon --foo=baz)) - @addons.heroku.should_receive(:upgrade_addon).with('example', 'my_addon', { 'foo' => 'baz' }) + allow(@addons).to receive(:args).and_return(%w(my_addon --foo=baz)) + expect(@addons.heroku).to receive(:upgrade_addon).with('example', 'my_addon', { 'foo' => 'baz' }) @addons.downgrade end it "downgrades an addon with a price" do stub_core.upgrade_addon("example", "my_addon", {}).returns({ "price" => "free" }) stderr, stdout = execute("addons:downgrade my_addon") - stderr.should == "" - stdout.should == <<-OUTPUT + expect(stderr).to eq("") + expect(stdout).to eq <<-OUTPUT Downgrading to my_addon on example... done, v99 (free) Use `heroku addons:docs my_addon` to view documentation. OUTPUT @@ -419,8 +419,8 @@ module Heroku::Command it "downgrades an addon with a price and message" do stub_core.upgrade_addon("example", "my_addon", {}).returns({ "price" => "free", "message" => "Don't Panic" }) stderr, stdout = execute("addons:downgrade my_addon") - stderr.should == "" - stdout.should == <<-OUTPUT + expect(stderr).to eq("") + expect(stdout).to eq <<-OUTPUT Downgrading to my_addon on example... done, v99 (free) Don't Panic Use `heroku addons:docs my_addon` to view documentation. @@ -429,23 +429,23 @@ module Heroku::Command end it "does not remove addons with no confirm" do - @addons.stub!(:args).and_return(%w( addon1 )) - @addons.should_receive(:confirm_command).once.and_return(false) - @addons.heroku.should_not_receive(:uninstall_addon) + allow(@addons).to receive(:args).and_return(%w( addon1 )) + expect(@addons).to receive(:confirm_command).once.and_return(false) + expect(@addons.heroku).not_to receive(:uninstall_addon) @addons.remove end it "removes addons after prompting for confirmation" do - @addons.stub!(:args).and_return(%w( addon1 )) - @addons.should_receive(:confirm_command).once.and_return(true) - @addons.heroku.should_receive(:uninstall_addon).with('example', 'addon1', :confirm => "example") + allow(@addons).to receive(:args).and_return(%w( addon1 )) + expect(@addons).to receive(:confirm_command).once.and_return(true) + expect(@addons.heroku).to receive(:uninstall_addon).with('example', 'addon1', :confirm => "example") @addons.remove end it "removes addons with confirm option" do - Heroku::Command.stub!(:current_options).and_return(:confirm => "example") - @addons.stub!(:args).and_return(%w( addon1 )) - @addons.heroku.should_receive(:uninstall_addon).with('example', 'addon1', :confirm => "example") + allow(Heroku::Command).to receive(:current_options).and_return(:confirm => "example") + allow(@addons).to receive(:args).and_return(%w( addon1 )) + expect(@addons.heroku).to receive(:uninstall_addon).with('example', 'addon1', :confirm => "example") @addons.remove end @@ -462,19 +462,19 @@ module Heroku::Command it "displays usage when no argument is specified" do stderr, stdout = execute('addons:docs') - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! Usage: heroku addons:docs ADDON ! Must specify ADDON to open docs for. STDERR - stdout.should == '' + expect(stdout).to eq('') end it "opens the addon if only one matches" do require("launchy") - Launchy.should_receive(:open).with("https://devcenter.heroku.com/articles/redistogo").and_return(Thread.new {}) + expect(Launchy).to receive(:open).with("https://devcenter.heroku.com/articles/redistogo").and_return(Thread.new {}) stderr, stdout = execute('addons:docs redistogo:nano') - stderr.should == '' - stdout.should == <<-STDOUT + expect(stderr).to eq('') + expect(stdout).to eq <<-STDOUT Opening redistogo:nano docs... done STDOUT end @@ -495,39 +495,39 @@ module Heroku::Command } ) stderr, stdout = execute('addons:docs qu') - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! Ambiguous addon name: qu ! Perhaps you meant `qux:foo` or `quux:bar`. STDERR - stdout.should == '' + expect(stdout).to eq('') Excon.stubs.shift end it "complains if no such addon exists" do stderr, stdout = execute('addons:docs unknown') - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! `unknown` is not a heroku add-on. ! See `heroku addons:list` for all available addons. STDERR - stdout.should == '' + expect(stdout).to eq('') end it "suggests alternatives if addon has typo" do stderr, stdout = execute('addons:docs redisgoto') - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! `redisgoto` is not a heroku add-on. ! Perhaps you meant `redistogo`. ! See `heroku addons:list` for all available addons. STDERR - stdout.should == '' + expect(stdout).to eq('') end it "complains if addon is not installed" do stderr, stdout = execute('addons:open deployhooks:http') - stderr.should == <<-STDOUT + expect(stderr).to eq <<-STDOUT ! Addon not installed: deployhooks:http STDOUT - stdout.should == '' + expect(stdout).to eq('') end end describe "opening an addon" do @@ -543,20 +543,20 @@ module Heroku::Command it "displays usage when no argument is specified" do stderr, stdout = execute('addons:open') - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! Usage: heroku addons:open ADDON ! Must specify ADDON to open. STDERR - stdout.should == '' + expect(stdout).to eq('') end it "opens the addon if only one matches" do api.post_addon('example', 'redistogo:nano') require("launchy") - Launchy.should_receive(:open).with("https://addons-sso.heroku.com/apps/example/addons/redistogo:nano").and_return(Thread.new {}) + expect(Launchy).to receive(:open).with("https://addons-sso.heroku.com/apps/example/addons/redistogo:nano").and_return(Thread.new {}) stderr, stdout = execute('addons:open redistogo:nano') - stderr.should == '' - stdout.should == <<-STDOUT + expect(stderr).to eq('') + expect(stdout).to eq <<-STDOUT Opening redistogo:nano for example... done STDOUT end @@ -577,39 +577,39 @@ module Heroku::Command } ) stderr, stdout = execute('addons:open deployhooks') - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! Ambiguous addon name: deployhooks ! Perhaps you meant `deployhooks:email` or `deployhooks:http`. STDERR - stdout.should == '' + expect(stdout).to eq('') Excon.stubs.shift end it "complains if no such addon exists" do stderr, stdout = execute('addons:open unknown') - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! `unknown` is not a heroku add-on. ! See `heroku addons:list` for all available addons. STDERR - stdout.should == '' + expect(stdout).to eq('') end it "suggests alternatives if addon has typo" do stderr, stdout = execute('addons:open redisgoto') - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! `redisgoto` is not a heroku add-on. ! Perhaps you meant `redistogo`. ! See `heroku addons:list` for all available addons. STDERR - stdout.should == '' + expect(stdout).to eq('') end it "complains if addon is not installed" do stderr, stdout = execute('addons:open deployhooks:http') - stderr.should == <<-STDOUT + expect(stderr).to eq <<-STDOUT ! Addon not installed: deployhooks:http STDOUT - stdout.should == '' + expect(stdout).to eq('') end end end diff --git a/spec/heroku/command/apps_spec.rb b/spec/heroku/command/apps_spec.rb index ac8f5689e..b598f4679 100644 --- a/spec/heroku/command/apps_spec.rb +++ b/spec/heroku/command/apps_spec.rb @@ -21,8 +21,8 @@ module Heroku::Command it "displays impicit app info" do stderr, stdout = execute("apps:info") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT === example Git URL: git@heroku.com:example.git Owner Email: email@example.com @@ -33,8 +33,8 @@ module Heroku::Command it "gets explicit app from --app" do stderr, stdout = execute("apps:info --app example") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT === example Git URL: git@heroku.com:example.git Owner Email: email@example.com @@ -45,8 +45,8 @@ module Heroku::Command it "shows shell app info when --shell option is used" do stderr, stdout = execute("apps:info --shell") - stderr.should == "" - stdout.should match Regexp.new(<<-STDOUT) + expect(stderr).to eq("") + expect(stdout).to match Regexp.new(<<-STDOUT) create_status=complete created_at=\\d{4}/\\d{2}/\\d{2} \\d{2}:\\d{2}:\\d{2} [+-]\\d{4} dynos=0 @@ -73,8 +73,8 @@ module Heroku::Command with_blank_git_repository do stderr, stdout = execute("apps:create") name = api.get_apps.body.first["name"] - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Creating #{name}... done, stack is bamboo-mri-1.9.2 http://#{name}.herokuapp.com/ | git@heroku.com:#{name}.git Git remote heroku added @@ -86,8 +86,8 @@ module Heroku::Command it "with a name" do with_blank_git_repository do stderr, stdout = execute("apps:create example") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Creating example... done, stack is bamboo-mri-1.9.2 http://example.herokuapp.com/ | git@heroku.com:example.git Git remote heroku added @@ -99,8 +99,8 @@ module Heroku::Command it "with -a name" do with_blank_git_repository do stderr, stdout = execute("apps:create -a example") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Creating example... done, stack is bamboo-mri-1.9.2 http://example.herokuapp.com/ | git@heroku.com:example.git Git remote heroku added @@ -112,8 +112,8 @@ module Heroku::Command it "with --no-remote" do with_blank_git_repository do stderr, stdout = execute("apps:create example --no-remote") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Creating example... done, stack is bamboo-mri-1.9.2 http://example.herokuapp.com/ | git@heroku.com:example.git STDOUT @@ -124,8 +124,8 @@ module Heroku::Command it "with addons" do with_blank_git_repository do stderr, stdout = execute("apps:create addonapp --addon custom_domains:basic,releases:basic") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Creating addonapp... done, stack is bamboo-mri-1.9.2 Adding custom_domains:basic to addonapp... done Adding releases:basic to addonapp... done @@ -139,8 +139,8 @@ module Heroku::Command it "with a buildpack" do with_blank_git_repository do stderr, stdout = execute("apps:create buildpackapp --buildpack http://example.org/buildpack.git") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Creating buildpackapp... done, stack is bamboo-mri-1.9.2 BUILDPACK_URL=http://example.org/buildpack.git http://buildpackapp.herokuapp.com/ | git@heroku.com:buildpackapp.git @@ -153,8 +153,8 @@ module Heroku::Command it "with an alternate remote name" do with_blank_git_repository do stderr, stdout = execute("apps:create alternate-remote --remote alternate") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Creating alternate-remote... done, stack is bamboo-mri-1.9.2 http://alternate-remote.herokuapp.com/ | git@heroku.com:alternate-remote.git Git remote alternate added @@ -178,8 +178,8 @@ module Heroku::Command it "succeeds" do stub_core.list.returns([["example", "user"]]) stderr, stdout = execute("apps") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT === My Apps example @@ -203,8 +203,8 @@ module Heroku::Command it "displays a message when the org has no apps" do Excon.stub({ :method => :get, :path => '/v1/organization/test-org/app' }, { :status => 200, :body => Heroku::OkJson.encode([]) }) stderr, stdout = execute("apps") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT There are no apps in organization test-org. STDOUT @@ -225,8 +225,8 @@ module Heroku::Command it "lists joined apps in an organization" do stderr, stdout = execute("apps") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT === Apps joined in organization test-org org-app-1 @@ -235,8 +235,8 @@ module Heroku::Command it "list all apps in an organization with the --all flag" do stderr, stdout = execute("apps --all") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT === Apps joined in organization test-org org-app-1 @@ -264,8 +264,8 @@ module Heroku::Command it "renames app" do with_blank_git_repository do stderr, stdout = execute("apps:rename example2") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Renaming example to example2... done http://example2.herokuapp.com/ | git@heroku.com:example2.git Don't forget to update your Git remotes on any local checkouts. @@ -277,11 +277,11 @@ module Heroku::Command it "displays an error if no name is specified" do stderr, stdout = execute("apps:rename") - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! Usage: heroku apps:rename NEWNAME ! Must specify NEWNAME to rename. STDERR - stdout.should == "" + expect(stdout).to eq("") end end @@ -294,8 +294,8 @@ module Heroku::Command it "succeeds with app explicitly specified with --app and user confirmation" do stderr, stdout = execute("apps:destroy --confirm example") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Destroying example (including all add-ons)... done STDOUT end @@ -308,25 +308,25 @@ module Heroku::Command it "fails with explicit app but no confirmation" do stderr, stdout = execute("apps:destroy example") - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! Confirmation did not match example. Aborted. STDERR - stdout.should == " + expect(stdout).to eq(" ! WARNING: Potentially Destructive Action ! This command will destroy example (including all add-ons). ! To proceed, type \"example\" or re-run this command with --confirm example -> " +> ") end it "fails without explicit app" do stderr, stdout = execute("apps:destroy") - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! Usage: heroku apps:destroy --app APP ! Must specify APP to destroy. STDERR - stdout.should == "" + expect(stdout).to eq("") end end @@ -338,13 +338,13 @@ module Heroku::Command it "creates adding heroku to git remote" do with_blank_git_repository do stderr, stdout = execute("apps:create example") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Creating example... done, stack is bamboo-mri-1.9.2 http://example.herokuapp.com/ | git@heroku.com:example.git Git remote heroku added STDOUT - `git remote`.strip.should match(/^heroku$/) + expect(`git remote`.strip).to match(/^heroku$/) api.delete_app("example") end end @@ -352,13 +352,13 @@ module Heroku::Command it "creates adding a custom git remote" do with_blank_git_repository do stderr, stdout = execute("apps:create example --remote myremote") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Creating example... done, stack is bamboo-mri-1.9.2 http://example.herokuapp.com/ | git@heroku.com:example.git Git remote myremote added STDOUT - `git remote`.strip.should match(/^myremote$/) + expect(`git remote`.strip).to match(/^myremote$/) api.delete_app("example") end end @@ -367,8 +367,8 @@ module Heroku::Command with_blank_git_repository do `git remote add heroku /tmp/git_spec_#{Process.pid}` stderr, stdout = execute("apps:create example") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Creating example... done, stack is bamboo-mri-1.9.2 http://example.herokuapp.com/ | git@heroku.com:example.git STDOUT @@ -387,7 +387,7 @@ module Heroku::Command api.delete_app("example2") remotes = `git remote -v` - remotes.should == <<-REMOTES + expect(remotes).to eq <<-REMOTES github\tgit@github.com:test/test.git (fetch) github\tgit@github.com:test/test.git (push) production\tgit@heroku.com:example2.git (fetch) @@ -405,7 +405,7 @@ module Heroku::Command api.post_app("name" => "example", "stack" => "cedar") stderr, stdout = execute("apps:destroy --confirm example") - `git remote`.strip.should_not include('heroku') + expect(`git remote`.strip).not_to include('heroku') end end end diff --git a/spec/heroku/command/auth_spec.rb b/spec/heroku/command/auth_spec.rb index c58eb0412..b5b981808 100644 --- a/spec/heroku/command/auth_spec.rb +++ b/spec/heroku/command/auth_spec.rb @@ -6,10 +6,10 @@ it "displays heroku help auth" do stderr, stdout = execute("auth") - stderr.should == "" - stdout.should include "Additional commands" - stdout.should include "auth:login" - stdout.should include "auth:logout" + expect(stderr).to eq("") + expect(stdout).to include "Additional commands" + expect(stdout).to include "auth:login" + expect(stdout).to include "auth:logout" end end @@ -17,8 +17,8 @@ it "displays the user's api key" do stderr, stdout = execute("auth:token") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT apikey01 STDOUT end @@ -27,8 +27,8 @@ describe "auth:whoami" do it "displays the user's email address" do stderr, stdout = execute("auth:whoami") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT email@example.com STDOUT end diff --git a/spec/heroku/command/base_spec.rb b/spec/heroku/command/base_spec.rb index acbd3af94..8b1cfec20 100644 --- a/spec/heroku/command/base_spec.rb +++ b/spec/heroku/command/base_spec.rb @@ -5,37 +5,37 @@ module Heroku::Command describe Base do before do @base = Base.new - @base.stub!(:display) - @client = mock('heroku client', :host => 'heroku.com') + allow(@base).to receive(:display) + @client = double('heroku client', :host => 'heroku.com') end describe "confirming" do it "confirms the app via --confirm" do - Heroku::Command.stub(:current_options).and_return(:confirm => "example") - @base.stub(:app).and_return("example") - @base.confirm_command.should be_true + allow(Heroku::Command).to receive(:current_options).and_return(:confirm => "example") + allow(@base).to receive(:app).and_return("example") + expect(@base.confirm_command).to be_truthy end it "does not confirms the app via --confirm on a mismatch" do - Heroku::Command.stub(:current_options).and_return(:confirm => "badapp") - @base.stub(:app).and_return("example") - lambda { @base.confirm_command}.should raise_error CommandFailed + allow(Heroku::Command).to receive(:current_options).and_return(:confirm => "badapp") + allow(@base).to receive(:app).and_return("example") + expect { @base.confirm_command}.to raise_error CommandFailed end it "confirms the app interactively via ask" do - @base.stub(:app).and_return("example") - @base.stub(:ask).and_return("example") - Heroku::Command.stub(:current_options).and_return({}) - @base.confirm_command.should be_true + allow(@base).to receive(:app).and_return("example") + allow(@base).to receive(:ask).and_return("example") + allow(Heroku::Command).to receive(:current_options).and_return({}) + expect(@base.confirm_command).to be_truthy end it "fails if the interactive confirm doesn't match" do - @base.stub(:app).and_return("example") - @base.stub(:ask).and_return("badresponse") - Heroku::Command.stub(:current_options).and_return({}) - capture_stderr do - lambda { @base.confirm_command }.should raise_error(SystemExit) - end.should == <<-STDERR + allow(@base).to receive(:app).and_return("example") + allow(@base).to receive(:ask).and_return("badresponse") + allow(Heroku::Command).to receive(:current_options).and_return({}) + expect(capture_stderr do + expect { @base.confirm_command }.to raise_error(SystemExit) + end).to eq <<-STDERR ! Confirmation did not match example. Aborted. STDERR end @@ -43,34 +43,34 @@ module Heroku::Command context "detecting the app" do it "attempts to find the app via the --app option" do - @base.stub!(:options).and_return(:app => "example") - @base.app.should == "example" + allow(@base).to receive(:options).and_return(:app => "example") + expect(@base.app).to eq("example") end it "attempts to find the app via the --confirm option" do - @base.stub!(:options).and_return(:confirm => "myconfirmapp") - @base.app.should == "myconfirmapp" + allow(@base).to receive(:options).and_return(:confirm => "myconfirmapp") + expect(@base.app).to eq("myconfirmapp") end it "attempts to find the app via HEROKU_APP when not explicitly specified" do ENV['HEROKU_APP'] = "myenvapp" - @base.app.should == "myenvapp" - @base.stub!(:options).and_return([]) - @base.app.should == "myenvapp" + expect(@base.app).to eq("myenvapp") + allow(@base).to receive(:options).and_return([]) + expect(@base.app).to eq("myenvapp") ENV.delete('HEROKU_APP') end it "overrides HEROKU_APP when explicitly specified" do ENV['HEROKU_APP'] = "myenvapp" - @base.stub!(:options).and_return(:app => "example") - @base.app.should == "example" + allow(@base).to receive(:options).and_return(:app => "example") + expect(@base.app).to eq("example") ENV.delete('HEROKU_APP') end it "read remotes from git config" do - Dir.stub(:chdir) - File.should_receive(:exists?).with(".git").and_return(true) - @base.should_receive(:git).with('remote -v').and_return(<<-REMOTES) + allow(Dir).to receive(:chdir) + expect(File).to receive(:exists?).with(".git").and_return(true) + expect(@base).to receive(:git).with('remote -v').and_return(<<-REMOTES) staging\tgit@heroku.com:example-staging.git (fetch) staging\tgit@heroku.com:example-staging.git (push) production\tgit@heroku.com:example.git (fetch) @@ -79,29 +79,29 @@ module Heroku::Command other\tgit@other.com:other.git (push) REMOTES - @heroku = mock - @heroku.stub(:host).and_return('heroku.com') - @base.stub(:heroku).and_return(@heroku) + @heroku = double + allow(@heroku).to receive(:host).and_return('heroku.com') + allow(@base).to receive(:heroku).and_return(@heroku) # need a better way to test internal functionality - @base.send(:git_remotes, '/home/dev/example').should == { 'staging' => 'example-staging', 'production' => 'example' } + expect(@base.send(:git_remotes, '/home/dev/example')).to eq({ 'staging' => 'example-staging', 'production' => 'example' }) end it "gets the app from remotes when there's only one app" do - @base.stub!(:git_remotes).and_return({ 'heroku' => 'example' }) - @base.stub!(:git).with("config heroku.remote").and_return("") - @base.app.should == 'example' + allow(@base).to receive(:git_remotes).and_return({ 'heroku' => 'example' }) + allow(@base).to receive(:git).with("config heroku.remote").and_return("") + expect(@base.app).to eq('example') end it "accepts a --remote argument to choose the app from the remote name" do - @base.stub!(:git_remotes).and_return({ 'staging' => 'example-staging', 'production' => 'example' }) - @base.stub!(:options).and_return(:remote => "staging") - @base.app.should == 'example-staging' + allow(@base).to receive(:git_remotes).and_return({ 'staging' => 'example-staging', 'production' => 'example' }) + allow(@base).to receive(:options).and_return(:remote => "staging") + expect(@base.app).to eq('example-staging') end it "raises when cannot determine which app is it" do - @base.stub!(:git_remotes).and_return({ 'staging' => 'example-staging', 'production' => 'example' }) - lambda { @base.app }.should raise_error(Heroku::Command::CommandFailed) + allow(@base).to receive(:git_remotes).and_return({ 'staging' => 'example-staging', 'production' => 'example' }) + expect { @base.app }.to raise_error(Heroku::Command::CommandFailed) end end diff --git a/spec/heroku/command/certs_spec.rb b/spec/heroku/command/certs_spec.rb index e1801f52b..0c26d50ff 100644 --- a/spec/heroku/command/certs_spec.rb +++ b/spec/heroku/command/certs_spec.rb @@ -43,7 +43,7 @@ module Heroku::Command it "shows a list of certs" do stub_core.ssl_endpoint_list("example").returns([endpoint, endpoint2]) stderr, stdout = execute("certs") - stdout.should == <<-STDOUT + expect(stdout).to eq <<-STDOUT Endpoint Common Name(s) Expires Trusted ------------------------ -------------- -------------------- ------- tokyo-1050.herokussl.com example.org 2013-08-01 21:34 UTC False @@ -54,7 +54,7 @@ module Heroku::Command it "warns about no SSL Endpoints if the app has no certs" do stub_core.ssl_endpoint_list("example").returns([]) stderr, stdout = execute("certs") - stdout.should == <<-STDOUT + expect(stdout).to eq <<-STDOUT example has no SSL Endpoints. Use `heroku certs:add CRT KEY` to add one. STDOUT @@ -63,12 +63,12 @@ module Heroku::Command describe "certs:add" do it "adds an endpoint" do - File.should_receive(:read).with("pem_file").and_return("pem content") - File.should_receive(:read).with("key_file").and_return("key content") + expect(File).to receive(:read).with("pem_file").and_return("pem content") + expect(File).to receive(:read).with("key_file").and_return("key content") stub_core.ssl_endpoint_add('example', 'pem content', 'key content').returns(endpoint) stderr, stdout = execute("certs:add --bypass pem_file key_file") - stdout.should == <<-STDOUT + expect(stdout).to eq <<-STDOUT Adding SSL Endpoint to example... done example now served by tokyo-1050.herokussl.com Certificate details: @@ -77,7 +77,7 @@ module Heroku::Command end it "shows usage if two arguments are not provided" do - lambda { execute("certs:add --bypass") }.should raise_error(CommandFailed, /Usage:/) + expect { execute("certs:add --bypass") }.to raise_error(CommandFailed, /Usage:/) end end @@ -87,7 +87,7 @@ module Heroku::Command stub_core.ssl_endpoint_info('example', 'tokyo-1050.herokussl.com').returns(endpoint) stderr, stdout = execute("certs:info") - stdout.should == <<-STDOUT + expect(stdout).to eq <<-STDOUT Fetching SSL Endpoint tokyo-1050.herokussl.com info for example... done Certificate details: #{certificate_details} @@ -98,7 +98,7 @@ module Heroku::Command stub_core.ssl_endpoint_info('example', 'tokyo-1050').returns(endpoint) stderr, stdout = execute("certs:info --endpoint tokyo-1050") - stdout.should == <<-STDOUT + expect(stdout).to eq <<-STDOUT Fetching SSL Endpoint tokyo-1050 info for example... done Certificate details: #{certificate_details} @@ -109,7 +109,7 @@ module Heroku::Command stub_core.ssl_endpoint_list("example").returns([]) stderr, stdout = execute("certs:info") - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! example has no SSL Endpoints. STDERR end @@ -121,31 +121,31 @@ module Heroku::Command stub_core.ssl_endpoint_remove('example', 'tokyo-1050.herokussl.com').returns(endpoint) stderr, stdout = execute("certs:remove --confirm example") - stdout.should include "Removing SSL Endpoint tokyo-1050.herokussl.com from example..." - stdout.should include "NOTE: Billing is still active. Remove SSL Endpoint add-on to stop billing." + expect(stdout).to include "Removing SSL Endpoint tokyo-1050.herokussl.com from example..." + expect(stdout).to include "NOTE: Billing is still active. Remove SSL Endpoint add-on to stop billing." end it "allows an endpoint to be specified" do stub_core.ssl_endpoint_remove('example', 'tokyo-1050').returns(endpoint) stderr, stdout = execute("certs:remove --confirm example --endpoint tokyo-1050") - stdout.should include "Removing SSL Endpoint tokyo-1050 from example..." - stdout.should include "NOTE: Billing is still active. Remove SSL Endpoint add-on to stop billing." + expect(stdout).to include "Removing SSL Endpoint tokyo-1050 from example..." + expect(stdout).to include "NOTE: Billing is still active. Remove SSL Endpoint add-on to stop billing." end it "requires confirmation" do stub_core.ssl_endpoint_list("example").returns([endpoint]) stderr, stdout = execute("certs:remove") - stdout.should include "WARNING: Potentially Destructive Action" - stdout.should include "This command will remove the endpoint tokyo-1050.herokussl.com from example." + expect(stdout).to include "WARNING: Potentially Destructive Action" + expect(stdout).to include "This command will remove the endpoint tokyo-1050.herokussl.com from example." end it "shows an error if an app has no endpoints" do stub_core.ssl_endpoint_list("example").returns([]) stderr, stdout = execute("certs:remove") - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! example has no SSL Endpoints. STDERR end @@ -153,8 +153,8 @@ module Heroku::Command describe "certs:update" do before do - File.should_receive(:read).with("pem_file").and_return("pem content") - File.should_receive(:read).with("key_file").and_return("key content") + expect(File).to receive(:read).with("pem_file").and_return("pem content") + expect(File).to receive(:read).with("key_file").and_return("key content") end it "updates an endpoint" do @@ -162,7 +162,7 @@ module Heroku::Command stub_core.ssl_endpoint_update('example', 'tokyo-1050.herokussl.com', 'pem content', 'key content').returns(endpoint) stderr, stdout = execute("certs:update --confirm example --bypass pem_file key_file") - stdout.should == <<-STDOUT + expect(stdout).to eq <<-STDOUT Updating SSL Endpoint tokyo-1050.herokussl.com for example... done Updated certificate details: #{certificate_details} @@ -173,7 +173,7 @@ module Heroku::Command stub_core.ssl_endpoint_update('example', 'tokyo-1050', 'pem content', 'key content').returns(endpoint) stderr, stdout = execute("certs:update --confirm example --bypass --endpoint tokyo-1050 pem_file key_file") - stdout.should == <<-STDOUT + expect(stdout).to eq <<-STDOUT Updating SSL Endpoint tokyo-1050 for example... done Updated certificate details: #{certificate_details} @@ -184,15 +184,15 @@ module Heroku::Command stub_core.ssl_endpoint_list("example").returns([endpoint]) stderr, stdout = execute("certs:update --bypass pem_file key_file") - stdout.should include "WARNING: Potentially Destructive Action" - stdout.should include "This command will change the certificate of endpoint tokyo-1050.herokussl.com on example." + expect(stdout).to include "WARNING: Potentially Destructive Action" + expect(stdout).to include "This command will change the certificate of endpoint tokyo-1050.herokussl.com on example." end it "shows an error if an app has no endpoints" do stub_core.ssl_endpoint_list("example").returns([]) stderr, stdout = execute("certs:update --bypass pem_file key_file") - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! example has no SSL Endpoints. STDERR end @@ -204,7 +204,7 @@ module Heroku::Command stub_core.ssl_endpoint_rollback('example', 'tokyo-1050.herokussl.com').returns(endpoint) stderr, stdout = execute("certs:rollback --confirm example") - stdout.should == <<-STDOUT + expect(stdout).to eq <<-STDOUT Rolling back SSL Endpoint tokyo-1050.herokussl.com for example... done New active certificate details: #{certificate_details} @@ -215,7 +215,7 @@ module Heroku::Command stub_core.ssl_endpoint_rollback('example', 'tokyo-1050').returns(endpoint) stderr, stdout = execute("certs:rollback --confirm example --endpoint tokyo-1050") - stdout.should == <<-STDOUT + expect(stdout).to eq <<-STDOUT Rolling back SSL Endpoint tokyo-1050 for example... done New active certificate details: #{certificate_details} @@ -226,15 +226,15 @@ module Heroku::Command stub_core.ssl_endpoint_list("example").returns([endpoint]) stderr, stdout = execute("certs:rollback") - stdout.should include "WARNING: Potentially Destructive Action" - stdout.should include "This command will rollback the certificate of endpoint tokyo-1050.herokussl.com on example." + expect(stdout).to include "WARNING: Potentially Destructive Action" + expect(stdout).to include "This command will rollback the certificate of endpoint tokyo-1050.herokussl.com on example." end it "shows an error if an app has no endpoints" do stub_core.ssl_endpoint_list("example").returns([]) stderr, stdout = execute("certs:rollback") - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! example has no SSL Endpoints. STDERR end diff --git a/spec/heroku/command/config_spec.rb b/spec/heroku/command/config_spec.rb index 8c30a2269..aaf816412 100644 --- a/spec/heroku/command/config_spec.rb +++ b/spec/heroku/command/config_spec.rb @@ -15,8 +15,8 @@ module Heroku::Command it "shows all configs" do api.put_config_vars("example", { 'FOO_BAR' => 'one', 'BAZ_QUX' => 'two' }) stderr, stdout = execute("config") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT === example Config Vars BAZ_QUX: two FOO_BAR: one @@ -26,8 +26,8 @@ module Heroku::Command it "does not trim long values" do api.put_config_vars("example", { 'LONG' => 'A' * 60 }) stderr, stdout = execute("config") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT === example Config Vars LONG: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA STDOUT @@ -36,8 +36,8 @@ module Heroku::Command it "handles when value is nil" do api.put_config_vars("example", { 'FOO_BAR' => 'one', 'BAZ_QUX' => nil }) stderr, stdout = execute("config") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT === example Config Vars BAZ_QUX: FOO_BAR: one @@ -47,8 +47,8 @@ module Heroku::Command it "handles when value is a boolean" do api.put_config_vars("example", { 'FOO_BAR' => 'one', 'BAZ_QUX' => true }) stderr, stdout = execute("config") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT === example Config Vars BAZ_QUX: true FOO_BAR: one @@ -58,8 +58,8 @@ module Heroku::Command it "shows configs in a shell compatible format" do api.put_config_vars("example", { 'A' => 'one', 'B' => 'two three' }) stderr, stdout = execute("config --shell") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT A=one B=two three STDOUT @@ -68,8 +68,8 @@ module Heroku::Command it "shows a single config for get" do api.put_config_vars("example", { 'LONG' => 'A' * 60 }) stderr, stdout = execute("config:get LONG") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA STDOUT end @@ -78,8 +78,8 @@ module Heroku::Command it "sets config vars" do stderr, stdout = execute("config:set A=1 B=2") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Setting config vars and restarting example... done, v1 A: 1 B: 2 @@ -88,8 +88,8 @@ module Heroku::Command it "allows config vars with = in the value" do stderr, stdout = execute("config:set A=b=c") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Setting config vars and restarting example... done, v1 A: b=c STDOUT @@ -97,8 +97,8 @@ module Heroku::Command it "sets config vars without changing case" do stderr, stdout = execute("config:set a=b") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Setting config vars and restarting example... done, v1 a: b STDOUT @@ -110,19 +110,19 @@ module Heroku::Command it "exits with a help notice when no keys are provides" do stderr, stdout = execute("config:unset") - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! Usage: heroku config:unset KEY1 [KEY2 ...] ! Must specify KEY to unset. STDERR - stdout.should == "" + expect(stdout).to eq("") end context "when one key is provided" do it "unsets a single key" do stderr, stdout = execute("config:unset A") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Unsetting A and restarting example... done, v1 STDOUT end @@ -132,8 +132,8 @@ module Heroku::Command it "unsets all given keys" do stderr, stdout = execute("config:unset A B") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Unsetting A and restarting example... done, v1 Unsetting B and restarting example... done, v2 STDOUT diff --git a/spec/heroku/command/domains_spec.rb b/spec/heroku/command/domains_spec.rb index 2b2432d66..c98cd31ea 100644 --- a/spec/heroku/command/domains_spec.rb +++ b/spec/heroku/command/domains_spec.rb @@ -21,8 +21,8 @@ module Heroku::Command it "lists message with no domains" do stderr, stdout = execute("domains") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT example has no domain names. STDOUT end @@ -30,8 +30,8 @@ module Heroku::Command it "lists domains when some exist" do api.post_domain("example", "example.com") stderr, stdout = execute("domains") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT === example Domain Names example.com @@ -43,8 +43,8 @@ module Heroku::Command it "adds domain names" do stderr, stdout = execute("domains:add example.com") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Adding example.com to example... done STDOUT api.delete_domain("example", "example.com") @@ -52,7 +52,7 @@ module Heroku::Command it "shows usage if no domain specified for add" do stderr, stdout = execute("domains:add") - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! Usage: heroku domains:add DOMAIN ! Must specify DOMAIN to add. STDERR @@ -61,15 +61,15 @@ module Heroku::Command it "removes domain names" do api.post_domain("example", "example.com") stderr, stdout = execute("domains:remove example.com") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Removing example.com from example... done STDOUT end it "shows usage if no domain specified for remove" do stderr, stdout = execute("domains:remove") - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! Usage: heroku domains:remove DOMAIN ! Must specify DOMAIN to remove. STDERR @@ -78,8 +78,8 @@ module Heroku::Command it "removes all domain names" do stub_core.remove_domains("example") stderr, stdout = execute("domains:clear") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Removing all domain names from example... done STDOUT end diff --git a/spec/heroku/command/drains_spec.rb b/spec/heroku/command/drains_spec.rb index 52edddc56..629f88ce8 100644 --- a/spec/heroku/command/drains_spec.rb +++ b/spec/heroku/command/drains_spec.rb @@ -7,8 +7,8 @@ it "can list drains" do stub_core.list_drains("example").returns("drains") stderr, stdout = execute("drains") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT drains STDOUT end @@ -16,8 +16,8 @@ it "can add drains" do stub_core.add_drain("example", "syslog://localhost/add").returns("added") stderr, stdout = execute("drains:add syslog://localhost/add") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT added STDOUT end @@ -25,8 +25,8 @@ it "can remove drains" do stub_core.remove_drain("example", "syslog://localhost/remove").returns("removed") stderr, stdout = execute("drains:remove syslog://localhost/remove") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT removed STDOUT end diff --git a/spec/heroku/command/fork_spec.rb b/spec/heroku/command/fork_spec.rb index af55bb6eb..3d2adb050 100644 --- a/spec/heroku/command/fork_spec.rb +++ b/spec/heroku/command/fork_spec.rb @@ -39,8 +39,8 @@ module Heroku::Command it "forks an app" do stderr, stdout = execute("fork example-fork") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Creating fork example-fork... done Copying slug... done Copying config vars... done @@ -49,8 +49,13 @@ module Heroku::Command end it "copies slug" do - Heroku::API.any_instance.should_receive(:get_releases_v3).with("example", "version ..; order=desc,max=1;").and_call_original - Heroku::API.any_instance.should_receive(:post_release_v3).with("example-fork", "SLUG_ID", "Forked from example").and_call_original + from_info = api.get_app("example").body + expect_any_instance_of(Heroku::API).to receive(:get_releases_v3).with("example", "version ..; order=desc,max=1;").and_call_original + expect_any_instance_of(Heroku::API).to receive(:post_release_v3).with("example-fork", + "SLUG_ID", + :description => "Forked from example", + :deploy_type => "fork", + :deploy_source => from_info["id"]).and_call_original execute("fork example-fork") end @@ -62,14 +67,14 @@ module Heroku::Command } api.put_config_vars("example", config_vars) execute("fork example-fork") - api.get_config_vars("example-fork").body.should == config_vars + expect(api.get_config_vars("example-fork").body).to eq(config_vars) end it "re-provisions add-ons" do addons = ["pgbackups:basic", "deployhooks:http"].sort addons.each { |a| api.post_addon("example", a) } execute("fork example-fork") - api.get_addons("example-fork").body.collect { |info| info["name"] }.sort.should == addons + expect(api.get_addons("example-fork").body.collect { |info| info["name"] }.sort).to eq(addons) end end @@ -83,7 +88,7 @@ module Heroku::Command execute("fork example-fork") raise rescue Heroku::Command::CommandFailed => e - e.message.should == "No releases on example" + expect(e.message).to eq("No releases on example") ensure Excon.stubs.shift end @@ -98,16 +103,16 @@ module Heroku::Command execute("fork example-fork") raise rescue Heroku::Command::CommandFailed => e - e.message.should == "No slug on example" + expect(e.message).to eq("No slug on example") ensure Excon.stubs.shift end end it "doesn't attempt to fork to the same app" do - lambda do + expect do execute("fork example") - end.should raise_error(Heroku::Command::CommandFailed, /same app/) + end.to raise_error(Heroku::Command::CommandFailed, /same app/) end it "confirms before deleting the app" do @@ -118,13 +123,14 @@ module Heroku::Command ensure Excon.stubs.shift end - api.get_apps.body.map { |app| app["name"] }.should == + expect(api.get_apps.body.map { |app| app["name"] }).to eq( %w( example example-fork ) + ) end it "deletes fork app on error, before re-raising" do stub(Heroku::Command).confirm_command.returns(true) - api.get_apps.body.map { |app| app["name"] }.should == %w( example ) + expect(api.get_apps.body.map { |app| app["name"] }).to eq(%w( example )) end end end diff --git a/spec/heroku/command/git_spec.rb b/spec/heroku/command/git_spec.rb index b878fad29..b57adc4e0 100644 --- a/spec/heroku/command/git_spec.rb +++ b/spec/heroku/command/git_spec.rb @@ -25,8 +25,8 @@ module Heroku::Command end end stderr, stdout = execute("git:clone example") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Cloning from app 'example'... Cloning into 'example'... STDOUT @@ -39,8 +39,8 @@ module Heroku::Command end end stderr, stdout = execute("git:clone example somedir") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Cloning from app 'example'... Cloning into 'somedir'... STDOUT @@ -53,8 +53,8 @@ module Heroku::Command end end stderr, stdout = execute("git:clone -a example") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Cloning from app 'example'... Cloning into 'example'... STDOUT @@ -67,8 +67,8 @@ module Heroku::Command end end stderr, stdout = execute("git:clone -a example somedir") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Cloning from app 'example'... Cloning into 'somedir'... STDOUT @@ -81,8 +81,8 @@ module Heroku::Command end end stderr, stdout = execute("git:clone example -r other") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Cloning from app 'example'... Cloning into 'example'... STDOUT @@ -109,8 +109,8 @@ module Heroku::Command stub(git).git('remote add heroku git@heroku.com:example.git') end stderr, stdout = execute("git:remote") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Git remote heroku added STDOUT end @@ -121,8 +121,8 @@ module Heroku::Command stub(git).git('remote add other git@heroku.com:example.git') end stderr, stdout = execute("git:remote -r other") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Git remote other added STDOUT end @@ -132,10 +132,10 @@ module Heroku::Command stub(git).git('remote').returns("heroku") end stderr, stdout = execute("git:remote") - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! Git remote heroku already exists STDERR - stdout.should == "" + expect(stdout).to eq("") end end diff --git a/spec/heroku/command/help_spec.rb b/spec/heroku/command/help_spec.rb index e851cdca5..5f1918a93 100644 --- a/spec/heroku/command/help_spec.rb +++ b/spec/heroku/command/help_spec.rb @@ -7,64 +7,64 @@ describe "help" do it "should show root help with no args" do stderr, stdout = execute("help") - stderr.should == "" - stdout.should include "Usage: heroku COMMAND [--app APP] [command-specific-options]" - stdout.should include "apps" - stdout.should include "help" + expect(stderr).to eq("") + expect(stdout).to include "Usage: heroku COMMAND [--app APP] [command-specific-options]" + expect(stdout).to include "apps" + expect(stdout).to include "help" end it "should show command help and namespace help when ambigious" do stderr, stdout = execute("help apps") - stderr.should == "" - stdout.should include "heroku apps" - stdout.should include "list your apps" - stdout.should include "Additional commands" - stdout.should include "apps:create" + expect(stderr).to eq("") + expect(stdout).to include "heroku apps" + expect(stdout).to include "list your apps" + expect(stdout).to include "Additional commands" + expect(stdout).to include "apps:create" end it "should show only command help when not ambiguous" do stderr, stdout = execute("help apps:create") - stderr.should == "" - stdout.should include "heroku apps:create" - stdout.should include "create a new app" - stdout.should_not include "Additional commands" + expect(stderr).to eq("") + expect(stdout).to include "heroku apps:create" + expect(stdout).to include "create a new app" + expect(stdout).not_to include "Additional commands" end it "should show command help with --help" do stderr, stdout = execute("apps:create --help") - stderr.should == "" - stdout.should include "Usage: heroku apps:create" - stdout.should include "create a new app" - stdout.should_not include "Additional commands" + expect(stderr).to eq("") + expect(stdout).to include "Usage: heroku apps:create" + expect(stdout).to include "create a new app" + expect(stdout).not_to include "Additional commands" end it "should redirect if the command is an alias" do stderr, stdout = execute("help create") - stderr.should == "" - stdout.should include "Alias: create redirects to apps:create" - stdout.should include "Usage: heroku apps:create" - stdout.should include "create a new app" - stdout.should_not include "Additional commands" + expect(stderr).to eq("") + expect(stdout).to include "Alias: create redirects to apps:create" + expect(stdout).to include "Usage: heroku apps:create" + expect(stdout).to include "create a new app" + expect(stdout).not_to include "Additional commands" end it "should show if the command does not exist" do stderr, stdout = execute("help sudo:sandwich") - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! sudo:sandwich is not a heroku command. See `heroku help`. STDERR - stdout.should == "" + expect(stdout).to eq("") end it "should show help with naked -h" do stderr, stdout = execute("-h") - stderr.should == "" - stdout.should include "Usage: heroku COMMAND" + expect(stderr).to eq("") + expect(stdout).to include "Usage: heroku COMMAND" end it "should show help with naked --help" do stderr, stdout = execute("--help") - stderr.should == "" - stdout.should include "Usage: heroku COMMAND" + expect(stderr).to eq("") + expect(stdout).to include "Usage: heroku COMMAND" end describe "with legacy help" do @@ -72,21 +72,21 @@ it "displays the legacy group in the namespace list" do stderr, stdout = execute("help") - stderr.should == "" - stdout.should include "Foo Group" + expect(stderr).to eq("") + expect(stdout).to include "Foo Group" end it "displays group help" do stderr, stdout = execute("help foo") - stderr.should == "" - stdout.should include "do a bar to foo" - stdout.should include "do a baz to foo" + expect(stderr).to eq("") + expect(stdout).to include "do a bar to foo" + expect(stdout).to include "do a baz to foo" end it "displays legacy command-specific help" do stderr, stdout = execute("help foo:bar") - stderr.should == "" - stdout.should include "do a bar to foo" + expect(stderr).to eq("") + expect(stdout).to include "do a bar to foo" end end end diff --git a/spec/heroku/command/keys_spec.rb b/spec/heroku/command/keys_spec.rb index cfc18737e..bb4d5d210 100644 --- a/spec/heroku/command/keys_spec.rb +++ b/spec/heroku/command/keys_spec.rb @@ -7,40 +7,33 @@ module Heroku::Command before(:each) do stub_core + allow(Heroku::Auth).to receive(:home_directory).and_return(Heroku::Helpers.home_directory) end context("add") do - - after(:each) do - api.delete_key("pedro@heroku") - end - it "tries to find a key if no key filename is supplied" do - Heroku::Auth.should_receive(:ask).and_return("y") - Heroku::Auth.should_receive(:generate_ssh_key) - File.should_receive(:exists?).with('.git').and_return(false) - File.should_receive(:exists?).with('/.ssh/id_rsa.pub').and_return(true) - File.should_receive(:read).with('/.ssh/id_rsa.pub').and_return(KEY) + expect(Heroku::Auth).to receive(:ask).and_return("y") stderr, stdout = execute("keys:add") - stderr.should == "" - stdout.should == <<-STDOUT -Could not find an existing public key. + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT +Could not find an existing public key at ~/.ssh/id_rsa.pub Would you like to generate one? [Yn] Generating new SSH public key. -Uploading SSH public key /.ssh/id_rsa.pub... done +Uploading SSH public key #{Heroku::Auth.home_directory}/.ssh/id_rsa.pub... done STDOUT + api.delete_key(`whoami`.strip + '@' + `hostname`.strip) end it "adds a key from a specified keyfile path" do - File.should_receive(:exists?).with('.git').and_return(false) - File.should_receive(:exists?).with('/my/key.pub').and_return(true) - File.should_receive(:read).with('/my/key.pub').and_return(KEY) + expect(File).to receive(:exists?).with('.git').and_return(false) + expect(File).to receive(:exists?).with('/my/key.pub').and_return(true) + expect(File).to receive(:read).with('/my/key.pub').and_return(KEY) stderr, stdout = execute("keys:add /my/key.pub") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Uploading SSH public key /my/key.pub... done STDOUT + api.delete_key("pedro@heroku") end - end context("index") do @@ -55,8 +48,8 @@ module Heroku::Command it "list keys, trimming the hex code for better display" do stderr, stdout = execute("keys") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT === email@example.com Keys ssh-rsa AAAAB3NzaC...Fyoke4MQ== pedro@heroku @@ -65,8 +58,8 @@ module Heroku::Command it "list keys showing the whole key hex with --long" do stderr, stdout = execute("keys --long") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT === email@example.com Keys ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAp9AJD5QABmOcrkHm6SINuQkDefaR0MUrfgZ1Pxir3a4fM1fwa00dsUwbUaRuR7FEFD8n1E9WwDf8SwQTHtyZsJg09G9myNqUzkYXCmydN7oGr5IdVhRyv5ixcdiE0hj7dRnOJg2poSQ3Qi+Ka8SVJzF7nIw1YhuicHPSbNIFKi5s0D5a+nZb/E6MNGvhxoFCQX2IcNxaJMqhzy1ESwlixz45aT72mXYq0LIxTTpoTqma1HuKdRY8HxoREiivjmMQulYP+CxXFcMyV9kxTKIUZ/FXqlC6G5vSm3J4YScSatPOj9ID5HowpdlIx8F6y4p1/28r2tTl4CY40FFyoke4MQ== pedro@heroku @@ -85,8 +78,8 @@ module Heroku::Command it "succeeds" do stderr, stdout = execute("keys:remove pedro@heroku") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Removing pedro@heroku SSH key... done STDOUT end @@ -95,11 +88,11 @@ module Heroku::Command it "displays an error if no key is specified" do stderr, stdout = execute("keys:remove") - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! Usage: heroku keys:remove KEY ! Must specify KEY to remove. STDERR - stdout.should == "" + expect(stdout).to eq("") end end @@ -108,8 +101,8 @@ module Heroku::Command it "succeeds" do stderr, stdout = execute("keys:clear") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Removing all SSH keys... done STDOUT end diff --git a/spec/heroku/command/labs_spec.rb b/spec/heroku/command/labs_spec.rb index 60c935074..a0848ece2 100644 --- a/spec/heroku/command/labs_spec.rb +++ b/spec/heroku/command/labs_spec.rb @@ -16,8 +16,8 @@ module Heroku::Command it "lists available features" do stderr, stdout = execute("labs:list") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT === User Features (email@example.com) [ ] sumo-rankings Heroku Sumo ranks and visualizes the scale of your app, and suggests the optimum combination of dynos and add-ons to take it to the next level. @@ -30,8 +30,8 @@ module Heroku::Command it "lists enabled features" do stub_core.list_features("example").returns([]) stderr, stdout = execute("labs") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT === User Features (email@example.com) [ ] sumo-rankings Heroku Sumo ranks and visualizes the scale of your app, and suggests the optimum combination of dynos and add-ons to take it to the next level. @@ -43,8 +43,8 @@ module Heroku::Command it "displays details of a feature" do stderr, stdout = execute("labs:info user_env_compile") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT === user_env_compile Docs: http://devcenter.heroku.com/articles/labs-user-env-compile Summary: Add user config vars to the environment during slug compilation @@ -53,17 +53,17 @@ module Heroku::Command it "shows usage if no feature name is specified for info" do stderr, stdout = execute("labs:info") - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! Usage: heroku labs:info FEATURE ! Must specify FEATURE for info. STDERR - stdout.should == "" + expect(stdout).to eq("") end it "enables a feature" do stderr, stdout = execute("labs:enable user_env_compile") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Enabling user_env_compile for example... done WARNING: This feature is experimental and may change or be removed without notice. For more information see: http://devcenter.heroku.com/articles/labs-user-env-compile @@ -72,29 +72,29 @@ module Heroku::Command it "shows usage if no feature name is specified for enable" do stderr, stdout = execute("labs:enable") - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! Usage: heroku labs:enable FEATURE ! Must specify FEATURE to enable. STDERR - stdout.should == "" + expect(stdout).to eq("") end it "disables a feature" do api.post_feature('user_env_compile', 'example') stderr, stdout = execute("labs:disable user_env_compile") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Disabling user_env_compile for example... done STDOUT end it "shows usage if no feature name is specified for disable" do stderr, stdout = execute("labs:disable") - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! Usage: heroku labs:disable FEATURE ! Must specify FEATURE to disable. STDERR - stdout.should == "" + expect(stdout).to eq("") end end end diff --git a/spec/heroku/command/logs_spec.rb b/spec/heroku/command/logs_spec.rb index edf15f541..9e69ab5c2 100644 --- a/spec/heroku/command/logs_spec.rb +++ b/spec/heroku/command/logs_spec.rb @@ -27,8 +27,8 @@ old_stdout_isatty = $stdout.isatty stub($stdout).isatty.returns(true) stderr, stdout = execute("logs") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT \e[36m2011-01-01T00:00:00+00:00 app[web.1]:\e[0m test STDOUT stub($stdout).isatty.returns(old_stdout_isatty) @@ -38,8 +38,8 @@ old_stdout_isatty = $stdout.isatty stub($stdout).isatty.returns(false) stderr, stdout = execute("logs") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT 2011-01-01T00:00:00+00:00 app[web.1]: test STDOUT stub($stdout).isatty.returns(old_stdout_isatty) @@ -48,8 +48,8 @@ it "does not use ansi if TERM is not set" do term = ENV.delete("TERM") stderr, stdout = execute("logs") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT 2011-01-01T00:00:00+00:00 app[web.1]: test STDOUT ENV["TERM"] = term diff --git a/spec/heroku/command/maintenance_spec.rb b/spec/heroku/command/maintenance_spec.rb index 77168e91a..8eea6967d 100644 --- a/spec/heroku/command/maintenance_spec.rb +++ b/spec/heroku/command/maintenance_spec.rb @@ -15,8 +15,8 @@ module Heroku::Command it "displays off for maintenance mode of an app" do stderr, stdout = execute("maintenance") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT off STDOUT end @@ -25,24 +25,24 @@ module Heroku::Command api.post_app_maintenance('example', '1') stderr, stdout = execute("maintenance") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT on STDOUT end it "turns on maintenance mode for the app" do stderr, stdout = execute("maintenance:on") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Enabling maintenance mode for example... done STDOUT end it "turns off maintenance mode for the app" do stderr, stdout = execute("maintenance:off") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Disabling maintenance mode for example... done STDOUT end diff --git a/spec/heroku/command/orgs_spec.rb b/spec/heroku/command/orgs_spec.rb index 11eafecc8..7f60db918 100644 --- a/spec/heroku/command/orgs_spec.rb +++ b/spec/heroku/command/orgs_spec.rb @@ -16,8 +16,8 @@ module Heroku::Command context(:index) do it "displays a message when you have no org memberships" do stderr, stdout = execute("orgs") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT You are not a member of any organizations. STDOUT end @@ -31,8 +31,8 @@ module Heroku::Command ) stderr, stdout = execute("orgs") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT test-org collaborator test-org2 admin @@ -48,8 +48,8 @@ module Heroku::Command ) stderr, stdout = execute("orgs") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT test-org collaborator test-org2 admin, default @@ -60,28 +60,28 @@ module Heroku::Command context(:default) do context "when a target org is specified" do it "sets the default org to the target" do - org_api.should_receive(:set_default_org).with("test-org").once + expect(org_api).to receive(:set_default_org).with("test-org").once stderr, stdout = execute("orgs:default test-org") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Setting test-org as the default organization... done STDOUT end it "removes the default org when the org name is 'personal'" do - org_api.should_receive(:remove_default_org).once + expect(org_api).to receive(:remove_default_org).once stderr, stdout = execute("orgs:default personal") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Setting personal account as default... done STDOUT end it "removes the defautl org when the personal flag is passed" do - org_api.should_receive(:remove_default_org).once + expect(org_api).to receive(:remove_default_org).once stderr, stdout = execute("orgs:default --personal") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Setting personal account as default... done STDOUT end @@ -98,16 +98,16 @@ module Heroku::Command ) stderr, stdout = execute("orgs:default") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT test-org is the default organization. STDOUT end it "displays personal account as default when no org present" do stderr, stdout = execute("orgs:default") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Personal account is default. STDOUT end @@ -117,12 +117,12 @@ module Heroku::Command context(:open) do before(:each) do require("launchy") - ::Launchy.should_receive(:open).with("https://dashboard.heroku.com/orgs/test-org/apps").once.and_return("") + expect(::Launchy).to receive(:open).with("https://dashboard.heroku.com/orgs/test-org/apps").once.and_return("") end it "opens the org specified in an argument" do stderr, stdout = execute("orgs:open --org test-org") - stdout.should == <<-STDOUT + expect(stdout).to eq <<-STDOUT Opening web interface for test-org... done STDOUT end @@ -136,7 +136,7 @@ module Heroku::Command ) stderr, stdout = execute("orgs:open") - stdout.should == <<-STDOUT + expect(stdout).to eq <<-STDOUT Opening web interface for test-org... done STDOUT end diff --git a/spec/heroku/command/pg_spec.rb b/spec/heroku/command/pg_spec.rb index dd89b357b..8ee5ce971 100644 --- a/spec/heroku/command/pg_spec.rb +++ b/spec/heroku/command/pg_spec.rb @@ -48,8 +48,8 @@ module Heroku::Command stub_pg.reset stderr, stdout = execute("pg:reset RONIN --confirm example") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Resetting HEROKU_POSTGRESQL_RONIN_URL... done STDOUT end @@ -58,15 +58,15 @@ module Heroku::Command stub_pg.reset stderr, stdout = execute("pg:reset RONIN") - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! Confirmation did not match example. Aborted. STDERR - stdout.should == " + expect(stdout).to eq(" ! WARNING: Destructive Action ! This command will affect the app: example ! To proceed, type \"example\" or re-run this command with --confirm example -> " +> ") end context "index" do @@ -83,8 +83,8 @@ module Heroku::Command ]) stderr, stdout = execute("pg") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT === HEROKU_POSTGRESQL_FOLLOW_URL Plan: Ronin Status: available @@ -134,8 +134,8 @@ module Heroku::Command ]) stderr, stdout = execute("pg:info RONIN") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT === HEROKU_POSTGRESQL_RONIN_URL Plan: Ronin Status: available @@ -154,20 +154,20 @@ module Heroku::Command context "promotion" do it "promotes the specified database" do stderr, stdout = execute("pg:promote RONIN --confirm example") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Promoting HEROKU_POSTGRESQL_RONIN_URL to DATABASE_URL... done STDOUT - api.get_config_vars("example").body["DATABASE_URL"].should == "postgres://ronin_database_url" + expect(api.get_config_vars("example").body["DATABASE_URL"]).to eq("postgres://ronin_database_url") end it "fails if no database is specified" do stderr, stdout = execute("pg:promote") - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! Usage: heroku pg:promote DATABASE ! Must specify DATABASE to promote. STDERR - stdout.should == "" + expect(stdout).to eq("") end end @@ -175,8 +175,8 @@ module Heroku::Command it "resets credentials and promotes to DATABASE_URL if it's the main DB" do stub_pg.rotate_credentials stderr, stdout = execute("pg:credentials iv --reset") - stderr.should == '' - stdout.should == <<-STDOUT + expect(stderr).to eq('') + expect(stdout).to eq <<-STDOUT Resetting credentials for HEROKU_POSTGRESQL_IVORY_URL (DATABASE_URL)... done Promoting HEROKU_POSTGRESQL_IVORY_URL (DATABASE_URL)... done STDOUT @@ -189,8 +189,8 @@ module Heroku::Command "HEROKU_POSTGRESQL_RESETME_URL" => "postgres://something_else" } stderr, stdout = execute("pg:credentials follo --reset") - stderr.should == '' - stdout.should_not include("Promoting") + expect(stderr).to eq('') + expect(stdout).not_to include("Promoting") end end @@ -198,9 +198,9 @@ module Heroku::Command context "unfollow" do it "sends request to unfollow" do hpg_client = double('Heroku::Client::HerokuPostgresql') - Heroku::Client::HerokuPostgresql.should_receive(:new).twice.and_return(hpg_client) - hpg_client.should_receive(:unfollow) - hpg_client.should_receive(:get_database).and_return( + expect(Heroku::Client::HerokuPostgresql).to receive(:new).twice.and_return(hpg_client) + expect(hpg_client).to receive(:unfollow) + expect(hpg_client).to receive(:get_database).and_return( :following => 'postgresql://user:pass@roninhost/database', :info => [ {"name"=>"Plan", "values"=>["Ronin"]}, @@ -215,8 +215,8 @@ module Heroku::Command ] ) stderr, stdout = execute("pg:unfollow HEROKU_POSTGRESQL_FOLLOW_URL --confirm example") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT ! HEROKU_POSTGRESQL_FOLLOW_URL will become writable and no longer ! follow Database on roninhost:5432/database. This cannot be undone. Unfollowing HEROKU_POSTGRESQL_FOLLOW_URL... done @@ -252,8 +252,8 @@ module Heroku::Command }) stderr, stdout = execute("pg:diagnose") - stderr.should == '' - stdout.should == <<-STDOUT + expect(stderr).to eq('') + expect(stdout).to eq <<-STDOUT Report abc123 for appname::dbcolor available for one month after creation on 2014-06-24 01:26:11.941197+00 diff --git a/spec/heroku/command/pgbackups_spec.rb b/spec/heroku/command/pgbackups_spec.rb index ed44be4ea..5db07aa4d 100644 --- a/spec/heroku/command/pgbackups_spec.rb +++ b/spec/heroku/command/pgbackups_spec.rb @@ -7,10 +7,10 @@ module Heroku::Command api.post_app("name" => "example") stub_core stderr, stdout = execute("pgbackups:capture") - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! Your app has no databases. STDERR - stdout.should == "" + expect(stdout).to eq("") api.delete_app("example") end end @@ -18,7 +18,7 @@ module Heroku::Command describe Pgbackups do before do @pgbackups = prepare_command(Pgbackups) - @pgbackups.heroku.stub!(:info).and_return({}) + allow(@pgbackups.heroku).to receive(:info).and_return({}) api.post_app("name" => "example") api.put_config_vars( @@ -64,8 +64,8 @@ module Heroku::Command }]) stderr, stdout = execute("pgbackups") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT ID Backup Time Status Size Database ---- ------------------------- --------- ---- -------- b001 2012-01-01 12:00:01 +0000 Capturing 1024 DATABASE @@ -77,7 +77,7 @@ module Heroku::Command let(:from_url) { "postgres://from/bar" } let(:attachment) { double('attachment', :display_name => from_name, :url => from_url ) } before do - @pgbackups.stub!(:resolve).and_return(attachment) + allow(@pgbackups).to receive(:resolve).and_return(attachment) end it "gets the url for the latest backup if nothing is specified" do @@ -85,34 +85,34 @@ module Heroku::Command stub_pgbackups.get_latest_backup.returns({"public_url" => "http://latest/backup.dump"}) old_stdout_isatty = STDOUT.isatty - $stdout.stub!(:isatty).and_return(true) + allow($stdout).to receive(:isatty).and_return(true) stderr, stdout = execute("pgbackups:url") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT http://latest/backup.dump STDOUT - $stdout.stub!(:isatty).and_return(old_stdout_isatty) + allow($stdout).to receive(:isatty).and_return(old_stdout_isatty) end it "gets the url for the named backup if a name is specified" do stub_pgbackups.get_backup.with("b001").returns({"public_url" => "http://latest/backup.dump" }) old_stdout_isatty = STDOUT.isatty - $stdout.stub!(:isatty).and_return(true) + allow($stdout).to receive(:isatty).and_return(true) stderr, stdout = execute("pgbackups:url b001") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT http://latest/backup.dump STDOUT - $stdout.stub!(:isatty).and_return(old_stdout_isatty) + allow($stdout).to receive(:isatty).and_return(old_stdout_isatty) end it "should capture a backup when requested" do backup_obj = {'to_url' => "s3://bucket/userid/b001.dump"} - @pgbackups.stub!(:args).and_return([]) - @pgbackups.stub!(:transfer!).with(from_url, from_name, nil, "BACKUP", {:expire => nil}).and_return(backup_obj) - @pgbackups.stub!(:poll_transfer!).with(backup_obj).and_return(backup_obj) + allow(@pgbackups).to receive(:args).and_return([]) + allow(@pgbackups).to receive(:transfer!).with(from_url, from_name, nil, "BACKUP", {:expire => nil}).and_return(backup_obj) + allow(@pgbackups).to receive(:poll_transfer!).with(backup_obj).and_return(backup_obj) @pgbackups.capture end @@ -120,9 +120,9 @@ module Heroku::Command it "should send expiration flag to client if specified on args" do backup_obj = {'to_url' => "s3://bucket/userid/b001.dump"} - @pgbackups.stub!(:options).and_return({:expire => true}) - @pgbackups.stub!(:transfer!).with(from_url, from_name, nil, "BACKUP", {:expire => true}).and_return(backup_obj) - @pgbackups.stub!(:poll_transfer!).with(backup_obj).and_return(backup_obj) + allow(@pgbackups).to receive(:options).and_return({:expire => true}) + allow(@pgbackups).to receive(:transfer!).with(from_url, from_name, nil, "BACKUP", {:expire => true}).and_return(backup_obj) + allow(@pgbackups).to receive(:poll_transfer!).with(backup_obj).and_return(backup_obj) @pgbackups.capture end @@ -130,11 +130,11 @@ module Heroku::Command it "destroys no backup without a name" do stub_core stderr, stdout = execute("pgbackups:destroy") - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! Usage: heroku pgbackups:destroy BACKUP_ID ! Must specify BACKUP_ID to destroy. STDERR - stdout.should == "" + expect(stdout).to eq("") end it "destroys a backup" do @@ -143,8 +143,8 @@ module Heroku::Command stub_pgbackups.delete_backup("b001").returns({}) stderr, stdout = execute("pgbackups:destroy b001") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Destroying b001... done STDOUT end @@ -172,11 +172,11 @@ def stub_failed_capture(log) it 'aborts on a generic error' do stub_failed_capture "something generic" stderr, stdout = execute("pgbackups:capture") - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! An error occurred and your backup did not finish. ! Please run `heroku logs --ps pgbackups` for details. STDERR - stdout.should == <<-STDOUT + expect(stdout).to eq <<-STDOUT HEROKU_POSTGRESQL_IVORY (DATABASE_URL) ----backup---> bar @@ -187,12 +187,12 @@ def stub_failed_capture(log) it 'aborts and informs when the database isnt up yet' do stub_failed_capture 'could not translate host name "ec2-42-42-42-42.compute-1.amazonaws.com" to address: Name or service not known' stderr, stdout = execute("pgbackups:capture") - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! An error occurred and your backup did not finish. ! Please run `heroku logs --ps pgbackups` for details. ! The database is not yet online. Please try again. STDERR - stdout.should == <<-STDOUT + expect(stdout).to eq <<-STDOUT HEROKU_POSTGRESQL_IVORY (DATABASE_URL) ----backup---> bar @@ -203,12 +203,12 @@ def stub_failed_capture(log) it 'aborts and informs when the credentials are incorrect' do stub_failed_capture 'psql: FATAL: database "randomname" does not exist' stderr, stdout = execute("pgbackups:capture") - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! An error occurred and your backup did not finish. ! Please run `heroku logs --ps pgbackups` for details. ! The database credentials are incorrect. STDERR - stdout.should == <<-STDOUT + expect(stdout).to eq <<-STDOUT HEROKU_POSTGRESQL_IVORY (DATABASE_URL) ----backup---> bar @@ -221,24 +221,22 @@ def stub_failed_capture(log) context "restore" do let(:attachment) { double('attachment', :display_name => 'someconfigvar', :url => 'postgres://fromhost/database') } before do - from_name, from_url = "FROM_NAME", "postgres://fromhost/database" - - @pgbackups_client = RSpec::Mocks::Mock.new("pgbackups_client") # avoid double r mock - @pgbackups.stub!(:pgbackup_client).and_return(@pgbackups_client) + @pgbackups_client = double("pgbackups_client") + allow(@pgbackups).to receive(:pgbackup_client).and_return(@pgbackups_client) end it "should receive a confirm_command on restore" do - @pgbackups_client.stub!(:get_latest_backup) { {"to_url" => "s3://bucket/user/bXXX.dump"} } + allow(@pgbackups_client).to receive(:get_latest_backup) { {"to_url" => "s3://bucket/user/bXXX.dump"} } - @pgbackups.should_receive(:confirm_command).and_return(false) - @pgbackups_client.should_not_receive(:transfer!) + expect(@pgbackups).to receive(:confirm_command).and_return(false) + expect(@pgbackups_client).not_to receive(:transfer!) @pgbackups.restore end it "aborts if no database addon is present" do - @pgbackups.should_receive(:resolve).and_raise(SystemExit) - lambda { @pgbackups.restore }.should raise_error(SystemExit) + expect(@pgbackups).to receive(:resolve).and_raise(SystemExit) + expect { @pgbackups.restore }.to raise_error(SystemExit) end context "for commands which perform restores" do @@ -250,13 +248,13 @@ def stub_failed_capture(log) "from_name" => "postgres://databasehost/dbname" } - @pgbackups.stub!(:confirm_command).and_return(true) - @pgbackups_client.should_receive(:create_transfer).and_return(@backup_obj) - @pgbackups.stub!(:poll_transfer!).and_return(@backup_obj) + allow(@pgbackups).to receive(:confirm_command).and_return(true) + expect(@pgbackups_client).to receive(:create_transfer).and_return(@backup_obj) + allow(@pgbackups).to receive(:poll_transfer!).and_return(@backup_obj) end it "should default to the latest backup" do - @pgbackups.stub(:args).and_return([]) + allow(@pgbackups).to receive(:args).and_return([]) mock(@pgbackups_client).get_latest_backup.returns(@backup_obj) @pgbackups.restore end @@ -265,28 +263,28 @@ def stub_failed_capture(log) it "should restore the named backup" do name = "backupname" args = ['DATABASE', name] - @pgbackups.stub(:args).and_return(args) - @pgbackups.stub(:shift_argument).and_return(*args) - @pgbackups.stub(:resolve).and_return(attachment) + allow(@pgbackups).to receive(:args).and_return(args) + allow(@pgbackups).to receive(:shift_argument).and_return(*args) + allow(@pgbackups).to receive(:resolve).and_return(attachment) mock(@pgbackups_client).get_backup.with(name).returns(@backup_obj) @pgbackups.restore end it "should handle external restores" do args = ['db_name_gets_shifted_out_in_resolve_db', 'http://external/file.dump'] - @pgbackups.stub(:args).and_return(args) - @pgbackups.stub(:shift_argument).and_return(*args) - @pgbackups.stub(:resolve).and_return(attachment) - @pgbackups_client.should_not_receive(:get_backup) - @pgbackups_client.should_not_receive(:get_latest_backup) + allow(@pgbackups).to receive(:args).and_return(args) + allow(@pgbackups).to receive(:shift_argument).and_return(*args) + allow(@pgbackups).to receive(:resolve).and_return(attachment) + expect(@pgbackups_client).not_to receive(:get_backup) + expect(@pgbackups_client).not_to receive(:get_latest_backup) @pgbackups.restore end end context "on errors" do before(:each) do - @pgbackups_client.stub!(:get_latest_backup => {"to_url" => "s3://bucket/user/bXXX.dump"} ) - @pgbackups.stub!(:confirm_command => true) + allow(@pgbackups_client).to receive(:get_latest_backup).and_return("to_url" => "s3://bucket/user/bXXX.dump") + allow(@pgbackups).to receive(:confirm_command).and_return(true) end def stub_error_backup_with_log(log) @@ -295,19 +293,19 @@ def stub_error_backup_with_log(log) "log" => log } - @pgbackups_client.should_receive(:create_transfer) { @backup_obj } - @pgbackups.stub!(:poll_transfer!) { @backup_obj } + expect(@pgbackups_client).to receive(:create_transfer) { @backup_obj } + allow(@pgbackups).to receive(:poll_transfer!) { @backup_obj } end it 'aborts for a generic error' do stub_error_backup_with_log 'something generic' - @pgbackups.should_receive(:error).with("An error occurred and your restore did not finish.\nPlease run `heroku logs --ps pgbackups` for details.") + expect(@pgbackups).to receive(:error).with("An error occurred and your restore did not finish.\nPlease run `heroku logs --ps pgbackups` for details.") @pgbackups.restore end it 'aborts and informs for expired s3 urls' do stub_error_backup_with_log 'Invalid dump format: /tmp/aDMyoXPrAX/b031.dump: XML document text' - @pgbackups.should_receive(:error).with { |message| message.should =~ /backup url is invalid/ } + expect(@pgbackups).to receive(:error).with(/backup url is invalid/) @pgbackups.restore end end diff --git a/spec/heroku/command/plugins_spec.rb b/spec/heroku/command/plugins_spec.rb index d45c03fdc..48dfd65ae 100644 --- a/spec/heroku/command/plugins_spec.rb +++ b/spec/heroku/command/plugins_spec.rb @@ -13,25 +13,25 @@ module Heroku::Command context("install") do before do - Heroku::Plugin.should_receive(:new).with('git://github.com/heroku/Plugin.git').and_return(@plugin) - @plugin.should_receive(:install).and_return(true) + expect(Heroku::Plugin).to receive(:new).with('git://github.com/heroku/Plugin.git').and_return(@plugin) + expect(@plugin).to receive(:install).and_return(true) end it "installs plugins" do - Heroku::Plugin.should_receive(:load_plugin).and_return(true) + expect(Heroku::Plugin).to receive(:load_plugin).and_return(true) stderr, stdout = execute("plugins:install git://github.com/heroku/Plugin.git") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Installing Plugin... done STDOUT end it "does not install plugins that do not load" do - Heroku::Plugin.should_receive(:load_plugin).and_return(false) - @plugin.should_receive(:uninstall).and_return(true) + expect(Heroku::Plugin).to receive(:load_plugin).and_return(false) + expect(@plugin).to receive(:uninstall).and_return(true) stderr, stdout = execute("plugins:install git://github.com/heroku/Plugin.git") - stderr.should == '' # normally would have error, but mocks/stubs don't allow - stdout.should == "Installing Plugin... " # also inaccurate, would end in ' failed' + expect(stderr).to eq('') # normally would have error, but mocks/stubs don't allow + expect(stdout).to eq("Installing Plugin... ") # also inaccurate, would end in ' failed' end end @@ -39,24 +39,24 @@ module Heroku::Command context("uninstall") do before do - Heroku::Plugin.should_receive(:new).with('Plugin').and_return(@plugin) + expect(Heroku::Plugin).to receive(:new).with('Plugin').and_return(@plugin) end it "uninstalls plugins" do - @plugin.should_receive(:uninstall).and_return(true) + expect(@plugin).to receive(:uninstall).and_return(true) stderr, stdout = execute("plugins:uninstall Plugin") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Uninstalling Plugin... done STDOUT end it "does not uninstall plugins that do not exist" do stderr, stdout = execute("plugins:uninstall Plugin") - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! Plugin plugin not found. STDERR - stdout.should == <<-STDOUT + expect(stdout).to eq <<-STDOUT Uninstalling Plugin... failed STDOUT end @@ -66,34 +66,34 @@ module Heroku::Command context("update") do before do - Heroku::Plugin.should_receive(:new).with('Plugin').and_return(@plugin) + expect(Heroku::Plugin).to receive(:new).with('Plugin').and_return(@plugin) end it "updates plugin by name" do - @plugin.should_receive(:update).and_return(true) + expect(@plugin).to receive(:update).and_return(true) stderr, stdout = execute("plugins:update Plugin") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Updating Plugin... done STDOUT end it "updates all plugins" do - Heroku::Plugin.stub(:list).and_return(['Plugin']) - @plugin.should_receive(:update).and_return(true) + allow(Heroku::Plugin).to receive(:list).and_return(['Plugin']) + expect(@plugin).to receive(:update).and_return(true) stderr, stdout = execute("plugins:update") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Updating Plugin... done STDOUT end it "does not update plugins that do not exist" do stderr, stdout = execute("plugins:update Plugin") - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! Plugin plugin not found. STDERR - stdout.should == <<-STDOUT + expect(stdout).to eq <<-STDOUT Updating Plugin... failed STDOUT end diff --git a/spec/heroku/command/ps_spec.rb b/spec/heroku/command/ps_spec.rb index 3949a4b5d..e7bd38424 100644 --- a/spec/heroku/command/ps_spec.rb +++ b/spec/heroku/command/ps_spec.rb @@ -18,11 +18,11 @@ end it "ps:dynos errors out on cedar apps" do - lambda { execute("ps:dynos") }.should raise_error(Heroku::Command::CommandFailed, "For Cedar apps, use `heroku ps`") + expect { execute("ps:dynos") }.to raise_error(Heroku::Command::CommandFailed, "For Cedar apps, use `heroku ps`") end it "ps:workers errors out on cedar apps" do - lambda { execute("ps:workers") }.should raise_error(Heroku::Command::CommandFailed, "For Cedar apps, use `heroku ps`") + expect { execute("ps:workers") }.to raise_error(Heroku::Command::CommandFailed, "For Cedar apps, use `heroku ps`") end describe "ps" do @@ -44,10 +44,10 @@ end.to_json, :status => 200 ) - Heroku::Command::Ps.any_instance.should_receive(:time_ago).exactly(10).times.and_return("2012/09/11 12:34:56 (~ 0s ago)") + expect_any_instance_of(Heroku::Command::Ps).to receive(:time_ago).exactly(10).times.and_return("2012/09/11 12:34:56 (~ 0s ago)") stderr, stdout = execute("ps") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT === web (1X): `bundle exec thin start -p $PORT` web.1: created 2012/09/11 12:34:56 (~ 0s ago) web.2: created 2012/09/11 12:34:56 (~ 0s ago) @@ -80,10 +80,10 @@ end.to_json, :status => 200 ) - Heroku::Command::Ps.any_instance.should_receive(:time_ago).twice.and_return('2012/09/11 12:34:56 (~ 0s ago)') + expect_any_instance_of(Heroku::Command::Ps).to receive(:time_ago).twice.and_return('2012/09/11 12:34:56 (~ 0s ago)') stderr, stdout = execute("ps") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT === run: one-off processes run.1 (1X): created 2012/09/11 12:34:56 (~ 0s ago): `bash` run.2 (1X): created 2012/09/11 12:34:56 (~ 0s ago): `bash` @@ -108,11 +108,11 @@ end.to_json, :status => 200 ) - Heroku::Command::Ps.any_instance.should_receive(:time_ago).twice.and_return("2012/09/11 12:34:56 (~ 0s ago)") + expect_any_instance_of(Heroku::Command::Ps).to receive(:time_ago).twice.and_return("2012/09/11 12:34:56 (~ 0s ago)") stderr, stdout = execute("ps") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT === web (2X): `bundle exec thin start -p $PORT` web.1: created 2012/09/11 12:34:56 (~ 0s ago) web.2: created 2012/09/11 12:34:56 (~ 0s ago) @@ -137,11 +137,11 @@ end.to_json, :status => 200 ) - Heroku::Command::Ps.any_instance.should_receive(:time_ago).twice.and_return("2012/09/11 12:34:56 (~ 0s ago)") + expect_any_instance_of(Heroku::Command::Ps).to receive(:time_ago).twice.and_return("2012/09/11 12:34:56 (~ 0s ago)") stderr, stdout = execute("ps") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT === web (PX): `bundle exec thin start -p $PORT` web.1: created 2012/09/11 12:34:56 (~ 0s ago) web.2: created 2012/09/11 12:34:56 (~ 0s ago) @@ -167,10 +167,10 @@ end.to_json, :status => 200 ) - Heroku::Command::Ps.any_instance.should_receive(:time_ago).exactly(4).times.and_return("2012/09/11 12:34:56 (~ 0s ago)") + expect_any_instance_of(Heroku::Command::Ps).to receive(:time_ago).exactly(4).times.and_return("2012/09/11 12:34:56 (~ 0s ago)") stderr, stdout = execute("ps") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT === run: one-off processes run.1 (PX): created 2012/09/11 12:34:56 (~ 0s ago): `bash` run.2 (2X): created 2012/09/11 12:34:56 (~ 0s ago): `bash` @@ -187,24 +187,24 @@ it "restarts all dynos with no args" do stderr, stdout = execute("ps:restart") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Restarting dynos... done STDOUT end it "restarts one dyno" do stderr, stdout = execute("ps:restart web.1") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Restarting web.1 dyno... done STDOUT end it "restarts a type of dyno" do stderr, stdout = execute("ps:restart web") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Restarting web dynos... done STDOUT end @@ -218,8 +218,8 @@ { :body => [{"quantity" => "5", "size" => "1X", "type" => "web"}], :status => 200}) stderr, stdout = execute("ps:scale web=5") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Scaling dynos... done, now running web at 5:1X. STDOUT end @@ -229,8 +229,8 @@ { :body => [{"quantity" => "3", "size" => "1X", "type" => "web"}], :status => 200}) stderr, stdout = execute("ps:scale web+2") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Scaling dynos... done, now running web at 3:1X. STDOUT end @@ -247,8 +247,8 @@ :status => 200 ) stderr, stdout = execute("ps:scale web=4:2X") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Scaling dynos... done, now running web at 4:2X. STDOUT end @@ -272,8 +272,8 @@ :status => 200 ) stderr, stdout = execute("ps:scale web=4:1X worker=2:2x") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Scaling dynos... done, now running web at 4:1X, worker at 2:2X. STDOUT end @@ -290,8 +290,8 @@ :status => 200 ) stderr, stdout = execute("ps:scale web=4:PX") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Scaling dynos... done, now running web at 4:PX. STDOUT end @@ -311,8 +311,8 @@ :status => 200 ) stderr, stdout = execute("ps:resize web=2X") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Resizing and restarting the specified dynos... done web dynos now 2X ($0.10/dyno-hour) STDOUT @@ -336,8 +336,8 @@ :status => 200 ) stderr, stdout = execute("ps:resize web=4x worker=2X") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Resizing and restarting the specified dynos... done web dynos now 4X ($0.20/dyno-hour) worker dynos now 2X ($0.10/dyno-hour) @@ -362,8 +362,8 @@ :status => 200 ) stderr, stdout = execute("ps:resize web=PX worker=Px") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Resizing and restarting the specified dynos... done web dynos now PX ($0.80/dyno-hour) worker dynos now PX ($0.80/dyno-hour) @@ -376,16 +376,16 @@ it "restarts one dyno" do stderr, stdout = execute("ps:restart ps.1") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Restarting ps.1 dyno... done STDOUT end it "restarts a type of dyno" do stderr, stdout = execute("ps:restart ps") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Restarting ps dynos... done STDOUT end @@ -408,8 +408,8 @@ it "displays the current number of dynos" do stderr, stdout = execute("ps:dynos") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT ~ `heroku ps:dynos QTY` has been deprecated and replaced with `heroku ps:scale dynos=QTY` example is running 0 dynos STDOUT @@ -417,8 +417,8 @@ it "sets the number of dynos" do stderr, stdout = execute("ps:dynos 5") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT ~ `heroku ps:dynos QTY` has been deprecated and replaced with `heroku ps:scale dynos=QTY` Scaling dynos... done, now running 5 STDOUT @@ -430,8 +430,8 @@ it "displays the current number of workers" do stderr, stdout = execute("ps:workers") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT ~ `heroku ps:workers QTY` has been deprecated and replaced with `heroku ps:scale workers=QTY` example is running 0 workers STDOUT @@ -439,8 +439,8 @@ it "sets the number of workers" do stderr, stdout = execute("ps:workers 5") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT ~ `heroku ps:workers QTY` has been deprecated and replaced with `heroku ps:scale workers=QTY` Scaling workers... done, now running 5 STDOUT diff --git a/spec/heroku/command/releases_spec.rb b/spec/heroku/command/releases_spec.rb index 8e600a8ec..fb75c5db9 100644 --- a/spec/heroku/command/releases_spec.rb +++ b/spec/heroku/command/releases_spec.rb @@ -23,10 +23,10 @@ end it "should list releases" do - Heroku::Command::Releases.any_instance.should_receive(:time_ago).exactly(5).times.and_return('2012/09/10 11:36:44 (~ 0s ago)', '2012/09/10 11:36:43 (~ 1s ago)', '2012/09/10 11:35:44 (~ 1m ago)', '2012/09/10 10:36:44 (~ 1h ago)', '2012/01/02 12:34:56') + expect_any_instance_of(Heroku::Command::Releases).to receive(:time_ago).exactly(5).times.and_return('2012/09/10 11:36:44 (~ 0s ago)', '2012/09/10 11:36:43 (~ 1s ago)', '2012/09/10 11:35:44 (~ 1m ago)', '2012/09/10 10:36:44 (~ 1h ago)', '2012/01/02 12:34:56') @stderr, @stdout = execute("releases") - @stderr.should == "" - @stdout.should == <<-STDOUT + expect(@stderr).to eq("") + expect(@stdout).to eq <<-STDOUT === example Releases v5 Config add SUPER_LONG_CONFIG_VAR_TO_GE.. email@example.com 2012/09/10 11:36:44 (~ 0s ago) v4 Config add QUX_QUUX email@example.com 2012/09/10 11:36:43 (~ 1s ago) @@ -38,10 +38,10 @@ end it "should list a specified number of releases" do - Heroku::Command::Releases.any_instance.should_receive(:time_ago).exactly(3).times.and_return('2012/09/10 11:36:44 (~ 0s ago)', '2012/09/10 11:36:43 (~ 1s ago)', '2012/09/10 11:35:44 (~ 1m ago)') + expect_any_instance_of(Heroku::Command::Releases).to receive(:time_ago).exactly(3).times.and_return('2012/09/10 11:36:44 (~ 0s ago)', '2012/09/10 11:36:43 (~ 1s ago)', '2012/09/10 11:35:44 (~ 1m ago)') @stderr, @stdout = execute("releases -n 3") - @stderr.should == "" - @stdout.should == <<-STDOUT + expect(@stderr).to eq("") + expect(@stdout).to eq <<-STDOUT === example Releases v5 Config add SUPER_LONG_CONFIG_VAR_TO_GE.. email@example.com 2012/09/10 11:36:44 (~ 0s ago) v4 Config add QUX_QUUX email@example.com 2012/09/10 11:36:43 (~ 1s ago) @@ -63,17 +63,17 @@ it "requires a release to be specified" do stderr, stdout = execute("releases:info") - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! Usage: heroku releases:info RELEASE STDERR - stdout.should == "" + expect(stdout).to eq("") end it "shows info for a single release" do - Heroku::Command::Releases.any_instance.should_receive(:time_ago).and_return("2012/09/11 12:34:56 (~ 0s ago)") + expect_any_instance_of(Heroku::Command::Releases).to receive(:time_ago).and_return("2012/09/11 12:34:56 (~ 0s ago)") stderr, stdout = execute("releases:info v1") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT === Release v1 By: email@example.com Change: Config add FOO_BAR @@ -88,10 +88,10 @@ end it "shows info for a single release in shell compatible format" do - Heroku::Command::Releases.any_instance.should_receive(:time_ago).and_return("2012/09/11 12:34:56 (~ 0s ago)") + expect_any_instance_of(Heroku::Command::Releases).to receive(:time_ago).and_return("2012/09/11 12:34:56 (~ 0s ago)") stderr, stdout = execute("releases:info v1 --shell") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT === Release v1 By: email@example.com Change: Config add FOO_BAR @@ -120,16 +120,16 @@ it "rolls back to the latest release with no argument" do stderr, stdout = execute("releases:rollback") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Rolling back example... done, v2 STDOUT end it "rolls back to the specified release" do stderr, stdout = execute("releases:rollback v1") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Rolling back example... done, v1 STDOUT end diff --git a/spec/heroku/command/run_spec.rb b/spec/heroku/command/run_spec.rb index 80a45dc84..966419faa 100644 --- a/spec/heroku/command/run_spec.rb +++ b/spec/heroku/command/run_spec.rb @@ -20,8 +20,8 @@ stub_rendezvous.start { $stdout.puts "output" } stderr, stdout = execute("run bin/foo") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Running `bin/foo` attached to terminal... up, run.1 output STDOUT @@ -31,8 +31,8 @@ describe "run:detached" do it "runs a command detached" do stderr, stdout = execute("run:detached bin/foo") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Running `bin/foo` detached... up, run.1 Use `heroku logs -p run.1` to view the output. STDOUT @@ -52,8 +52,8 @@ stub_rendezvous.start { $stdout.puts("rake_output") } stderr, stdout = execute("run:rake foo") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT WARNING: `heroku run:rake` has been deprecated. Please use `heroku run rake` instead. Running `rake foo` attached to terminal... up, run.1 rake_output @@ -64,8 +64,8 @@ stub_rendezvous.start { $stdout.puts("rake_output") } stderr, stdout = execute("rake foo") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT WARNING: `heroku rake` has been deprecated. Please use `heroku run rake` instead. Running `rake foo` attached to terminal... up, run.1 rake_output @@ -76,8 +76,8 @@ describe "run:console" do it "has been removed" do stderr, stdout = execute("run:console") - stderr.should == "" - stdout.should =~ /has been removed/ + expect(stderr).to eq("") + expect(stdout).to match(/has been removed/) end end end diff --git a/spec/heroku/command/sharing_spec.rb b/spec/heroku/command/sharing_spec.rb index 029696226..080506f82 100644 --- a/spec/heroku/command/sharing_spec.rb +++ b/spec/heroku/command/sharing_spec.rb @@ -18,8 +18,8 @@ module Heroku::Command it "lists collaborators" do api.post_collaborator("example", "collaborator@example.com") stderr, stdout = execute("sharing") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT === example Access List collaborator@example.com collaborator email@example.com collaborator @@ -31,8 +31,8 @@ module Heroku::Command it "adds collaborators with default access to view only" do stderr, stdout = execute("sharing:add collaborator@example.com") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Adding collaborator@example.com to example as collaborator... done STDOUT end @@ -40,8 +40,8 @@ module Heroku::Command it "removes collaborators" do api.post_collaborator("example", "collaborator@example.com") stderr, stdout = execute("sharing:remove collaborator@example.com") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Removing collaborator@example.com from example collaborators... done STDOUT end @@ -49,8 +49,8 @@ module Heroku::Command it "transfers ownership" do api.post_collaborator("example", "collaborator@example.com") stderr, stdout = execute("sharing:transfer collaborator@example.com") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Transferring example to collaborator@example.com... done STDOUT end diff --git a/spec/heroku/command/stack_spec.rb b/spec/heroku/command/stack_spec.rb index 7aba8d710..c0cc016ac 100644 --- a/spec/heroku/command/stack_spec.rb +++ b/spec/heroku/command/stack_spec.rb @@ -15,8 +15,8 @@ module Heroku::Command it "index should provide list" do stderr, stdout = execute("stack") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT === example Available Stacks aspen-mri-1.8.6 bamboo-ree-1.8.7 @@ -28,8 +28,8 @@ module Heroku::Command it "migrate should succeed" do stderr, stdout = execute("stack:migrate bamboo-ree-1.8.7") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT Stack set. Next release on example will use bamboo-ree-1.8.7. Run `git push heroku master` to create a new release on bamboo-ree-1.8.7. STDOUT diff --git a/spec/heroku/command/status_spec.rb b/spec/heroku/command/status_spec.rb index 9ab629a5a..01b0ea331 100644 --- a/spec/heroku/command/status_spec.rb +++ b/spec/heroku/command/status_spec.rb @@ -21,11 +21,11 @@ module Heroku::Command } ) - Heroku::Command::Status.any_instance.should_receive(:time_ago).and_return('2012/09/11 09:34:56 (~ 3h ago)', '2012/09/11 12:33:56 (~ 1m ago)', '2012/09/11 12:29:56 (~ 5m ago)', '2012/09/11 12:24:56 (~ 10m ago)', '2012/09/11 12:04:56 (~ 30m ago)', '2012/09/11 11:34:56 (~ 1h ago)', '2012/09/11 10:34:56 (~ 2h ago)', '2012/09/11 09:34:56 (~ 3h ago)') + expect_any_instance_of(Heroku::Command::Status).to receive(:time_ago).and_return('2012/09/11 09:34:56 (~ 3h ago)', '2012/09/11 12:33:56 (~ 1m ago)', '2012/09/11 12:29:56 (~ 5m ago)', '2012/09/11 12:24:56 (~ 10m ago)', '2012/09/11 12:04:56 (~ 30m ago)', '2012/09/11 11:34:56 (~ 1h ago)', '2012/09/11 10:34:56 (~ 2h ago)', '2012/09/11 09:34:56 (~ 3h ago)') stderr, stdout = execute("status") - stderr.should == '' - stdout.should == <<-STDOUT + expect(stderr).to eq('') + expect(stdout).to eq <<-STDOUT === Heroku Status Development: red Production: red diff --git a/spec/heroku/command/version_spec.rb b/spec/heroku/command/version_spec.rb index cdd8c09bf..eb60f1571 100644 --- a/spec/heroku/command/version_spec.rb +++ b/spec/heroku/command/version_spec.rb @@ -6,8 +6,8 @@ module Heroku::Command it "shows version info" do stderr, stdout = execute("version") - stderr.should == "" - stdout.should == <<-STDOUT + expect(stderr).to eq("") + expect(stdout).to eq <<-STDOUT #{Heroku.user_agent} STDOUT end diff --git a/spec/heroku/command_spec.rb b/spec/heroku/command_spec.rb index ff3e277ab..8e6581566 100644 --- a/spec/heroku/command_spec.rb +++ b/spec/heroku/command_spec.rb @@ -41,9 +41,9 @@ def to_s context "and the user includes --confirm APP --app APP2" do it "should warn that the app and confirm do not match and not continue" do - capture_stderr do + expect(capture_stderr do run "addons:add my_addon --confirm APP --app APP2" - end.should == " ! Mismatch between --app and --confirm\n" + end).to eq(" ! Mismatch between --app and --confirm\n") end end end @@ -83,11 +83,11 @@ def to_s end it "should not continue if the confirmation does not match" do - Heroku::Command.stub(:current_options).and_return(:confirm => 'not_example') + allow(Heroku::Command).to receive(:current_options).and_return(:confirm => 'not_example') - lambda do + expect do Heroku::Command.confirm_command('example') - end.should raise_error(Heroku::Command::CommandFailed) + end.to raise_error(Heroku::Command::CommandFailed) end it "should not continue if the user doesn't confirm" do @@ -104,41 +104,41 @@ def to_s describe "parsing errors" do it "extracts error messages from response when available in XML" do - Heroku::Command.extract_error('Invalid app name').should == 'Invalid app name' + expect(Heroku::Command.extract_error('Invalid app name')).to eq('Invalid app name') end it "extracts error messages from response when available in JSON" do - Heroku::Command.extract_error("{\"error\":\"Invalid app name\"}").should == 'Invalid app name' + expect(Heroku::Command.extract_error("{\"error\":\"Invalid app name\"}")).to eq('Invalid app name') end it "extracts error messages from response when available in plain text" do response = FakeResponse.new(:body => "Invalid app name", :headers => { :content_type => "text/plain; charset=UTF8" }) - Heroku::Command.extract_error(response).should == 'Invalid app name' + expect(Heroku::Command.extract_error(response)).to eq('Invalid app name') end it "shows Internal Server Error when the response doesn't contain a XML or JSON" do - Heroku::Command.extract_error('

HTTP 500

').should == "Internal server error.\nRun `heroku status` to check for known platform issues." + expect(Heroku::Command.extract_error('

HTTP 500

')).to eq("Internal server error.\nRun `heroku status` to check for known platform issues.") end it "shows Internal Server Error when the response is not plain text" do response = FakeResponse.new(:body => "Foobar", :headers => { :content_type => "application/xml" }) - Heroku::Command.extract_error(response).should == "Internal server error.\nRun `heroku status` to check for known platform issues." + expect(Heroku::Command.extract_error(response)).to eq("Internal server error.\nRun `heroku status` to check for known platform issues.") end it "allows a block to redefine the default error" do - Heroku::Command.extract_error("Foobar") { "Ok!" }.should == 'Ok!' + expect(Heroku::Command.extract_error("Foobar") { "Ok!" }).to eq('Ok!') end it "doesn't format the response if set to raw" do - Heroku::Command.extract_error("Foobar", :raw => true) { "Ok!" }.should == 'Ok!' + expect(Heroku::Command.extract_error("Foobar", :raw => true) { "Ok!" }).to eq('Ok!') end it "handles a nil body in parse_error_xml" do - lambda { Heroku::Command.parse_error_xml(nil) }.should_not raise_error + expect { Heroku::Command.parse_error_xml(nil) }.not_to raise_error end it "handles a nil body in parse_error_json" do - lambda { Heroku::Command.parse_error_json(nil) }.should_not raise_error + expect { Heroku::Command.parse_error_json(nil) }.not_to raise_error end end @@ -149,27 +149,27 @@ class Heroku::Command::Test::Multiple; end require "heroku/command/help" require "heroku/command/apps" - Heroku::Command.parse("unknown").should be_nil - Heroku::Command.parse("list").should include(:klass => Heroku::Command::Apps, :method => :index) - Heroku::Command.parse("apps").should include(:klass => Heroku::Command::Apps, :method => :index) - Heroku::Command.parse("apps:create").should include(:klass => Heroku::Command::Apps, :method => :create) + expect(Heroku::Command.parse("unknown")).to be_nil + expect(Heroku::Command.parse("list")).to include(:klass => Heroku::Command::Apps, :method => :index) + expect(Heroku::Command.parse("apps")).to include(:klass => Heroku::Command::Apps, :method => :index) + expect(Heroku::Command.parse("apps:create")).to include(:klass => Heroku::Command::Apps, :method => :create) end context "help" do it "works as a prefix" do - heroku("help ps:scale").should =~ /scale dynos by/ + expect(heroku("help ps:scale")).to match(/scale dynos by/) end it "works as an option" do - heroku("ps:scale -h").should =~ /scale dynos by/ - heroku("ps:scale --help").should =~ /scale dynos by/ + expect(heroku("ps:scale -h")).to match(/scale dynos by/) + expect(heroku("ps:scale --help")).to match(/scale dynos by/) end end context "when no commands match" do it "displays the version if --version is used" do - heroku("--version").should == <<-STDOUT + expect(heroku("--version")).to eq <<-STDOUT #{Heroku.user_agent} STDOUT end @@ -182,12 +182,12 @@ class Heroku::Command::Test::Multiple; end execute("aps") rescue SystemExit end - captured_stderr.string.should == <<-STDERR + expect(captured_stderr.string).to eq <<-STDERR ! `aps` is not a heroku command. ! Perhaps you meant `apps` or `ps`. ! See `heroku help` for a list of available commands. STDERR - captured_stdout.string.should == "" + expect(captured_stdout.string).to eq("") $stderr, $stdout = original_stderr, original_stdout end @@ -199,11 +199,11 @@ class Heroku::Command::Test::Multiple; end execute("sandwich") rescue SystemExit end - captured_stderr.string.should == <<-STDERR + expect(captured_stderr.string).to eq <<-STDERR ! `sandwich` is not a heroku command. ! See `heroku help` for a list of available commands. STDERR - captured_stdout.string.should == "" + expect(captured_stdout.string).to eq("") $stderr, $stdout = original_stderr, original_stdout end diff --git a/spec/heroku/helpers/heroku_postgresql_spec.rb b/spec/heroku/helpers/heroku_postgresql_spec.rb index 5f0d285a9..3720d3732 100644 --- a/spec/heroku/helpers/heroku_postgresql_spec.rb +++ b/spec/heroku/helpers/heroku_postgresql_spec.rb @@ -6,9 +6,9 @@ describe Heroku::Helpers::HerokuPostgresql::Resolver do before do - @resolver = described_class.new('appname', mock(:api)) - @resolver.stub(:app_config_vars) { app_config_vars } - @resolver.stub(:app_attachments) { app_attachments } + @resolver = described_class.new('appname', double(:api)) + allow(@resolver).to receive(:app_config_vars) { app_config_vars } + allow(@resolver).to receive(:app_attachments) { app_attachments } end let(:app_config_vars) do @@ -47,37 +47,37 @@ it "resolves DATABASE" do att = @resolver.resolve('DATABASE') - att.display_name.should == "HEROKU_POSTGRESQL_IVORY_URL (DATABASE_URL)" - att.url.should == "postgres://default" + expect(att.display_name).to eq("HEROKU_POSTGRESQL_IVORY_URL (DATABASE_URL)") + expect(att.url).to eq("postgres://default") end end context "when no app is specified or inferred, and identifier does not have app::db shorthand" do it 'exits, complaining about the missing app' do - api = mock('api') - api.stub(:get_attachments).and_raise("getting this far will cause an inaccurate 'internal server error' message") + api = double('api') + allow(api).to receive(:get_attachments).and_raise("getting this far will cause an inaccurate 'internal server error' message") no_app_resolver = described_class.new(nil, api) - no_app_resolver.should_receive(:error).with { |msg| expect(msg).to match(/No app specified/) }.and_raise(SystemExit) + expect(no_app_resolver).to receive(:error).with(/No app specified/).and_raise(SystemExit) expect { no_app_resolver.resolve('black') }.to raise_error(SystemExit) end end context "when the identifier has ::" do it 'changes the resolver app to the left of the ::' do - @resolver.app_name.should == 'appname' + expect(@resolver.app_name).to eq('appname') att = @resolver.resolve('app2::black') - @resolver.app_name.should == 'app2' + expect(@resolver.app_name).to eq('app2') end it 'resolves database names on the right of the ::' do att = @resolver.resolve('app2::black') - att.url.should == "postgres://black" # since we're mocking out the app_config_vars + expect(att.url).to eq("postgres://black") # since we're mocking out the app_config_vars end it 'looks allows nothing after the :: to use the default' do att = @resolver.resolve('app2::', 'DATABASE_URL') - att.url.should == "postgres://default" + expect(att.url).to eq("postgres://default") end end @@ -93,86 +93,86 @@ it "resolves DATABASE" do att = @resolver.resolve('DATABASE') - att.display_name.should == "HEROKU_POSTGRESQL_IVORY_URL (DATABASE_URL)" - att.url.should == "postgres://default" + expect(att.display_name).to eq("HEROKU_POSTGRESQL_IVORY_URL (DATABASE_URL)") + expect(att.url).to eq("postgres://default") end end it "resolves default using NAME" do att = @resolver.resolve('IVORY') - att.display_name.should == "HEROKU_POSTGRESQL_IVORY_URL (DATABASE_URL)" - att.url.should == "postgres://default" + expect(att.display_name).to eq("HEROKU_POSTGRESQL_IVORY_URL (DATABASE_URL)") + expect(att.url).to eq("postgres://default") end it "resolves non-default using NAME" do att = @resolver.resolve('BLACK') - att.display_name.should == "HEROKU_POSTGRESQL_BLACK_URL" - att.url.should == "postgres://black" + expect(att.display_name).to eq("HEROKU_POSTGRESQL_BLACK_URL") + expect(att.url).to eq("postgres://black") end it "resolves default using NAME_URL" do att = @resolver.resolve('IVORY_URL') - att.display_name.should == "HEROKU_POSTGRESQL_IVORY_URL (DATABASE_URL)" - att.url.should == "postgres://default" + expect(att.display_name).to eq("HEROKU_POSTGRESQL_IVORY_URL (DATABASE_URL)") + expect(att.url).to eq("postgres://default") end it "resolves non-default using NAME_URL" do att = @resolver.resolve('BLACK_URL') - att.display_name.should == "HEROKU_POSTGRESQL_BLACK_URL" - att.url.should == "postgres://black" + expect(att.display_name).to eq("HEROKU_POSTGRESQL_BLACK_URL") + expect(att.url).to eq("postgres://black") end it "resolves default using lowercase" do att = @resolver.resolve('ivory') - att.display_name.should == "HEROKU_POSTGRESQL_IVORY_URL (DATABASE_URL)" - att.url.should == "postgres://default" + expect(att.display_name).to eq("HEROKU_POSTGRESQL_IVORY_URL (DATABASE_URL)") + expect(att.url).to eq("postgres://default") end it "resolves non-default using lowercase" do att = @resolver.resolve('black') - att.display_name.should == "HEROKU_POSTGRESQL_BLACK_URL" - att.url.should == "postgres://black" + expect(att.display_name).to eq("HEROKU_POSTGRESQL_BLACK_URL") + expect(att.url).to eq("postgres://black") end it "resolves non-default using part of name" do att = @resolver.resolve('bla') - att.display_name.should == "HEROKU_POSTGRESQL_BLACK_URL" - att.url.should == "postgres://black" + expect(att.display_name).to eq("HEROKU_POSTGRESQL_BLACK_URL") + expect(att.url).to eq("postgres://black") end it "throws an error if it doesnt exist" do - @resolver.should_receive(:error).with("Unknown database: violet. Valid options are: DATABASE_URL, HEROKU_POSTGRESQL_BLACK_URL, HEROKU_POSTGRESQL_IVORY_URL") + expect(@resolver).to receive(:error).with("Unknown database: violet. Valid options are: DATABASE_URL, HEROKU_POSTGRESQL_BLACK_URL, HEROKU_POSTGRESQL_IVORY_URL") @resolver.resolve("violet") end context "default" do it "errors if there is no default" do - @resolver.should_receive(:error).with("Unknown database. Valid options are: DATABASE_URL, HEROKU_POSTGRESQL_BLACK_URL, HEROKU_POSTGRESQL_IVORY_URL") + expect(@resolver).to receive(:error).with("Unknown database. Valid options are: DATABASE_URL, HEROKU_POSTGRESQL_BLACK_URL, HEROKU_POSTGRESQL_IVORY_URL") @resolver.resolve(nil) end it "uses the default if nothing(nil) specified" do att = @resolver.resolve(nil, "DATABASE_URL") - att.display_name.should == "HEROKU_POSTGRESQL_IVORY_URL (DATABASE_URL)" - att.url.should == "postgres://default" + expect(att.display_name).to eq("HEROKU_POSTGRESQL_IVORY_URL (DATABASE_URL)") + expect(att.url).to eq("postgres://default") end it "uses the default if nothing(empty) specified" do att = @resolver.resolve('', "DATABASE_URL") - att.display_name.should == "HEROKU_POSTGRESQL_IVORY_URL (DATABASE_URL)" - att.url.should == "postgres://default" + expect(att.display_name).to eq("HEROKU_POSTGRESQL_IVORY_URL (DATABASE_URL)") + expect(att.url).to eq("postgres://default") end it 'throws an error if given an empty string and asked for the default and there is no default' do app_config_vars.delete 'DATABASE_URL' - @resolver.should_receive(:error).with("Unknown database. Valid options are: HEROKU_POSTGRESQL_BLACK_URL, HEROKU_POSTGRESQL_IVORY_URL") + expect(@resolver).to receive(:error).with("Unknown database. Valid options are: HEROKU_POSTGRESQL_BLACK_URL, HEROKU_POSTGRESQL_IVORY_URL") att = @resolver.resolve('', "DATABASE_URL") end it 'throws an error if given an empty string and asked for the default and the default doesnt match' do app_config_vars['DATABASE_URL'] = 'something different' - @resolver.should_receive(:error).with("Unknown database. Valid options are: HEROKU_POSTGRESQL_BLACK_URL, HEROKU_POSTGRESQL_IVORY_URL") + expect(@resolver).to receive(:error).with("Unknown database. Valid options are: HEROKU_POSTGRESQL_BLACK_URL, HEROKU_POSTGRESQL_IVORY_URL") att = @resolver.resolve('', "DATABASE_URL") end diff --git a/spec/heroku/helpers_spec.rb b/spec/heroku/helpers_spec.rb index fc7925ec0..9dfb8dd60 100644 --- a/spec/heroku/helpers_spec.rb +++ b/spec/heroku/helpers_spec.rb @@ -8,9 +8,9 @@ module Heroku context "display_object" do it "should display Array correctly" do - capture_stdout do + expect(capture_stdout do display_object([1,2,3]) - end.should == <<-OUT + end).to eq <<-OUT 1 2 3 @@ -18,9 +18,9 @@ module Heroku end it "should display { :header => [] } list correctly" do - capture_stdout do + expect(capture_stdout do display_object({:first_header => [1,2,3], :last_header => [7,8,9]}) - end.should == <<-OUT + end).to eq <<-OUT === first_header 1 2 @@ -35,9 +35,9 @@ module Heroku end it "should display String properly" do - capture_stdout do + expect(capture_stdout do display_object('string') - end.should == <<-OUT + end).to eq <<-OUT string OUT end diff --git a/spec/heroku/plugin_spec.rb b/spec/heroku/plugin_spec.rb index f6c650162..550cf30b2 100644 --- a/spec/heroku/plugin_spec.rb +++ b/spec/heroku/plugin_spec.rb @@ -6,20 +6,20 @@ module Heroku include SandboxHelper it "lives in ~/.heroku/plugins" do - Plugin.stub!(:home_directory).and_return('/home/user') - Plugin.directory.should == '/home/user/.heroku/plugins' + allow(Plugin).to receive(:home_directory).and_return('/home/user') + expect(Plugin.directory).to eq('/home/user/.heroku/plugins') end it "extracts the name from git urls" do - Plugin.new('git://github.com/heroku/plugin.git').name.should == 'plugin' + expect(Plugin.new('git://github.com/heroku/plugin.git').name).to eq('plugin') end describe "management" do before(:each) do @sandbox = "/tmp/heroku_plugins_spec_#{Process.pid}" FileUtils.mkdir_p(@sandbox) - Dir.stub!(:pwd).and_return(@sandbox) - Plugin.stub!(:directory).and_return(@sandbox) + allow(Dir).to receive(:pwd).and_return(@sandbox) + allow(Plugin).to receive(:directory).and_return(@sandbox) end after(:each) do @@ -29,8 +29,8 @@ module Heroku it "lists installed plugins" do FileUtils.mkdir_p(@sandbox + '/plugin1') FileUtils.mkdir_p(@sandbox + '/plugin2') - Plugin.list.should include 'plugin1' - Plugin.list.should include 'plugin2' + expect(Plugin.list).to include 'plugin1' + expect(Plugin.list).to include 'plugin2' end it "installs pulling from the plugin url" do @@ -38,8 +38,8 @@ module Heroku FileUtils.mkdir_p(plugin_folder) `cd #{plugin_folder} && git init && echo 'test' > README && git add . && git commit -m 'my plugin'` Plugin.new(plugin_folder).install - File.directory?("#{@sandbox}/heroku_plugin").should be_true - File.read("#{@sandbox}/heroku_plugin/README").should == "test\n" + expect(File.directory?("#{@sandbox}/heroku_plugin")).to be_truthy + expect(File.read("#{@sandbox}/heroku_plugin/README")).to eq("test\n") end it "reinstalls over old copies" do @@ -48,8 +48,8 @@ module Heroku `cd #{plugin_folder} && git init && echo 'test' > README && git add . && git commit -m 'my plugin'` Plugin.new(plugin_folder).install Plugin.new(plugin_folder).install - File.directory?("#{@sandbox}/heroku_plugin").should be_true - File.read("#{@sandbox}/heroku_plugin/README").should == "test\n" + expect(File.directory?("#{@sandbox}/heroku_plugin")).to be_truthy + expect(File.read("#{@sandbox}/heroku_plugin/README")).to eq("test\n") end context "update" do @@ -64,8 +64,8 @@ module Heroku it "updates existing copies" do Plugin.new('heroku_plugin').update - File.directory?("#{@sandbox}/heroku_plugin").should be_true - File.read("#{@sandbox}/heroku_plugin/README").should == "updated\n" + expect(File.directory?("#{@sandbox}/heroku_plugin")).to be_truthy + expect(File.read("#{@sandbox}/heroku_plugin/README")).to eq("updated\n") end it "warns on legacy plugins" do @@ -76,7 +76,7 @@ module Heroku rescue SystemExit end end - stderr.should == <<-STDERR + expect(stderr).to eq <<-STDERR ! heroku_plugin is a legacy plugin installation. ! Enable updating by reinstalling with `heroku plugins:install`. STDERR @@ -84,7 +84,7 @@ module Heroku it "raises exception on symlinked plugins" do `cd #{@sandbox} && ln -s heroku_plugin heroku_plugin_symlink` - lambda { Plugin.new('heroku_plugin_symlink').update }.should raise_error Heroku::Plugin::ErrorUpdatingSymlinkPlugin + expect { Plugin.new('heroku_plugin_symlink').update }.to raise_error Heroku::Plugin::ErrorUpdatingSymlinkPlugin end end @@ -93,21 +93,21 @@ module Heroku it "uninstalls removing the folder" do FileUtils.mkdir_p(@sandbox + '/plugin1') Plugin.new('git://github.com/heroku/plugin1.git').uninstall - Plugin.list.should == [] + expect(Plugin.list).to eq([]) end it "adds the lib folder in the plugin to the load path, if present" do FileUtils.mkdir_p(@sandbox + '/plugin/lib') File.open(@sandbox + '/plugin/lib/my_custom_plugin_file.rb', 'w') { |f| f.write "" } Plugin.load! - lambda { require 'my_custom_plugin_file' }.should_not raise_error(LoadError) + expect { require 'my_custom_plugin_file' }.not_to raise_error end it "loads init.rb, if present" do FileUtils.mkdir_p(@sandbox + '/plugin') File.open(@sandbox + '/plugin/init.rb', 'w') { |f| f.write "LoadedInit = true" } Plugin.load! - LoadedInit.should be_true + expect(LoadedInit).to be_truthy end describe "when there are plugin load errors" do @@ -118,7 +118,7 @@ module Heroku it "should not throw an error" do capture_stderr do - lambda { Plugin.load! }.should_not raise_error + expect { Plugin.load! }.not_to raise_error end end @@ -126,7 +126,7 @@ module Heroku stderr = capture_stderr do Plugin.load! end - stderr.should include('some_non_existant_file (LoadError)') + expect(stderr).to include('some_non_existant_file (LoadError)') end it "should still load other plugins" do @@ -135,8 +135,8 @@ module Heroku stderr = capture_stderr do Plugin.load! end - stderr.should include('some_non_existant_file (LoadError)') - LoadedPlugin2.should be_true + expect(stderr).to include('some_non_existant_file (LoadError)') + expect(LoadedPlugin2).to be_truthy end end @@ -151,20 +151,20 @@ module Heroku it "should show confirmation to remove deprecated plugins if in an interactive shell" do old_stdin_isatty = STDIN.isatty - STDIN.stub!(:isatty).and_return(true) - Plugin.should_receive(:confirm).with("The plugin heroku-releases has been deprecated. Would you like to remove it? (y/N)").and_return(true) - Plugin.should_receive(:remove_plugin).with("heroku-releases") + allow(STDIN).to receive(:isatty).and_return(true) + expect(Plugin).to receive(:confirm).with("The plugin heroku-releases has been deprecated. Would you like to remove it? (y/N)").and_return(true) + expect(Plugin).to receive(:remove_plugin).with("heroku-releases") Plugin.load! - STDIN.stub!(:isatty).and_return(old_stdin_isatty) + allow(STDIN).to receive(:isatty).and_return(old_stdin_isatty) end it "should not prompt for deprecation if not in an interactive shell" do old_stdin_isatty = STDIN.isatty - STDIN.stub!(:isatty).and_return(false) - Plugin.should_not_receive(:confirm) - Plugin.should_not_receive(:remove_plugin).with("heroku-releases") + allow(STDIN).to receive(:isatty).and_return(false) + expect(Plugin).not_to receive(:confirm) + expect(Plugin).not_to receive(:remove_plugin).with("heroku-releases") Plugin.load! - STDIN.stub!(:isatty).and_return(old_stdin_isatty) + allow(STDIN).to receive(:isatty).and_return(old_stdin_isatty) end end end diff --git a/spec/heroku/updater_spec.rb b/spec/heroku/updater_spec.rb index bc1f4be3e..8599664f1 100644 --- a/spec/heroku/updater_spec.rb +++ b/spec/heroku/updater_spec.rb @@ -5,40 +5,105 @@ module Heroku describe Updater do - it "calculates the latest local version" do - Heroku::Updater.latest_local_version.should == Heroku::VERSION + describe('::latest_local_version') do + it 'calculates the latest local version' do + expect(subject.latest_local_version).to eq(Heroku::VERSION) + end end - it "calculates compare_versions" do - Heroku::Updater.compare_versions('1.1.1', '1.1.1').should == 0 + describe('::compare_versions') do + it 'calculates compare_versions' do + expect(subject.compare_versions('1.1.1', '1.1.1')).to eq(0) - Heroku::Updater.compare_versions('2.1.1', '1.1.1').should == 1 - Heroku::Updater.compare_versions('1.1.1', '2.1.1').should == -1 + expect(subject.compare_versions('2.1.1', '1.1.1')).to eq(1) + expect(subject.compare_versions('1.1.1', '2.1.1')).to eq(-1) - Heroku::Updater.compare_versions('1.2.1', '1.1.1').should == 1 - Heroku::Updater.compare_versions('1.1.1', '1.2.1').should == -1 + expect(subject.compare_versions('1.2.1', '1.1.1')).to eq(1) + expect(subject.compare_versions('1.1.1', '1.2.1')).to eq(-1) - Heroku::Updater.compare_versions('1.1.2', '1.1.1').should == 1 - Heroku::Updater.compare_versions('1.1.1', '1.1.2').should == -1 + expect(subject.compare_versions('1.1.2', '1.1.1')).to eq(1) + expect(subject.compare_versions('1.1.1', '1.1.2')).to eq(-1) - Heroku::Updater.compare_versions('2.1.1', '1.2.1').should == 1 - Heroku::Updater.compare_versions('1.2.1', '2.1.1').should == -1 + expect(subject.compare_versions('2.1.1', '1.2.1')).to eq(1) + expect(subject.compare_versions('1.2.1', '2.1.1')).to eq(-1) - Heroku::Updater.compare_versions('2.1.1', '1.1.2').should == 1 - Heroku::Updater.compare_versions('1.1.2', '2.1.1').should == -1 + expect(subject.compare_versions('2.1.1', '1.1.2')).to eq(1) + expect(subject.compare_versions('1.1.2', '2.1.1')).to eq(-1) - Heroku::Updater.compare_versions('1.2.4', '1.2.3').should == 1 - Heroku::Updater.compare_versions('1.2.3', '1.2.4').should == -1 + expect(subject.compare_versions('1.2.4', '1.2.3')).to eq(1) + expect(subject.compare_versions('1.2.3', '1.2.4')).to eq(-1) - Heroku::Updater.compare_versions('1.2.1', '1.2' ).should == 1 - Heroku::Updater.compare_versions('1.2', '1.2.1').should == -1 + expect(subject.compare_versions('1.2.1', '1.2' )).to eq(1) + expect(subject.compare_versions('1.2', '1.2.1')).to eq(-1) - Heroku::Updater.compare_versions('1.1.1.pre1', '1.1.1').should == 1 - Heroku::Updater.compare_versions('1.1.1', '1.1.1.pre1').should == -1 + expect(subject.compare_versions('1.1.1.pre1', '1.1.1')).to eq(1) + expect(subject.compare_versions('1.1.1', '1.1.1.pre1')).to eq(-1) - Heroku::Updater.compare_versions('1.1.1.pre2', '1.1.1.pre1').should == 1 - Heroku::Updater.compare_versions('1.1.1.pre1', '1.1.1.pre2').should == -1 + expect(subject.compare_versions('1.1.1.pre2', '1.1.1.pre1')).to eq(1) + expect(subject.compare_versions('1.1.1.pre1', '1.1.1.pre2')).to eq(-1) + end end + describe '::update' do + before do + Excon.stub({:host => 'assets.heroku.com', :path => '/heroku-client/VERSION'}, {:body => "3.9.7\n"}) + end + + describe 'non-beta' do + before do + zip = File.read(File.expand_path('../../fixtures/heroku-client-3.9.7.zip', __FILE__)) + hash = "615792e1f06800a6d744f518887b10c09aa914eab51d0f7fbbefd81a8a64af93" + Excon.stub({:host => 'toolbelt.heroku.com', :path => '/download/zip'}, {:body => zip}) + Excon.stub({:host => 'toolbelt.heroku.com', :path => '/update/hash'}, {:body => "#{hash}\n"}) + end + + context 'with no update available' do + before do + allow(subject).to receive(:latest_local_version).and_return('3.9.7') + end + + it 'does not update' do + expect(subject.update(false)).to be_nil + end + end + + context 'with an update available' do + before do + allow(subject).to receive(:latest_local_version).and_return('3.9.6') + end + + it 'updates' do + expect(subject.update(false)).to eq('3.9.7') + end + end + end + + describe 'beta' do + before do + zip = File.read(File.expand_path('../../fixtures/heroku-client-3.9.7.zip', __FILE__)) + Excon.stub({:host => 'toolbelt.heroku.com', :path => '/download/beta-zip'}, {:body => zip}) + end + + context 'with no update available' do + before do + allow(subject).to receive(:latest_local_version).and_return('3.9.7') + end + + it 'still updates' do + expect(subject.update(true)).to eq('3.9.7') + end + end + + context 'with a beta older than what we have' do + before do + allow(subject).to receive(:latest_local_version).and_return('3.9.8') + end + + it 'does not update' do + expect(subject.update(true)).to be_nil + end + end + end + end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index b3bfda110..04956a28d 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -2,12 +2,10 @@ require "rubygems" -require "excon" +require "coveralls" +Coveralls.wear! -# ensure these are around for errors -# as their require is generally deferred -require "heroku-api" -require "rest_client" +require "excon" require "heroku/cli" require "rspec" @@ -35,12 +33,12 @@ def stub_api_request(method, path) def prepare_command(klass) command = klass.new - command.stub!(:app).and_return("example") - command.stub!(:ask).and_return("") - command.stub!(:display) - command.stub!(:hputs) - command.stub!(:hprint) - command.stub!(:heroku).and_return(mock('heroku client', :host => 'heroku.com')) + allow(command).to receive(:app).and_return("example") + allow(command).to receive(:ask).and_return("") + allow(command).to receive(:display) + allow(command).to receive(:hputs) + allow(command).to receive(:hprint) + allow(command).to receive(:heroku).and_return(double('heroku client', :host => 'heroku.com')) command end @@ -211,7 +209,6 @@ def home_directory require "support/organizations_mock_helper" RSpec.configure do |config| - config.color_enabled = true config.include DisplayMessageMatcher config.order = 'rand' config.before { Heroku::Helpers.error_with_failure = false } diff --git a/spec/support/openssl_mock_helper.rb b/spec/support/openssl_mock_helper.rb index 70268c482..fda0e6a76 100644 --- a/spec/support/openssl_mock_helper.rb +++ b/spec/support/openssl_mock_helper.rb @@ -1,8 +1,8 @@ def mock_openssl - @ctx_mock = mock "SSLContext", :key= => nil, :cert= => nil, :ssl_version= => nil - @tcp_socket_mock = mock "TCPSocket", :close => true - @ssl_socket_mock = mock "SSLSocket", :sync= => true, :connect => true, :close => true, :to_io => $stdin + @ctx_mock = double "SSLContext", :key= => nil, :cert= => nil, :ssl_version= => nil + @tcp_socket_mock = double "TCPSocket", :close => true + @ssl_socket_mock = double "SSLSocket", :sync= => true, :connect => true, :close => true, :to_io => $stdin - OpenSSL::SSL::SSLSocket.stub(:new).and_return(@ssl_socket_mock) - OpenSSL::SSL::SSLContext.stub(:new).and_return(@ctx_mock) + allow(OpenSSL::SSL::SSLSocket).to receive(:new).and_return(@ssl_socket_mock) + allow(OpenSSL::SSL::SSLContext).to receive(:new).and_return(@ctx_mock) end