rubypath 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,383 @@
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 :each_component do
40
+ let(:block) { nil }
41
+ let(:opts) { Hash.new }
42
+ let(:str) { '/path/to/templates/dir/' }
43
+ subject { path.send described_method, opts, &block }
44
+
45
+ it { should be_a Enumerator }
46
+
47
+ it 'should return all components' do
48
+ expect(subject.to_a).to eq %w(path to templates dir)
49
+ end
50
+
51
+ context 'with empty option' do
52
+ let(:opts) { {empty: true} }
53
+
54
+ it 'should also return empty path components' do
55
+ expect(subject.to_a).to eq ([''] + %w(path to templates dir) + [''])
56
+ end
57
+ end
58
+
59
+ context 'with block' do
60
+ let(:block) { proc{|fn| fn} }
61
+
62
+ it 'should yield components' do
63
+ expect {|b|
64
+ path.send described_method, &b
65
+ }.to yield_successive_args(*%w(path to templates dir))
66
+ end
67
+
68
+ it { should eq path }
69
+ end
70
+ end
71
+
72
+ describe_method :components do
73
+ let(:str) { '/path/to/templates/index.html' }
74
+ subject { path.send described_method }
75
+
76
+ it { should be_a Array }
77
+ it { should eq %w(path to templates index.html) }
78
+ end
79
+
80
+ describe_method :dirname, aliases: [:parent] do
81
+ shared_examples 'dirname' do
82
+ it 'should return parent directory' do
83
+ expect(Path(base, 'path/to/file').send(described_method)).to eq "#{base}path/to"
84
+ end
85
+
86
+ context 'when hitting root' do
87
+ it 'should return root' do
88
+ expect(Path(base, 'path').send(described_method)).to eq base[0]
89
+ end
90
+ end
91
+
92
+ context 'when being root' do
93
+ it 'should return nil' do
94
+ expect(Path(base[0]).send(described_method)).to eq nil
95
+ end
96
+ end
97
+ end
98
+
99
+ context 'with absolute path' do
100
+ let(:base) { '/' }
101
+ it_behaves_like 'dirname'
102
+ end
103
+
104
+ context 'with relative path' do
105
+ let(:base) { './' }
106
+ it_behaves_like 'dirname'
107
+ end
108
+ end
109
+
110
+ with_backends :mock, :sys do
111
+ describe_method :expand, aliases: [:expand_path, :absolute, :absolute_path] do
112
+ let(:cwd) { '/working/dir' }
113
+ let(:base) { cwd }
114
+ let(:args) { Array.new }
115
+ before do
116
+ Path.mock do |root, back|
117
+ back.cwd = cwd
118
+ back.current_user = 'test'
119
+ back.homes = {'test' => '/home/test', 'otto' => '/srv/home/otto'}
120
+ end
121
+ end
122
+
123
+ around{|example| Path::Backend.mock &example }
124
+
125
+ shared_examples '#expand' do
126
+ subject { Path(path).send(described_method, *args) }
127
+
128
+ it 'should expand path' do
129
+ expect(subject).to eq expanded_path
130
+ end
131
+
132
+ it { should be_a Path }
133
+ end
134
+
135
+ context '~' do
136
+ let(:path) { '~' }
137
+ let(:expanded_path) { '/home/test' }
138
+ it_behaves_like '#expand'
139
+ end
140
+
141
+ context '~/path' do
142
+ let(:path) { '~/path/to/file.txt' }
143
+ let(:expanded_path) { '/home/test/path/to/file.txt' }
144
+ it_behaves_like '#expand'
145
+ end
146
+
147
+ context '~user' do
148
+ let(:path) { '~otto' }
149
+ let(:expanded_path) { '/srv/home/otto' }
150
+ it_behaves_like '#expand'
151
+ end
152
+
153
+ context '~user/path' do
154
+ let(:path) { '~otto/path/to/file.txt' }
155
+ let(:expanded_path) { '/srv/home/otto/path/to/file.txt' }
156
+ it_behaves_like '#expand'
157
+ end
158
+
159
+ context '/abs/path' do
160
+ let(:path) { '/abs/path/to/file.txt' }
161
+ let(:expanded_path) { '/abs/path/to/file.txt' }
162
+ it_behaves_like '#expand'
163
+ end
164
+
165
+ context 'rel/path' do
166
+ let(:path) { 'rel/path/to/file.txt' }
167
+ let(:expanded_path) { '/working/dir/rel/path/to/file.txt' }
168
+ it_behaves_like '#expand'
169
+ end
170
+
171
+ context './path' do
172
+ let(:path) { './path/to/file.txt' }
173
+ let(:expanded_path) { '/working/dir/path/to/file.txt' }
174
+ it_behaves_like '#expand'
175
+ end
176
+
177
+ context 'with base option' do
178
+ let(:base) { '/base/./' }
179
+ let(:args) { [base: '/base/./'] }
180
+
181
+ context '~' do
182
+ let(:path) { '~' }
183
+ let(:expanded_path) { '/home/test' }
184
+ it_behaves_like '#expand'
185
+ end
186
+
187
+ context '~/path' do
188
+ let(:path) { '~/path/to/file.txt' }
189
+ let(:expanded_path) { '/home/test/path/to/file.txt' }
190
+ it_behaves_like '#expand'
191
+ end
192
+
193
+ context '~user' do
194
+ let(:path) { '~otto' }
195
+ let(:expanded_path) { '/srv/home/otto' }
196
+ it_behaves_like '#expand'
197
+ end
198
+
199
+ context '~user/path' do
200
+ let(:path) { '~otto/path/to/file.txt' }
201
+ let(:expanded_path) { '/srv/home/otto/path/to/file.txt' }
202
+ it_behaves_like '#expand'
203
+ end
204
+
205
+ context '/abs/path' do
206
+ let(:path) { '/abs/path/to/file.txt' }
207
+ let(:expanded_path) { '/abs/path/to/file.txt' }
208
+ it_behaves_like '#expand'
209
+ end
210
+
211
+ context 'rel/path' do
212
+ let(:path) { 'rel/path/to/file.txt' }
213
+ let(:expanded_path) { '/base/rel/path/to/file.txt' }
214
+ it_behaves_like '#expand'
215
+ end
216
+
217
+ context './path' do
218
+ let(:path) { './path/to/file.txt' }
219
+ let(:expanded_path) { '/base/path/to/file.txt' }
220
+ it_behaves_like '#expand'
221
+ end
222
+ end
223
+
224
+ context 'with path args' do
225
+ let(:args) { ['..', 'fuu', 'net.txt'] }
226
+
227
+ context '~' do
228
+ let(:path) { '~' }
229
+ let(:expanded_path) { '/home/fuu/net.txt' }
230
+ it_behaves_like '#expand'
231
+ end
232
+
233
+ context '~/path' do
234
+ let(:path) { '~/path/to/file.txt' }
235
+ let(:expanded_path) { '/home/test/path/to/fuu/net.txt' }
236
+ it_behaves_like '#expand'
237
+ end
238
+
239
+ context '~user' do
240
+ let(:path) { '~otto' }
241
+ let(:expanded_path) { '/srv/home/fuu/net.txt' }
242
+ it_behaves_like '#expand'
243
+ end
244
+
245
+ context '~user/path' do
246
+ let(:path) { '~otto/path/to/file.txt' }
247
+ let(:expanded_path) { '/srv/home/otto/path/to/fuu/net.txt' }
248
+ it_behaves_like '#expand'
249
+ end
250
+
251
+ context '/abs/path' do
252
+ let(:path) { '/abs/path/to/file.txt' }
253
+ let(:expanded_path) { '/abs/path/to/fuu/net.txt' }
254
+ it_behaves_like '#expand'
255
+ end
256
+
257
+ context 'rel/path' do
258
+ let(:path) { 'rel/path/to/file.txt' }
259
+ let(:expanded_path) { '/working/dir/rel/path/to/fuu/net.txt' }
260
+ it_behaves_like '#expand'
261
+ end
262
+
263
+ context './path' do
264
+ let(:path) { './path/to/file.txt' }
265
+ let(:expanded_path) { '/working/dir/path/to/fuu/net.txt' }
266
+ it_behaves_like '#expand'
267
+ end
268
+ end
269
+ end
270
+ end
271
+
272
+ describe_method :ascend, aliases: [:each_ancestors] do
273
+ shared_examples 'ascend' do
274
+ context 'with block' do
275
+ let(:block) { proc{} }
276
+ subject { path.send described_method, &block }
277
+
278
+ it { should eq path }
279
+
280
+ it 'should yield part paths' do
281
+ expect{|b| path.send described_method, &b }.to yield_successive_args *expected_paths
282
+ end
283
+
284
+ it 'should yield Path objects' do
285
+ expect{|b| path.send described_method, &b }.to yield_successive_args *expected_paths.map{ Path }
286
+ end
287
+ end
288
+
289
+ context 'w/o block' do
290
+ subject { path.send described_method }
291
+
292
+ it { should be_a Enumerator }
293
+
294
+ it 'should yield part paths' do
295
+ expect{|b| subject.each &b }.to yield_successive_args *expected_paths
296
+ end
297
+
298
+ it 'should yield path objects' do
299
+ expect{|b| subject.each &b }.to yield_successive_args *expected_paths.map{ Path }
300
+ end
301
+ end
302
+ end
303
+
304
+ context 'with absolute path' do
305
+ let(:path) { Path '/path/to/file.txt' }
306
+ let(:expected_paths) { %w(/path/to/file.txt /path/to /path /)}
307
+ it_behaves_like 'ascend'
308
+ end
309
+
310
+ context 'with relative path' do
311
+ let(:path) { Path 'path/to/file.txt' }
312
+ let(:expected_paths) { %w(path/to/file.txt path/to path .)}
313
+ it_behaves_like 'ascend'
314
+ end
315
+ end
316
+
317
+ describe '#as_relative' do
318
+ subject { Path(path).as_relative }
319
+
320
+ context 'with absolute path' do
321
+ let(:path) { '/path/to/file.txt' }
322
+ it { should eq 'path/to/file.txt' }
323
+ end
324
+
325
+ context 'with relative path' do
326
+ let(:path) { 'path/to/file.txt' }
327
+ it { should eq 'path/to/file.txt' }
328
+ end
329
+
330
+ context 'with filename only' do
331
+ let(:path) { 'file.txt' }
332
+ it { should eq 'file.txt' }
333
+ end
334
+ end
335
+
336
+ describe '#as_absolute' do
337
+ subject { Path(path).as_absolute }
338
+
339
+ context 'with absolute path' do
340
+ let(:path) { '/path/to/file.txt' }
341
+ it { should eq '/path/to/file.txt' }
342
+ end
343
+
344
+ context 'with relative path' do
345
+ let(:path) { 'path/to/file.txt' }
346
+ it { should eq '/path/to/file.txt' }
347
+ end
348
+
349
+ context 'with filename only' do
350
+ let(:path) { 'file.txt' }
351
+ it { should eq '/file.txt' }
352
+ end
353
+ end
354
+
355
+ describe_method :ancestors do
356
+ shared_examples 'ancestors' do
357
+ subject { path.send described_method }
358
+
359
+ it { should be_a Array }
360
+
361
+ it 'should contain part paths' do
362
+ expect{|b| subject.each &b }.to yield_successive_args *expected_paths
363
+ end
364
+
365
+ it 'should contain path objects' do
366
+ expect{|b| subject.each &b }.to yield_successive_args *expected_paths.map{ Path }
367
+ end
368
+ end
369
+
370
+ context 'with absolute path' do
371
+ let(:path) { Path '/path/to/file.txt' }
372
+ let(:expected_paths) { %w(/path/to/file.txt /path/to /path /)}
373
+ it_behaves_like 'ancestors'
374
+ end
375
+
376
+ context 'with relative path' do
377
+ let(:path) { Path 'path/to/file.txt' }
378
+ let(:expected_paths) { %w(path/to/file.txt path/to path .)}
379
+ it_behaves_like 'ancestors'
380
+ end
381
+ end
382
+ end
383
+ end
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+
3
+ describe Path do
4
+ describe 'Path Predicates' do
5
+ describe '#absolute?' do
6
+ subject { Path(path).absolute? }
7
+
8
+ context 'with absolute path' do
9
+ let(:path) { '/abs/path/to/file' }
10
+ it { should be true }
11
+ end
12
+
13
+ context 'with relative path' do
14
+ let(:path) { 'path/to/file' }
15
+ it { should be false }
16
+ end
17
+ end
18
+
19
+ describe '#relative?' do
20
+ subject { Path(path).relative? }
21
+
22
+ context 'with absolute path' do
23
+ let(:path) { '/abs/path/to/file' }
24
+ it { should be false }
25
+ end
26
+
27
+ context 'with relative path' do
28
+ let(:path) { 'path/to/file' }
29
+ it { should be true }
30
+ end
31
+ end
32
+
33
+ describe '#mountpoint?' do
34
+ let(:path) { Path('/tmp') }
35
+
36
+ context 'without args' do
37
+ it 'should invoke backend with current path' do
38
+ expect(Path::Backend.instance).to receive(:mountpoint?).with('/tmp').and_return(false)
39
+ path.mountpoint?
40
+ end
41
+ end
42
+
43
+ context 'with args' do
44
+ it 'should invoke backend with joined path' do
45
+ expect(Path::Backend.instance).to receive(:mountpoint?).with('/tmp/fuu').and_return(false)
46
+ path.mountpoint?('fuu')
47
+ end
48
+ end
49
+ end
50
+
51
+ describe_method :dotfile? do
52
+ subject { path.dotfile? }
53
+
54
+ context 'with dotfile' do
55
+ let(:path) { Path '.abc' }
56
+ it { should be true }
57
+ end
58
+
59
+ context 'with path to dotfile' do
60
+ let(:path) { Path '/apth/to/.abc' }
61
+ it { should be true }
62
+ end
63
+
64
+ context 'with normal file' do
65
+ let(:path) { Path '/path/to/file' }
66
+ it { should be false }
67
+ end
68
+
69
+ context 'with path to file within a dotdir' do
70
+ let(:path) { Path '/home/user/.local/file' }
71
+ it { should be false }
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,42 @@
1
+ require 'rspec'
2
+
3
+ if ENV['CI'] || (defined?(:RUBY_ENGINE) && RUBY_ENGINE != 'rbx')
4
+ require 'coveralls'
5
+ Coveralls.wear! do
6
+ add_filter 'spec'
7
+ end
8
+ end
9
+
10
+ require 'bundler'
11
+ Bundler.require :default, :test
12
+
13
+ require 'rubypath'
14
+
15
+ Dir[File.expand_path('spec/support/**/*.rb')].each {|f| require f}
16
+
17
+ RSpec.configure do |config|
18
+ # ## Mock Framework
19
+ #
20
+ # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
21
+ #
22
+ # config.mock_with :mocha
23
+ # config.mock_with :flexmock
24
+ # config.mock_with :rr
25
+
26
+ # Run specs in random order to surface order dependencies. If you find an
27
+ # order dependency and want to debug it, you can fix the order by providing
28
+ # the seed, which is printed after each run.
29
+ # --seed 1234
30
+ config.order = 'random'
31
+
32
+ # Raise error when using old :should expectation syntax.
33
+ config.raise_errors_for_deprecations!
34
+
35
+ config.around(:each) do |example|
36
+ Path::Backend.mock root: :tmp, &example
37
+ end
38
+
39
+ config.after do
40
+ Timecop.return
41
+ end
42
+ end
@@ -0,0 +1,18 @@
1
+ module DescribeMethod
2
+ def describe_aliases(*args, &block)
3
+ args.each do |mth|
4
+ name = (mth == args.first ? "##{mth}" : "##{mth} (alias of #{args.first})")
5
+
6
+ describe(name) do
7
+ let(:described_method) { mth }
8
+ module_eval &block
9
+ end
10
+ end
11
+ end
12
+
13
+ def describe_method(mth, opts = {}, &block)
14
+ describe_aliases *([mth] + (opts[:aliases] || []).to_ary), &block
15
+ end
16
+
17
+ RSpec.configure{|c| c.extend DescribeMethod }
18
+ end
@@ -0,0 +1,31 @@
1
+ module WithBackend
2
+
3
+ def with_backends(*args, &block)
4
+ args.each do |backend|
5
+ be = case backend
6
+ when :mock
7
+ lambda { |ex| Path::Backend.mock &ex }
8
+ when :sys
9
+ lambda { |ex| Path::Backend.mock(root: :tmp, &ex) }
10
+ else
11
+ raise ArgumentError.new 'Unknown backend.'
12
+ end
13
+
14
+ describe "with #{backend.upcase} FS" do
15
+ let(:backend_type) { backend }
16
+ around do |example|
17
+ be.call(example)
18
+ end
19
+
20
+ module_eval &block
21
+ end
22
+ end
23
+ end
24
+ alias_method :with_backend, :with_backends
25
+
26
+ def pending_backend(*args)
27
+ before { pending "Pending on #{backend_type} backend." if args.include? backend_type }
28
+ end
29
+
30
+ RSpec.configure{|c| c.extend WithBackend }
31
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rubypath
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jan Graichen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ description: Path library incorporating File, Dir, Pathname, IO methods as well as
28
+ a virtual mock filesystem.
29
+ email:
30
+ - jg@altimos.de
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - LICENSE.txt
36
+ - README.md
37
+ - doc/file.README.html
38
+ - lib/rubypath.rb
39
+ - lib/rubypath/backend.rb
40
+ - lib/rubypath/backend/mock.rb
41
+ - lib/rubypath/backend/sys.rb
42
+ - lib/rubypath/comparison.rb
43
+ - lib/rubypath/construction.rb
44
+ - lib/rubypath/dir_operations.rb
45
+ - lib/rubypath/extensions.rb
46
+ - lib/rubypath/file_operations.rb
47
+ - lib/rubypath/file_predicates.rb
48
+ - lib/rubypath/identity.rb
49
+ - lib/rubypath/io_operations.rb
50
+ - lib/rubypath/mock.rb
51
+ - lib/rubypath/path_operations.rb
52
+ - lib/rubypath/path_predicates.rb
53
+ - lib/rubypath/version.rb
54
+ - rubypath.gemspec
55
+ - spec/rubypath/comparison_spec.rb
56
+ - spec/rubypath/construction_spec.rb
57
+ - spec/rubypath/dir_operations_spec.rb
58
+ - spec/rubypath/extensions_spec.rb
59
+ - spec/rubypath/file_operations_spec.rb
60
+ - spec/rubypath/file_predicates_spec.rb
61
+ - spec/rubypath/identity_spec.rb
62
+ - spec/rubypath/io_operations_spec.rb
63
+ - spec/rubypath/path_operations_spec.rb
64
+ - spec/rubypath/path_predicates_spec.rb
65
+ - spec/spec_helper.rb
66
+ - spec/support/describe_method.rb
67
+ - spec/support/with_backend.rb
68
+ homepage: https://github.com/jgraichen/rubypath
69
+ licenses:
70
+ - LGPLv3
71
+ metadata: {}
72
+ post_install_message:
73
+ rdoc_options: []
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ requirements: []
87
+ rubyforge_project:
88
+ rubygems_version: 2.2.2
89
+ signing_key:
90
+ specification_version: 4
91
+ summary: Path library incorporating File, Dir, Pathname, IO methods as well as a virtual
92
+ mock filesystem.
93
+ test_files:
94
+ - spec/rubypath/comparison_spec.rb
95
+ - spec/rubypath/construction_spec.rb
96
+ - spec/rubypath/dir_operations_spec.rb
97
+ - spec/rubypath/extensions_spec.rb
98
+ - spec/rubypath/file_operations_spec.rb
99
+ - spec/rubypath/file_predicates_spec.rb
100
+ - spec/rubypath/identity_spec.rb
101
+ - spec/rubypath/io_operations_spec.rb
102
+ - spec/rubypath/path_operations_spec.rb
103
+ - spec/rubypath/path_predicates_spec.rb
104
+ - spec/spec_helper.rb
105
+ - spec/support/describe_method.rb
106
+ - spec/support/with_backend.rb
107
+ has_rdoc: