virtfs 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +8 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +154 -0
  8. data/Rakefile +5 -0
  9. data/lib/virtfs-nativefs-thick.rb +1 -0
  10. data/lib/virtfs-nativefs-thin.rb +1 -0
  11. data/lib/virtfs.rb +38 -0
  12. data/lib/virtfs/activation.rb +97 -0
  13. data/lib/virtfs/block_io.rb +140 -0
  14. data/lib/virtfs/byte_range.rb +71 -0
  15. data/lib/virtfs/context.rb +300 -0
  16. data/lib/virtfs/context_manager.rb +175 -0
  17. data/lib/virtfs/context_switch_class_methods.rb +96 -0
  18. data/lib/virtfs/delegate_module.rb +40 -0
  19. data/lib/virtfs/dir_instance_delegate.rb +3 -0
  20. data/lib/virtfs/exception.rb +13 -0
  21. data/lib/virtfs/file_instance_delegate.rb +3 -0
  22. data/lib/virtfs/file_modes_and_options.rb +293 -0
  23. data/lib/virtfs/find_class_methods.rb +106 -0
  24. data/lib/virtfs/io_buffer.rb +133 -0
  25. data/lib/virtfs/io_instance_delegate.rb +3 -0
  26. data/lib/virtfs/kernel.rb +146 -0
  27. data/lib/virtfs/nativefs/thick.rb +30 -0
  28. data/lib/virtfs/nativefs/thick/dir_class_methods.rb +38 -0
  29. data/lib/virtfs/nativefs/thick/file_class_methods.rb +178 -0
  30. data/lib/virtfs/nativefs/thin.rb +32 -0
  31. data/lib/virtfs/nativefs/thin/dir.rb +30 -0
  32. data/lib/virtfs/nativefs/thin/dir_class_methods.rb +41 -0
  33. data/lib/virtfs/nativefs/thin/file.rb +112 -0
  34. data/lib/virtfs/nativefs/thin/file_class_methods.rb +181 -0
  35. data/lib/virtfs/protofs/protofs.rb +7 -0
  36. data/lib/virtfs/protofs/protofs_base.rb +12 -0
  37. data/lib/virtfs/protofs/protofs_dir.rb +13 -0
  38. data/lib/virtfs/protofs/protofs_dir_class.rb +31 -0
  39. data/lib/virtfs/protofs/protofs_file.rb +27 -0
  40. data/lib/virtfs/protofs/protofs_file_class.rb +136 -0
  41. data/lib/virtfs/stat.rb +100 -0
  42. data/lib/virtfs/thin_dir_delegator.rb +79 -0
  43. data/lib/virtfs/thin_file_delegator.rb +77 -0
  44. data/lib/virtfs/thin_io_delegator_methods.rb +301 -0
  45. data/lib/virtfs/thin_io_delegator_methods_bufferio.rb +337 -0
  46. data/lib/virtfs/v_dir.rb +238 -0
  47. data/lib/virtfs/v_file.rb +480 -0
  48. data/lib/virtfs/v_io.rb +243 -0
  49. data/lib/virtfs/v_pathname.rb +128 -0
  50. data/lib/virtfs/version.rb +3 -0
  51. data/spec/activate_spec.rb +202 -0
  52. data/spec/chroot_spec.rb +120 -0
  53. data/spec/context_manager_class_spec.rb +246 -0
  54. data/spec/context_manager_instance_spec.rb +255 -0
  55. data/spec/context_spec.rb +335 -0
  56. data/spec/data/UTF-16LE-data.txt +0 -0
  57. data/spec/data/UTF-8-data.txt +212 -0
  58. data/spec/dir_class_spec.rb +506 -0
  59. data/spec/dir_instance_spec.rb +208 -0
  60. data/spec/file_class_spec.rb +2106 -0
  61. data/spec/file_instance_spec.rb +154 -0
  62. data/spec/file_modes_and_options_spec.rb +1556 -0
  63. data/spec/find_spec.rb +142 -0
  64. data/spec/io_bufferio_size_shared_examples.rb +371 -0
  65. data/spec/io_bufferio_size_spec.rb +861 -0
  66. data/spec/io_bufferio_spec.rb +801 -0
  67. data/spec/io_class_spec.rb +145 -0
  68. data/spec/io_instance_spec.rb +516 -0
  69. data/spec/kernel_spec.rb +285 -0
  70. data/spec/mount_spec.rb +186 -0
  71. data/spec/nativefs_local_root_spec.rb +132 -0
  72. data/spec/path_spec.rb +39 -0
  73. data/spec/spec_helper.rb +126 -0
  74. data/tasks/rspec.rake +3 -0
  75. data/tasks/yard.rake +7 -0
  76. data/test/UTF-8-demo.txt +212 -0
  77. data/test/bench.rb +18 -0
  78. data/test/bio_internal_test.rb +45 -0
  79. data/test/delegate_io.rb +31 -0
  80. data/test/delegate_module.rb +62 -0
  81. data/test/encode_test.rb +42 -0
  82. data/test/enoent_test.rb +30 -0
  83. data/test/namespace_test.rb +42 -0
  84. data/test/read_block_valid_encoding.rb +44 -0
  85. data/test/read_test.rb +78 -0
  86. data/test/stream_readers.rb +46 -0
  87. data/test/utf-16-demo.txt +0 -0
  88. data/test/utf8_to_utf16.rb +77 -0
  89. data/test/wrapper_test.rb +34 -0
  90. data/virtfs.gemspec +29 -0
  91. metadata +230 -0
