io 0.0.1
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.
- data/Rakefile +10 -0
- data/lib/vfs.rb +20 -0
- data/lib/vfs/drivers/local.rb +175 -0
- data/lib/vfs/drivers/specification.rb +169 -0
- data/lib/vfs/entries/dir.rb +253 -0
- data/lib/vfs/entries/entry.rb +147 -0
- data/lib/vfs/entries/file.rb +154 -0
- data/lib/vfs/entries/universal_entry.rb +24 -0
- data/lib/vfs/entry_proxy.rb +42 -0
- data/lib/vfs/error.rb +4 -0
- data/lib/vfs/integration.rb +30 -0
- data/lib/vfs/path.rb +125 -0
- data/lib/vfs/vfs.rb +38 -0
- data/readme.md +119 -0
- data/spec/container_spec.rb +31 -0
- data/spec/dir_spec.rb +249 -0
- data/spec/entry_spec.rb +42 -0
- data/spec/file_spec.rb +210 -0
- data/spec/misc_spec.rb +19 -0
- data/spec/path_spec.rb +125 -0
- data/spec/spec_helper.rb +50 -0
- data/spec/storages/local_spec.rb +24 -0
- data/spec/storages/local_spec/emptygit +0 -0
- data/spec/universal_entry_spec.rb +73 -0
- metadata +68 -0
data/spec/file_spec.rb
ADDED
@@ -0,0 +1,210 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'File' do
|
4
|
+
with_test_dir
|
5
|
+
|
6
|
+
before do
|
7
|
+
@path = test_dir['a/b/c']
|
8
|
+
end
|
9
|
+
|
10
|
+
describe 'existence' do
|
11
|
+
it "should check only files" do
|
12
|
+
@path.should_not exist
|
13
|
+
@path.dir.create
|
14
|
+
@path.should be_dir
|
15
|
+
@path.file.should_not exist
|
16
|
+
@path.file.create
|
17
|
+
@path.should be_file
|
18
|
+
@path.file.should exist
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe 'read' do
|
23
|
+
it 'should raise error if not exist' do
|
24
|
+
-> {@path.read}.should raise_error(Vfs::Error, /not exist/)
|
25
|
+
-> {@path.read{|buff|}}.should raise_error(Vfs::Error, /not exist/)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should not raise error in silent mode' do
|
29
|
+
@path.read(bang: false).should == ''
|
30
|
+
data = ""; @path.read(bang: false){|buff| data << buff}; data.should == ''
|
31
|
+
end
|
32
|
+
|
33
|
+
it "reading" do
|
34
|
+
@path.write('something')
|
35
|
+
|
36
|
+
@path.read.should == 'something'
|
37
|
+
@path.read(bang: false).should == 'something'
|
38
|
+
data = ""; @path.read{|buff| data << buff}; data.should == 'something'
|
39
|
+
end
|
40
|
+
|
41
|
+
# it 'content' do
|
42
|
+
# @path.write('something')
|
43
|
+
# @path.content.should == 'something'
|
44
|
+
# end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe 'creation' do
|
48
|
+
it 'create' do
|
49
|
+
file = @path.file
|
50
|
+
|
51
|
+
file.should_receive(:write).with('', {})
|
52
|
+
file.create
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should be chainable' do
|
56
|
+
@path.file.create.should == @path
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe 'write' do
|
61
|
+
it 'should create parent dirs if not exists' do
|
62
|
+
@path.parent.should_not exist
|
63
|
+
@path.write 'something'
|
64
|
+
@path.read.should == 'something'
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'should override existing file' do
|
68
|
+
@path.write 'something'
|
69
|
+
@path.should be_file
|
70
|
+
@path.write 'other'
|
71
|
+
@path.read.should == 'other'
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'should override existing dir' do
|
75
|
+
@path.dir.create
|
76
|
+
@path.should be_dir
|
77
|
+
@path.write 'another'
|
78
|
+
@path.read.should == 'another'
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'writing' do
|
82
|
+
@path.write 'something'
|
83
|
+
@path.read.should == 'something'
|
84
|
+
|
85
|
+
@path.write do |writer|
|
86
|
+
writer.write 'another'
|
87
|
+
end
|
88
|
+
@path.read.should == 'another'
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'append' do
|
92
|
+
file = @path.file
|
93
|
+
file.should_receive(:write).with('something', append: true)
|
94
|
+
file.append 'something'
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'should correctly display errors (from error)' do
|
98
|
+
-> {test_dir['test'].write{|writer| raise 'some error'}}.should raise_error(/some error/)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'update' do
|
103
|
+
@path.write 'something'
|
104
|
+
@path.update do |data|
|
105
|
+
data.should == 'something'
|
106
|
+
'another'
|
107
|
+
end
|
108
|
+
@path.read.should == 'another'
|
109
|
+
end
|
110
|
+
|
111
|
+
describe 'copying' do
|
112
|
+
before do
|
113
|
+
@from = @path.file
|
114
|
+
@from.write('something')
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'should not copy to itself' do
|
118
|
+
-> {@from.copy_to @from}.should raise_error(Vfs::Error, /itself/)
|
119
|
+
end
|
120
|
+
|
121
|
+
def check_copy_for to
|
122
|
+
target = @from.copy_to to
|
123
|
+
target.read.should == 'something'
|
124
|
+
target.should == to
|
125
|
+
|
126
|
+
# overriding
|
127
|
+
@from.write 'another'
|
128
|
+
target = @from.copy_to to
|
129
|
+
target.read.should == 'another'
|
130
|
+
target.should == to
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'should copy to file (and overwrite)' do
|
134
|
+
check_copy_for test_dir.file('to')
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'should copy to dir (and overwrite)' do
|
138
|
+
check_copy_for test_dir.dir("to")
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'should copy to UniversalEntry (and overwrite)' do
|
142
|
+
check_copy_for test_dir.entry('to')
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'should be chainable' do
|
146
|
+
to = test_dir['to']
|
147
|
+
@from.copy_to(to).should == to
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should autocreate parent's path if not exist (from error)" do
|
151
|
+
to = test_dir['parent_path/to']
|
152
|
+
@from.copy_to(to)
|
153
|
+
to.read.should == 'something'
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
describe 'moving' do
|
158
|
+
it 'move_to' do
|
159
|
+
from, to = @path.file('from'), @path.file('to')
|
160
|
+
from.should_receive(:copy_to).with(to)
|
161
|
+
from.should_receive(:destroy).with()
|
162
|
+
from.move_to to
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'should be chainable' do
|
166
|
+
from, to = @path.file('from').create, @path.file('to')
|
167
|
+
from.move_to(to).should == to
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
describe 'destroying' do
|
172
|
+
it "should not raise error if it's trying to destroy a dir" do
|
173
|
+
@path.dir.create
|
174
|
+
@path.file.destroy
|
175
|
+
@path.entry.should_not exist
|
176
|
+
end
|
177
|
+
|
178
|
+
it "shouldn't raise if file not exist" do
|
179
|
+
@path.file.destroy
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'should be chainable' do
|
183
|
+
@path.file.destroy.should == @path
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
describe "extra stuff" do
|
188
|
+
it 'render' do
|
189
|
+
template = test_dir / 'letter.erb'
|
190
|
+
template.write "Hello dear <%= name %>"
|
191
|
+
template.render(name: 'Mary').should == "Hello dear Mary"
|
192
|
+
end
|
193
|
+
|
194
|
+
begin
|
195
|
+
require 'haml'
|
196
|
+
|
197
|
+
it 'render using other template engines' do
|
198
|
+
template = test_dir / 'letter.haml'
|
199
|
+
template.write "Hello dear \#{name}"
|
200
|
+
template.render(name: 'Mary').should =~ /Hello dear Mary/
|
201
|
+
end
|
202
|
+
rescue LoadError
|
203
|
+
warn "no :haml template engine, skipping rendering with haml specs"
|
204
|
+
end
|
205
|
+
|
206
|
+
it 'size' do
|
207
|
+
@path.file.write('data').size.should == 4
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
data/spec/misc_spec.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Miscellaneous' do
|
4
|
+
with_test_dir
|
5
|
+
|
6
|
+
it "File should respond to :to_file, :to_entry" do
|
7
|
+
path = "#{test_dir.path}/file"
|
8
|
+
File.open(path, 'w'){|f| f.write 'something'}
|
9
|
+
|
10
|
+
file = nil
|
11
|
+
begin
|
12
|
+
file = File.open path
|
13
|
+
file.to_file.path.should == file.path
|
14
|
+
file.to_entry.path.should == file.path
|
15
|
+
ensure
|
16
|
+
file.close
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/spec/path_spec.rb
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Path" do
|
4
|
+
before(:all){Path = Vfs::Path}
|
5
|
+
after(:all){remove_constants :Path}
|
6
|
+
|
7
|
+
it 'validations' do
|
8
|
+
%w(
|
9
|
+
/
|
10
|
+
/a
|
11
|
+
/a/b/c
|
12
|
+
/a/../c
|
13
|
+
/a/...
|
14
|
+
~/a
|
15
|
+
./a
|
16
|
+
/~a
|
17
|
+
/a~b
|
18
|
+
/a.b~
|
19
|
+
).each{|path| Path.should be_valid(path)}
|
20
|
+
|
21
|
+
special = ['']
|
22
|
+
(%w(
|
23
|
+
/a/~/c
|
24
|
+
/a/./c
|
25
|
+
/a/
|
26
|
+
~/
|
27
|
+
./
|
28
|
+
) + special).each{|path| Path.should_not be_valid(path)}
|
29
|
+
end
|
30
|
+
|
31
|
+
# it 'tmp' do
|
32
|
+
# (Path.new('.') + '..').should == './..'
|
33
|
+
# end
|
34
|
+
|
35
|
+
it 'normalize' do
|
36
|
+
special = ['/a/../..', nil]
|
37
|
+
(%w(
|
38
|
+
/a /a
|
39
|
+
~/a ~/a
|
40
|
+
./a ./a
|
41
|
+
/a/../c /c
|
42
|
+
/ /
|
43
|
+
~ ~
|
44
|
+
/a~/b /a~/b
|
45
|
+
. .
|
46
|
+
) + special).each_slice(2) do |path, normalized_path|
|
47
|
+
Path.normalize(path).should == normalized_path
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it "+" do
|
52
|
+
special = [
|
53
|
+
'/a', '../..', nil,
|
54
|
+
'/', '..', nil,
|
55
|
+
'.', '..', './..',
|
56
|
+
]
|
57
|
+
(%w(
|
58
|
+
/ /a /a
|
59
|
+
/ ~/a ~/a
|
60
|
+
/ ./a ./a
|
61
|
+
/a b/c /a/b/c
|
62
|
+
/a/b/c ../d /a/b/d
|
63
|
+
) + special).each_slice(3) do |base, path, sum|
|
64
|
+
(Path.new(base) + path).should == sum
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'parent' do
|
69
|
+
special = [
|
70
|
+
'/', nil,
|
71
|
+
'~', nil,
|
72
|
+
'.', './..'
|
73
|
+
]
|
74
|
+
(%w(
|
75
|
+
/a/b/c /a/b
|
76
|
+
) + special).each_slice(2) do |path, parent|
|
77
|
+
Path.new(path).parent.should == parent
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should raise error if current dir outside of root" do
|
82
|
+
-> {Path.new('/a/../..')}.should raise_error(/outside.*root/)
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should guess if current dir is a dir" do
|
86
|
+
[
|
87
|
+
'/a', false,
|
88
|
+
'/', true,
|
89
|
+
'~', true,
|
90
|
+
'.', true,
|
91
|
+
'/a/..', true,
|
92
|
+
'/a/../b', false,
|
93
|
+
].each_slice 2 do |path, result|
|
94
|
+
Path.new(path).probably_dir?.should == result
|
95
|
+
end
|
96
|
+
|
97
|
+
path = Path.new('/a/b/c')
|
98
|
+
[
|
99
|
+
path, false,
|
100
|
+
(path + '..'), true,
|
101
|
+
path.parent, true,
|
102
|
+
|
103
|
+
(path + '/'), true,
|
104
|
+
(path + '/a'), false,
|
105
|
+
].each_slice 2 do |path, result|
|
106
|
+
path.probably_dir?.should == result
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'name' do
|
111
|
+
%w(
|
112
|
+
/a a
|
113
|
+
/a/b/c c
|
114
|
+
/ /
|
115
|
+
~ ~
|
116
|
+
. .
|
117
|
+
).each_slice 2 do |path, name|
|
118
|
+
Path.new(path).name.should == name
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'to_s' do
|
123
|
+
Path.new.to_s.class.should == String
|
124
|
+
end
|
125
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'rspec_ext'
|
2
|
+
require 'ruby_ext'
|
3
|
+
|
4
|
+
require 'tilt'
|
5
|
+
require 'vfs'
|
6
|
+
|
7
|
+
rspec do
|
8
|
+
def self.with_test_dir
|
9
|
+
before do
|
10
|
+
@test_dir = "/tmp/test_dir".to_dir
|
11
|
+
|
12
|
+
FileUtils.rm_r test_dir.path if File.exist? test_dir.path
|
13
|
+
FileUtils.mkdir_p test_dir.path
|
14
|
+
end
|
15
|
+
|
16
|
+
after do
|
17
|
+
FileUtils.rm_r test_dir.path if File.exist? test_dir.path
|
18
|
+
@test_dir = nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_dir
|
23
|
+
@test_dir
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# require 'fakefs/spec_helpers'
|
28
|
+
#
|
29
|
+
# include FakeFS::SpecHelpers
|
30
|
+
# use_fakefs self
|
31
|
+
#
|
32
|
+
#
|
33
|
+
# #
|
34
|
+
# # FakeFS fixes
|
35
|
+
# #
|
36
|
+
# FakeFS::File::Stat.class_eval do
|
37
|
+
# # there's also file? method defined on File::Stat
|
38
|
+
# def file?; !directory? end
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# FakeFS::File.class_eval do
|
42
|
+
# class << self
|
43
|
+
# # File.delete should raise error if it's directory
|
44
|
+
# alias_method :delete_without_bang, :delete
|
45
|
+
# def delete path
|
46
|
+
# raise Errno::EPERM, "Operation not permitted - #{path}" if directory?(path)
|
47
|
+
# delete_without_bang path
|
48
|
+
# end
|
49
|
+
# end
|
50
|
+
# end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'vfs/drivers/local'
|
2
|
+
require 'vfs/drivers/specification'
|
3
|
+
|
4
|
+
describe Vfs::Drivers::Local do
|
5
|
+
with_tmp_spec_dir
|
6
|
+
|
7
|
+
before do
|
8
|
+
@driver = Vfs::Drivers::Local.new spec_dir
|
9
|
+
@driver.open
|
10
|
+
end
|
11
|
+
|
12
|
+
after do
|
13
|
+
@driver.close
|
14
|
+
end
|
15
|
+
|
16
|
+
it_should_behave_like 'vfs driver basic'
|
17
|
+
it_should_behave_like 'vfs driver attributes basic'
|
18
|
+
it_should_behave_like 'vfs driver files'
|
19
|
+
it_should_behave_like 'vfs driver full attributes for files'
|
20
|
+
it_should_behave_like 'vfs driver dirs'
|
21
|
+
it_should_behave_like 'vfs driver full attributes for dirs'
|
22
|
+
it_should_behave_like 'vfs driver query'
|
23
|
+
it_should_behave_like 'vfs driver tmp dir'
|
24
|
+
end
|
File without changes
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'UniversalEntry' do
|
4
|
+
with_test_dir
|
5
|
+
|
6
|
+
before do
|
7
|
+
@path = test_dir['a/b/c']
|
8
|
+
end
|
9
|
+
|
10
|
+
describe 'existence' do
|
11
|
+
it "should check both files and dirs" do
|
12
|
+
@path.should_not exist
|
13
|
+
@path.dir.create
|
14
|
+
@path.should be_dir
|
15
|
+
@path.should exist
|
16
|
+
|
17
|
+
@path.file.create
|
18
|
+
@path.should be_file
|
19
|
+
@path.should exist
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe 'destroying' do
|
24
|
+
it "should destroy both files and dirs" do
|
25
|
+
@path.dir.create
|
26
|
+
@path.should be_dir
|
27
|
+
@path.destroy
|
28
|
+
@path.should_not exist
|
29
|
+
|
30
|
+
@path.file.create
|
31
|
+
@path.should be_file
|
32
|
+
@path.destroy
|
33
|
+
@path.should_not exist
|
34
|
+
|
35
|
+
@path.file.create
|
36
|
+
@path.destroy
|
37
|
+
@path.file.should_not exist
|
38
|
+
end
|
39
|
+
|
40
|
+
it "shouldn't raise if file not exist" do
|
41
|
+
@path.destroy
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe 'copy_to' do
|
46
|
+
before do
|
47
|
+
@from = @path.dir
|
48
|
+
@from.create
|
49
|
+
@from.file('file').write 'something'
|
50
|
+
@from.dir('dir').create.tap do |dir|
|
51
|
+
dir.file('file2').write 'something2'
|
52
|
+
end
|
53
|
+
|
54
|
+
@to = test_dir['to']
|
55
|
+
end
|
56
|
+
|
57
|
+
it "shoud copy dir" do
|
58
|
+
@from.entry.copy_to @to
|
59
|
+
@to['dir/file2'].file?.should be_true
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should copy file" do
|
63
|
+
@from['file'].entry.copy_to @to
|
64
|
+
@to.file.should be_true
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should raise if entry not exist" do
|
68
|
+
-> {@from['non existing'].entry.copy_to @to}.should raise_error(/not exist/)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe 'move_to'
|
73
|
+
end
|