artofmission-heroku 1.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|