fspath 2.1.1 → 3.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.
- checksums.yaml +8 -8
- data/.appveyor.yml +20 -0
- data/.rubocop.yml +8 -2
- data/.travis.yml +3 -3
- data/LICENSE.txt +1 -1
- data/README.markdown +34 -8
- data/fspath.gemspec +1 -1
- data/lib/fspath.rb +55 -7
- data/spec/fspath_spec.rb +224 -93
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YWYxMDFiMmI4MTkyOGMyYTEzNjkwODA4Njk0ZDRlOTc3MTZjYTIzZQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NGYwZDllNTE0MDdkYmY1NWMyYmFmMjIwMTRiZjg3ZmEzMjk4YjM4OQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZmVmOGJkY2NjMzlkODE2N2M4MjI0ZDViZTdjMTdlYzIyYTRmNTk1ZDE1ZGYz
|
10
|
+
NGIwMWE5ZmEwODQ5NGEyYzQ5MWZjYzI3ZDgwMmZlMzI0MjFlM2EyM2JiYjVm
|
11
|
+
MTkyZDYyMzkzODcyMWU3ZmY3ZjlkZDIzY2UwMmMxMTM3YWJmYjM=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YmEwNWIzNDdkMTUyNDczZDAyNDQ5MjFkZjBlZjY0OWNmMzFjMDA3NWQ1MWY2
|
14
|
+
ZDM4ODI0NDUwM2NmNTNjZGRmYzBkYjQzZmY4ZGU2MDk2NjQzZDFkMzY4ZmJk
|
15
|
+
NDQ2MzJhNzJhNGIxYjhjMTRlY2U5OTU4OWQ3ODRiMTE5YzllOGE=
|
data/.appveyor.yml
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
version: '{build}-{branch}'
|
2
|
+
install:
|
3
|
+
- bundle config path vendor/bundle
|
4
|
+
- bundle install -j4
|
5
|
+
build: off
|
6
|
+
test_script:
|
7
|
+
- ps: |
|
8
|
+
$path = $env:Path
|
9
|
+
$rubypaths = ls -Path C:\Ruby*\bin
|
10
|
+
$ErrorActionPreference = "Stop"
|
11
|
+
foreach ($rubypath in $rubypaths) {
|
12
|
+
echo "################################################################################"
|
13
|
+
$env:Path = "$rubypath;" + $path
|
14
|
+
ruby --version
|
15
|
+
bundle exec rspec
|
16
|
+
if ($LASTEXITCODE -gt 0) {
|
17
|
+
exit 1
|
18
|
+
}
|
19
|
+
}
|
20
|
+
$env:Path = $path
|
data/.rubocop.yml
CHANGED
@@ -6,7 +6,7 @@ Lint/EndAlignment:
|
|
6
6
|
AlignWith: variable
|
7
7
|
|
8
8
|
Metrics/ClassLength:
|
9
|
-
Max:
|
9
|
+
Max: 200
|
10
10
|
|
11
11
|
Metrics/MethodLength:
|
12
12
|
Max: 15
|
@@ -49,11 +49,17 @@ Style/PercentLiteralDelimiters:
|
|
49
49
|
Style/Semicolon:
|
50
50
|
AllowAsExpressionSeparator: true
|
51
51
|
|
52
|
+
Style/SignalException:
|
53
|
+
EnforcedStyle: semantic
|
54
|
+
|
52
55
|
Style/SpaceBeforeBlockBraces:
|
53
56
|
EnforcedStyle: no_space
|
54
57
|
|
55
58
|
Style/SpaceInsideHashLiteralBraces:
|
56
59
|
EnforcedStyle: no_space
|
57
60
|
|
58
|
-
Style/
|
61
|
+
Style/TrailingCommaInArguments:
|
62
|
+
EnforcedStyleForMultiline: no_comma
|
63
|
+
|
64
|
+
Style/TrailingCommaInLiteral:
|
59
65
|
EnforcedStyleForMultiline: comma
|
data/.travis.yml
CHANGED
data/LICENSE.txt
CHANGED
data/README.markdown
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
[](https://rubygems.org/gems/fspath)
|
2
2
|
[](https://travis-ci.org/toy/fspath)
|
3
|
+
[](https://ci.appveyor.com/project/toy/fspath)
|
3
4
|
[](https://codeclimate.com/github/toy/fspath)
|
4
5
|
[](https://gemnasium.com/toy/fspath)
|
5
|
-
[](https://inch-ci.org/github/toy/fspath)
|
6
7
|
|
7
8
|
# fspath
|
8
9
|
|
@@ -24,17 +25,42 @@ Common dir for paths:
|
|
24
25
|
|
25
26
|
FSPath.common_dir('/a/b/c/d/e/f', '/a/b/c/1/hello', '/a/b/c/2/world') # => FSPath('/a/b/c')
|
26
27
|
|
27
|
-
|
28
|
+
Temp file (args are passed to `Tempfile.new`):
|
28
29
|
|
29
|
-
FSPath
|
30
|
+
FSPath.temp_file{ |f| …; p f.path; … }
|
31
|
+
|
32
|
+
f = FSPath.temp_file
|
33
|
+
…
|
34
|
+
f.close
|
35
|
+
|
36
|
+
Temp file path (args are passed to `Tempfile.new`):
|
37
|
+
|
38
|
+
FSPath.temp_file_path{ |path| …; p path; … }
|
39
|
+
|
40
|
+
path = FSPath.temp_file_path
|
41
|
+
…
|
42
|
+
# file will be removed on next GC run if reference to path is lost
|
30
43
|
|
31
|
-
|
44
|
+
Temp directory (args are passed to `Dir.mktmpdir`):
|
32
45
|
|
33
|
-
FSPath
|
46
|
+
FSPath.temp_dir{ |dir| …; p dir; … }
|
47
|
+
|
48
|
+
dir = FSPath.temp_dir
|
49
|
+
…
|
50
|
+
# the dir is not removed when temp_dir is run without block
|
51
|
+
|
52
|
+
Join paths:
|
53
|
+
|
54
|
+
FSPath('a') / 'b' / 'c' # => FSPath('a/b/c')
|
34
55
|
|
35
|
-
|
56
|
+
Read/write:
|
36
57
|
|
37
|
-
FSPath('a').
|
58
|
+
FSPath('a.txt').read
|
59
|
+
FSPath('b.bin').binread
|
60
|
+
FSPath('a.txt').write(text)
|
61
|
+
FSPath('b.bin').binwrite(data)
|
62
|
+
FSPath('a.txt').append(more_text)
|
63
|
+
FSPath('b.bin').binappend(more_data)
|
38
64
|
|
39
65
|
Escape glob:
|
40
66
|
|
@@ -60,4 +86,4 @@ Path parts:
|
|
60
86
|
|
61
87
|
## Copyright
|
62
88
|
|
63
|
-
Copyright (c) 2010-
|
89
|
+
Copyright (c) 2010-2016 Ivan Kuchin. See LICENSE.txt for details.
|
data/fspath.gemspec
CHANGED
data/lib/fspath.rb
CHANGED
@@ -64,6 +64,7 @@ class FSPath < Pathname
|
|
64
64
|
def temp_file_path(*args)
|
65
65
|
if block_given?
|
66
66
|
temp_file(*args) do |file|
|
67
|
+
file.close
|
67
68
|
yield file.path
|
68
69
|
end
|
69
70
|
else
|
@@ -104,15 +105,39 @@ class FSPath < Pathname
|
|
104
105
|
self.class.new(super(self.class.new(other)))
|
105
106
|
end
|
106
107
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
108
|
+
unless Pathname.method_defined?(:binread)
|
109
|
+
# Read data from file opened in binary mode
|
110
|
+
def binread(length = nil, offset = nil)
|
111
|
+
open('rb') do |f|
|
112
|
+
f.seek(offset) if offset
|
113
|
+
f.read(length)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
unless Pathname.method_defined?(:write)
|
119
|
+
# Write data to file
|
120
|
+
def write(data, offset = nil)
|
121
|
+
_write(data, offset, false)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
unless Pathname.method_defined?(:binwrite)
|
126
|
+
# Write data to file opened in binary mode
|
127
|
+
def binwrite(data, offset = nil)
|
128
|
+
_write(data, offset, true)
|
111
129
|
end
|
112
130
|
end
|
113
131
|
|
114
132
|
# Append data to file
|
115
133
|
def append(data)
|
134
|
+
open('a') do |f|
|
135
|
+
f.write(data)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
# Append data to file opened in binary mode
|
140
|
+
def binappend(data)
|
116
141
|
open('ab') do |f|
|
117
142
|
f.write(data)
|
118
143
|
end
|
@@ -164,15 +189,22 @@ class FSPath < Pathname
|
|
164
189
|
end
|
165
190
|
|
166
191
|
# Returns path parts
|
192
|
+
# FSPath('/a/b/c').parts # ['/', 'a', 'b', 'c']
|
193
|
+
# FSPath('a/b/c').parts # ['a', 'b', 'c']
|
194
|
+
# FSPath('./a/b/c').parts # ['.', 'a', 'b', 'c']
|
195
|
+
# FSPath('a/../b/c').parts # ['a', '..', 'b', 'c']
|
167
196
|
def parts
|
168
|
-
split_names(@path)
|
197
|
+
prefix, parts = split_names(@path)
|
198
|
+
prefix.empty? ? parts : [prefix] + parts
|
169
199
|
end
|
170
200
|
|
171
201
|
unless pwd.is_a?(self)
|
172
202
|
# Fixing glob
|
173
203
|
def self.glob(*args)
|
174
204
|
if block_given?
|
175
|
-
super
|
205
|
+
super do |f|
|
206
|
+
yield new(f)
|
207
|
+
end
|
176
208
|
else
|
177
209
|
super.map{ |f| new(f) }
|
178
210
|
end
|
@@ -239,7 +271,9 @@ class FSPath < Pathname
|
|
239
271
|
|
240
272
|
# Fixing each_entry
|
241
273
|
def each_entry
|
242
|
-
super
|
274
|
+
super do |f|
|
275
|
+
yield self.class.new(f)
|
276
|
+
end
|
243
277
|
end
|
244
278
|
|
245
279
|
# Fixing entries
|
@@ -260,6 +294,20 @@ private
|
|
260
294
|
def escape_glob_string
|
261
295
|
@path.gsub(/([\*\?\[\]\{\}])/, '\\\\\1')
|
262
296
|
end
|
297
|
+
|
298
|
+
def _write(data, offset, binmode)
|
299
|
+
mode = if offset
|
300
|
+
Fcntl::O_CREAT | Fcntl::O_RDWR # fix for jruby 1.8 truncating with WRONLY
|
301
|
+
else
|
302
|
+
Fcntl::O_CREAT | Fcntl::O_WRONLY | Fcntl::O_TRUNC
|
303
|
+
end
|
304
|
+
|
305
|
+
open(mode) do |f|
|
306
|
+
f.binmode if binmode
|
307
|
+
f.seek(offset) if offset
|
308
|
+
f.write(data)
|
309
|
+
end
|
310
|
+
end
|
263
311
|
end
|
264
312
|
|
265
313
|
# Add FSPath method as alias to FSPath.new
|
data/spec/fspath_spec.rb
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
require 'fspath'
|
2
2
|
|
3
3
|
describe FSPath do
|
4
|
-
class ZPath < FSPath
|
4
|
+
class ZPath < FSPath; end
|
5
|
+
|
6
|
+
# check_have_symlink? from test/fileutils/test_fileutils.rb
|
7
|
+
def self.symlinks_supported?
|
8
|
+
File.symlink '', ''
|
9
|
+
rescue NotImplementedError, Errno::EACCES
|
10
|
+
false
|
11
|
+
rescue
|
12
|
+
true
|
5
13
|
end
|
6
14
|
|
7
15
|
it 'inherits from Pathname' do
|
@@ -12,17 +20,23 @@ describe FSPath do
|
|
12
20
|
expect(FSPath('.')).to eql(FSPath.new('.'))
|
13
21
|
end
|
14
22
|
|
15
|
-
describe '
|
23
|
+
describe '.~' do
|
16
24
|
it 'returns current user home directory' do
|
17
|
-
expect(
|
25
|
+
expect(File).to receive(:expand_path).
|
26
|
+
with('~').and_return('/home/this')
|
27
|
+
|
28
|
+
expect(FSPath.~).to eq(FSPath('/home/this'))
|
18
29
|
end
|
19
30
|
|
20
31
|
it 'returns other user home directory' do
|
21
|
-
expect(
|
32
|
+
expect(File).to receive(:expand_path).
|
33
|
+
with('~root').and_return('/home/root')
|
34
|
+
|
35
|
+
expect(FSPath.~('root')).to eq(FSPath('/home/root'))
|
22
36
|
end
|
23
37
|
end
|
24
38
|
|
25
|
-
describe 'common_dir' do
|
39
|
+
describe '.common_dir' do
|
26
40
|
it 'returns dirname if called with one path' do
|
27
41
|
expect(FSPath.common_dir('/a/b/c')).to eq(FSPath('/a/b'))
|
28
42
|
end
|
@@ -37,52 +51,83 @@ describe FSPath do
|
|
37
51
|
end
|
38
52
|
end
|
39
53
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
54
|
+
describe '.temp_file' do
|
55
|
+
[FSPath, ZPath].each do |klass|
|
56
|
+
context "when called on #{klass}" do
|
57
|
+
it "returns Tempfile with path returning instance of #{klass}" do
|
58
|
+
expect(klass.temp_file).to be_kind_of(Tempfile)
|
59
|
+
expect(klass.temp_file.path).to be_kind_of(klass)
|
60
|
+
end
|
46
61
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
62
|
+
it "yields Tempfile with path returning instance of #{klass}" do
|
63
|
+
yielded = nil
|
64
|
+
klass.temp_file{ |y| yielded = y }
|
65
|
+
expect(yielded).to be_kind_of(Tempfile)
|
66
|
+
expect(yielded.path).to be_kind_of(klass)
|
67
|
+
end
|
52
68
|
end
|
69
|
+
end
|
53
70
|
|
54
|
-
|
55
|
-
|
56
|
-
|
71
|
+
it 'returns result of block' do
|
72
|
+
expect(FSPath.temp_file{ :result }).to eq(:result)
|
73
|
+
end
|
57
74
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
75
|
+
it 'calls appropriate initializer (jruby 1.8 mode bug)' do
|
76
|
+
expect do
|
77
|
+
FSPath.temp_file('abc', '.'){}
|
78
|
+
end.not_to raise_error
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe '.temp_file_path' do
|
83
|
+
[FSPath, ZPath].each do |klass|
|
84
|
+
context "when called on #{klass}" do
|
85
|
+
it "returns an instance of #{klass} with temporary path" do
|
86
|
+
expect(klass.temp_file_path).to be_kind_of(klass)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "yields an instance of #{klass} with temporary path" do
|
90
|
+
yielded = nil
|
91
|
+
klass.temp_file_path{ |y| yielded = y }
|
92
|
+
expect(yielded).to be_kind_of(klass)
|
93
|
+
end
|
62
94
|
end
|
63
95
|
end
|
64
96
|
|
65
|
-
|
66
|
-
|
67
|
-
|
97
|
+
it 'does not allow GC to finalize TempFile' do
|
98
|
+
paths = Array.new(1000){ FSPath.temp_file_path }
|
99
|
+
expect(paths).to be_all(&:exist?)
|
100
|
+
GC.start
|
101
|
+
expect(paths).to be_all(&:exist?)
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'returns result of block' do
|
105
|
+
expect(FSPath.temp_file_path{ :result }).to eq(:result)
|
106
|
+
end
|
107
|
+
|
108
|
+
describe 'closing file handle' do
|
109
|
+
before do
|
110
|
+
@tempfile = nil
|
111
|
+
allow(FSPath::Tempfile).to receive(:new).once.
|
112
|
+
and_wrap_original{ |m, *args| @tempfile = m.call(*args) }
|
68
113
|
end
|
69
114
|
|
70
|
-
it 'does not
|
71
|
-
|
72
|
-
expect(
|
73
|
-
|
74
|
-
expect(paths).to be_all(&:exist?)
|
115
|
+
it 'closes the file handle, but does not unlink path before return' do
|
116
|
+
path = FSPath.temp_file_path
|
117
|
+
expect(@tempfile).to be_closed
|
118
|
+
expect(path).to exist
|
75
119
|
end
|
76
120
|
|
77
|
-
it
|
78
|
-
|
79
|
-
|
80
|
-
|
121
|
+
it 'closes the file handle, but does not unlink path before yield' do
|
122
|
+
FSPath.temp_file_path do |path|
|
123
|
+
expect(@tempfile).to be_closed
|
124
|
+
expect(path).to exist
|
125
|
+
end
|
81
126
|
end
|
82
127
|
end
|
83
128
|
end
|
84
129
|
|
85
|
-
describe 'temp_dir' do
|
130
|
+
describe '.temp_dir' do
|
86
131
|
it 'returns result of running Dir.mktmpdir as FSPath instance' do
|
87
132
|
@path = '/tmp/a/b/1'
|
88
133
|
allow(Dir).to receive(:mktmpdir).and_return(@path)
|
@@ -100,7 +145,7 @@ describe FSPath do
|
|
100
145
|
end
|
101
146
|
end
|
102
147
|
|
103
|
-
describe '
|
148
|
+
describe '#/' do
|
104
149
|
it 'joins path with string' do
|
105
150
|
expect(FSPath('a') / 'b').to eq(FSPath('a/b'))
|
106
151
|
end
|
@@ -114,7 +159,7 @@ describe FSPath do
|
|
114
159
|
end
|
115
160
|
end
|
116
161
|
|
117
|
-
describe '
|
162
|
+
describe '#+' do
|
118
163
|
it 'returns instance of FSPath' do
|
119
164
|
expect(FSPath('a') + 'b').to be_instance_of(FSPath)
|
120
165
|
end
|
@@ -128,7 +173,7 @@ describe FSPath do
|
|
128
173
|
end
|
129
174
|
end
|
130
175
|
|
131
|
-
describe 'relative_path_from' do
|
176
|
+
describe '#relative_path_from' do
|
132
177
|
it 'returns instance of FSPath' do
|
133
178
|
expect(FSPath('a').relative_path_from('b')).to be_instance_of(FSPath)
|
134
179
|
end
|
@@ -138,58 +183,136 @@ describe FSPath do
|
|
138
183
|
end
|
139
184
|
end
|
140
185
|
|
141
|
-
describe '
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
@data = double(:data)
|
146
|
-
@size = double(:size)
|
186
|
+
describe 'read/write' do
|
187
|
+
let(:path){ FSPath.temp_file_path }
|
188
|
+
let(:crlf_text){ "a\nb\rc\r\nd" }
|
189
|
+
let(:described_method){ |example| example.full_description[/#(\S+)/, 1] }
|
147
190
|
|
148
|
-
|
149
|
-
|
191
|
+
def binread(path)
|
192
|
+
path.open('rb', &:read)
|
150
193
|
end
|
151
194
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
195
|
+
def binwrite(path, data)
|
196
|
+
path.open('wb'){ |f| f.write(data) }
|
197
|
+
end
|
198
|
+
|
199
|
+
describe '#binread' do
|
200
|
+
it 'reads data' do
|
201
|
+
binwrite(path, 'data')
|
202
|
+
expect(path.binread).to eq('data')
|
203
|
+
end
|
204
|
+
|
205
|
+
it 'limits data when length is set' do
|
206
|
+
binwrite(path, 'data')
|
207
|
+
expect(path.binread(3)).to eq('dat')
|
156
208
|
end
|
157
209
|
|
210
|
+
it 'skips data when offset is set' do
|
211
|
+
binwrite(path, 'data')
|
212
|
+
expect(path.binread(nil, 1)).to eq('ata')
|
213
|
+
end
|
214
|
+
|
215
|
+
it 'skips and limits data when length and offset are set' do
|
216
|
+
binwrite(path, 'data')
|
217
|
+
expect(path.binread(2, 1)).to eq('at')
|
218
|
+
end
|
219
|
+
|
220
|
+
it 'opens file in binary mode' do
|
221
|
+
binwrite(path, crlf_text)
|
222
|
+
expect(path.binread).to eq(crlf_text)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
shared_examples 'writing' do
|
158
227
|
it 'writes data' do
|
159
|
-
|
160
|
-
|
228
|
+
path.send(described_method, 'data')
|
229
|
+
expect(path.read).to eq('data')
|
161
230
|
end
|
162
231
|
|
163
|
-
it 'returns
|
164
|
-
expect(
|
232
|
+
it 'returns the length of data written' do
|
233
|
+
expect(path.send(described_method, 'data')).to eq(4)
|
165
234
|
end
|
166
235
|
end
|
167
236
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
237
|
+
shared_examples 'overwriting' do
|
238
|
+
context 'when offset is not specified' do
|
239
|
+
it 'overwrites file' do
|
240
|
+
path.send(described_method, 'longer data')
|
241
|
+
path.send(described_method, 'data')
|
242
|
+
expect(path.read).to eq('data')
|
243
|
+
end
|
172
244
|
end
|
173
245
|
|
174
|
-
|
175
|
-
|
176
|
-
|
246
|
+
context 'when offset is specified' do
|
247
|
+
it 'overwrites part of file and does not truncate it' do
|
248
|
+
path.send(described_method, 'longer data')
|
249
|
+
path.send(described_method, 'data', 2)
|
250
|
+
expect(path.read).to eq('lodata data')
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
shared_examples 'appending' do
|
256
|
+
it 'appends data to the end of file' do
|
257
|
+
path.send(described_method, 'data')
|
258
|
+
path.send(described_method, 'more data')
|
259
|
+
expect(path.read).to eq('datamore data')
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
shared_examples 'writes in text mode' do
|
264
|
+
it 'opens file in text mode' do
|
265
|
+
test_path = FSPath.temp_file_path
|
266
|
+
test_path.open('w'){ |f| f.write(crlf_text) }
|
267
|
+
|
268
|
+
path.send(described_method, crlf_text)
|
269
|
+
expect(binread(path)).to eq(binread(test_path))
|
177
270
|
end
|
271
|
+
end
|
272
|
+
|
273
|
+
shared_examples 'writes in binary mode' do
|
274
|
+
it 'opens file in binary mode' do
|
275
|
+
test_path = FSPath.temp_file_path
|
276
|
+
test_path.open('wb'){ |f| f.write(crlf_text) }
|
178
277
|
|
179
|
-
|
180
|
-
expect(
|
278
|
+
path.send(described_method, crlf_text)
|
279
|
+
expect(binread(path)).to eq(binread(test_path))
|
181
280
|
end
|
182
281
|
end
|
282
|
+
|
283
|
+
describe '#write' do
|
284
|
+
include_examples 'writing'
|
285
|
+
include_examples 'overwriting'
|
286
|
+
include_examples 'writes in text mode'
|
287
|
+
end
|
288
|
+
|
289
|
+
describe '#binwrite' do
|
290
|
+
include_examples 'writing'
|
291
|
+
include_examples 'overwriting'
|
292
|
+
include_examples 'writes in binary mode'
|
293
|
+
end
|
294
|
+
|
295
|
+
describe '#append' do
|
296
|
+
include_examples 'writing'
|
297
|
+
include_examples 'appending'
|
298
|
+
include_examples 'writes in text mode'
|
299
|
+
end
|
300
|
+
|
301
|
+
describe '#binappend' do
|
302
|
+
include_examples 'writing'
|
303
|
+
include_examples 'appending'
|
304
|
+
include_examples 'writes in binary mode'
|
305
|
+
end
|
183
306
|
end
|
184
307
|
|
185
|
-
describe 'escape_glob' do
|
308
|
+
describe '#escape_glob' do
|
186
309
|
it 'escapes glob pattern characters' do
|
187
310
|
expect(FSPath('*/**/?[a-z]{abc,def}').escape_glob).
|
188
311
|
to eq(FSPath('\*/\*\*/\?\[a-z\]\{abc,def\}'))
|
189
312
|
end
|
190
313
|
end
|
191
314
|
|
192
|
-
describe 'glob' do
|
315
|
+
describe '#glob' do
|
193
316
|
it 'joins with arguments and expands glob' do
|
194
317
|
expect(FSPath).to receive(:glob).with('a/b/c/**/*')
|
195
318
|
FSPath('a/b/c').glob('**', '*')
|
@@ -209,63 +332,71 @@ describe FSPath do
|
|
209
332
|
|
210
333
|
describe 'path parts' do
|
211
334
|
describe 'ascending' do
|
212
|
-
|
213
|
-
|
214
|
-
@ascendants = %w[/a/b/c /a/b /a /].map(&method(:FSPath))
|
215
|
-
end
|
335
|
+
let(:path){ FSPath('/a/b/c') }
|
336
|
+
let(:expected){ %w[/a/b/c /a/b /a /].map(&method(:FSPath)) }
|
216
337
|
|
217
|
-
describe 'ascendants' do
|
338
|
+
describe '#ascendants' do
|
218
339
|
it 'returns list of ascendants' do
|
219
|
-
expect(
|
340
|
+
expect(path.ascendants).to eq(expected)
|
220
341
|
end
|
221
342
|
end
|
222
343
|
|
223
|
-
describe 'ascend' do
|
344
|
+
describe '#ascend' do
|
224
345
|
it 'returns list of ascendants' do
|
225
|
-
expect(
|
346
|
+
expect(path.ascend).to eq(expected)
|
226
347
|
end
|
227
348
|
|
228
349
|
it 'yields and returns list of ascendants if called with block' do
|
229
350
|
ascendants = []
|
230
|
-
expect(
|
231
|
-
ascendants <<
|
232
|
-
end).to eq(
|
233
|
-
expect(ascendants).to eq(
|
351
|
+
expect(path.ascend do |sub_path|
|
352
|
+
ascendants << sub_path
|
353
|
+
end).to eq(expected)
|
354
|
+
expect(ascendants).to eq(expected)
|
234
355
|
end
|
235
356
|
end
|
236
357
|
end
|
237
358
|
|
238
359
|
describe 'descending' do
|
239
|
-
|
240
|
-
|
241
|
-
@descendants = %w[/ /a /a/b /a/b/c].map(&method(:FSPath))
|
242
|
-
end
|
360
|
+
let(:path){ FSPath('/a/b/c') }
|
361
|
+
let(:expected){ %w[/ /a /a/b /a/b/c].map(&method(:FSPath)) }
|
243
362
|
|
244
|
-
describe 'descendants' do
|
363
|
+
describe '#descendants' do
|
245
364
|
it 'returns list of descendants' do
|
246
|
-
expect(
|
365
|
+
expect(path.descendants).to eq(expected)
|
247
366
|
end
|
248
367
|
end
|
249
368
|
|
250
|
-
describe 'descend' do
|
369
|
+
describe '#descend' do
|
251
370
|
it 'returns list of descendants' do
|
252
|
-
expect(
|
371
|
+
expect(path.descend).to eq(expected)
|
253
372
|
end
|
254
373
|
|
255
374
|
it 'yields and returns list of descendants if called with block' do
|
256
375
|
descendants = []
|
257
|
-
expect(
|
258
|
-
descendants <<
|
259
|
-
end).to eq(
|
260
|
-
expect(descendants).to eq(
|
376
|
+
expect(path.descend do |sub_path|
|
377
|
+
descendants << sub_path
|
378
|
+
end).to eq(expected)
|
379
|
+
expect(descendants).to eq(expected)
|
261
380
|
end
|
262
381
|
end
|
263
382
|
end
|
264
383
|
|
265
|
-
describe 'parts' do
|
266
|
-
it 'returns path parts
|
384
|
+
describe '#parts' do
|
385
|
+
it 'returns path parts for absolute path' do
|
267
386
|
expect(FSPath('/a/b/c').parts).to eq(%w[/ a b c])
|
268
387
|
end
|
388
|
+
|
389
|
+
it 'returns path parts for relative path' do
|
390
|
+
expect(FSPath('a/b/c').parts).to eq(%w[a b c])
|
391
|
+
end
|
392
|
+
|
393
|
+
it 'returns path parts for path prefixed with .' do
|
394
|
+
expect(FSPath('./a/b/c').parts).to eq(%w[. a b c])
|
395
|
+
end
|
396
|
+
|
397
|
+
it 'returns path parts for path containing ..' do
|
398
|
+
expect(FSPath('a/../b/c').parts).to eq(%w[a .. b c])
|
399
|
+
end
|
269
400
|
end
|
270
401
|
end
|
271
402
|
|
@@ -343,7 +474,7 @@ describe FSPath do
|
|
343
474
|
symlink.make_symlink __FILE__
|
344
475
|
fspath? symlink.readlink
|
345
476
|
end
|
346
|
-
end
|
477
|
+
end if symlinks_supported?
|
347
478
|
|
348
479
|
it 'uses FSPath for realdirpath' do
|
349
480
|
fspath? FSPath(__FILE__).realdirpath
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fspath
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ivan Kuchin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-07-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -44,6 +44,7 @@ executables: []
|
|
44
44
|
extensions: []
|
45
45
|
extra_rdoc_files: []
|
46
46
|
files:
|
47
|
+
- .appveyor.yml
|
47
48
|
- .gitignore
|
48
49
|
- .rubocop.yml
|
49
50
|
- .travis.yml
|
@@ -73,7 +74,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
73
74
|
version: '0'
|
74
75
|
requirements: []
|
75
76
|
rubyforge_project: fspath
|
76
|
-
rubygems_version: 2.4
|
77
|
+
rubygems_version: 2.6.4
|
77
78
|
signing_key:
|
78
79
|
specification_version: 4
|
79
80
|
summary: Better than Pathname
|