droxi 0.1.1 → 0.1.2
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/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
|
|