aptible-cli 0.14.1 → 0.15.0
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.
- checksums.yaml +4 -4
- data/README.md +10 -1
- data/aptible-cli.gemspec +1 -0
- data/bin/aptible +9 -5
- data/lib/aptible/cli.rb +36 -0
- data/lib/aptible/cli/agent.rb +10 -6
- data/lib/aptible/cli/error.rb +6 -0
- data/lib/aptible/cli/formatter.rb +21 -0
- data/lib/aptible/cli/formatter/grouped_keyed_list.rb +54 -0
- data/lib/aptible/cli/formatter/keyed_list.rb +25 -0
- data/lib/aptible/cli/formatter/keyed_object.rb +16 -0
- data/lib/aptible/cli/formatter/list.rb +33 -0
- data/lib/aptible/cli/formatter/node.rb +8 -0
- data/lib/aptible/cli/formatter/object.rb +38 -0
- data/lib/aptible/cli/formatter/root.rb +46 -0
- data/lib/aptible/cli/formatter/value.rb +25 -0
- data/lib/aptible/cli/helpers/app.rb +1 -0
- data/lib/aptible/cli/helpers/database.rb +22 -6
- data/lib/aptible/cli/helpers/operation.rb +3 -2
- data/lib/aptible/cli/helpers/tunnel.rb +1 -3
- data/lib/aptible/cli/helpers/vhost.rb +9 -46
- data/lib/aptible/cli/renderer.rb +26 -0
- data/lib/aptible/cli/renderer/base.rb +8 -0
- data/lib/aptible/cli/renderer/json.rb +26 -0
- data/lib/aptible/cli/renderer/text.rb +99 -0
- data/lib/aptible/cli/resource_formatter.rb +136 -0
- data/lib/aptible/cli/subcommands/apps.rb +26 -14
- data/lib/aptible/cli/subcommands/backup.rb +22 -4
- data/lib/aptible/cli/subcommands/config.rb +15 -11
- data/lib/aptible/cli/subcommands/db.rb +82 -31
- data/lib/aptible/cli/subcommands/deploy.rb +1 -1
- data/lib/aptible/cli/subcommands/endpoints.rb +11 -8
- data/lib/aptible/cli/subcommands/operation.rb +2 -1
- data/lib/aptible/cli/subcommands/rebuild.rb +1 -1
- data/lib/aptible/cli/subcommands/restart.rb +1 -1
- data/lib/aptible/cli/subcommands/services.rb +8 -9
- data/lib/aptible/cli/version.rb +1 -1
- data/spec/aptible/cli/agent_spec.rb +11 -14
- data/spec/aptible/cli/formatter_spec.rb +4 -0
- data/spec/aptible/cli/renderer/json_spec.rb +63 -0
- data/spec/aptible/cli/renderer/text_spec.rb +150 -0
- data/spec/aptible/cli/resource_formatter_spec.rb +113 -0
- data/spec/aptible/cli/subcommands/apps_spec.rb +144 -28
- data/spec/aptible/cli/subcommands/backup_spec.rb +37 -16
- data/spec/aptible/cli/subcommands/config_spec.rb +95 -0
- data/spec/aptible/cli/subcommands/db_spec.rb +185 -93
- data/spec/aptible/cli/subcommands/endpoints_spec.rb +10 -8
- data/spec/aptible/cli/subcommands/operation_spec.rb +0 -1
- data/spec/aptible/cli/subcommands/rebuild_spec.rb +17 -0
- data/spec/aptible/cli/subcommands/services_spec.rb +8 -12
- data/spec/aptible/cli_spec.rb +31 -0
- data/spec/fabricators/account_fabricator.rb +11 -0
- data/spec/fabricators/app_fabricator.rb +15 -0
- data/spec/fabricators/configuration_fabricator.rb +8 -0
- data/spec/fabricators/database_image_fabricator.rb +17 -0
- data/spec/fabricators/operation_fabricator.rb +1 -0
- data/spec/fabricators/service_fabricator.rb +4 -0
- data/spec/spec_helper.rb +63 -1
- metadata +55 -4
- data/spec/aptible/cli/helpers/vhost_spec.rb +0 -105
@@ -18,7 +18,6 @@ end
|
|
18
18
|
|
19
19
|
describe Aptible::CLI::Agent do
|
20
20
|
before do
|
21
|
-
allow(subject).to receive(:ask)
|
22
21
|
allow(subject).to receive(:save_token)
|
23
22
|
allow(subject).to receive(:attach_to_operation_logs)
|
24
23
|
allow(subject).to receive(:fetch_token) { double 'token' }
|
@@ -29,6 +28,135 @@ describe Aptible::CLI::Agent do
|
|
29
28
|
let!(:service) { Fabricate(:service, app: app, process_type: 'web') }
|
30
29
|
let(:op) { Fabricate(:operation, status: 'succeeded', resource: app) }
|
31
30
|
|
31
|
+
describe '#apps' do
|
32
|
+
it 'lists an app in an account' do
|
33
|
+
allow(Aptible::Api::Account).to receive(:all).and_return([account])
|
34
|
+
subject.send('apps')
|
35
|
+
|
36
|
+
expect(captured_output_text)
|
37
|
+
.to eq("=== #{account.handle}\n#{app.handle}\n")
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'lists multiple apps in an account' do
|
41
|
+
allow(Aptible::Api::Account).to receive(:all).and_return([account])
|
42
|
+
app2 = Fabricate(:app, handle: 'foobar', account: account)
|
43
|
+
subject.send('apps')
|
44
|
+
|
45
|
+
expect(captured_output_text)
|
46
|
+
.to eq("=== #{account.handle}\n#{app.handle}\n#{app2.handle}\n")
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'lists multiple apps, grouped by account in text output' do
|
50
|
+
account1 = Fabricate(:account, handle: 'Aaccount1')
|
51
|
+
app11 = Fabricate(:app, account: account1, handle: 'app11')
|
52
|
+
|
53
|
+
account2 = Fabricate(:account, handle: 'Baccount2')
|
54
|
+
app21 = Fabricate(:app, account: account2, handle: 'app21')
|
55
|
+
app22 = Fabricate(:app, account: account2, handle: 'app21')
|
56
|
+
|
57
|
+
allow(Aptible::Api::Account).to receive(:all)
|
58
|
+
.and_return([account1, account2])
|
59
|
+
|
60
|
+
subject.send('apps')
|
61
|
+
|
62
|
+
expected_text = [
|
63
|
+
"=== #{account1.handle}",
|
64
|
+
app11.handle,
|
65
|
+
'',
|
66
|
+
"=== #{account2.handle}",
|
67
|
+
app21.handle,
|
68
|
+
app22.handle,
|
69
|
+
''
|
70
|
+
].join("\n")
|
71
|
+
|
72
|
+
expect(captured_output_text).to eq(expected_text)
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'lists filters down to one account' do
|
76
|
+
account2 = Fabricate(:account, handle: 'account2')
|
77
|
+
app2 = Fabricate(:app, account: account2, handle: 'app2')
|
78
|
+
allow(subject).to receive(:options)
|
79
|
+
.and_return(environment: account2.handle)
|
80
|
+
|
81
|
+
allow(Aptible::Api::Account).to receive(:all)
|
82
|
+
.and_return([account, account2])
|
83
|
+
subject.send('apps')
|
84
|
+
|
85
|
+
expect(captured_output_text)
|
86
|
+
.to eq("=== #{account2.handle}\n#{app2.handle}\n")
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'includes services in JSON' do
|
90
|
+
account = Fabricate(:account, handle: 'account')
|
91
|
+
app = Fabricate(:app, account: account, handle: 'app')
|
92
|
+
allow(Aptible::Api::Account).to receive(:all).and_return([account])
|
93
|
+
|
94
|
+
s1 = Fabricate(
|
95
|
+
:service,
|
96
|
+
app: app, process_type: 's1', command: 'true', container_count: 2
|
97
|
+
)
|
98
|
+
s2 = Fabricate(
|
99
|
+
:service,
|
100
|
+
app: app, process_type: 's2', container_memory_limit_mb: 2048
|
101
|
+
)
|
102
|
+
|
103
|
+
expected_json = [
|
104
|
+
{
|
105
|
+
'environment' => {
|
106
|
+
'id' => account.id,
|
107
|
+
'handle' => account.handle
|
108
|
+
},
|
109
|
+
'handle' => app.handle,
|
110
|
+
'id' => app.id,
|
111
|
+
'status' => app.status,
|
112
|
+
'git_remote' => app.git_repo,
|
113
|
+
'services' => [
|
114
|
+
{
|
115
|
+
'service' => s1.process_type,
|
116
|
+
'id' => s1.id,
|
117
|
+
'command' => s1.command,
|
118
|
+
'container_count' => s1.container_count,
|
119
|
+
'container_size' => s1.container_memory_limit_mb
|
120
|
+
},
|
121
|
+
{
|
122
|
+
'service' => s2.process_type,
|
123
|
+
'id' => s2.id,
|
124
|
+
'command' => 'CMD',
|
125
|
+
'container_count' => s2.container_count,
|
126
|
+
'container_size' => s2.container_memory_limit_mb
|
127
|
+
}
|
128
|
+
]
|
129
|
+
}
|
130
|
+
]
|
131
|
+
|
132
|
+
subject.send('apps')
|
133
|
+
|
134
|
+
expect(captured_output_json).to eq(expected_json)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
describe '#apps:create' do
|
139
|
+
before do
|
140
|
+
allow(Aptible::Api::Account).to receive(:all) { [account] }
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'creates an app' do
|
144
|
+
expect(account).to receive(:create_app)
|
145
|
+
.with(handle: 'foo').and_return(app)
|
146
|
+
|
147
|
+
subject.send('apps:create', 'foo')
|
148
|
+
end
|
149
|
+
|
150
|
+
it 're-raises errors' do
|
151
|
+
app.errors.full_messages << 'oops'
|
152
|
+
expect(account).to receive(:create_app)
|
153
|
+
.with(handle: 'foo').and_return(app)
|
154
|
+
|
155
|
+
expect { subject.send('apps:create', 'foo') }
|
156
|
+
.to raise_error(Thor::Error, /oops/i)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
32
160
|
describe '#apps:scale' do
|
33
161
|
before do
|
34
162
|
allow(Aptible::Api::App).to receive(:all) { [app] }
|
@@ -54,29 +182,29 @@ describe Aptible::CLI::Agent do
|
|
54
182
|
|
55
183
|
it 'should scale container size and count together' do
|
56
184
|
stub_options(container_count: 3, container_size: 1024)
|
57
|
-
expect($stderr).not_to receive(:puts)
|
58
185
|
expect(service).to receive(:create_operation!)
|
59
186
|
.with(type: 'scale', container_count: 3, container_size: 1024)
|
60
187
|
.and_return(op)
|
61
188
|
subject.send('apps:scale', 'web')
|
189
|
+
expect(captured_logs).not_to match(/deprecated/i)
|
62
190
|
end
|
63
191
|
|
64
192
|
it 'should scale container count alone' do
|
65
193
|
stub_options(container_count: 3)
|
66
|
-
expect($stderr).not_to receive(:puts)
|
67
194
|
expect(service).to receive(:create_operation!)
|
68
195
|
.with(type: 'scale', container_count: 3)
|
69
196
|
.and_return(op)
|
70
197
|
subject.send('apps:scale', 'web')
|
198
|
+
expect(captured_logs).not_to match(/deprecated/i)
|
71
199
|
end
|
72
200
|
|
73
201
|
it 'should scale container size alone' do
|
74
202
|
stub_options(container_size: 1024)
|
75
|
-
expect($stderr).not_to receive(:puts)
|
76
203
|
expect(service).to receive(:create_operation!)
|
77
204
|
.with(type: 'scale', container_size: 1024)
|
78
205
|
.and_return(op)
|
79
206
|
subject.send('apps:scale', 'web')
|
207
|
+
expect(captured_logs).not_to match(/deprecated/i)
|
80
208
|
end
|
81
209
|
|
82
210
|
it 'should fail if neither container_count nor container_size is set' do
|
@@ -87,20 +215,20 @@ describe Aptible::CLI::Agent do
|
|
87
215
|
|
88
216
|
it 'should scale container count (legacy)' do
|
89
217
|
stub_options
|
90
|
-
expect($stderr).to receive(:puts).once
|
91
218
|
expect(service).to receive(:create_operation!)
|
92
219
|
.with(type: 'scale', container_count: 3)
|
93
220
|
.and_return(op)
|
94
221
|
subject.send('apps:scale', 'web', '3')
|
222
|
+
expect(captured_logs).to match(/deprecated/i)
|
95
223
|
end
|
96
224
|
|
97
225
|
it 'should scale container size (legacy)' do
|
98
226
|
stub_options(size: 90210)
|
99
|
-
expect($stderr).to receive(:puts).once
|
100
227
|
expect(service).to receive(:create_operation!)
|
101
228
|
.with(type: 'scale', container_size: 90210)
|
102
229
|
.and_return(op)
|
103
230
|
subject.send('apps:scale', 'web')
|
231
|
+
expect(captured_logs).to match(/deprecated/i)
|
104
232
|
end
|
105
233
|
|
106
234
|
it 'should fail when using both current and legacy count' do
|
@@ -157,41 +285,29 @@ describe Aptible::CLI::Agent do
|
|
157
285
|
end
|
158
286
|
|
159
287
|
it 'should fail if number is not a valid number (legacy)' do
|
160
|
-
expect($stderr).to receive(:puts).once
|
161
288
|
allow(subject).to receive(:options) { { app: 'hello' } }
|
162
289
|
allow(service).to receive(:create_operation) { op }
|
163
290
|
|
164
291
|
expect do
|
165
292
|
subject.send('apps:scale', 'web', 'potato')
|
166
293
|
end.to raise_error(ArgumentError)
|
167
|
-
end
|
168
|
-
end
|
169
294
|
|
170
|
-
|
171
|
-
before do
|
172
|
-
allow(Aptible::Api::App).to receive(:all) { [app] }
|
173
|
-
allow(Aptible::Api::Account).to receive(:all) { [account] }
|
295
|
+
expect(captured_logs).to match(/deprecated/i)
|
174
296
|
end
|
297
|
+
end
|
175
298
|
|
176
|
-
|
177
|
-
|
299
|
+
describe '#apps:deprovision' do
|
300
|
+
let(:operation) { Fabricate(:operation, resource: app) }
|
178
301
|
|
179
|
-
|
180
|
-
.to raise_error(/invalid argument/im)
|
181
|
-
end
|
182
|
-
end
|
302
|
+
before { allow(subject).to receive(:ensure_app).and_return(app) }
|
183
303
|
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
allow(Aptible::Api::Account).to receive(:all) { [account] }
|
188
|
-
end
|
304
|
+
it 'deprovisions an app' do
|
305
|
+
expect(app).to receive(:create_operation!)
|
306
|
+
.with(type: 'deprovision').and_return(operation)
|
189
307
|
|
190
|
-
|
191
|
-
allow(subject).to receive(:options) { { app: 'hello' } }
|
308
|
+
expect(subject).not_to receive(:attach_to_operation_logs)
|
192
309
|
|
193
|
-
|
194
|
-
.to raise_error(/invalid argument/im)
|
310
|
+
subject.send('apps:deprovision')
|
195
311
|
end
|
196
312
|
end
|
197
313
|
|
@@ -7,21 +7,23 @@ describe Aptible::CLI::Agent do
|
|
7
7
|
let(:database) { Fabricate(:database, account: account, handle: 'some-db') }
|
8
8
|
let!(:backup) do
|
9
9
|
# created_at: 2016-06-14 13:24:11 +0000
|
10
|
-
Fabricate(
|
10
|
+
Fabricate(
|
11
|
+
:backup,
|
12
|
+
database: database, created_at: Time.at(1465910651), account: account
|
13
|
+
)
|
11
14
|
end
|
12
15
|
|
13
|
-
let(:
|
16
|
+
let(:default_handle) { 'some-db-at-2016-06-14-13-24-11' }
|
14
17
|
|
15
18
|
before do
|
16
19
|
allow(subject).to receive(:fetch_token).and_return(token)
|
17
|
-
allow(subject).to receive(:say) { |m| messages << m }
|
18
20
|
allow(Aptible::Api::Account).to receive(:all) { [account, alt_account] }
|
19
21
|
end
|
20
22
|
|
21
23
|
describe '#backup:restore' do
|
22
24
|
it 'fails if the backup cannot be found' do
|
23
|
-
expect(Aptible::Api::Backup).to receive(:find)
|
24
|
-
.and_return(nil)
|
25
|
+
expect(Aptible::Api::Backup).to receive(:find)
|
26
|
+
.with(1, token: token).and_return(nil)
|
25
27
|
|
26
28
|
expect { subject.send('backup:restore', 1) }
|
27
29
|
.to raise_error('Backup #1 not found')
|
@@ -31,23 +33,26 @@ describe Aptible::CLI::Agent do
|
|
31
33
|
let(:op) { Fabricate(:operation, resource: backup) }
|
32
34
|
|
33
35
|
before do
|
34
|
-
expect(Aptible::Api::Backup).to receive(:find)
|
35
|
-
.and_return(backup)
|
36
|
-
expect(subject).to receive(:attach_to_operation_logs).with(op)
|
36
|
+
expect(Aptible::Api::Backup).to receive(:find)
|
37
|
+
.with(1, token: token).and_return(backup)
|
37
38
|
end
|
38
39
|
|
39
40
|
it 'provides a default handle and no disk size' do
|
40
|
-
h = 'some-db-at-2016-06-14-13-24-11'
|
41
|
-
|
42
41
|
expect(backup).to receive(:create_operation!) do |options|
|
43
|
-
expect(options[:handle]).to eq(
|
42
|
+
expect(options[:handle]).to eq(default_handle)
|
44
43
|
expect(options[:disk_size]).not_to be_present
|
45
44
|
expect(options[:destination_account]).not_to be_present
|
46
45
|
op
|
47
46
|
end
|
48
47
|
|
48
|
+
expect(subject).to receive(:attach_to_operation_logs).with(op) do
|
49
|
+
Fabricate(:database, account: account, handle: default_handle)
|
50
|
+
end
|
51
|
+
|
49
52
|
subject.send('backup:restore', 1)
|
50
|
-
|
53
|
+
|
54
|
+
expect(captured_logs)
|
55
|
+
.to match(/restoring backup into #{default_handle}/im)
|
51
56
|
end
|
52
57
|
|
53
58
|
it 'accepts a handle' do
|
@@ -61,9 +66,13 @@ describe Aptible::CLI::Agent do
|
|
61
66
|
op
|
62
67
|
end
|
63
68
|
|
69
|
+
expect(subject).to receive(:attach_to_operation_logs).with(op) do
|
70
|
+
Fabricate(:database, account: account, handle: h)
|
71
|
+
end
|
72
|
+
|
64
73
|
subject.options = { handle: h }
|
65
74
|
subject.send('backup:restore', 1)
|
66
|
-
expect(
|
75
|
+
expect(captured_logs).to match(/restoring backup into #{h}/im)
|
67
76
|
end
|
68
77
|
|
69
78
|
it 'accepts a container size' do
|
@@ -77,6 +86,10 @@ describe Aptible::CLI::Agent do
|
|
77
86
|
op
|
78
87
|
end
|
79
88
|
|
89
|
+
expect(subject).to receive(:attach_to_operation_logs).with(op) do
|
90
|
+
Fabricate(:database, account: account, handle: default_handle)
|
91
|
+
end
|
92
|
+
|
80
93
|
subject.options = { container_size: s }
|
81
94
|
subject.send('backup:restore', 1)
|
82
95
|
end
|
@@ -92,6 +105,10 @@ describe Aptible::CLI::Agent do
|
|
92
105
|
op
|
93
106
|
end
|
94
107
|
|
108
|
+
expect(subject).to receive(:attach_to_operation_logs).with(op) do
|
109
|
+
Fabricate(:database, account: account, handle: default_handle)
|
110
|
+
end
|
111
|
+
|
95
112
|
subject.options = { size: s }
|
96
113
|
subject.send('backup:restore', 1)
|
97
114
|
end
|
@@ -103,6 +120,10 @@ describe Aptible::CLI::Agent do
|
|
103
120
|
op
|
104
121
|
end
|
105
122
|
|
123
|
+
expect(subject).to receive(:attach_to_operation_logs).with(op) do
|
124
|
+
Fabricate(:database, account: alt_account, handle: default_handle)
|
125
|
+
end
|
126
|
+
|
106
127
|
subject.options = { environment: 'alt' }
|
107
128
|
subject.send('backup:restore', 1)
|
108
129
|
end
|
@@ -131,19 +152,19 @@ describe Aptible::CLI::Agent do
|
|
131
152
|
|
132
153
|
it 'can show a subset of backups' do
|
133
154
|
subject.send('backup:list', database.handle)
|
134
|
-
expect(
|
155
|
+
expect(captured_output_text.split("\n").size).to eq(5)
|
135
156
|
end
|
136
157
|
|
137
158
|
it 'allows scoping via environment' do
|
138
159
|
subject.options = { max_age: '1w', environment: database.account.handle }
|
139
160
|
subject.send('backup:list', database.handle)
|
140
|
-
expect(
|
161
|
+
expect(captured_output_text.split("\n").size).to eq(5)
|
141
162
|
end
|
142
163
|
|
143
164
|
it 'shows more backups if requested' do
|
144
165
|
subject.options = { max_age: '2y' }
|
145
166
|
subject.send('backup:list', database.handle)
|
146
|
-
expect(
|
167
|
+
expect(captured_output_text.split("\n").size).to eq(9)
|
147
168
|
end
|
148
169
|
|
149
170
|
it 'errors out if max_age is invalid' do
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Aptible::CLI::Agent do
|
4
|
+
let(:account) { Fabricate(:account) }
|
5
|
+
let(:app) { Fabricate(:app, account: account) }
|
6
|
+
|
7
|
+
let(:token) { double('token') }
|
8
|
+
before { allow(subject).to receive(:fetch_token).and_return(token) }
|
9
|
+
|
10
|
+
before do
|
11
|
+
allow(Aptible::Api::App).to receive(:all)
|
12
|
+
.with(token: token).and_return([app])
|
13
|
+
allow(Aptible::Api::Account).to receive(:all)
|
14
|
+
.with(token: token).and_return([account])
|
15
|
+
end
|
16
|
+
|
17
|
+
before { allow(subject).to receive(:options) { { app: app.handle } } }
|
18
|
+
let(:operation) { Fabricate(:operation, resource: app) }
|
19
|
+
|
20
|
+
describe '#config' do
|
21
|
+
before { allow(subject).to receive(:options).and_return(app: app.handle) }
|
22
|
+
|
23
|
+
it 'shows nothing for an unconfigured app' do
|
24
|
+
subject.send('config')
|
25
|
+
expect(captured_output_text).to eq('')
|
26
|
+
expect(captured_output_json).to match_array([])
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'shows an empty configuration' do
|
30
|
+
app.current_configuration = Fabricate(:configuration, app: app)
|
31
|
+
subject.send('config')
|
32
|
+
expect(captured_output_text).to eq('')
|
33
|
+
expect(captured_output_json).to match_array([])
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should show environment variables' do
|
37
|
+
app.current_configuration = Fabricate(
|
38
|
+
:configuration, app: app, env: { 'FOO' => 'BAR', 'QUX' => 'two words' }
|
39
|
+
)
|
40
|
+
subject.send('config')
|
41
|
+
|
42
|
+
expect(captured_output_text).to match(/FOO=BAR/)
|
43
|
+
expect(captured_output_text).to match(/QUX=two\\ words/)
|
44
|
+
|
45
|
+
expected = [
|
46
|
+
{
|
47
|
+
'key' => 'FOO', 'value' => 'BAR',
|
48
|
+
'shell_export' => 'FOO=BAR'
|
49
|
+
},
|
50
|
+
{
|
51
|
+
'key' => 'QUX', 'value' => 'two words',
|
52
|
+
'shell_export' => 'QUX=two\\ words'
|
53
|
+
}
|
54
|
+
]
|
55
|
+
|
56
|
+
expect(captured_output_json).to match_array(expected)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe '#config:set' do
|
61
|
+
it 'sets environment variables' do
|
62
|
+
expect(app).to receive(:create_operation!)
|
63
|
+
.with(type: 'configure', env: { 'FOO' => 'BAR' })
|
64
|
+
.and_return(operation)
|
65
|
+
|
66
|
+
expect(subject).to receive(:attach_to_operation_logs)
|
67
|
+
.with(operation)
|
68
|
+
|
69
|
+
subject.send('config:set', 'FOO=BAR')
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'rejects environment variables that start with -' do
|
73
|
+
expect { subject.send('config:set', '-foo=bar') }
|
74
|
+
.to raise_error(/invalid argument/im)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe '#config:rm' do
|
79
|
+
it 'unsets environment variables' do
|
80
|
+
expect(app).to receive(:create_operation!)
|
81
|
+
.with(type: 'configure', env: { 'FOO' => '' })
|
82
|
+
.and_return(operation)
|
83
|
+
|
84
|
+
expect(subject).to receive(:attach_to_operation_logs)
|
85
|
+
.with(operation)
|
86
|
+
|
87
|
+
subject.send('config:unset', 'FOO')
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'rejects environment variables that start with -' do
|
91
|
+
expect { subject.send('config:rm', '-foo') }
|
92
|
+
.to raise_error(/invalid argument/im)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|