droxi 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- Commands::CD.exec(client, state)
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
- Commands::CD.exec(client, state, '/testing')
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
- Commands::CD.exec(client, state, '-')
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
- Commands::CD.exec(client, state, '/bogus_dir')
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 { Commands::CD.exec(client, state, 'a', 'b') }
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 = '/testing'
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
- Commands::CP.exec(client, state, 'source', 'dest')
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
- Commands::CP.exec(client, state, 'source', 'dest')
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
- Commands::CP.exec(client, state, 'source1', 'source2', 'dest')
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 { Commands::CP.exec(client, state) }
100
- test2 = proc { Commands::CP.exec(client, state, 'a') }
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
- lines = TestUtils.output_of(Commands::CP, :exec, client, state,
106
- 'bogus', '/testing')
107
- lines.size.must_equal 1
108
- lines.first.start_with?('cp: ').must_equal true
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
- lines = TestUtils.output_of(Commands::DEBUG, :exec, client, state, '1')
116
- lines.size.must_equal 1
117
- lines.first.start_with?('debug: ').must_equal true
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
- TestUtils.output_of(Commands::DEBUG, :exec, client, state, '1')
123
- .must_equal(['1'])
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
- lines = TestUtils.output_of(Commands::DEBUG, :exec, client, state, 'x')
129
- lines.size.must_equal 1
130
- lines.first.must_match(/^#<.+>$/)
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 { Commands::DEBUG.exec(client, state) }
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
- TestUtils.output_of(Commands::FORGET, :exec, client, state, *args)
149
- .size.must_equal 2
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
- Commands::GET.exec(client, state, '/testing/test.txt')
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 { Commands::GET.exec(client, state) }
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
- lines = TestUtils.output_of(Commands::GET, :exec, client, state, 'bogus')
174
- lines.size.must_equal 1
175
- lines.first.start_with?('get: ').must_equal true
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
- TestUtils.output_of(Commands::LS, :exec, client, state)
224
- .must_equal(['test '])
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
- TestUtils.output_of(Commands::LS, :exec, client, state, '/testing')
231
- .must_equal(['test '])
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
- lines = TestUtils.output_of(Commands::LS, :exec, client, state,
238
- '-l', '/testing')
239
- lines.size.must_equal 1
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
- lines = TestUtils.output_of(Commands::LS, :exec, client, state, 'bogus')
245
- lines.size.must_equal 1
246
- lines.first.start_with?('ls: ').must_equal true
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
- lines = TestUtils.output_of(Commands::MEDIA, :exec, client, state, path)
255
- lines.size.must_equal 1
256
- %r{https://.+\..+/}.match(lines.first).wont_be_nil
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
- lines = TestUtils.output_of(Commands::MEDIA, :exec, client, state,
261
- '/testing')
262
- lines.size.must_equal 1
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 { Commands::MEDIA.exec(client, state) }
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
- lines = TestUtils.output_of(Commands::MEDIA, :exec, client, state, '%')
273
- lines.size.must_equal 1
274
- lines.first.start_with?('media: ').must_equal true
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 = '/testing'
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
- Commands::MV.exec(client, state, 'source', 'dest')
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
- Commands::MV.exec(client, state, 'source', 'dest')
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
- Commands::MV.exec(client, state, 'source1', 'source2', 'dest')
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 { Commands::MV.exec(client, state) }
324
- test2 = proc { Commands::MV.exec(client, state, 'a') }
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
- lines = TestUtils.output_of(Commands::MV, :exec, client, state,
330
- 'bogus1', 'bogus2', 'bogus3')
331
- lines.size.must_equal 3
332
- lines.all? { |line| line.start_with?('mv: ') }.must_equal true
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
- Commands::PUT.exec(client, state, 'test.txt')
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
- Commands::PUT.exec(client, state, 'test.txt', 'dest.txt')
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
- Commands::PUT.exec(client, state, 'test.txt', 'testing')
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 { Commands::PUT.exec(client, state) }
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
- lines = TestUtils.output_of(Commands::SHARE, :exec, client, state,
374
- '/testing/test.txt')
375
- lines.size.must_equal 1
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 { Commands::SHARE.exec(client, state) }
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
- lines = TestUtils.output_of(Commands::SHARE, :exec, client, state, '%')
386
- lines.size.must_equal 1
387
- lines.first.start_with?('share: ').must_equal true
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
- Commands::RM.exec(client, state, '/testing/test')
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 { Commands::RM.exec(client, state) }
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
- lines = TestUtils.output_of(Commands::RM, :exec, client, state, 'bogus')
413
- lines.size.must_equal 1
414
- lines.first.start_with?('rm: ').must_equal true
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
- TestUtils.output_of(Commands::HELP, :exec, client, state)
421
- .join.split.size.must_equal Commands::NAMES.size
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
- lines = TestUtils.output_of(Commands::HELP, :exec, client, state, 'help')
426
- lines.size.must_be :>=, 2
427
- lines.first.must_equal Commands::HELP.usage
428
- lines.drop(1).join(' ').must_equal Commands::HELP.description
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
- TestUtils.output_of(Commands::HELP, :exec, client, state, 'bogus')
433
- .size.must_equal 1
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 { Commands::HELP.exec(client, state, 'a', 'b') }
438
- .must_raise Commands::UsageError
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
- proc { Commands.exec('lcd ~bogus', client, state) }
463
- .must_output "lcd: ~bogus: no such file or directory\n"
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
- out, _err = capture_io { Commands.exec('get', client, state) }
478
- out.start_with?('Usage: ').must_equal true
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
- out, _err = capture_io { Commands.exec('drink soda', client, state) }
483
- out.start_with?('droxi: ').must_equal true
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