memfs 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.
- checksums.yaml +7 -0
- data/.DS_Store +0 -0
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.travis.yml +3 -0
- data/Gemfile +4 -0
- data/Guardfile +8 -0
- data/LICENSE.txt +22 -0
- data/README.md +128 -0
- data/Rakefile +6 -0
- data/lib/fileutils.rb +1738 -0
- data/lib/memfs/dir.rb +33 -0
- data/lib/memfs/fake/directory.rb +51 -0
- data/lib/memfs/fake/entry.rb +73 -0
- data/lib/memfs/fake/file/content.rb +47 -0
- data/lib/memfs/fake/file.rb +36 -0
- data/lib/memfs/fake/symlink.rb +32 -0
- data/lib/memfs/file/stat.rb +48 -0
- data/lib/memfs/file.rb +284 -0
- data/lib/memfs/file_system.rb +157 -0
- data/lib/memfs/filesystem_access.rb +7 -0
- data/lib/memfs/version.rb +3 -0
- data/lib/memfs.rb +100 -0
- data/memfs.gemspec +29 -0
- data/spec/fileutils_spec.rb +961 -0
- data/spec/memfs/dir_spec.rb +104 -0
- data/spec/memfs/fake/directory_spec.rb +115 -0
- data/spec/memfs/fake/entry_spec.rb +140 -0
- data/spec/memfs/fake/file/content_spec.rb +154 -0
- data/spec/memfs/fake/file_spec.rb +37 -0
- data/spec/memfs/fake/symlink_spec.rb +43 -0
- data/spec/memfs/file/stat_spec.rb +209 -0
- data/spec/memfs/file_spec.rb +928 -0
- data/spec/memfs/file_system_spec.rb +393 -0
- data/spec/memfs_spec.rb +54 -0
- data/spec/spec_helper.rb +20 -0
- metadata +203 -0
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module MemFs
|
4
|
+
describe Dir do
|
5
|
+
subject { MemFs::Dir }
|
6
|
+
|
7
|
+
before :each do
|
8
|
+
subject.mkdir '/test'
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '.chdir' do
|
12
|
+
it "changes the current working directory" do
|
13
|
+
subject.chdir '/test'
|
14
|
+
expect(subject.getwd).to eq('/test')
|
15
|
+
end
|
16
|
+
|
17
|
+
it "returns zero" do
|
18
|
+
expect(subject.chdir('/test')).to be_zero
|
19
|
+
end
|
20
|
+
|
21
|
+
it "raises an error when the folder does not exist" do
|
22
|
+
expect { subject.chdir('/nowhere') }.to raise_error(Errno::ENOENT)
|
23
|
+
end
|
24
|
+
|
25
|
+
context "when a block is given" do
|
26
|
+
it "changes current working directory for the block" do
|
27
|
+
subject.chdir '/test' do
|
28
|
+
expect(subject.pwd).to eq('/test')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
it "gets back to previous directory once the block is finished" do
|
33
|
+
subject.chdir '/'
|
34
|
+
previous_dir = subject.pwd
|
35
|
+
subject.chdir('/test') {}
|
36
|
+
expect(subject.pwd).to eq(previous_dir)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '.entries' do
|
42
|
+
it "returns an array containing all of the filenames in the given directory" do
|
43
|
+
%w[/test/dir1 /test/dir2].each { |dir| subject.mkdir dir }
|
44
|
+
fs.touch '/test/file1', '/test/file2'
|
45
|
+
expect(subject.entries('/test')).to eq(%w[. .. dir1 dir2 file1 file2])
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe ".exists?" do
|
50
|
+
it "returns true if the given +path+ exists and is a directory" do
|
51
|
+
subject.mkdir('/test-dir')
|
52
|
+
expect(subject.exists?('/test-dir')).to be_true
|
53
|
+
end
|
54
|
+
|
55
|
+
it "returns false if the given +path+ does not exist" do
|
56
|
+
expect(subject.exists?('/test-dir')).to be_false
|
57
|
+
end
|
58
|
+
|
59
|
+
it "returns false if the given +path+ is not a directory" do
|
60
|
+
fs.touch('/test-file')
|
61
|
+
expect(subject.exists?('/test-file')).to be_false
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe '.getwd' do
|
66
|
+
it "returns the path to the current working directory" do
|
67
|
+
expect(subject.getwd).to eq(FileSystem.instance.getwd)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe '.mkdir' do
|
72
|
+
it "creates a directory" do
|
73
|
+
subject.mkdir '/new-folder'
|
74
|
+
expect(File.directory?('/new-folder')).to be_true
|
75
|
+
end
|
76
|
+
|
77
|
+
context "when the directory already exist" do
|
78
|
+
it "raises an exception" do
|
79
|
+
expect { subject.mkdir('/') }.to raise_error(Errno::EEXIST)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe ".pwd" do
|
85
|
+
it_behaves_like 'aliased method', :pwd, :getwd
|
86
|
+
end
|
87
|
+
|
88
|
+
describe ".rmdir" do
|
89
|
+
it "deletes the named directory" do
|
90
|
+
subject.mkdir('/test-dir')
|
91
|
+
subject.rmdir('/test-dir')
|
92
|
+
expect(subject.exists?('/test-dir')).to be_false
|
93
|
+
end
|
94
|
+
|
95
|
+
context "when the directory is not empty" do
|
96
|
+
it "raises an exception" do
|
97
|
+
subject.mkdir('/test-dir')
|
98
|
+
subject.mkdir('/test-dir/test-sub-dir')
|
99
|
+
expect { subject.rmdir('/test-dir') }.to raise_error(Errno::ENOTEMPTY)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module MemFs
|
4
|
+
module Fake
|
5
|
+
describe Directory do
|
6
|
+
let(:directory) { Directory.new('/test') }
|
7
|
+
|
8
|
+
describe '.new' do
|
9
|
+
it "sets . in the entries list" do
|
10
|
+
expect(directory.entries).to include('.' => directory)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "sets .. in the entries list" do
|
14
|
+
expect(directory.entries).to have_key('..')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#add_entry' do
|
19
|
+
let(:entry) { Directory.new('new_entry') }
|
20
|
+
|
21
|
+
it "adds the entry to the entries list" do
|
22
|
+
directory.add_entry entry
|
23
|
+
expect(directory.entries).to include('new_entry' => entry)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "sets the parent of the added entry" do
|
27
|
+
directory.add_entry entry
|
28
|
+
expect(entry.parent).to be(directory)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "empty?" do
|
33
|
+
it "returns true if the directory is empty" do
|
34
|
+
expect(directory).to be_empty
|
35
|
+
end
|
36
|
+
|
37
|
+
it "returns false if the directory is not empty" do
|
38
|
+
directory.add_entry Directory.new('test')
|
39
|
+
expect(directory).not_to be_empty
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '#entry_names' do
|
44
|
+
it "returns the list of the names of the entries in the directory" do
|
45
|
+
3.times do |n|
|
46
|
+
directory.add_entry Directory.new("dir#{n}")
|
47
|
+
end
|
48
|
+
|
49
|
+
expect(directory.entry_names).to eq(%w[. .. dir0 dir1 dir2])
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe '#find' do
|
54
|
+
let(:sub_directory) { Directory.new('sub_dir') }
|
55
|
+
let(:file) { File.new('file') }
|
56
|
+
|
57
|
+
before :each do
|
58
|
+
sub_directory.add_entry file
|
59
|
+
directory.add_entry sub_directory
|
60
|
+
end
|
61
|
+
|
62
|
+
it "returns the named entry if it is one of the entries" do
|
63
|
+
expect(directory.find('sub_dir')).to be(sub_directory)
|
64
|
+
end
|
65
|
+
|
66
|
+
it "calls find on the next directory in the search chain" do
|
67
|
+
expect(directory.find('sub_dir/file')).to be(file)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should remove any leading / in the path" do
|
71
|
+
expect(directory.find('/sub_dir/file')).to be(file)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe '#parent=' do
|
76
|
+
let(:parent) { Directory.new('parent') }
|
77
|
+
|
78
|
+
it "sets the .. entry in entries list" do
|
79
|
+
directory.parent = parent
|
80
|
+
expect(directory.entries).to include('..' => parent)
|
81
|
+
end
|
82
|
+
|
83
|
+
it "sets the parent directory" do
|
84
|
+
directory.parent = parent
|
85
|
+
expect(directory.parent).to be(parent)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "#path" do
|
90
|
+
let(:root) { Directory.new('/') }
|
91
|
+
|
92
|
+
it "returns the directory path" do
|
93
|
+
directory.parent = root
|
94
|
+
expect(directory.path).to eq('/test')
|
95
|
+
end
|
96
|
+
|
97
|
+
context "when the directory is /" do
|
98
|
+
it "returns /" do
|
99
|
+
expect(root.path).to eq('/')
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe "#remove_entry" do
|
105
|
+
let(:file) { File.new('file') }
|
106
|
+
|
107
|
+
it "removes an entry from the entries list" do
|
108
|
+
directory.add_entry file
|
109
|
+
directory.remove_entry file
|
110
|
+
expect(directory.entries).not_to have_value(file)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module MemFs
|
4
|
+
module Fake
|
5
|
+
describe Entry do
|
6
|
+
let(:entry) { Entry.new('test') }
|
7
|
+
let(:parent) { Directory.new('parent') }
|
8
|
+
let(:time) { Time.now - 5000 }
|
9
|
+
|
10
|
+
before(:each) do
|
11
|
+
parent.parent = Directory.new('/')
|
12
|
+
entry.parent = parent
|
13
|
+
end
|
14
|
+
|
15
|
+
shared_examples 'it has accessors for' do |attribute|
|
16
|
+
let(:expected) { value }
|
17
|
+
|
18
|
+
it attribute do
|
19
|
+
entry.send(:"#{attribute}=", value)
|
20
|
+
expect(entry.public_send(attribute)).to eq(expected)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it_behaves_like 'it has accessors for', :name do
|
25
|
+
let(:value) { 'test' }
|
26
|
+
end
|
27
|
+
|
28
|
+
it_behaves_like 'it has accessors for', :atime do
|
29
|
+
let(:value) { time }
|
30
|
+
end
|
31
|
+
|
32
|
+
it_behaves_like 'it has accessors for', :mtime do
|
33
|
+
let(:value) { time }
|
34
|
+
end
|
35
|
+
|
36
|
+
it_behaves_like 'it has accessors for', :uid do
|
37
|
+
let(:value) { 42 }
|
38
|
+
end
|
39
|
+
|
40
|
+
it_behaves_like 'it has accessors for', :gid do
|
41
|
+
let(:value) { 42 }
|
42
|
+
end
|
43
|
+
|
44
|
+
it_behaves_like 'it has accessors for', :mode do
|
45
|
+
let(:value) { 0777 }
|
46
|
+
let(:expected) { 0100777 }
|
47
|
+
end
|
48
|
+
|
49
|
+
it_behaves_like 'it has accessors for', :parent do
|
50
|
+
let(:value) { parent }
|
51
|
+
end
|
52
|
+
|
53
|
+
describe ".delete" do
|
54
|
+
it "removes the entry from its parent" do
|
55
|
+
entry.delete
|
56
|
+
expect(parent.entries).not_to have_value(entry)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe '.dereferenced' do
|
61
|
+
it "returns the entry itself" do
|
62
|
+
expect(entry.dereferenced).to be(entry)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe '.find' do
|
67
|
+
it "raises an error" do
|
68
|
+
expect { entry.find('test') }.to raise_error(Errno::ENOTDIR)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe ".new" do
|
73
|
+
it "sets its default uid to the current user's uid" do
|
74
|
+
expect(entry.uid).to eq(Etc.getpwuid.uid)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "sets its default gid to the current user's gid" do
|
78
|
+
expect(entry.gid).to eq(Etc.getpwuid.gid)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "extract its name from the path passed as argument" do
|
82
|
+
expect(entry.name).to eq('test')
|
83
|
+
end
|
84
|
+
|
85
|
+
it "sets an empty string as name if none is given" do
|
86
|
+
expect(Entry.new.name).to be_empty
|
87
|
+
end
|
88
|
+
|
89
|
+
it "sets the access time" do
|
90
|
+
expect(Entry.new.atime).to be_a(Time)
|
91
|
+
end
|
92
|
+
|
93
|
+
it "sets the modification time" do
|
94
|
+
expect(entry.mtime).to be_a(Time)
|
95
|
+
end
|
96
|
+
|
97
|
+
it "sets atime and mtime to the same value" do
|
98
|
+
expect(entry.atime).to eq(entry.mtime)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe ".path" do
|
103
|
+
it "returns the complete path of the entry" do
|
104
|
+
expect(entry.path).to eq('/parent/test')
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "#dev" do
|
109
|
+
it "returns an integer representing the device on which the entry resides" do
|
110
|
+
expect(entry.dev).to be_a(Fixnum)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe "#ino" do
|
115
|
+
it "Returns the inode number for the entry" do
|
116
|
+
expect(entry.ino).to be_a(Fixnum)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe "#touch" do
|
121
|
+
let(:time) { Time.now - 5000 }
|
122
|
+
|
123
|
+
before :each do
|
124
|
+
entry.atime = time
|
125
|
+
entry.mtime = time
|
126
|
+
end
|
127
|
+
|
128
|
+
it "sets the access time to now" do
|
129
|
+
entry.touch
|
130
|
+
expect(entry.atime).not_to eq(time)
|
131
|
+
end
|
132
|
+
|
133
|
+
it "sets the modification time to now" do
|
134
|
+
entry.touch
|
135
|
+
expect(entry.mtime).not_to eq(time)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,154 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module MemFs
|
4
|
+
module Fake
|
5
|
+
|
6
|
+
describe File::Content do
|
7
|
+
subject { File::Content.new }
|
8
|
+
|
9
|
+
describe "#<<" do
|
10
|
+
it "writes the given string to the contained string" do
|
11
|
+
subject << 'test'
|
12
|
+
expect(subject.to_s).to eq('test')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#initialize" do
|
17
|
+
context "when no argument is given" do
|
18
|
+
it "initialize the contained string to an empty one" do
|
19
|
+
expect(subject.to_s).to eq('')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "when an argument is given" do
|
24
|
+
subject { File::Content.new(base_value) }
|
25
|
+
|
26
|
+
context "when the argument is a string" do
|
27
|
+
let(:base_value) { 'test' }
|
28
|
+
|
29
|
+
it "initialize the contained string with the given one" do
|
30
|
+
expect(subject.to_s).to eq('test')
|
31
|
+
end
|
32
|
+
|
33
|
+
it "duplicates the original string to prevent modifications on it" do
|
34
|
+
expect(subject.to_s).not_to be(base_value)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "when the argument is not a string" do
|
39
|
+
let(:base_value) { 42 }
|
40
|
+
|
41
|
+
it "converts it to a string" do
|
42
|
+
expect(subject.to_s).to eq('42')
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "#puts" do
|
49
|
+
it "appends the given string to the contained string" do
|
50
|
+
subject.puts 'test'
|
51
|
+
expect(subject.to_s).to eq("test\n")
|
52
|
+
end
|
53
|
+
|
54
|
+
it "appends all given strings to the contained string" do
|
55
|
+
subject.puts 'this', 'is', 'a', 'test'
|
56
|
+
expect(subject.to_s).to eq("this\nis\na\ntest\n")
|
57
|
+
end
|
58
|
+
|
59
|
+
context "when a line break is present at the end of the given string" do
|
60
|
+
it "doesn't add any line break" do
|
61
|
+
subject.puts "test\n"
|
62
|
+
expect(subject.to_s).not_to eq("test\n\n")
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "#to_s" do
|
68
|
+
context "when the content is empty" do
|
69
|
+
it "returns an empty string" do
|
70
|
+
expect(subject.to_s).to eq('')
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context "when the content is not empty" do
|
75
|
+
it "returns the content's string" do
|
76
|
+
subject << 'test'
|
77
|
+
expect(subject.to_s).to eq('test')
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "#write" do
|
83
|
+
it "writes the given string in content" do
|
84
|
+
subject.write 'test'
|
85
|
+
expect(subject.to_s).to eq('test')
|
86
|
+
end
|
87
|
+
|
88
|
+
it "returns the number of bytes written" do
|
89
|
+
expect(subject.write('test')).to eq(4)
|
90
|
+
end
|
91
|
+
|
92
|
+
context "when the argument is not a string" do
|
93
|
+
it "converts it to a string" do
|
94
|
+
subject.write 42
|
95
|
+
expect(subject.to_s).to eq('42')
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context "when the argument is a non-ascii string" do
|
100
|
+
it "returns the correct number of bytes written" do
|
101
|
+
expect(subject.write('é')).to eq(1)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context "when initialized with a string argument" do
|
107
|
+
subject { File::Content.new('test') }
|
108
|
+
|
109
|
+
describe "#read" do
|
110
|
+
it "reads +length+ bytes from the contained string" do
|
111
|
+
expect(subject.read(2)).to eq('te')
|
112
|
+
end
|
113
|
+
|
114
|
+
context "when there is nothing else to read" do
|
115
|
+
it "returns nil" do
|
116
|
+
subject.read 4
|
117
|
+
expect(subject.read(1)).to be_nil
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context "when the optional +buffer+ argument is provided" do
|
122
|
+
it "inserts the output in the buffer" do
|
123
|
+
string = String.new
|
124
|
+
subject.read(2, string)
|
125
|
+
expect(string).to eq('te')
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe "#pos" do
|
131
|
+
context "when the string has not been read" do
|
132
|
+
it "returns 0" do
|
133
|
+
expect(subject.pos).to eq(0)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
context "when the string has been read" do
|
138
|
+
it "returns the current offset" do
|
139
|
+
subject.read 2
|
140
|
+
expect(subject.pos).to eq(2)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
describe "#close" do
|
146
|
+
it "responds to close" do
|
147
|
+
expect(subject).to respond_to(:close)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module MemFs
|
4
|
+
module Fake
|
5
|
+
describe File do
|
6
|
+
let(:file) { fs.find!('/test-file') }
|
7
|
+
|
8
|
+
before do
|
9
|
+
fs.touch('/test-file')
|
10
|
+
end
|
11
|
+
|
12
|
+
it "stores the modification made on its content" do
|
13
|
+
file.content << 'test'
|
14
|
+
expect(fs.find!('/test-file').content.to_s).to eq('test')
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "#close" do
|
18
|
+
it "sets the file as closed?" do
|
19
|
+
file.close
|
20
|
+
expect(file).to be_closed
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#content" do
|
25
|
+
it "returns the file content" do
|
26
|
+
expect(file.content).not_to be_nil
|
27
|
+
end
|
28
|
+
|
29
|
+
context "when the file is empty" do
|
30
|
+
it "returns an empty string container" do
|
31
|
+
expect(file.content.to_s).to be_empty
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module MemFs
|
4
|
+
module Fake
|
5
|
+
describe Symlink do
|
6
|
+
describe '#content' do
|
7
|
+
it "returns the target's content" do
|
8
|
+
MemFs::File.open('/test-file', 'w') { |f| f.puts "test" }
|
9
|
+
s = Symlink.new('/test-link', '/test-file')
|
10
|
+
expect(s.content).to be(s.dereferenced.content)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#dereferenced' do
|
15
|
+
it "returns the target if it's not a symlink" do
|
16
|
+
fs.touch '/test-file'
|
17
|
+
target = fs.find!('/test-file')
|
18
|
+
|
19
|
+
s = Symlink.new('/test-link', '/test-file')
|
20
|
+
|
21
|
+
expect(s.dereferenced).to eq(target)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "returns the last target of the chain" do
|
25
|
+
fs.touch '/test-file'
|
26
|
+
target = fs.find!('/test-file')
|
27
|
+
|
28
|
+
fs.symlink '/test-file', '/test-link'
|
29
|
+
s = Symlink.new('/test-link2', '/test-link')
|
30
|
+
|
31
|
+
expect(s.dereferenced).to eq(target)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#target' do
|
36
|
+
it "returns the target of the symlink" do
|
37
|
+
s = Symlink.new('/test-link', '/test-file')
|
38
|
+
expect(s.target).to eq('/test-file')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|