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.
@@ -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