artofmission-heroku 1.6.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +66 -0
- data/Rakefile +107 -0
- data/bin/heroku +15 -0
- data/lib/heroku.rb +5 -0
- data/lib/heroku/client.rb +487 -0
- data/lib/heroku/command.rb +96 -0
- data/lib/heroku/commands/account.rb +13 -0
- data/lib/heroku/commands/addons.rb +109 -0
- data/lib/heroku/commands/app.rb +239 -0
- data/lib/heroku/commands/auth.rb +137 -0
- data/lib/heroku/commands/base.rb +133 -0
- data/lib/heroku/commands/bundles.rb +51 -0
- data/lib/heroku/commands/config.rb +55 -0
- data/lib/heroku/commands/db.rb +129 -0
- data/lib/heroku/commands/domains.rb +31 -0
- data/lib/heroku/commands/help.rb +148 -0
- data/lib/heroku/commands/keys.rb +49 -0
- data/lib/heroku/commands/logs.rb +11 -0
- data/lib/heroku/commands/maintenance.rb +13 -0
- data/lib/heroku/commands/plugins.rb +25 -0
- data/lib/heroku/commands/ps.rb +37 -0
- data/lib/heroku/commands/service.rb +23 -0
- data/lib/heroku/commands/sharing.rb +29 -0
- data/lib/heroku/commands/ssl.rb +33 -0
- data/lib/heroku/commands/version.rb +7 -0
- data/lib/heroku/helpers.rb +23 -0
- data/lib/heroku/plugin.rb +65 -0
- data/spec/base.rb +23 -0
- data/spec/client_spec.rb +366 -0
- data/spec/command_spec.rb +15 -0
- data/spec/commands/addons_spec.rb +47 -0
- data/spec/commands/app_spec.rb +175 -0
- data/spec/commands/auth_spec.rb +104 -0
- data/spec/commands/base_spec.rb +114 -0
- data/spec/commands/bundles_spec.rb +48 -0
- data/spec/commands/config_spec.rb +45 -0
- data/spec/commands/db_spec.rb +53 -0
- data/spec/commands/domains_spec.rb +31 -0
- data/spec/commands/keys_spec.rb +60 -0
- data/spec/commands/logs_spec.rb +21 -0
- data/spec/commands/maintenance_spec.rb +21 -0
- data/spec/commands/plugins_spec.rb +26 -0
- data/spec/commands/ps_spec.rb +16 -0
- data/spec/commands/sharing_spec.rb +32 -0
- data/spec/commands/ssl_spec.rb +25 -0
- data/spec/plugin_spec.rb +64 -0
- metadata +150 -0
@@ -0,0 +1,175 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../base'
|
2
|
+
|
3
|
+
module Heroku::Command
|
4
|
+
describe App do
|
5
|
+
before(:each) do
|
6
|
+
@cli = prepare_command(App)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "shows app info, converting bytes to kbs/mbs" do
|
10
|
+
@cli.stub!(:args).and_return(['myapp'])
|
11
|
+
@cli.heroku.should_receive(:info).with('myapp').and_return({ :name => 'myapp', :collaborators => [], :addons => [], :repo_size => 2*1024, :database_size => 5*1024*1024 })
|
12
|
+
@cli.should_receive(:display).with('=== myapp')
|
13
|
+
@cli.should_receive(:display).with('Web URL: http://myapp.heroku.com/')
|
14
|
+
@cli.should_receive(:display).with('Repo size: 2k')
|
15
|
+
@cli.should_receive(:display).with('Data size: 5M')
|
16
|
+
@cli.info
|
17
|
+
end
|
18
|
+
|
19
|
+
it "shows app info using the --app syntax" do
|
20
|
+
@cli.stub!(:args).and_return(['--app', 'myapp'])
|
21
|
+
@cli.heroku.should_receive(:info).with('myapp').and_return({ :collaborators => [], :addons => []})
|
22
|
+
@cli.info
|
23
|
+
end
|
24
|
+
|
25
|
+
it "shows app info reading app from current git dir" do
|
26
|
+
@cli.stub!(:args).and_return([])
|
27
|
+
@cli.stub!(:extract_app_in_dir).and_return('myapp')
|
28
|
+
@cli.heroku.should_receive(:info).with('myapp').and_return({ :collaborators => [], :addons => []})
|
29
|
+
@cli.info
|
30
|
+
end
|
31
|
+
|
32
|
+
it "creates without a name" do
|
33
|
+
@cli.heroku.should_receive(:create).with(nil, {}).and_return("untitled-123")
|
34
|
+
@cli.create
|
35
|
+
end
|
36
|
+
|
37
|
+
it "creates with a name" do
|
38
|
+
@cli.stub!(:args).and_return([ 'myapp' ])
|
39
|
+
@cli.heroku.should_receive(:create).with('myapp', {}).and_return("myapp")
|
40
|
+
@cli.create
|
41
|
+
end
|
42
|
+
|
43
|
+
it "renames an app" do
|
44
|
+
@cli.stub!(:args).and_return([ 'myapp2' ])
|
45
|
+
@cli.heroku.should_receive(:update).with('myapp', { :name => 'myapp2' })
|
46
|
+
@cli.rename
|
47
|
+
end
|
48
|
+
|
49
|
+
it "runs a rake command on the app" do
|
50
|
+
@cli.stub!(:args).and_return(([ 'db:migrate' ]))
|
51
|
+
@cli.heroku.should_receive(:start).
|
52
|
+
with('myapp', 'rake db:migrate', attached=true).
|
53
|
+
and_return(['foo', 'bar', 'baz'])
|
54
|
+
@cli.rake
|
55
|
+
end
|
56
|
+
|
57
|
+
it "runs a single console command on the app" do
|
58
|
+
@cli.stub!(:args).and_return([ '2+2' ])
|
59
|
+
@cli.heroku.should_receive(:console).with('myapp', '2+2')
|
60
|
+
@cli.console
|
61
|
+
end
|
62
|
+
|
63
|
+
it "offers a console, opening and closing the session with the client" do
|
64
|
+
@console = mock('heroku console')
|
65
|
+
@cli.stub!(:console_history_read)
|
66
|
+
@cli.stub!(:console_history_add)
|
67
|
+
@cli.heroku.should_receive(:console).with('myapp').and_yield(@console)
|
68
|
+
Readline.should_receive(:readline).and_return('exit')
|
69
|
+
@cli.console
|
70
|
+
end
|
71
|
+
|
72
|
+
it "asks to restart servers" do
|
73
|
+
@cli.heroku.should_receive(:restart).with('myapp')
|
74
|
+
@cli.restart
|
75
|
+
end
|
76
|
+
|
77
|
+
it "scales dynos" do
|
78
|
+
@cli.stub!(:args).and_return(['+4'])
|
79
|
+
@cli.heroku.should_receive(:set_dynos).with('myapp', '+4').and_return(7)
|
80
|
+
@cli.dynos
|
81
|
+
end
|
82
|
+
|
83
|
+
it "destroys the app specified with --app if user confirms" do
|
84
|
+
@cli.stub!(:ask).and_return('y')
|
85
|
+
@cli.stub!(:args).and_return(['--app', 'myapp'])
|
86
|
+
@cli.heroku.stub!(:info).and_return({})
|
87
|
+
@cli.heroku.should_receive(:destroy).with('myapp')
|
88
|
+
@cli.destroy
|
89
|
+
end
|
90
|
+
|
91
|
+
it "doesn't destroy the app if the user doesn't confirms" do
|
92
|
+
@cli.stub!(:ask).and_return('no')
|
93
|
+
@cli.stub!(:args).and_return(['--app', 'myapp'])
|
94
|
+
@cli.heroku.stub!(:info).and_return({})
|
95
|
+
@cli.heroku.should_not_receive(:destroy)
|
96
|
+
@cli.destroy
|
97
|
+
end
|
98
|
+
|
99
|
+
it "doesn't destroy the app in the current dir" do
|
100
|
+
@cli.stub!(:extract_app).and_return('myapp')
|
101
|
+
@cli.heroku.should_not_receive(:destroy)
|
102
|
+
@cli.destroy
|
103
|
+
end
|
104
|
+
|
105
|
+
context "Git Integration" do
|
106
|
+
include SandboxHelper
|
107
|
+
before(:all) do
|
108
|
+
# setup a git dir to serve as a remote
|
109
|
+
@git = "/tmp/git_spec_#{Process.pid}"
|
110
|
+
FileUtils.mkdir_p(@git)
|
111
|
+
FileUtils.cd(@git) { |d| `git --bare init` }
|
112
|
+
end
|
113
|
+
|
114
|
+
after(:all) do
|
115
|
+
FileUtils.rm_rf(@git)
|
116
|
+
end
|
117
|
+
|
118
|
+
# setup sandbox in /tmp
|
119
|
+
before(:each) do
|
120
|
+
@sandbox = "/tmp/app_spec_#{Process.pid}"
|
121
|
+
FileUtils.mkdir_p(@sandbox)
|
122
|
+
bash "git init"
|
123
|
+
Dir.stub!(:pwd).and_return(@sandbox)
|
124
|
+
end
|
125
|
+
|
126
|
+
after(:each) do
|
127
|
+
FileUtils.rm_rf(@sandbox)
|
128
|
+
end
|
129
|
+
|
130
|
+
it "creates adding heroku to git remote" do
|
131
|
+
@cli.heroku.should_receive(:create).and_return('myapp')
|
132
|
+
@cli.create
|
133
|
+
bash("git remote").strip.should == 'heroku'
|
134
|
+
end
|
135
|
+
|
136
|
+
it "creates adding a custom git remote" do
|
137
|
+
@cli.stub!(:args).and_return([ 'myapp', '--remote', 'myremote' ])
|
138
|
+
@cli.heroku.should_receive(:create).and_return('myapp')
|
139
|
+
@cli.create
|
140
|
+
bash("git remote").strip.should == 'myremote'
|
141
|
+
end
|
142
|
+
|
143
|
+
it "doesn't add a git remote if it already exists" do
|
144
|
+
@cli.heroku.should_receive(:create).and_return('myapp')
|
145
|
+
bash "git remote add heroku #{@git}"
|
146
|
+
@cli.create
|
147
|
+
end
|
148
|
+
|
149
|
+
it "renames updating the corresponding heroku git remote" do
|
150
|
+
bash "git remote add github git@github.com:test/test.git"
|
151
|
+
bash "git remote add production git@heroku.com:myapp.git"
|
152
|
+
bash "git remote add staging git@heroku.com:myapp-staging.git"
|
153
|
+
|
154
|
+
@cli.heroku.stub!(:update)
|
155
|
+
@cli.stub!(:args).and_return([ 'myapp2' ])
|
156
|
+
@cli.rename
|
157
|
+
remotes = bash("git remote -v")
|
158
|
+
remotes.should include('git@github.com:test/test.git')
|
159
|
+
remotes.should include('git@heroku.com:myapp-staging.git')
|
160
|
+
remotes.should include('git@heroku.com:myapp2.git')
|
161
|
+
remotes.should_not include('git@heroku.com:myapp.git')
|
162
|
+
end
|
163
|
+
|
164
|
+
it "destroys removing any remotes pointing to the app" do
|
165
|
+
bash("git remote add heroku git@heroku.com:myapp.git")
|
166
|
+
@cli.stub!(:args).and_return(['--app', 'myapp'])
|
167
|
+
@cli.heroku.stub!(:info).and_return({})
|
168
|
+
@cli.stub!(:ask).and_return('y')
|
169
|
+
@cli.heroku.should_receive(:destroy)
|
170
|
+
@cli.destroy
|
171
|
+
bash("git remote").strip.should == ''
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../base'
|
2
|
+
|
3
|
+
module Heroku::Command
|
4
|
+
describe Auth do
|
5
|
+
before do
|
6
|
+
@cli = prepare_command(Auth)
|
7
|
+
@sandbox = "#{Dir.tmpdir}/cli_spec_#{Process.pid}"
|
8
|
+
File.open(@sandbox, "w") { |f| f.write "user\npass\n" }
|
9
|
+
@cli.stub!(:credentials_file).and_return(@sandbox)
|
10
|
+
@cli.stub!(:running_on_a_mac?).and_return(false)
|
11
|
+
end
|
12
|
+
|
13
|
+
after do
|
14
|
+
FileUtils.rm_rf(@sandbox)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "reads credentials from the credentials file" do
|
18
|
+
@cli.read_credentials.should == %w(user pass)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "takes the user from the first line and the password from the second line" do
|
22
|
+
@cli.user.should == 'user'
|
23
|
+
@cli.password.should == 'pass'
|
24
|
+
end
|
25
|
+
|
26
|
+
it "asks for credentials when the file doesn't exist" do
|
27
|
+
FileUtils.rm_rf(@sandbox)
|
28
|
+
@cli.should_receive(:ask_for_credentials).and_return([ 'u', 'p'])
|
29
|
+
@cli.should_receive(:save_credentials)
|
30
|
+
@cli.get_credentials.should == [ 'u', 'p' ]
|
31
|
+
end
|
32
|
+
|
33
|
+
it "writes the credentials to a file" do
|
34
|
+
@cli.stub!(:credentials).and_return(['one', 'two'])
|
35
|
+
@cli.should_receive(:set_credentials_permissions)
|
36
|
+
@cli.write_credentials
|
37
|
+
File.read(@sandbox).should == "one\ntwo\n"
|
38
|
+
end
|
39
|
+
|
40
|
+
it "sets ~/.heroku/credentials to be readable only by the user" do
|
41
|
+
unless RUBY_PLATFORM =~ /mswin32|mingw32/
|
42
|
+
sandbox = "#{Dir.tmpdir}/cli_spec_#{Process.pid}"
|
43
|
+
FileUtils.rm_rf(sandbox)
|
44
|
+
FileUtils.mkdir_p(sandbox)
|
45
|
+
fname = "#{sandbox}/file"
|
46
|
+
system "touch #{fname}"
|
47
|
+
@cli.stub!(:credentials_file).and_return(fname)
|
48
|
+
@cli.set_credentials_permissions
|
49
|
+
File.stat(sandbox).mode.should == 040700
|
50
|
+
File.stat(fname).mode.should == 0100600
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
it "writes credentials and uploads authkey when credentials are saved" do
|
55
|
+
@cli.stub!(:credentials)
|
56
|
+
@cli.should_receive(:write_credentials)
|
57
|
+
Heroku::Command.should_receive(:run_internal).with('keys:add', [])
|
58
|
+
@cli.save_credentials
|
59
|
+
end
|
60
|
+
|
61
|
+
it "preserves the args when running keys:add" do
|
62
|
+
@cli.stub!(:credentials)
|
63
|
+
@cli.stub!(:args).and_return(['mykey.pub'])
|
64
|
+
Heroku::Command.should_receive(:run_internal).with('keys:add', ['mykey.pub'])
|
65
|
+
@cli.save_credentials
|
66
|
+
end
|
67
|
+
|
68
|
+
it "save_credentials deletes the credentials when the upload authkey is unauthorized" do
|
69
|
+
@cli.stub!(:write_credentials)
|
70
|
+
@cli.stub!(:retry_login?).and_return(false)
|
71
|
+
Heroku::Command.should_receive(:run_internal).with('keys:add', []).and_raise(RestClient::Unauthorized)
|
72
|
+
@cli.should_receive(:delete_credentials)
|
73
|
+
lambda { @cli.save_credentials }.should raise_error(RestClient::Unauthorized)
|
74
|
+
end
|
75
|
+
|
76
|
+
it "save_credentials deletes the credentials when there's no authkey" do
|
77
|
+
@cli.stub!(:write_credentials)
|
78
|
+
Heroku::Command.should_receive(:run_internal).with('keys:add', []).and_raise(RuntimeError)
|
79
|
+
@cli.should_receive(:delete_credentials)
|
80
|
+
lambda { @cli.save_credentials }.should raise_error
|
81
|
+
end
|
82
|
+
|
83
|
+
it "save_credentials deletes the credentials when the authkey is weak" do
|
84
|
+
@cli.stub!(:write_credentials)
|
85
|
+
Heroku::Command.should_receive(:run_internal).with('keys:add', []).and_raise(RestClient::RequestFailed)
|
86
|
+
@cli.should_receive(:delete_credentials)
|
87
|
+
lambda { @cli.save_credentials }.should raise_error
|
88
|
+
end
|
89
|
+
|
90
|
+
it "asks for login again when not authorized, for three times" do
|
91
|
+
@cli.stub!(:read_credentials)
|
92
|
+
@cli.stub!(:write_credentials)
|
93
|
+
@cli.stub!(:delete_credentials)
|
94
|
+
Heroku::Command.stub!(:run_internal).with('keys:add', []).and_raise(RestClient::Unauthorized)
|
95
|
+
@cli.should_receive(:ask_for_credentials).exactly(4).times
|
96
|
+
lambda { @cli.save_credentials }.should raise_error(RestClient::Unauthorized)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "deletes the credentials file" do
|
100
|
+
FileUtils.should_receive(:rm_f).with(@cli.credentials_file)
|
101
|
+
@cli.delete_credentials
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../base'
|
2
|
+
|
3
|
+
module Heroku::Command
|
4
|
+
describe Base do
|
5
|
+
before do
|
6
|
+
@args = [1, 2]
|
7
|
+
@base = Base.new(@args)
|
8
|
+
@base.stub!(:display)
|
9
|
+
@client = mock('heroku client', :host => 'heroku.com')
|
10
|
+
end
|
11
|
+
|
12
|
+
it "initializes the heroku client with the Auth command" do
|
13
|
+
Heroku::Command.should_receive(:run_internal).with('auth:client', @args)
|
14
|
+
@base.heroku
|
15
|
+
end
|
16
|
+
|
17
|
+
context "detecting the app" do
|
18
|
+
before do
|
19
|
+
@base.stub!(:heroku).and_return(@client)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "attempts to find the app via the --app argument" do
|
23
|
+
@base.stub!(:args).and_return(['--app', 'myapp'])
|
24
|
+
@base.extract_app.should == 'myapp'
|
25
|
+
end
|
26
|
+
|
27
|
+
it "read remotes from git config" do
|
28
|
+
File.stub!(:exists?).with('/home/dev/myapp/.git/config').and_return(true)
|
29
|
+
File.stub!(:read).with('/home/dev/myapp/.git/config').and_return("
|
30
|
+
[core]
|
31
|
+
repositoryformatversion = 0
|
32
|
+
filemode = true
|
33
|
+
bare = false
|
34
|
+
logallrefupdates = true
|
35
|
+
[remote \"staging\"]
|
36
|
+
url = git@heroku.com:myapp-staging.git
|
37
|
+
fetch = +refs/heads/*:refs/remotes/staging/*
|
38
|
+
[remote \"production\"]
|
39
|
+
url = git@heroku.com:myapp.git
|
40
|
+
fetch = +refs/heads/*:refs/remotes/production/*
|
41
|
+
[remote \"github\"]
|
42
|
+
url = git@github.com:myapp.git
|
43
|
+
fetch = +refs/heads/*:refs/remotes/github/*
|
44
|
+
")
|
45
|
+
@base.git_remotes('/home/dev/myapp').should == { 'staging' => 'myapp-staging', 'production' => 'myapp' }
|
46
|
+
end
|
47
|
+
|
48
|
+
it "attempts to find the git config file in parent folders" do
|
49
|
+
File.should_receive(:exists?).with('/home/dev/myapp/app/models/.git/config').and_return(false)
|
50
|
+
File.should_receive(:exists?).with('/home/dev/myapp/app/.git/config').and_return(false)
|
51
|
+
File.should_receive(:exists?).with('/home/dev/myapp/.git/config').and_return(true)
|
52
|
+
File.should_receive(:read).with('/home/dev/myapp/.git/config').and_return('')
|
53
|
+
@base.git_remotes('/home/dev/myapp/app/models')
|
54
|
+
end
|
55
|
+
|
56
|
+
it "gets the app from remotes when there's only one app" do
|
57
|
+
@base.stub!(:git_remotes).and_return({ 'heroku' => 'myapp' })
|
58
|
+
@base.extract_app.should == 'myapp'
|
59
|
+
end
|
60
|
+
|
61
|
+
it "uses the remote named after the current folder name when there are multiple" do
|
62
|
+
@base.stub!(:git_remotes).and_return({ 'staging' => 'myapp-staging', 'production' => 'myapp' })
|
63
|
+
Dir.stub!(:pwd).and_return('/home/dev/myapp')
|
64
|
+
@base.extract_app.should == 'myapp'
|
65
|
+
end
|
66
|
+
|
67
|
+
it "accepts a --remote argument to choose the app from the remote name" do
|
68
|
+
@base.stub!(:git_remotes).and_return({ 'staging' => 'myapp-staging', 'production' => 'myapp' })
|
69
|
+
@base.stub!(:args).and_return(['--remote', 'staging'])
|
70
|
+
@base.extract_app.should == 'myapp-staging'
|
71
|
+
end
|
72
|
+
|
73
|
+
it "raises when cannot determine which app is it" do
|
74
|
+
@base.stub!(:git_remotes).and_return({ 'staging' => 'myapp-staging', 'production' => 'myapp' })
|
75
|
+
lambda { @base.extract_app }.should raise_error(Heroku::Command::CommandFailed)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context "option parsing" do
|
80
|
+
it "extracts options from args" do
|
81
|
+
@base.stub!(:args).and_return(%w( a b --something value c d ))
|
82
|
+
@base.extract_option('--something').should == 'value'
|
83
|
+
end
|
84
|
+
|
85
|
+
it "accepts options without value" do
|
86
|
+
@base.stub!(:args).and_return(%w( a b --something))
|
87
|
+
@base.extract_option('--something').should be_true
|
88
|
+
end
|
89
|
+
|
90
|
+
it "doesn't consider parameters as a value" do
|
91
|
+
@base.stub!(:args).and_return(%w( a b --something --something-else c d))
|
92
|
+
@base.extract_option('--something').should be_true
|
93
|
+
end
|
94
|
+
|
95
|
+
it "accepts a default value" do
|
96
|
+
@base.stub!(:args).and_return(%w( a b --something))
|
97
|
+
@base.extract_option('--something', 'default').should == 'default'
|
98
|
+
end
|
99
|
+
|
100
|
+
it "is not affected by multiple arguments with the same value" do
|
101
|
+
@base.stub!(:args).and_return(%w( --arg1 val --arg2 val ))
|
102
|
+
@base.extract_option('--arg1').should == 'val'
|
103
|
+
@base.args.should == ['--arg2', 'val']
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe "formatting" do
|
108
|
+
it "formats app urls (http and git), displayed as output on create and other commands" do
|
109
|
+
@base.stub!(:heroku).and_return(mock('heroku client', :host => 'example.com'))
|
110
|
+
@base.app_urls('test').should == "http://test.example.com/ | git@example.com:test.git"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../base'
|
2
|
+
|
3
|
+
module Heroku::Command
|
4
|
+
describe Bundles do
|
5
|
+
before do
|
6
|
+
@bundles = prepare_command(Bundles)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "lists bundles" do
|
10
|
+
@bundles.heroku.should_receive(:bundles).with('myapp').and_return([])
|
11
|
+
@bundles.list
|
12
|
+
end
|
13
|
+
|
14
|
+
it "captures a bundle with the specified name" do
|
15
|
+
@bundles.stub!(:args).and_return(['mybundle'])
|
16
|
+
@bundles.heroku.should_receive(:bundle_capture).with('myapp', 'mybundle')
|
17
|
+
@bundles.capture
|
18
|
+
end
|
19
|
+
|
20
|
+
it "captures a bundle with no name" do
|
21
|
+
@bundles.heroku.should_receive(:bundle_capture).with('myapp', nil)
|
22
|
+
@bundles.capture
|
23
|
+
end
|
24
|
+
|
25
|
+
it "destroys a bundle" do
|
26
|
+
@bundles.stub!(:args).and_return(['mybundle'])
|
27
|
+
@bundles.heroku.should_receive(:bundle_destroy).with('myapp', 'mybundle')
|
28
|
+
@bundles.destroy
|
29
|
+
end
|
30
|
+
|
31
|
+
it "downloads a bundle to appname.tar.gz" do
|
32
|
+
@bundles.stub!(:args).and_return(['mybundle'])
|
33
|
+
@bundles.heroku.should_receive(:bundle_url).with('myapp', 'mybundle').and_return('https://s3.amazonaws.com/herokubundles/123.tar.gz')
|
34
|
+
RestClient.should_receive(:get).with('https://s3.amazonaws.com/herokubundles/123.tar.gz').and_return('bundle contents')
|
35
|
+
@file = mock('bundle file')
|
36
|
+
File.should_receive(:open).with('myapp.tar.gz', 'wb').and_yield(@file)
|
37
|
+
@file.should_receive(:write).with('bundle contents')
|
38
|
+
File.stub!(:stat).and_return(mock('app stat', :size => 1234))
|
39
|
+
@bundles.download
|
40
|
+
end
|
41
|
+
|
42
|
+
it "animates a bundle" do
|
43
|
+
@bundles.stub!(:args).and_return(['mybundle'])
|
44
|
+
@bundles.heroku.should_receive(:create).with(nil, :origin_bundle_app => 'myapp', :origin_bundle => 'mybundle')
|
45
|
+
@bundles.animate
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../base'
|
2
|
+
|
3
|
+
module Heroku::Command
|
4
|
+
describe Config do
|
5
|
+
before do
|
6
|
+
@config = prepare_command(Config)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "shows all configs" do
|
10
|
+
@config.heroku.should_receive(:config_vars).and_return({ 'A' => 'one', 'B' => 'two' })
|
11
|
+
@config.should_receive(:display).with('A => one')
|
12
|
+
@config.should_receive(:display).with('B => two')
|
13
|
+
@config.index
|
14
|
+
end
|
15
|
+
|
16
|
+
it "trims long values" do
|
17
|
+
@config.heroku.should_receive(:config_vars).and_return({ 'LONG' => 'A' * 60 })
|
18
|
+
@config.should_receive(:display).with('LONG => AAAAAAAAAAAAAAAA...AAAAAAAAAAAAAAAA')
|
19
|
+
@config.index
|
20
|
+
end
|
21
|
+
|
22
|
+
it "sets config vars" do
|
23
|
+
@config.stub!(:args).and_return(['a=1', 'b=2'])
|
24
|
+
@config.heroku.should_receive(:add_config_vars).with('myapp', {'a'=>'1','b'=>'2'})
|
25
|
+
@config.add
|
26
|
+
end
|
27
|
+
|
28
|
+
it "allows config vars with = in the value" do
|
29
|
+
@config.stub!(:args).and_return(['a=b=c'])
|
30
|
+
@config.heroku.should_receive(:add_config_vars).with('myapp', {'a'=>'b=c'})
|
31
|
+
@config.add
|
32
|
+
end
|
33
|
+
|
34
|
+
it "unsets config vars" do
|
35
|
+
@config.stub!(:args).and_return(['a'])
|
36
|
+
@config.heroku.should_receive(:remove_config_var).with('myapp', 'a')
|
37
|
+
@config.remove
|
38
|
+
end
|
39
|
+
|
40
|
+
it "resets config" do
|
41
|
+
@config.heroku.should_receive(:clear_config_vars).with('myapp')
|
42
|
+
@config.clear
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|