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