rubypath 0.3.2 → 1.0.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.
@@ -1,21 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Path do
4
- describe 'Identity' do
5
- let(:str) { '/path/to/file' }
6
- let(:args) { [str] }
7
- let(:path) { described_class.new(*args) }
8
- subject { path }
9
-
10
- describe_method :path, aliases: [:to_path, :to_str, :to_s] do
11
- subject { path.send described_method }
12
-
13
- it { should eq str }
14
-
15
- # Should not return same object as internal variable
16
- # to avoid in-place modifications like
17
- # `Path.new('/abc').path.delete!('abc')`
18
- it { should_not equal path.send(:instance_variable_get, :@path) }
19
- end
20
- end
21
- end
@@ -1,128 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Path do
4
- let(:delta) { 1.0 }
5
-
6
- describe 'IO Operations' do
7
- with_backends :mock, :sys do
8
-
9
- describe_method :read do
10
- let(:path) { Path '/file' }
11
- let(:args) { Array.new }
12
- subject { path.send described_method, *args }
13
-
14
- context 'with existing file' do
15
- before { path.write 'CONTENT' }
16
- before { path.mtime = Time.new(1970) }
17
- before { path.atime = Time.new(1970) }
18
-
19
- it { should eq 'CONTENT' }
20
-
21
- it 'should update access time' do
22
- subject
23
- expect(path.atime).to be_within(delta).of(Time.now)
24
- end
25
-
26
- context 'with read length and offset' do
27
- let(:args) { [4, 2] }
28
-
29
- it { should eq 'NTEN' }
30
-
31
- context 'with oversized length' do
32
- let(:args) { [10, 2] }
33
- it { should eq 'NTENT' }
34
- end
35
-
36
- context 'with oversized offset' do
37
- let(:args) { [10, 10] }
38
- it { should eq nil }
39
- end
40
- end
41
- end
42
-
43
- context 'with existing directory' do
44
- before { path.mkdir }
45
-
46
- it 'should raise EISDIR error' do
47
- expect { subject }.to raise_error(Errno::EISDIR, "Is a directory - /file")
48
- end
49
- end
50
-
51
- context 'with non-existent file' do
52
- before { expect(path).to_not be_existent }
53
-
54
- it 'should raise ENOENT error' do
55
- expect { subject }.to raise_error(Errno::ENOENT, "No such file or directory - /file")
56
- end
57
- end
58
- end
59
-
60
- describe_method :write do
61
- let(:path) { Path '/file' }
62
- let(:args) { Array.new }
63
- subject { path.send described_method, 'CONTENT', *args }
64
-
65
- shared_examples '#write' do
66
- it 'should write content' do
67
- subject
68
- expect(path.read).to eq expected_content
69
- end
70
-
71
- it { should be_a Path }
72
- it { expect(subject.path).to eq path.path}
73
- end
74
-
75
- context 'with existing file' do
76
- before { path.touch }
77
- before { path.mtime = Time.new(1970) }
78
- before { path.atime = Time.new(1970) }
79
- let(:expected_content) { 'CONTENT' }
80
-
81
- it_behaves_like '#write'
82
-
83
- it 'should update mtime' do
84
- expect{ subject }.to change{ path.mtime }
85
- expect(path.mtime).to be_within(delta).of(Time.now)
86
- end
87
-
88
- it 'should not update atime' do
89
- expect{ subject }.to_not change{ path.atime }
90
- end
91
-
92
- context 'with offset' do
93
- before { path.write '12345678901234567890' }
94
- let(:args) { [4] }
95
- let(:expected_content) { '1234CONTENT234567890' }
96
-
97
- it_behaves_like '#write'
98
- end
99
- end
100
-
101
- context 'with existing directory' do
102
- before { path.mkdir }
103
-
104
- it 'should write content' do
105
- expect{ subject }.to raise_error(Errno::EISDIR, "Is a directory - /file")
106
- end
107
- end
108
-
109
- context 'with non-existing file' do
110
- before { expect(path).to_not be_existent }
111
- let(:expected_content) { 'CONTENT' }
112
-
113
- it_behaves_like '#write'
114
-
115
- it 'should set mtime' do
116
- subject
117
- expect(path.mtime).to be_within(delta).of(Time.now)
118
- end
119
-
120
- it 'should set atime' do
121
- subject
122
- expect(path.atime).to be_within(delta).of(Time.now)
123
- end
124
- end
125
- end
126
- end
127
- end
128
- end
@@ -1,483 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Path do
4
- describe 'Path Operations' do
5
- let(:str) { '/root/path' }
6
- let(:args) { [str] }
7
- let(:path) { Path(*args) }
8
- subject { path }
9
-
10
- describe_method :join do
11
- subject { path.send(described_method, *join_args) }
12
-
13
- context 'with single string' do
14
- let(:join_args) { ['to/file.txt'] }
15
- it { should eq '/root/path/to/file.txt' }
16
- end
17
-
18
- context 'with multiple strings' do
19
- let(:join_args) { ['to/', 'file.txt'] }
20
- it { should eq '/root/path/to/file.txt' }
21
- end
22
-
23
- context 'with multiple args' do
24
- let(:join_args) { ['to/', Path('dir'), Pathname.new('sub/file.txt')] }
25
- it { should eq '/root/path/to/dir/sub/file.txt' }
26
- end
27
-
28
- context 'with absolute path' do
29
- let(:join_args) { ['/path/to/file.txt'] }
30
- it { should eq '/path/to/file.txt' }
31
- end
32
-
33
- context 'with mixed paths' do
34
- let(:join_args) { ['rel/file', '/path/to/file.txt', 'sub'] }
35
- it { should eq '/path/to/file.txt/sub' }
36
- end
37
- end
38
-
39
- describe_method :cleanpath do
40
- subject { path.send(described_method) }
41
-
42
- context 'with out dot components' do
43
- let(:path) { Path 'path/to/file.txt' }
44
- it { should eq 'path/to/file.txt' }
45
- end
46
-
47
- context 'with leading dot' do
48
- let(:path) { Path './file.txt' }
49
- it { should eq 'file.txt' }
50
- end
51
-
52
- context 'with including dot' do
53
- let(:path) { Path 'path/to/./file.txt' }
54
- it { should eq 'path/to/file.txt' }
55
- end
56
-
57
- context 'with double dot' do
58
- let(:path) { Path 'path/to/../file.txt' }
59
- it { should eq 'path/file.txt' }
60
- end
61
-
62
- context 'with multiple dots' do
63
- let(:path) { Path 'path/to/../../opath/to/./../file.txt' }
64
- it { should eq 'opath/file.txt' }
65
- end
66
-
67
- context 'with trailing slash' do
68
- let(:path) { Path 'path/to/../../dir/' }
69
- it { expect(subject.to_s).to eq 'dir/' }
70
- end
71
- end
72
-
73
- describe_method :each_component do
74
- let(:block) { nil }
75
- let(:opts) { Hash.new }
76
- let(:str) { '/path/to/templates/dir/' }
77
- subject { path.send described_method, opts, &block }
78
-
79
- it { should be_a Enumerator }
80
-
81
- it 'should return all components' do
82
- expect(subject.to_a).to eq %w(path to templates dir)
83
- end
84
-
85
- context 'with empty option' do
86
- let(:opts) { {empty: true} }
87
-
88
- it 'should also return empty path components' do
89
- expect(subject.to_a).to eq([''] + %w(path to templates dir) + [''])
90
- end
91
- end
92
-
93
- context 'with block' do
94
- let(:block) { proc{|fn| fn } }
95
-
96
- it 'should yield components' do
97
- expect do |b|
98
- path.send described_method, &b
99
- end.to yield_successive_args(*%w(path to templates dir))
100
- end
101
-
102
- it { should eq path }
103
- end
104
- end
105
-
106
- describe_method :components do
107
- let(:str) { '/path/to/templates/index.html' }
108
- subject { path.send described_method }
109
-
110
- it { should be_a Array }
111
- it { should eq %w(path to templates index.html) }
112
-
113
- context 'with should include leading empty components' do
114
- let(:str) { 'path/to/dir/' }
115
- subject { path.send described_method, empty: true }
116
-
117
- it { should eq ['path', 'to', 'dir', ''] }
118
- end
119
- end
120
-
121
- describe_method :dirname, aliases: [:parent] do
122
- shared_examples 'dirname' do
123
- it 'should return parent directory' do
124
- expect(Path(base, 'path/to/file').send(described_method))
125
- .to eq "#{base}path/to"
126
- end
127
-
128
- context 'when hitting root' do
129
- it 'should return root' do
130
- expect(Path(base, 'path').send(described_method)).to eq base[0]
131
- end
132
- end
133
-
134
- context 'when being root' do
135
- it 'should return nil' do
136
- expect(Path(base[0]).send(described_method)).to eq nil
137
- end
138
- end
139
- end
140
-
141
- context 'with absolute path' do
142
- let(:base) { '/' }
143
- it_behaves_like 'dirname'
144
- end
145
-
146
- context 'with relative path' do
147
- let(:base) { './' }
148
- it_behaves_like 'dirname'
149
- end
150
- end
151
-
152
- with_backends :mock, :sys do
153
- describe_method :expand, aliases: [:expand_path,
154
- :absolute, :absolute_path] do
155
- let(:cwd) { '/working/dir' }
156
- let(:base) { cwd }
157
- let(:args) { Array.new }
158
- before do
159
- Path.mock do |root, back|
160
- back.cwd = cwd
161
- back.current_user = 'test'
162
- back.homes = {'test' => '/home/test', 'otto' => '/srv/home/otto'}
163
- end
164
- end
165
-
166
- around{|example| Path::Backend.mock(&example) }
167
-
168
- shared_examples '#expand' do
169
- subject { Path(path).send(described_method, *args) }
170
-
171
- it 'should expand path' do
172
- expect(subject).to eq expanded_path
173
- end
174
-
175
- it { should be_a Path }
176
- end
177
-
178
- context '~' do
179
- let(:path) { '~' }
180
- let(:expanded_path) { '/home/test' }
181
- it_behaves_like '#expand'
182
- end
183
-
184
- context '~/path' do
185
- let(:path) { '~/path/to/file.txt' }
186
- let(:expanded_path) { '/home/test/path/to/file.txt' }
187
- it_behaves_like '#expand'
188
- end
189
-
190
- context '~user' do
191
- let(:path) { '~otto' }
192
- let(:expanded_path) { '/srv/home/otto' }
193
- it_behaves_like '#expand'
194
- end
195
-
196
- context '~user/path' do
197
- let(:path) { '~otto/path/to/file.txt' }
198
- let(:expanded_path) { '/srv/home/otto/path/to/file.txt' }
199
- it_behaves_like '#expand'
200
- end
201
-
202
- context '/abs/path' do
203
- let(:path) { '/abs/path/to/file.txt' }
204
- let(:expanded_path) { '/abs/path/to/file.txt' }
205
- it_behaves_like '#expand'
206
- end
207
-
208
- context 'rel/path' do
209
- let(:path) { 'rel/path/to/file.txt' }
210
- let(:expanded_path) { '/working/dir/rel/path/to/file.txt' }
211
- it_behaves_like '#expand'
212
- end
213
-
214
- context './path' do
215
- let(:path) { './path/to/file.txt' }
216
- let(:expanded_path) { '/working/dir/path/to/file.txt' }
217
- it_behaves_like '#expand'
218
- end
219
-
220
- context 'with base option' do
221
- let(:base) { '/base/./' }
222
- let(:args) { [base: '/base/./'] }
223
-
224
- context '~' do
225
- let(:path) { '~' }
226
- let(:expanded_path) { '/home/test' }
227
- it_behaves_like '#expand'
228
- end
229
-
230
- context '~/path' do
231
- let(:path) { '~/path/to/file.txt' }
232
- let(:expanded_path) { '/home/test/path/to/file.txt' }
233
- it_behaves_like '#expand'
234
- end
235
-
236
- context '~user' do
237
- let(:path) { '~otto' }
238
- let(:expanded_path) { '/srv/home/otto' }
239
- it_behaves_like '#expand'
240
- end
241
-
242
- context '~user/path' do
243
- let(:path) { '~otto/path/to/file.txt' }
244
- let(:expanded_path) { '/srv/home/otto/path/to/file.txt' }
245
- it_behaves_like '#expand'
246
- end
247
-
248
- context '/abs/path' do
249
- let(:path) { '/abs/path/to/file.txt' }
250
- let(:expanded_path) { '/abs/path/to/file.txt' }
251
- it_behaves_like '#expand'
252
- end
253
-
254
- context 'rel/path' do
255
- let(:path) { 'rel/path/to/file.txt' }
256
- let(:expanded_path) { '/base/rel/path/to/file.txt' }
257
- it_behaves_like '#expand'
258
- end
259
-
260
- context './path' do
261
- let(:path) { './path/to/file.txt' }
262
- let(:expanded_path) { '/base/path/to/file.txt' }
263
- it_behaves_like '#expand'
264
- end
265
- end
266
-
267
- context 'with path args' do
268
- let(:args) { ['..', 'fuu', 'net.txt'] }
269
-
270
- context '~' do
271
- let(:path) { '~' }
272
- let(:expanded_path) { '/home/fuu/net.txt' }
273
- it_behaves_like '#expand'
274
- end
275
-
276
- context '~/path' do
277
- let(:path) { '~/path/to/file.txt' }
278
- let(:expanded_path) { '/home/test/path/to/fuu/net.txt' }
279
- it_behaves_like '#expand'
280
- end
281
-
282
- context '~user' do
283
- let(:path) { '~otto' }
284
- let(:expanded_path) { '/srv/home/fuu/net.txt' }
285
- it_behaves_like '#expand'
286
- end
287
-
288
- context '~user/path' do
289
- let(:path) { '~otto/path/to/file.txt' }
290
- let(:expanded_path) { '/srv/home/otto/path/to/fuu/net.txt' }
291
- it_behaves_like '#expand'
292
- end
293
-
294
- context '/abs/path' do
295
- let(:path) { '/abs/path/to/file.txt' }
296
- let(:expanded_path) { '/abs/path/to/fuu/net.txt' }
297
- it_behaves_like '#expand'
298
- end
299
-
300
- context 'rel/path' do
301
- let(:path) { 'rel/path/to/file.txt' }
302
- let(:expanded_path) { '/working/dir/rel/path/to/fuu/net.txt' }
303
- it_behaves_like '#expand'
304
- end
305
-
306
- context './path' do
307
- let(:path) { './path/to/file.txt' }
308
- let(:expanded_path) { '/working/dir/path/to/fuu/net.txt' }
309
- it_behaves_like '#expand'
310
- end
311
- end
312
- end
313
- end
314
-
315
- describe_method :relative_from, aliases: [:relative_path_from] do
316
- let(:base) { Path '/path/three/four/five' }
317
- let(:path) { Path '/path/one/two' }
318
- subject { path.relative_from base }
319
-
320
- it { should eq '../../../one/two' }
321
-
322
- context 'with collapsing paths' do
323
- let(:base) { Path '/path/one/two' }
324
- let(:path) { Path '/path/one' }
325
- it { should eq '..' }
326
- end
327
-
328
- context 'with relative paths' do
329
- let(:base) { Path 'path/one' }
330
- let(:path) { Path 'path/two' }
331
- it { should eq '../two' }
332
- end
333
-
334
- context 'with mixed paths' do
335
- let(:base) { Path '/root/path/one' }
336
- let(:path) { Path 'path/two' }
337
- subject { ->{ path.relative_from base } }
338
- it { should raise_error ArgumentError }
339
- end
340
-
341
- context 'with dots in path' do
342
- let(:base) { Path '/path/one/three/../two' }
343
- let(:path) { Path '/path/one/two/six' }
344
- it { should eq 'six' }
345
- end
346
-
347
- context 'with same path (I)' do
348
- let(:base) { Path '/path/one/two/six' }
349
- let(:path) { Path '/path/one/two/six' }
350
- it { should eq '.' }
351
- it { expect(subject.to_s).to eq '.' }
352
- end
353
-
354
- context 'with same path (I)' do
355
- let(:base) { Path '/' }
356
- let(:path) { Path '/' }
357
- it { should eq '.' }
358
- it { expect(subject.to_s).to eq '.' }
359
- end
360
-
361
- describe 'preserve trailing slash' do
362
- let(:base) { Path('/blog/2014/06/my-blog-title-1/').dirname }
363
- let(:path) { Path '/blog/2014/07/another-blog-title/' }
364
- it { expect(subject.to_s).to eq '../07/another-blog-title/' }
365
- end
366
- end
367
-
368
- describe_method :ascend, aliases: [:each_ancestors] do
369
- shared_examples 'ascend' do
370
- context 'with block' do
371
- let(:block) { proc{} }
372
- subject { path.send described_method, &block }
373
-
374
- it { should eq path }
375
-
376
- it 'should yield part paths' do
377
- expect{|b| path.send(described_method, &b) }
378
- .to yield_successive_args(*expected_paths)
379
- end
380
-
381
- it 'should yield Path objects' do
382
- expect{|b| path.send(described_method, &b) }
383
- .to yield_successive_args(*expected_paths.map{ Path })
384
- end
385
- end
386
-
387
- context 'w/o block' do
388
- subject { path.send described_method }
389
-
390
- it { should be_a Enumerator }
391
-
392
- it 'should yield part paths' do
393
- expect{|b| subject.each(&b) }
394
- .to yield_successive_args(*expected_paths)
395
- end
396
-
397
- it 'should yield path objects' do
398
- expect{|b| subject.each(&b) }
399
- .to yield_successive_args(*expected_paths.map{ Path })
400
- end
401
- end
402
- end
403
-
404
- context 'with absolute path' do
405
- let(:path) { Path '/path/to/file.txt' }
406
- let(:expected_paths) { %w(/path/to/file.txt /path/to /path /) }
407
- it_behaves_like 'ascend'
408
- end
409
-
410
- context 'with relative path' do
411
- let(:path) { Path 'path/to/file.txt' }
412
- let(:expected_paths) { %w(path/to/file.txt path/to path .) }
413
- it_behaves_like 'ascend'
414
- end
415
- end
416
-
417
- describe '#as_relative' do
418
- subject { Path(path).as_relative }
419
-
420
- context 'with absolute path' do
421
- let(:path) { '/path/to/file.txt' }
422
- it { should eq 'path/to/file.txt' }
423
- end
424
-
425
- context 'with relative path' do
426
- let(:path) { 'path/to/file.txt' }
427
- it { should eq 'path/to/file.txt' }
428
- end
429
-
430
- context 'with filename only' do
431
- let(:path) { 'file.txt' }
432
- it { should eq 'file.txt' }
433
- end
434
- end
435
-
436
- describe '#as_absolute' do
437
- subject { Path(path).as_absolute }
438
-
439
- context 'with absolute path' do
440
- let(:path) { '/path/to/file.txt' }
441
- it { should eq '/path/to/file.txt' }
442
- end
443
-
444
- context 'with relative path' do
445
- let(:path) { 'path/to/file.txt' }
446
- it { should eq '/path/to/file.txt' }
447
- end
448
-
449
- context 'with filename only' do
450
- let(:path) { 'file.txt' }
451
- it { should eq '/file.txt' }
452
- end
453
- end
454
-
455
- describe_method :ancestors do
456
- shared_examples 'ancestors' do
457
- subject { path.send described_method }
458
-
459
- it { should be_a Array }
460
-
461
- it 'should contain part paths' do
462
- expect{|b| subject.each &b }.to yield_successive_args *expected_paths
463
- end
464
-
465
- it 'should contain path objects' do
466
- expect{|b| subject.each &b }.to yield_successive_args *expected_paths.map{ Path }
467
- end
468
- end
469
-
470
- context 'with absolute path' do
471
- let(:path) { Path '/path/to/file.txt' }
472
- let(:expected_paths) { %w(/path/to/file.txt /path/to /path /)}
473
- it_behaves_like 'ancestors'
474
- end
475
-
476
- context 'with relative path' do
477
- let(:path) { Path 'path/to/file.txt' }
478
- let(:expected_paths) { %w(path/to/file.txt path/to path .)}
479
- it_behaves_like 'ancestors'
480
- end
481
- end
482
- end
483
- end