@@ -0,0 +1,142 @@
1
+ require 'spec_helper'
2
+
3
+ describe VirtFS, "find and support methods (#{$fs_interface} interface)" do
4
+ before(:each) do
5
+ reset_context
6
+ @this_dir = VfsRealDir.getwd
7
+ end
8
+
9
+ describe "::glob_depth" do
10
+ it "should return the find depth required for the glob pattern" do
11
+ expect(VirtFS.glob_depth("*")).to eq(1)
12
+ expect(VirtFS.glob_depth("*/*")).to eq(2)
13
+ expect(VirtFS.glob_depth("*/*/*.rb")).to eq(3)
14
+ expect(VirtFS.glob_depth("**")).to eq(nil)
15
+ expect(VirtFS.glob_depth("*.d/**/*.rb")).to eq(nil)
16
+ end
17
+ end
18
+
19
+ describe "::find" do
20
+ before(:each) do
21
+ @full_path = File.expand_path(__FILE__)
22
+ @rel_path = File.basename(@full_path)
23
+ @this_dir = VfsRealDir.getwd
24
+ @root = File::SEPARATOR
25
+ end
26
+
27
+ context "with no filesystems mounted" do
28
+ it "should raise Errno::ENOENT when given a nonexistent directory" do
29
+ expect do
30
+ VirtFS.find("nonexistent_directory")
31
+ end.to raise_error(
32
+ Errno::ENOENT, "No such file or directory - nonexistent_directory"
33
+ )
34
+ end
35
+
36
+ it "should raise Errno::ENOENT when given a directory that exists in the native FS" do
37
+ expect do
38
+ VirtFS.find(@this_dir)
39
+ end.to raise_error(
40
+ Errno::ENOENT, "No such file or directory - #{@this_dir}"
41
+ )
42
+ end
43
+ end
44
+
45
+ context "with FS mounted on '/'" do
46
+ before(:each) do
47
+ @native_fs = nativefs_class.new
48
+ VirtFS.mount(@native_fs, @root)
49
+ VirtFS.dir_chdir(@this_dir)
50
+ end
51
+
52
+ it "should raise Errno::ENOENT when given a nonexistent directory" do
53
+ expect do
54
+ VirtFS.find("nonexistent_directory")
55
+ end.to raise_error(
56
+ Errno::ENOENT, "No such file or directory - nonexistent_directory"
57
+ )
58
+ end
59
+
60
+ it "should return an enum when no block is given" do
61
+ expect(VirtFS.find(@this_dir)).to be_kind_of(Enumerator)
62
+ end
63
+
64
+ it "should enumerate the same file names as standard Find.find" do
65
+ require 'find'
66
+ expect(VirtFS.find(@this_dir).to_a).to match_array(Find.find(@this_dir).to_a)
67
+ end
68
+
69
+ it "should retrieve paths that don't exceed the given depth - relative to the start directory" do
70
+ require 'pathname'
71
+ (0..4).each do |depth|
72
+ VirtFS.find(@this_dir, depth) do |p|
73
+ expect(Pathname.new(p.sub(@this_dir, "")).each_filename.to_a.length).to be <= depth
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+
80
+ describe "::glob_str?" do
81
+ it "should return false when string isn't a glob" do
82
+ expect(VirtFS.glob_str?("hello")).to be false
83
+ end
84
+
85
+ it "should return true when string is a glob" do
86
+ expect(VirtFS.glob_str?("*.rb")).to be true
87
+ expect(VirtFS.glob_str?("foo.r?")).to be true
88
+ end
89
+
90
+ it "should return false when glob characters are escaped" do
91
+ expect(VirtFS.glob_str?("\\*.rb")).to be false
92
+ expect(VirtFS.glob_str?("foo.r\\?")).to be false
93
+ end
94
+ end
95
+
96
+ describe "::dir_and_glob" do
97
+ before(:each) do
98
+ VirtFS.cwd = @this_dir
99
+ end
100
+
101
+ it "should return pwd and glob pattern given simple glob pattern" do
102
+ expect(VirtFS.dir_and_glob("*.rb")).to match_array([ @this_dir, nil, "*.rb" ])
103
+ expect(VirtFS.dir_and_glob("*.d/*.rb")).to match_array([ @this_dir, nil, "*.d/*.rb" ])
104
+ expect(VirtFS.dir_and_glob("*.d/**/*.rb")).to match_array([ @this_dir, nil, "*.d/**/*.rb" ])
105
+ expect(VirtFS.dir_and_glob("*.d/src/*.rb")).to match_array([ @this_dir, nil, "*.d/src/*.rb" ])
106
+ end
107
+
108
+ it "should return pwd + path and glob pattern given glob pattern with relative path" do
109
+ dir = VfsRealFile.join(@this_dir, "spec")
110
+ expect(VirtFS.dir_and_glob("spec/*.rb")).to match_array([ dir, "spec", "*.rb" ])
111
+ expect(VirtFS.dir_and_glob("spec/*.d/*.rb")).to match_array([ dir, "spec", "*.d/*.rb" ])
112
+ expect(VirtFS.dir_and_glob("spec/*.d/**/*.rb")).to match_array([ dir, "spec", "*.d/**/*.rb" ])
113
+ expect(VirtFS.dir_and_glob("spec/*.d/src/*.rb")).to match_array([ dir, "spec", "*.d/src/*.rb" ])
114
+
115
+ dir = VfsRealFile.join(@this_dir, "lib", "spec")
116
+ expect(VirtFS.dir_and_glob("lib/spec/*.rb")).to match_array([ dir, "lib/spec", "*.rb" ])
117
+ expect(VirtFS.dir_and_glob("lib/spec/*.d/*.rb")).to match_array([ dir, "lib/spec", "*.d/*.rb" ])
118
+ expect(VirtFS.dir_and_glob("lib/spec/*.d/**/*.rb")).to match_array([ dir, "lib/spec", "*.d/**/*.rb" ])
119
+ expect(VirtFS.dir_and_glob("lib/spec/*.d/src/*.rb")).to match_array([ dir, "lib/spec", "*.d/src/*.rb" ])
120
+ end
121
+
122
+ it "should return pwd and glob pattern given simple glob pattern" do
123
+ dir = VirtFS.normalize_path(VfsRealFile.join(@this_dir, ".."))
124
+ expect(VirtFS.dir_and_glob("../*.rb")).to match_array([ dir, "..", "*.rb" ])
125
+ expect(VirtFS.dir_and_glob("../*.d/*.rb")).to match_array([ dir, "..", "*.d/*.rb" ])
126
+ expect(VirtFS.dir_and_glob("../*.d/**/*.rb")).to match_array([ dir, "..", "*.d/**/*.rb" ])
127
+ expect(VirtFS.dir_and_glob("../*.d/src/*.rb")).to match_array([ dir, "..", "*.d/src/*.rb" ])
128
+
129
+ expect(VirtFS.dir_and_glob("dir/../*.rb")).to match_array([ @this_dir, "dir/..", "*.rb" ])
130
+ expect(VirtFS.dir_and_glob("dir/../*.d/*.rb")).to match_array([ @this_dir, "dir/..", "*.d/*.rb" ])
131
+ expect(VirtFS.dir_and_glob("dir/../*.d/**/*.rb")).to match_array([ @this_dir, "dir/..", "*.d/**/*.rb" ])
132
+ expect(VirtFS.dir_and_glob("dir/../*.d/src/*.rb")).to match_array([ @this_dir, "dir/..", "*.d/src/*.rb" ])
133
+ end
134
+
135
+ it "should return path and glob pattern given fully qualified glob pattern" do
136
+ expect(VirtFS.dir_and_glob("/bin/*.rb")).to match_array([ "/bin", "/bin", "*.rb" ])
137
+ expect(VirtFS.dir_and_glob("/bin/*.d/*.rb")).to match_array([ "/bin", "/bin", "*.d/*.rb" ])
138
+ expect(VirtFS.dir_and_glob("/bin/*.d/**/*.rb")).to match_array([ "/bin", "/bin", "*.d/**/*.rb" ])
139
+ expect(VirtFS.dir_and_glob("/bin/*.d/src/*.rb")).to match_array([ "/bin", "/bin", "*.d/src/*.rb" ])
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,371 @@
1
+ shared_examples_for "common_bytes" do
2
+ it "should return an enum" do
3
+ expect(suppress_warnings { @vfile_read_obj.bytes }).to be_kind_of(Enumerator)
4
+ end
5
+
6
+ it "should enumerate the same bytes as the standard File#bytes" do
7
+ rbytes = suppress_warnings { @rfile_obj.bytes.to_a }
8
+ vbytes = suppress_warnings { @vfile_read_obj.bytes.to_a }
9
+ expect(vbytes).to match_array(rbytes)
10
+ end
11
+ end
12
+
13
+ shared_examples_for "common_chars" do
14
+ it "should return an enum" do
15
+ expect(suppress_warnings { @vfile_read_test_obj.chars }).to be_kind_of(Enumerator)
16
+ end
17
+
18
+ it "should enumerate the same characters as the standard File#chars" do
19
+ rchars = suppress_warnings { @rfile_obj.chars.to_a }
20
+ vchars = suppress_warnings { @vfile_read_test_obj.chars.to_a }
21
+ expect(vchars).to match_array(rchars)
22
+ end
23
+ end
24
+
25
+ shared_examples_for "common_each" do
26
+ it "should return an enum when no block is given" do
27
+ expect(@vfile_read_obj.each).to be_kind_of(Enumerator)
28
+ end
29
+
30
+ it "should return the IO object when block is given" do
31
+ expect(@vfile_read_obj.each { true }).to eq(@vfile_read_obj)
32
+ end
33
+
34
+ it "should enumerate the same lines as the standard File#each" do
35
+ expect(@vfile_read_test_obj.each.to_a).to match_array(@rfile_obj.each.to_a)
36
+ end
37
+ end
38
+
39
+ shared_examples_for "common_each_byte" do
40
+ it "should return an enum when no block is given" do
41
+ expect(@vfile_read_obj.each_byte).to be_kind_of(Enumerator)
42
+ end
43
+
44
+ it "should return the IO object when block is given" do
45
+ expect(@vfile_read_obj.each_byte { true }).to eq(@vfile_read_obj)
46
+ end
47
+
48
+ it "should enumerate the same bytes as the standard File#each_byte" do
49
+ expect(@vfile_read_obj.each_byte.to_a).to match_array(@rfile_obj.each_byte.to_a)
50
+ end
51
+ end
52
+
53
+ shared_examples_for "common_each_char" do
54
+ it "should return an enum when no block is given" do
55
+ expect(@vfile_read_test_obj.each_char).to be_kind_of(Enumerator)
56
+ end
57
+
58
+ it "should return the IO object when block is given" do
59
+ expect(@vfile_read_test_obj.each_char { true }).to eq(@vfile_read_test_obj)
60
+ end
61
+
62
+ it "should enumerate the same lines as the standard File#each_char" do
63
+ expect(@vfile_read_test_obj.each_char.to_a).to match_array(@rfile_obj.each_char.to_a)
64
+ end
65
+ end
66
+
67
+ shared_examples_for "common_each_each_codepoint" do
68
+ it "should return an enum when no block is given" do
69
+ expect(@vfile_read_test_obj.each_codepoint).to be_kind_of(Enumerator)
70
+ end
71
+
72
+ it "should return the IO object when block is given" do
73
+ expect(@vfile_read_test_obj.each_codepoint { true }).to eq(@vfile_read_test_obj)
74
+ end
75
+
76
+ it "should enumerate the same values as the standard IO#each_codepoint" do
77
+ expect(@vfile_read_test_obj.each_codepoint.to_a).to match_array(@rfile_obj.each_codepoint.to_a)
78
+ end
79
+ end
80
+
81
+ shared_examples_for "common_getbyte" do
82
+ it "should return a Fixnum" do
83
+ expect(@vfile_read_obj.getbyte).to be_kind_of(Fixnum)
84
+ end
85
+
86
+ it "should return nil when at EOF" do
87
+ @vfile_read_obj.read
88
+ expect(@vfile_read_obj.getbyte).to be_nil
89
+ end
90
+
91
+ it "should read all the bytes in the file" do
92
+ byte_count = 0
93
+ byte_count += 1 until @vfile_read_obj.getbyte.nil?
94
+ expect(byte_count).to eq(@file_size)
95
+ end
96
+
97
+ it "should return the same values as the standard IO#getbyte" do
98
+ while (vrv = @vfile_read_obj.getbyte)
99
+ expect(vrv).to eq(@rfile_obj.getbyte)
100
+ end
101
+ expect(@rfile_obj.getbyte).to be_nil
102
+ end
103
+ end
104
+
105
+ shared_examples_for "common_getc" do
106
+ it "should return a character of the expected encoding" do
107
+ expect(@vfile_read_test_obj.getc.encoding).to eq(@expected_returned_encoding)
108
+ end
109
+
110
+ it "should return nil when at EOF" do
111
+ @vfile_read_test_obj.read
112
+ expect(@vfile_read_test_obj.getc).to be_nil
113
+ end
114
+
115
+ it "should read all the characters in the file" do
116
+ byte_count = 0
117
+ while (vrv = @vfile_read_test_obj.getc)
118
+ byte_count += vrv.bytesize
119
+ end
120
+ expect(byte_count).to eq(@expected_full_read_size)
121
+ end
122
+
123
+ it "should return the same values as the standard IO#getc" do
124
+ while (vrv = @vfile_read_test_obj.getc)
125
+ expect(vrv).to eq(@rfile_obj.getc)
126
+ end
127
+ expect(@rfile_obj.getc).to be_nil
128
+ end
129
+ end
130
+
131
+ shared_examples_for "common_gets" do
132
+ it "should read an entire line by default" do
133
+ rv = @vfile_read_test_obj.gets
134
+ expect(rv[-1]).to eq($/.encode(rv.encoding))
135
+ end
136
+
137
+ it "should read the entire file - given a nil separator" do
138
+ rv = @vfile_read_test_obj.gets(nil)
139
+ expect(rv.bytesize).to eq(@expected_full_read_size)
140
+ end
141
+
142
+ it "should return nil when at EOF" do
143
+ @vfile_read_test_obj.gets(nil)
144
+ rv = @vfile_read_test_obj.gets
145
+ expect(rv).to be_nil
146
+ end
147
+
148
+ it "should read the same lines as the standard File#gets" do
149
+ while (vrv = @vfile_read_test_obj.gets)
150
+ expect(vrv).to eq(@rfile_obj.gets)
151
+ end
152
+ expect(@rfile_obj.gets).to be_nil
153
+ end
154
+ end
155
+
156
+ shared_examples_for "common_lines" do
157
+ it "should return an enum" do
158
+ expect(suppress_warnings { @vfile_read_test_obj.lines }).to be_kind_of(Enumerator)
159
+ end
160
+
161
+ it "should enumerate the same lines as the standard File#lines" do
162
+ rlines = suppress_warnings { @rfile_obj.lines.to_a }
163
+ vlines = suppress_warnings { @vfile_read_test_obj.lines.to_a }
164
+ expect(vlines).to match_array(rlines)
165
+ end
166
+ end
167
+
168
+ shared_examples_for "common_read" do
169
+ it "should read the number of bytes requested - when EOF not reached" do
170
+ read_size = @file_size / 2
171
+ rv = @vfile_read_test_obj.read(read_size)
172
+ expect(rv.bytesize).to eq(read_size)
173
+ end
174
+
175
+ it "should read data into buffer, when supplied" do
176
+ read_size = @file_size / 2
177
+ rbuf = ""
178
+ rv = @vfile_read_test_obj.read(read_size, rbuf)
179
+ expect(rv).to eq(rbuf)
180
+ end
181
+
182
+ it "should read the whole file by default" do
183
+ rv = @vfile_read_test_obj.read
184
+ expect(rv.bytesize).to eq(@expected_full_read_size)
185
+ end
186
+
187
+ it "should read at most, the size of the file" do
188
+ rv = @vfile_read_test_obj.read(@test_file_size + 100)
189
+ expect(rv.bytesize).to eq(@test_file_size) # given length, not transcoded
190
+ end
191
+
192
+ it "should return nil when attempting to read length at EOF" do
193
+ @vfile_read_test_obj.read(@test_file_size)
194
+ expect(@vfile_read_test_obj.read(@test_file_size)).to be_nil
195
+ end
196
+
197
+ it "should return empty string when attempting to read to EOF at EOF" do
198
+ @vfile_read_test_obj.read(@test_file_size)
199
+ expect(@vfile_read_test_obj.read).to eq("")
200
+ end
201
+
202
+ it "should read the same data as the standard File#read" do
203
+ read_size = 20
204
+ loop do
205
+ rv1 = @vfile_read_test_obj.read(read_size)
206
+ rv2 = @rfile_obj.read(read_size)
207
+ expect(rv1).to eq(rv2)
208
+ break if rv1.nil? || rv1.empty?
209
+ end
210
+ end
211
+
212
+ it "should return a string of expected encoding when reading whole file" do
213
+ rv = @vfile_read_test_obj.read
214
+ expect(rv.encoding).to eq(@expected_returned_encoding)
215
+ end
216
+
217
+ it "should return a string of 'binary_encoding' when reading partial file" do
218
+ rv = @vfile_read_test_obj.read(10)
219
+ expect(rv.encoding).to eq(@binary_encoding)
220
+ end
221
+ end
222
+
223
+ shared_examples_for "common_readlines" do
224
+ it "should return an Array" do
225
+ expect(@vfile_read_obj.readlines).to be_kind_of(Array)
226
+ end
227
+
228
+ it "should enumerate the same lines as the standard File#readlines" do
229
+ expect(@vfile_read_test_obj.readlines).to match_array(@rfile_obj.readlines)
230
+ end
231
+ end
232
+
233
+ shared_examples_for "common_ungetbyte" do
234
+ it "should return nil" do
235
+ expect(@vfile_read_test_obj.ungetbyte(@bytes_for_char)).to be_nil
236
+ end
237
+
238
+ it "should return a string in the expected encoding" do
239
+ @vfile_read_test_obj.ungetbyte(@bytes_for_char)
240
+ expect(@vfile_read_test_obj.getc.encoding).to eq(@expected_returned_encoding)
241
+ end
242
+
243
+ it "should work at the beginning of the file - with getc" do
244
+ @vfile_read_test_obj.ungetbyte(@bytes_for_char)
245
+ rv = @vfile_read_test_obj.getc.encode(@default_encoding)
246
+ expect(rv).to eql(@char.encode(@default_encoding))
247
+ end
248
+
249
+ it "should work at the beginning of the file - with gets" do
250
+ @vfile_read_test_obj.ungetbyte(@bytes_for_char)
251
+ rv = @vfile_read_test_obj.gets[0].encode(@default_encoding)
252
+ expect(rv).to eq(@char.encode(@default_encoding))
253
+ end
254
+
255
+ it "should work at EOF" do
256
+ @vfile_read_test_obj.read
257
+ @vfile_read_test_obj.ungetbyte(@bytes_for_char)
258
+ rv = @vfile_read_test_obj.gets.encode(@default_encoding)
259
+ expect(rv.index(@char.encode(@default_encoding))).to eq(0)
260
+ end
261
+
262
+ it "should return the character in next getc" do
263
+ char0 = @vfile_read_test_obj.getc.encode(@default_encoding)
264
+ expect(char0).to_not eq(@char)
265
+
266
+ @vfile_read_test_obj.rewind
267
+ @vfile_read_test_obj.ungetbyte(@bytes_for_char)
268
+
269
+ char1 = @vfile_read_test_obj.getc.encode(@default_encoding)
270
+ expect(char1).to eq(@char.encode(@default_encoding))
271
+ char1 = @vfile_read_test_obj.getc.encode(@default_encoding)
272
+ expect(char1).to eq(char0)
273
+ end
274
+
275
+ it "should return the character in next gets" do
276
+ char0 = @vfile_read_test_obj.getc.encode(@default_encoding)
277
+ expect(char0).to_not eq(@char)
278
+
279
+ @vfile_read_test_obj.rewind
280
+ @vfile_read_test_obj.ungetbyte(@bytes_for_char)
281
+
282
+ str = @vfile_read_test_obj.gets.encode(@default_encoding)
283
+ expect(str[0]).to eq(@char.encode(@default_encoding))
284
+ expect(str[1]).to eq(char0)
285
+ end
286
+
287
+ it "should work within the body of the file" do
288
+ offset = @test_file_size
289
+ @vfile_read_test_obj.pos = offset
290
+ @vfile_read_test_obj.ungetbyte(@bytes_for_char)
291
+ rv = @vfile_read_test_obj.gets.encode(@default_encoding)
292
+ expect(rv.index(@char.encode(@default_encoding))).to eq(0)
293
+ end
294
+ end
295
+
296
+ shared_examples_for "common_ungetc" do
297
+ it "should return nil" do
298
+ expect(@vfile_read_test_obj.ungetc("X")).to be_nil
299
+ end
300
+
301
+ it "should return a string in the expected encoding" do
302
+ char = "X"
303
+ @vfile_read_test_obj.ungetc(char)
304
+ expect(@vfile_read_test_obj.getc.encoding).to eq(@expected_returned_encoding)
305
+ end
306
+
307
+ it "should work at the beginning of the file - with getc" do
308
+ char = "X"
309
+ @vfile_read_test_obj.ungetc(char)
310
+ rv = @vfile_read_test_obj.getc.encode(@default_encoding)
311
+ expect(rv).to eql(char)
312
+ end
313
+
314
+ it "should work at the beginning of the file - with gets" do
315
+ char = "X"
316
+ @vfile_read_test_obj.ungetc(char)
317
+ rv = @vfile_read_test_obj.gets[0].encode(@default_encoding)
318
+ expect(rv).to eq(char)
319
+ end
320
+
321
+ it "should work with a string at the beginning of the file - with gets" do
322
+ char = "HELLO"
323
+ @vfile_read_test_obj.ungetc(char)
324
+ rv = @vfile_read_test_obj.gets.encode(@default_encoding)
325
+ expect(rv.index(char)).to eq(0)
326
+ end
327
+
328
+ it "should work at EOF" do
329
+ @vfile_read_test_obj.read
330
+ char = "HELLO"
331
+ @vfile_read_test_obj.ungetc(char)
332
+ rv = @vfile_read_test_obj.gets.encode(@default_encoding)
333
+ expect(rv.index(char)).to eq(0)
334
+ end
335
+
336
+ it "should return the character in next getc" do
337
+ char = "X"
338
+ char0 = @vfile_read_test_obj.getc.encode(@default_encoding)
339
+ expect(char0).to_not eq(char)
340
+
341
+ @vfile_read_test_obj.rewind
342
+ @vfile_read_test_obj.ungetc(char)
343
+
344
+ char1 = @vfile_read_test_obj.getc.encode(@default_encoding)
345
+ expect(char1).to eq(char)
346
+ char1 = @vfile_read_test_obj.getc.encode(@default_encoding)
347
+ expect(char1).to eq(char0)
348
+ end
349
+
350
+ it "should return the character in next gets" do
351
+ char = "X"
352
+ char0 = @vfile_read_test_obj.getc.encode(@default_encoding)
353
+ expect(char0).to_not eq(char)
354
+
355
+ @vfile_read_test_obj.rewind
356
+ @vfile_read_test_obj.ungetc(char)
357
+
358
+ str = @vfile_read_test_obj.gets.encode(@default_encoding)
359
+ expect(str[0]).to eq(char)
360
+ expect(str[1]).to eq(char0)
361
+ end
362
+
363
+ it "should work within the body of the file" do
364
+ offset = @test_file_size
365
+ @vfile_read_test_obj.pos = offset
366
+ char = "HELLO"
367
+ @vfile_read_test_obj.ungetc(char)
368
+ rv = @vfile_read_test_obj.gets.encode(@default_encoding)
369
+ expect(rv.index(char)).to eq(0)
370
+ end
371
+ end