droxi 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/droxi +1 -1
- data/droxi.1.template +8 -1
- data/droxi.gemspec +2 -2
- data/lib/droxi/commands.rb +169 -92
- data/lib/droxi/complete.rb +1 -1
- data/lib/droxi.rb +24 -8
- data/spec/commands_spec.rb +273 -113
- data/spec/testutils.rb +6 -3
- metadata +2 -2
data/spec/commands_spec.rb
CHANGED
@@ -14,7 +14,6 @@ describe Commands do
|
|
14
14
|
|
15
15
|
TEMP_FILENAME = 'test.txt'
|
16
16
|
TEMP_FOLDER = 'test'
|
17
|
-
TEST_FOLDER = 'testing'
|
18
17
|
|
19
18
|
before do
|
20
19
|
Dir.chdir(original_dir)
|
@@ -33,47 +32,55 @@ describe Commands do
|
|
33
32
|
end
|
34
33
|
|
35
34
|
describe 'when executing the cd command' do
|
35
|
+
before do
|
36
|
+
@cd = proc do |*args|
|
37
|
+
capture_io { Commands::CD.exec(client, state, *args) }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
36
41
|
it 'must change to the root directory when given no args' do
|
37
42
|
state.pwd = '/testing'
|
38
|
-
|
43
|
+
@cd.call
|
39
44
|
state.pwd.must_equal '/'
|
40
45
|
end
|
41
46
|
|
42
47
|
it 'must change to the stated directory when given 1 arg' do
|
43
48
|
state.pwd = '/'
|
44
|
-
|
49
|
+
@cd.call('/testing')
|
45
50
|
state.pwd.must_equal '/testing'
|
46
51
|
end
|
47
52
|
|
48
53
|
it 'must change and set previous directory correctly' do
|
49
54
|
state.pwd = '/testing'
|
50
55
|
state.pwd = '/'
|
51
|
-
|
56
|
+
@cd.call('-')
|
52
57
|
state.pwd.must_equal '/testing'
|
53
58
|
state.oldpwd.must_equal '/'
|
54
59
|
end
|
55
60
|
|
56
61
|
it 'must not change to a bogus directory' do
|
57
62
|
state.pwd = '/'
|
58
|
-
|
63
|
+
@cd.call('/bogus_dir')
|
59
64
|
state.pwd.must_equal '/'
|
60
65
|
end
|
61
66
|
|
62
67
|
it 'must fail with UsageError when given multiple args' do
|
63
|
-
proc {
|
64
|
-
.must_raise Commands::UsageError
|
68
|
+
proc { @cd.call('a', 'b') }.must_raise Commands::UsageError
|
65
69
|
end
|
66
70
|
end
|
67
71
|
|
68
72
|
describe 'when executing the cp command' do
|
69
73
|
before do
|
70
|
-
state.pwd =
|
74
|
+
state.pwd = TestUtils::TEST_ROOT
|
75
|
+
@copy = proc do |*args|
|
76
|
+
capture_io { Commands::CP.exec(client, state, *args) }
|
77
|
+
end
|
71
78
|
end
|
72
79
|
|
73
80
|
it 'must copy source to dest when given 2 args and last arg is non-dir' do
|
74
81
|
TestUtils.structure(client, state, 'source')
|
75
82
|
TestUtils.not_structure(client, state, 'dest')
|
76
|
-
|
83
|
+
@copy.call('source', 'dest')
|
77
84
|
%w(source dest).all? do |dir|
|
78
85
|
state.metadata("/testing/#{dir}")
|
79
86
|
end.must_equal true
|
@@ -82,97 +89,135 @@ describe Commands do
|
|
82
89
|
it 'must copy source into dest when given 2 args and last arg is dir' do
|
83
90
|
TestUtils.structure(client, state, 'source', 'dest')
|
84
91
|
TestUtils.not_structure(client, state, 'dest/source')
|
85
|
-
|
92
|
+
@copy.call('source', 'dest')
|
86
93
|
state.metadata('/testing/dest/source').wont_be_nil
|
87
94
|
end
|
88
95
|
|
89
96
|
it 'must copy sources into dest when given 3 or more args' do
|
90
97
|
TestUtils.structure(client, state, 'source1', 'source2', 'dest')
|
91
98
|
TestUtils.not_structure(client, state, 'dest/source1', 'dest/source2')
|
92
|
-
|
99
|
+
@copy.call('source1', 'source2', 'dest')
|
93
100
|
%w(source2 source2).all? do |dir|
|
94
101
|
state.metadata("/testing/dest/#{dir}")
|
95
102
|
end.must_equal true
|
96
103
|
end
|
97
104
|
|
98
105
|
it 'must fail with UsageError when given <2 args' do
|
99
|
-
test1 = proc {
|
100
|
-
test2 = proc {
|
106
|
+
test1 = proc { @copy.call }
|
107
|
+
test2 = proc { @copy.call('a') }
|
101
108
|
[test1, test2].each { |test| test.must_raise Commands::UsageError }
|
102
109
|
end
|
103
110
|
|
104
111
|
it 'must give an error message if trying to copy a bogus file' do
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
112
|
+
_, err = @copy.call('bogus', '/testing')
|
113
|
+
err.lines.size.must_equal 1
|
114
|
+
err.start_with?('cp: ').must_equal true
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'must fail to overwrite file without -f flag' do
|
118
|
+
TestUtils.structure(client, state, 'source.txt', 'dest.txt')
|
119
|
+
_, err = @copy.call('source.txt', 'dest.txt')
|
120
|
+
err.lines.size.must_equal 1
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'must also cp normally with -f flag' do
|
124
|
+
TestUtils.structure(client, state, 'source.txt')
|
125
|
+
TestUtils.not_structure(client, state, 'dest.txt')
|
126
|
+
_, err = @copy.call('-f', 'source.txt', 'dest.txt')
|
127
|
+
err.must_be :empty?
|
109
128
|
end
|
110
129
|
end
|
111
130
|
|
112
131
|
describe 'when executing the debug command' do
|
132
|
+
before do
|
133
|
+
@debug = proc do |*args|
|
134
|
+
capture_io { Commands::DEBUG.exec(client, state, *args) }
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
113
138
|
it 'must fail with an error message if debug mode is not enabled' do
|
114
139
|
ARGV.clear
|
115
|
-
|
116
|
-
lines.size.must_equal 1
|
117
|
-
|
140
|
+
_, err = @debug.call('1')
|
141
|
+
err.lines.size.must_equal 1
|
142
|
+
err.start_with?('debug: ').must_equal true
|
118
143
|
end
|
119
144
|
|
120
145
|
it 'must evaluate the string if debug mode is enabled' do
|
121
146
|
ARGV << '--debug'
|
122
|
-
|
123
|
-
|
147
|
+
out, _ = @debug.call('1')
|
148
|
+
out.must_equal("1\n")
|
124
149
|
end
|
125
150
|
|
126
151
|
it 'must print the resulting exception if given exceptional input' do
|
127
152
|
ARGV << '--debug'
|
128
|
-
|
129
|
-
lines.size.must_equal 1
|
130
|
-
|
153
|
+
_, err = @debug.call('x')
|
154
|
+
err.lines.size.must_equal 1
|
155
|
+
err.must_match(/^#<.+>$/)
|
131
156
|
end
|
132
157
|
|
133
158
|
it 'must fail with UsageError when given no args' do
|
134
|
-
proc {
|
135
|
-
.must_raise Commands::UsageError
|
159
|
+
proc { @debug.call }.must_raise Commands::UsageError
|
136
160
|
end
|
137
161
|
end
|
138
162
|
|
139
163
|
describe 'when executing the forget command' do
|
140
164
|
it 'must clear entire cache when given no arguments' do
|
141
|
-
Commands::LS.exec(client, state, '/')
|
165
|
+
capture_io { Commands::LS.exec(client, state, '/') }
|
142
166
|
Commands::FORGET.exec(client, state)
|
143
167
|
state.cache.empty?.must_equal true
|
144
168
|
end
|
145
169
|
|
146
170
|
it 'must accept multiple arguments' do
|
147
171
|
args = %w(bogus1, bogus2)
|
148
|
-
|
149
|
-
|
172
|
+
_, err = capture_io { Commands::FORGET.exec(client, state, *args) }
|
173
|
+
err.lines.size.must_equal 2
|
150
174
|
end
|
151
175
|
|
152
176
|
it 'must recursively clear contents of directory argument' do
|
153
|
-
Commands::LS.exec(client, state, '/', '/testing')
|
177
|
+
capture_io { Commands::LS.exec(client, state, '/', '/testing') }
|
154
178
|
Commands::FORGET.exec(client, state, '/')
|
155
179
|
state.cache.size.must_equal 1
|
156
180
|
end
|
157
181
|
end
|
158
182
|
|
159
183
|
describe 'when executing the get command' do
|
184
|
+
before do
|
185
|
+
state.pwd = TestUtils::TEST_ROOT
|
186
|
+
@get = proc do |*args|
|
187
|
+
capture_io { Commands::GET.exec(client, state, *args) }
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
160
191
|
it 'must get a file of the same name when given args' do
|
161
192
|
TestUtils.structure(client, state, 'test.txt')
|
162
|
-
|
193
|
+
@get.call('test.txt')
|
163
194
|
`ls test.txt`.chomp.must_equal 'test.txt'
|
164
195
|
`rm test.txt`
|
165
196
|
end
|
166
197
|
|
167
198
|
it 'must fail with UsageError when given no args' do
|
168
|
-
proc {
|
169
|
-
.must_raise Commands::UsageError
|
199
|
+
proc { @get.call }.must_raise Commands::UsageError
|
170
200
|
end
|
171
201
|
|
172
202
|
it 'must give an error message if trying to get a bogus file' do
|
173
|
-
|
174
|
-
lines.size.must_equal 1
|
175
|
-
|
203
|
+
_, err = @get.call('bogus')
|
204
|
+
err.lines.size.must_equal 1
|
205
|
+
err[/^get: /].wont_be_nil
|
206
|
+
end
|
207
|
+
|
208
|
+
it 'must fail if trying to get existing file without -f' do
|
209
|
+
TestUtils.structure(client, state, 'test.txt')
|
210
|
+
`touch test.txt`
|
211
|
+
_, err = @get.call('test.txt')
|
212
|
+
err.lines.size.must_equal 1
|
213
|
+
err[/^get: /].wont_be_nil
|
214
|
+
end
|
215
|
+
|
216
|
+
it 'must not fail if trying to get existing file with -f' do
|
217
|
+
TestUtils.structure(client, state, 'test.txt')
|
218
|
+
`touch test.txt`
|
219
|
+
_, err = @get.call('-f', 'test.txt')
|
220
|
+
err.must_be :empty?
|
176
221
|
end
|
177
222
|
end
|
178
223
|
|
@@ -209,7 +254,7 @@ describe Commands do
|
|
209
254
|
it 'must fail if given bogus directory name' do
|
210
255
|
pwd = Dir.pwd
|
211
256
|
oldpwd = state.local_oldpwd
|
212
|
-
Commands::LCD.exec(client, state, '/bogus_dir')
|
257
|
+
capture_io { Commands::LCD.exec(client, state, '/bogus_dir') }
|
213
258
|
Dir.pwd.must_equal pwd
|
214
259
|
state.local_oldpwd.must_equal oldpwd
|
215
260
|
Dir.chdir(pwd)
|
@@ -217,61 +262,70 @@ describe Commands do
|
|
217
262
|
end
|
218
263
|
|
219
264
|
describe 'when executing the ls command' do
|
265
|
+
before do
|
266
|
+
@ls = proc do |*args|
|
267
|
+
capture_io { Commands::LS.exec(client, state, *args) }
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
220
271
|
it 'must list the working directory contents when given no args' do
|
221
272
|
TestUtils.exact_structure(client, state, 'test')
|
222
273
|
state.pwd = '/testing'
|
223
|
-
|
224
|
-
|
274
|
+
out, _ = @ls.call
|
275
|
+
out.must_equal("test \n")
|
225
276
|
end
|
226
277
|
|
227
278
|
it 'must list the stated directory contents when given args' do
|
228
279
|
state.pwd = '/'
|
229
280
|
TestUtils.exact_structure(client, state, 'test')
|
230
|
-
|
231
|
-
|
281
|
+
out, _ = @ls.call('/testing')
|
282
|
+
out.must_equal("test \n")
|
232
283
|
end
|
233
284
|
|
234
285
|
it 'must give a longer description with the -l option' do
|
235
286
|
state.pwd = '/'
|
236
287
|
TestUtils.exact_structure(client, state, 'test')
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
lines.first[/d +0 \w{3} .\d \d\d:\d\d test/].wont_be_nil
|
288
|
+
out, _ = @ls.call('-l', '/testing')
|
289
|
+
out.lines.size.must_equal 1
|
290
|
+
out[/^d +0 \w{3} .\d \d\d:\d\d test$/].wont_be_nil
|
241
291
|
end
|
242
292
|
|
243
293
|
it 'must give an error message if trying to list a bogus file' do
|
244
|
-
|
245
|
-
lines.size.must_equal 1
|
246
|
-
|
294
|
+
_, err = @ls.call('bogus')
|
295
|
+
err.lines.size.must_equal 1
|
296
|
+
err.start_with?('ls: ').must_equal true
|
247
297
|
end
|
248
298
|
end
|
249
299
|
|
250
300
|
describe 'when executing the media command' do
|
301
|
+
before do
|
302
|
+
@media = proc do |*args|
|
303
|
+
capture_io { Commands::MEDIA.exec(client, state, *args) }
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
251
307
|
it 'must yield URL when given file path' do
|
252
308
|
TestUtils.structure(client, state, 'test.txt')
|
253
309
|
path = '/testing/test.txt'
|
254
|
-
|
255
|
-
lines.size.must_equal 1
|
256
|
-
%r{https://.+\..+/}.match(
|
310
|
+
out, _ = @media.call(path)
|
311
|
+
out.lines.size.must_equal 1
|
312
|
+
%r{https://.+\..+/}.match(out).wont_be_nil
|
257
313
|
end
|
258
314
|
|
259
315
|
it 'must fail with error when given directory path' do
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
%r{https://.+\..+/}.match(lines.first).must_be_nil
|
316
|
+
_, err = @media.call('/testing')
|
317
|
+
err.lines.size.must_equal 1
|
318
|
+
%r{https://.+\..+/}.match(err).must_be_nil
|
264
319
|
end
|
265
320
|
|
266
321
|
it 'must fail with UsageError when given no args' do
|
267
|
-
proc {
|
268
|
-
.must_raise Commands::UsageError
|
322
|
+
proc { @media.call }.must_raise Commands::UsageError
|
269
323
|
end
|
270
324
|
|
271
325
|
it 'must give an error message if trying to link a bogus file' do
|
272
|
-
|
273
|
-
lines.size.must_equal 1
|
274
|
-
|
326
|
+
_, err = @media.call('%')
|
327
|
+
err.lines.size.must_equal 1
|
328
|
+
err.start_with?('media: ').must_equal true
|
275
329
|
end
|
276
330
|
end
|
277
331
|
|
@@ -290,13 +344,16 @@ describe Commands do
|
|
290
344
|
|
291
345
|
describe 'when executing the mv command' do
|
292
346
|
before do
|
293
|
-
state.pwd =
|
347
|
+
state.pwd = TestUtils::TEST_ROOT
|
348
|
+
@move = proc do |*args|
|
349
|
+
capture_io { Commands::MV.exec(client, state, *args) }
|
350
|
+
end
|
294
351
|
end
|
295
352
|
|
296
353
|
it 'must move source to dest when given 2 args and last arg is non-dir' do
|
297
354
|
TestUtils.structure(client, state, 'source')
|
298
355
|
TestUtils.not_structure(client, state, 'dest')
|
299
|
-
|
356
|
+
@move.call('source', 'dest')
|
300
357
|
state.metadata('/testing/source').must_be_nil
|
301
358
|
state.metadata('/testing/dest').wont_be_nil
|
302
359
|
end
|
@@ -304,7 +361,7 @@ describe Commands do
|
|
304
361
|
it 'must move source into dest when given 2 args and last arg is dir' do
|
305
362
|
TestUtils.structure(client, state, 'source', 'dest')
|
306
363
|
TestUtils.not_structure(client, state, 'dest/source')
|
307
|
-
|
364
|
+
@move.call('source', 'dest')
|
308
365
|
state.metadata('/testing/source').must_be_nil
|
309
366
|
state.metadata('/testing/dest/source').wont_be_nil
|
310
367
|
end
|
@@ -312,7 +369,7 @@ describe Commands do
|
|
312
369
|
it 'must move sources into dest when given 3 or more args' do
|
313
370
|
TestUtils.structure(client, state, 'source1', 'source2', 'dest')
|
314
371
|
TestUtils.not_structure(client, state, 'dest/source1', 'dest/source2')
|
315
|
-
|
372
|
+
@move.call('source1', 'source2', 'dest')
|
316
373
|
%w(source2 source2).all? do |dir|
|
317
374
|
state.metadata("/testing/#{dir}").must_be_nil
|
318
375
|
state.metadata("/testing/dest/#{dir}")
|
@@ -320,79 +377,122 @@ describe Commands do
|
|
320
377
|
end
|
321
378
|
|
322
379
|
it 'must fail with UsageError when given <2 args' do
|
323
|
-
test1 = proc {
|
324
|
-
test2 = proc {
|
380
|
+
test1 = proc { @move.call }
|
381
|
+
test2 = proc { @move.call('a') }
|
325
382
|
[test1, test2].each { |test| test.must_raise Commands::UsageError }
|
326
383
|
end
|
327
384
|
|
328
385
|
it 'must give an error message if trying to move a bogus file' do
|
329
|
-
|
330
|
-
|
331
|
-
lines.
|
332
|
-
|
386
|
+
_, err = @move.call('bogus1', 'bogus2', 'bogus3')
|
387
|
+
err.lines.size.must_equal 3
|
388
|
+
err.lines.all? { |line| line.start_with?('mv: ') }.must_equal true
|
389
|
+
end
|
390
|
+
|
391
|
+
it 'must fail to overwrite file without -f flag' do
|
392
|
+
TestUtils.structure(client, state, 'source.txt', 'dest.txt')
|
393
|
+
_, err = @move.call('source.txt', 'dest.txt')
|
394
|
+
err.lines.size.must_equal 1
|
395
|
+
end
|
396
|
+
|
397
|
+
it 'must overwrite with -f flag' do
|
398
|
+
TestUtils.structure(client, state, 'source.txt', 'dest.txt')
|
399
|
+
_, err = @move.call('-f', 'source.txt', 'dest.txt')
|
400
|
+
err.must_be :empty?
|
401
|
+
state.metadata('/testing/source.txt').must_be_nil
|
333
402
|
end
|
334
403
|
end
|
335
404
|
|
336
405
|
describe 'when executing the put command' do
|
406
|
+
before do
|
407
|
+
state.pwd = TestUtils::TEST_ROOT
|
408
|
+
@put = proc do |*args|
|
409
|
+
capture_io { Commands::PUT.exec(client, state, *args) }
|
410
|
+
end
|
411
|
+
end
|
412
|
+
|
337
413
|
it 'must put a file of the same name when given 1 arg' do
|
338
414
|
TestUtils.not_structure(client, state, 'test.txt')
|
339
|
-
state.pwd = '/testing'
|
340
415
|
`echo hello > test.txt`
|
341
|
-
|
416
|
+
@put.call('test.txt')
|
342
417
|
`rm test.txt`
|
343
418
|
state.metadata('/testing/test.txt').wont_be_nil
|
344
419
|
end
|
345
420
|
|
346
421
|
it 'must put a file with the stated name when given 2 args' do
|
347
422
|
TestUtils.not_structure(client, state, 'dest.txt')
|
348
|
-
state.pwd = '/testing'
|
349
423
|
`echo hello > test.txt`
|
350
|
-
|
424
|
+
@put.call('test.txt', 'dest.txt')
|
351
425
|
`rm test.txt`
|
352
426
|
state.metadata('/testing/dest.txt').wont_be_nil
|
353
427
|
end
|
354
428
|
|
355
429
|
it 'must put file in directory if second arg is directory' do
|
356
430
|
TestUtils.not_structure(client, state, 'test.txt')
|
357
|
-
state.pwd = '/'
|
358
431
|
`touch test.txt`
|
359
|
-
|
432
|
+
@put.call('test.txt', '/testing')
|
360
433
|
`rm test.txt`
|
361
434
|
state.metadata('/testing/test.txt').wont_be_nil
|
362
435
|
end
|
363
436
|
|
437
|
+
it 'must not overwrite without -f option' do
|
438
|
+
TestUtils.structure(client, state, 'test.txt')
|
439
|
+
TestUtils.not_structure(client, state, 'test (1).txt')
|
440
|
+
`touch test.txt`
|
441
|
+
@put.call('test.txt')
|
442
|
+
`rm test.txt`
|
443
|
+
state.metadata('/testing/test (1).txt').wont_be_nil
|
444
|
+
end
|
445
|
+
|
446
|
+
it 'must overwrite with -f option' do
|
447
|
+
TestUtils.structure(client, state, 'test.txt')
|
448
|
+
TestUtils.not_structure(client, state, 'test (1).txt')
|
449
|
+
`touch test.txt`
|
450
|
+
@put.call('-f', 'test.txt')
|
451
|
+
`rm test.txt`
|
452
|
+
state.metadata('/testing/test (1).txt').must_be_nil
|
453
|
+
end
|
454
|
+
|
364
455
|
it 'must fail with UsageError when given no args' do
|
365
|
-
proc {
|
366
|
-
.must_raise Commands::UsageError
|
456
|
+
proc { @put.call }.must_raise Commands::UsageError
|
367
457
|
end
|
368
458
|
end
|
369
459
|
|
370
460
|
describe 'when executing the share command' do
|
461
|
+
before do
|
462
|
+
@share = proc do |*args|
|
463
|
+
capture_io { Commands::SHARE.exec(client, state, *args) }
|
464
|
+
end
|
465
|
+
end
|
466
|
+
|
371
467
|
it 'must yield URL when given file path' do
|
372
468
|
TestUtils.structure(client, state, 'test.txt')
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
%r{https://.+\..+/}.match(lines.first).wont_be_nil
|
469
|
+
out, _ = @share.call('/testing/test.txt')
|
470
|
+
out.lines.size.must_equal 1
|
471
|
+
%r{https://.+\..+/}.match(out).wont_be_nil
|
377
472
|
end
|
378
473
|
|
379
474
|
it 'must fail with UsageError when given no args' do
|
380
|
-
proc {
|
381
|
-
.must_raise Commands::UsageError
|
475
|
+
proc { @share.call }.must_raise Commands::UsageError
|
382
476
|
end
|
383
477
|
|
384
478
|
it 'must give an error message if trying to share a bogus file' do
|
385
|
-
|
386
|
-
lines.size.must_equal 1
|
387
|
-
|
479
|
+
_, err = @share.call('%')
|
480
|
+
err.lines.size.must_equal 1
|
481
|
+
err.start_with?('share: ').must_equal true
|
388
482
|
end
|
389
483
|
end
|
390
484
|
|
391
485
|
describe 'when executing the rm command' do
|
486
|
+
before do
|
487
|
+
@rm = proc do |*args|
|
488
|
+
capture_io { Commands::RM.exec(client, state, *args) }
|
489
|
+
end
|
490
|
+
end
|
491
|
+
|
392
492
|
it 'must remove the remote file when given args' do
|
393
|
-
TestUtils.structure(client, state, 'test')
|
394
|
-
|
395
|
-
state.metadata('/testing/test').must_be_nil
|
493
|
+
TestUtils.structure(client, state, 'test.txt')
|
494
|
+
@rm.call('/testing/test.txt')
|
495
|
+
state.metadata('/testing/test.txt').must_be_nil
|
396
496
|
end
|
397
497
|
|
398
498
|
it 'must change pwd to existing dir if the current one is removed' do
|
@@ -404,38 +504,98 @@ describe Commands do
|
|
404
504
|
end
|
405
505
|
|
406
506
|
it 'must fail with UsageError when given no args' do
|
407
|
-
proc {
|
408
|
-
.must_raise Commands::UsageError
|
507
|
+
proc { @rm.call }.must_raise Commands::UsageError
|
409
508
|
end
|
410
509
|
|
411
510
|
it 'must give an error message if trying to remove a bogus file' do
|
412
|
-
|
413
|
-
lines.size.must_equal 1
|
414
|
-
|
511
|
+
_, err = @rm.call('bogus')
|
512
|
+
err.lines.size.must_equal 1
|
513
|
+
err.start_with?('rm: ').must_equal true
|
514
|
+
end
|
515
|
+
|
516
|
+
it 'must give error message if trying to remove dir without -r option' do
|
517
|
+
TestUtils.structure(client, state, 'test')
|
518
|
+
_, err = @rm.call('/testing/test')
|
519
|
+
err.lines.size.must_equal 1
|
520
|
+
err.start_with?('rm: ').must_equal true
|
521
|
+
end
|
522
|
+
|
523
|
+
it 'must remove dir recursively when given -r option' do
|
524
|
+
TestUtils.structure(client, state, 'test', 'test/dir', 'test/file.txt')
|
525
|
+
@rm.call('-r', '/testing/test')
|
526
|
+
paths = %w(/testing/test /testing/test/dir /testing/test/file.txt)
|
527
|
+
paths.each { |path| state.metadata(path).must_be_nil }
|
415
528
|
end
|
416
529
|
end
|
417
530
|
|
418
531
|
describe 'when executing the help command' do
|
532
|
+
before do
|
533
|
+
@help = proc do |*args|
|
534
|
+
capture_io { Commands::HELP.exec(client, state, *args) }
|
535
|
+
end
|
536
|
+
end
|
537
|
+
|
419
538
|
it 'must print a list of commands when given no args' do
|
420
|
-
|
421
|
-
|
539
|
+
out, _ = @help.call
|
540
|
+
out.split.size.must_equal Commands::NAMES.size
|
422
541
|
end
|
423
542
|
|
424
543
|
it 'must print help for a command when given it as an arg' do
|
425
|
-
|
426
|
-
lines.size.must_be :>=, 2
|
427
|
-
lines.first.must_equal Commands::HELP.usage
|
428
|
-
lines.drop(1).join(' ').
|
544
|
+
out, _ = @help.call('help')
|
545
|
+
out.lines.size.must_be :>=, 2
|
546
|
+
out.lines.first.chomp.must_equal Commands::HELP.usage
|
547
|
+
out.lines.drop(1).join(' ').tr("\n", '')
|
548
|
+
.must_equal Commands::HELP.description
|
429
549
|
end
|
430
550
|
|
431
551
|
it 'must print an error message if given a bogus name as an arg' do
|
432
|
-
|
433
|
-
|
552
|
+
_, err = @help.call('bogus')
|
553
|
+
err.lines.size.must_equal 1
|
554
|
+
err.start_with?('help: ').must_equal true
|
434
555
|
end
|
435
556
|
|
436
557
|
it 'must fail with UsageError when given multiple args' do
|
437
|
-
proc {
|
438
|
-
|
558
|
+
proc { @help.call('a', 'b') }.must_raise Commands::UsageError
|
559
|
+
end
|
560
|
+
end
|
561
|
+
|
562
|
+
describe 'when executing the rmdir command' do
|
563
|
+
before do
|
564
|
+
@rmdir = proc do |*args|
|
565
|
+
capture_io { Commands::RMDIR.exec(client, state, *args) }
|
566
|
+
end
|
567
|
+
end
|
568
|
+
|
569
|
+
it 'must remove remote directories if empty' do
|
570
|
+
TestUtils.exact_structure(client, state, 'dir1', 'dir2')
|
571
|
+
Commands::RMDIR.exec(client, state, '/testing/dir?')
|
572
|
+
paths = %w(/testing/dir1 /testing/dir2)
|
573
|
+
paths.each { |path| state.metadata(path).must_be_nil }
|
574
|
+
end
|
575
|
+
|
576
|
+
it 'must fail with error if remote directory not empty' do
|
577
|
+
TestUtils.structure(client, state, 'test', 'test/file.txt')
|
578
|
+
_, err = @rmdir.call('/testing/test')
|
579
|
+
err.lines.size.must_equal 1
|
580
|
+
err.start_with?('rmdir: ').must_equal true
|
581
|
+
end
|
582
|
+
|
583
|
+
it 'must fail with error if used on file' do
|
584
|
+
TestUtils.structure(client, state, 'test.txt')
|
585
|
+
_, err = @rmdir.call('/testing/test.txt')
|
586
|
+
err.lines.size.must_equal 1
|
587
|
+
err.start_with?('rmdir: ').must_equal true
|
588
|
+
end
|
589
|
+
|
590
|
+
it 'must fail with error if given bogus name' do
|
591
|
+
TestUtils.not_structure(client, state, 'bogus')
|
592
|
+
_, err = @rmdir.call('/testing/bogus')
|
593
|
+
err.lines.size.must_equal 1
|
594
|
+
err.start_with?('rmdir: ').must_equal true
|
595
|
+
end
|
596
|
+
|
597
|
+
it 'must fail with UsageError when given no args' do
|
598
|
+
proc { @rmdir.call }.must_raise Commands::UsageError
|
439
599
|
end
|
440
600
|
end
|
441
601
|
|
@@ -459,8 +619,8 @@ describe Commands do
|
|
459
619
|
end
|
460
620
|
|
461
621
|
it "must execute a command when given the command's name" do
|
462
|
-
|
463
|
-
|
622
|
+
_, err = capture_io { Commands.exec('lcd ~bogus', client, state) }
|
623
|
+
err.must_equal "lcd: ~bogus: no such file or directory\n"
|
464
624
|
end
|
465
625
|
|
466
626
|
it 'must do nothing when given an empty string' do
|
@@ -469,18 +629,18 @@ describe Commands do
|
|
469
629
|
|
470
630
|
it 'must handle backslash-escaped spaces correctly' do
|
471
631
|
TestUtils.structure(client, state, 'folder with spaces')
|
472
|
-
proc { Commands.exec('ls folder\ with\ spaces', client, state) }
|
632
|
+
proc { Commands.exec('ls /testing/folder\ with\ spaces', client, state) }
|
473
633
|
.must_be_silent
|
474
634
|
end
|
475
635
|
|
476
636
|
it 'must give a usage error message for incorrect arg count' do
|
477
|
-
|
478
|
-
|
637
|
+
_, err = capture_io { Commands.exec('get', client, state) }
|
638
|
+
err.start_with?('Usage: ').must_equal true
|
479
639
|
end
|
480
640
|
|
481
641
|
it 'must give an error message for invalid command name' do
|
482
|
-
|
483
|
-
|
642
|
+
_, err = capture_io { Commands.exec('drink soda', client, state) }
|
643
|
+
err.start_with?('droxi: ').must_equal true
|
484
644
|
end
|
485
645
|
end
|
486
646
|
|