memfs 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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