io-like 0.3.1 → 0.4.0.pre1

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 (71) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +1 -1
  3. data/NEWS.md +14 -1
  4. data/README.md +75 -94
  5. data/lib/io/like.rb +1916 -1314
  6. data/lib/io/like_helpers/abstract_io.rb +512 -0
  7. data/lib/io/like_helpers/blocking_io.rb +86 -0
  8. data/lib/io/like_helpers/buffered_io.rb +555 -0
  9. data/lib/io/like_helpers/character_io/basic_reader.rb +122 -0
  10. data/lib/io/like_helpers/character_io/converter_reader.rb +252 -0
  11. data/lib/io/like_helpers/character_io.rb +529 -0
  12. data/lib/io/like_helpers/delegated_io.rb +250 -0
  13. data/lib/io/like_helpers/duplexed_io.rb +259 -0
  14. data/lib/io/like_helpers/io.rb +21 -0
  15. data/lib/io/like_helpers/io_wrapper.rb +290 -0
  16. data/lib/io/like_helpers/pipeline.rb +77 -0
  17. data/lib/io/like_helpers/ruby_facts.rb +33 -0
  18. data/lib/io/like_helpers.rb +14 -0
  19. metadata +107 -224
  20. data/.yardopts +0 -1
  21. data/Rakefile +0 -228
  22. data/ruby.1.8.mspec +0 -7
  23. data/spec/binmode_spec.rb +0 -29
  24. data/spec/close_read_spec.rb +0 -64
  25. data/spec/close_spec.rb +0 -36
  26. data/spec/close_write_spec.rb +0 -61
  27. data/spec/closed_spec.rb +0 -16
  28. data/spec/each_byte_spec.rb +0 -38
  29. data/spec/each_line_spec.rb +0 -11
  30. data/spec/each_spec.rb +0 -11
  31. data/spec/eof_spec.rb +0 -11
  32. data/spec/fixtures/classes.rb +0 -96
  33. data/spec/fixtures/gets.txt +0 -9
  34. data/spec/fixtures/numbered_lines.txt +0 -5
  35. data/spec/fixtures/one_byte.txt +0 -1
  36. data/spec/fixtures/paragraphs.txt +0 -7
  37. data/spec/fixtures/readlines.txt +0 -6
  38. data/spec/flush_spec.rb +0 -8
  39. data/spec/getc_spec.rb +0 -44
  40. data/spec/gets_spec.rb +0 -212
  41. data/spec/isatty_spec.rb +0 -6
  42. data/spec/lineno_spec.rb +0 -84
  43. data/spec/output_spec.rb +0 -47
  44. data/spec/pos_spec.rb +0 -53
  45. data/spec/print_spec.rb +0 -97
  46. data/spec/printf_spec.rb +0 -24
  47. data/spec/putc_spec.rb +0 -57
  48. data/spec/puts_spec.rb +0 -99
  49. data/spec/read_spec.rb +0 -162
  50. data/spec/readchar_spec.rb +0 -49
  51. data/spec/readline_spec.rb +0 -60
  52. data/spec/readlines_spec.rb +0 -140
  53. data/spec/readpartial_spec.rb +0 -92
  54. data/spec/rewind_spec.rb +0 -56
  55. data/spec/seek_spec.rb +0 -72
  56. data/spec/shared/each.rb +0 -204
  57. data/spec/shared/eof.rb +0 -116
  58. data/spec/shared/pos.rb +0 -39
  59. data/spec/shared/tty.rb +0 -12
  60. data/spec/shared/write.rb +0 -53
  61. data/spec/sync_spec.rb +0 -56
  62. data/spec/sysread_spec.rb +0 -87
  63. data/spec/sysseek_spec.rb +0 -68
  64. data/spec/syswrite_spec.rb +0 -60
  65. data/spec/tell_spec.rb +0 -7
  66. data/spec/to_io_spec.rb +0 -19
  67. data/spec/tty_spec.rb +0 -6
  68. data/spec/ungetc_spec.rb +0 -118
  69. data/spec/write_spec.rb +0 -61
  70. data/spec_helper.rb +0 -49
  71. /data/{LICENSE-rubyspec → rubyspec/LICENSE} +0 -0
data/spec/shared/eof.rb DELETED
@@ -1,116 +0,0 @@
1
- require File.dirname(__FILE__) + '/../fixtures/classes'
2
-
3
- describe :io_like__eof, :shared => true do
4
- before :each do
5
- @filename = File.dirname(__FILE__) + '/../fixtures/readlines.txt'
6
- @file = File.open(@filename, 'r')
7
- @iowrapper = ReadableIOWrapper.open(@file)
8
- end
9
-
10
- after :each do
11
- @iowrapper.close unless @iowrapper.closed?
12
- @file.close unless @file.closed?
13
- end
14
-
15
- it "returns false when not at end of file" do
16
- @iowrapper.send(@method).should == false
17
- @iowrapper.read(1)
18
- @iowrapper.send(@method).should == false
19
- end
20
-
21
- it "returns true after reading with read with no parameters" do
22
- @iowrapper.read
23
- @iowrapper.send(@method).should == true
24
- end
25
-
26
- it "returns true after reading with read" do
27
- @iowrapper.read(File.size(@filename))
28
- @iowrapper.send(@method).should == true
29
- end
30
-
31
- it "returns true after reading with sysread" do
32
- @iowrapper.sysread(File.size(@filename))
33
- @iowrapper.send(@method).should == true
34
- end
35
-
36
- it "returns true after reading with readlines" do
37
- @iowrapper.readlines
38
- @iowrapper.send(@method).should == true
39
- end
40
-
41
- it "returns true on just opened empty stream" do
42
- path = tmp('empty.txt')
43
- File.open(path, "w") { |empty| } # ensure it exists
44
- File.open(path) do |empty|
45
- ReadableIOWrapper.open(empty) do |iowrapper|
46
- iowrapper.send(@method).should == true
47
- end
48
- end
49
- File.delete(path)
50
- end
51
-
52
- it "returns false on just opened non-empty stream" do
53
- @iowrapper.send(@method).should == false
54
- end
55
-
56
- it "should not consume the data from the stream" do
57
- @iowrapper.send(@method).should == false
58
- @iowrapper.getc.should == 86
59
- end
60
-
61
- it "raises IOError on closed stream" do
62
- lambda { IOSpecs.closed_file.send(@method) }.should raise_error(IOError)
63
- end
64
-
65
- it "raises IOError on stream not opened for reading" do
66
- IOSpecs.writable_iowrapper do |iowrapper|
67
- lambda { iowrapper.send(@method) }.should raise_error(IOError)
68
- end
69
- end
70
-
71
- it "raises IOError on stream closed for reading by close_read" do
72
- @iowrapper.close_read
73
- lambda { @iowrapper.send(@method) }.should raise_error(IOError)
74
- end
75
-
76
- it "returns true on one-byte stream after single-byte read" do
77
- File.open(File.dirname(__FILE__) + '/../fixtures/one_byte.txt') do |one_byte|
78
- WritableIOWrapper.open(one_byte) do |iowrapper|
79
- one_byte.read(1)
80
- one_byte.send(@method).should == true
81
- end
82
- end
83
- end
84
-
85
- it "returns true on receiving side of Pipe when writing side is closed" do
86
- r, w = IO.pipe
87
- iowrapper_r = ReadableIOWrapper.open(r)
88
- iowrapper_w = WritableIOWrapper.open(w)
89
- iowrapper_w.close
90
- w.close
91
-
92
- iowrapper_r.send(@method).should == true
93
-
94
- iowrapper_r.close
95
- r.close
96
- end
97
-
98
- it "returns false on receiving side of Pipe when writing side wrote some data" do
99
- r, w = IO.pipe
100
- iowrapper_r = ReadableIOWrapper.open(r)
101
- iowrapper_w = WritableIOWrapper.open(w)
102
- iowrapper_w.sync = true
103
-
104
- iowrapper_w.puts "hello"
105
- iowrapper_r.send(@method).should == false
106
- iowrapper_w.close
107
- w.close
108
-
109
- iowrapper_r.send(@method).should == false
110
- iowrapper_r.read
111
- iowrapper_r.send(@method).should == true
112
-
113
- iowrapper_r.close
114
- r.close
115
- end
116
- end
data/spec/shared/pos.rb DELETED
@@ -1,39 +0,0 @@
1
- describe :io_like__pos, :shared => true do
2
- before :each do
3
- @fname = tmp('IO_Like__pos_test')
4
- File.open(@fname, 'w') { |f| f.write("123") }
5
- end
6
-
7
- after :each do
8
- File.unlink(@fname)
9
- end
10
-
11
- it "gets the offset" do
12
- IOSpecs.readable_iowrapper do |iowrapper|
13
- iowrapper.send(@method).should == 0
14
- iowrapper.read(1)
15
- iowrapper.send(@method).should == 1
16
- iowrapper.read(2)
17
- iowrapper.send(@method).should == 3
18
- end
19
- end
20
-
21
- it "raises IOError on closed stream" do
22
- lambda { IOSpecs.closed_file.send(@method) }.should raise_error(IOError)
23
- end
24
-
25
- # BOGUS EXPECTATION
26
- # This fails for File and IO. It used to pass because the end of file was not
27
- # actually reached with just 2 bytes read from the file.
28
- #it "resets #eof?" do
29
- # File.open(@fname) do |f|
30
- # ReadableIOWrapper.open(f) do |iowrapper|
31
- # iowrapper.read(1)
32
- # iowrapper.read(1)
33
- # iowrapper.eof?.should == true
34
- # iowrapper.send(@method)
35
- # iowrapper.eof?.should == false
36
- # end
37
- # end
38
- #end
39
- end
data/spec/shared/tty.rb DELETED
@@ -1,12 +0,0 @@
1
- require File.dirname(__FILE__) + '/../fixtures/classes'
2
-
3
- describe :io_like__tty, :shared => true do
4
- it "returns false if this stream is open" do
5
- IOSpecs.readable_iowrapper { |io| io.send(@method) }.should == false
6
- IOSpecs.writable_iowrapper { |io| io.send(@method) }.should == false
7
- end
8
-
9
- it "raises IOError on closed stream" do
10
- lambda { IOSpecs.closed_file.send(@method) }.should raise_error(IOError)
11
- end
12
- end
data/spec/shared/write.rb DELETED
@@ -1,53 +0,0 @@
1
- require File.dirname(__FILE__) + '/../fixtures/classes'
2
-
3
- describe :io_like__write, :shared => true do
4
- before :each do
5
- @filename = tmp("IO_Like__shared_write_test")
6
- @content = "012345678901234567890123456789"
7
- File.open(@filename, "w") { |f| f.write(@content) }
8
- @file = File.open(@filename, "r+")
9
- @iowrapper = IOWrapper.open(@file)
10
- end
11
-
12
- after :each do
13
- @iowrapper.close unless @iowrapper.closed?
14
- @file.close unless @file.closed?
15
- File.delete(@filename)
16
- end
17
-
18
- it "coerces the argument to a string using to_s" do
19
- (obj = mock('test')).should_receive(:to_s).and_return('a string')
20
- @iowrapper.send(@method, obj)
21
- end
22
-
23
- it "does not warn if called after IO#read" do
24
- @iowrapper.read(5)
25
- lambda { @iowrapper.send(@method, "fghij") }.should_not complain
26
- end
27
-
28
- it "writes to the current position after IO#read" do
29
- @iowrapper.read(5)
30
- @iowrapper.send(@method, "abcd")
31
- @iowrapper.rewind
32
- @iowrapper.read.should == "01234abcd901234567890123456789"
33
- end
34
-
35
- it "advances the file position by the count of given bytes" do
36
- @iowrapper.send(@method, "abcde")
37
- @iowrapper.read(10).should == "5678901234"
38
- end
39
-
40
- it "raises IOError on read-only stream if writing more than zero bytes" do
41
- lambda do
42
- IOSpecs.readable_iowrapper do |iowrapper|
43
- iowrapper.send(@method, "abcde")
44
- end
45
- end.should raise_error(IOError)
46
- end
47
-
48
- it "raises IOError on closed stream if writing more than zero bytes" do
49
- lambda do
50
- IOSpecs.closed_file.send(@method, "abcde")
51
- end.should raise_error(IOError)
52
- end
53
- end
data/spec/sync_spec.rb DELETED
@@ -1,56 +0,0 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
2
- require File.dirname(__FILE__) + '/fixtures/classes'
3
-
4
- describe "IO::Like#sync=" do
5
- before :each do
6
- @file = File.dirname(__FILE__) + '/fixtures/readlines.txt'
7
- @f = File.open(@file)
8
- @iowrapper = ReadableIOWrapper.open(@f)
9
- end
10
-
11
- after :each do
12
- @iowrapper.close unless @iowrapper.closed?
13
- @f.close unless @f.closed?
14
- end
15
-
16
- it "sets the sync mode to true or false" do
17
- @iowrapper.sync = true
18
- @iowrapper.sync.should == true
19
- @iowrapper.sync = false
20
- @iowrapper.sync.should == false
21
- end
22
-
23
- it "accepts non-boolean arguments" do
24
- @iowrapper.sync = 10
25
- @iowrapper.sync.should == true
26
- @iowrapper.sync = nil
27
- @iowrapper.sync.should == false
28
- @iowrapper.sync = Object.new
29
- @iowrapper.sync.should == true
30
- end
31
-
32
- it "raises IOError on closed stream" do
33
- lambda { IOSpecs.closed_file.sync = true }.should raise_error(IOError)
34
- end
35
- end
36
-
37
- describe "IO::Like#sync" do
38
- before :each do
39
- @file = File.dirname(__FILE__) + '/fixtures/readlines.txt'
40
- @f = File.open(@file)
41
- @iowrapper = ReadableIOWrapper.open(@f)
42
- end
43
-
44
- after :each do
45
- @iowrapper.close unless @iowrapper.closed?
46
- @f.close unless @f.closed?
47
- end
48
-
49
- it "returns the current sync mode" do
50
- @iowrapper.sync.should == false
51
- end
52
-
53
- it "raises IOError on closed stream" do
54
- lambda { IOSpecs.closed_file.sync }.should raise_error(IOError)
55
- end
56
- end
data/spec/sysread_spec.rb DELETED
@@ -1,87 +0,0 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
2
- require File.dirname(__FILE__) + '/fixtures/classes'
3
-
4
- describe "IO::Like#sysread on a file" do
5
- before :each do
6
- @filename = tmp("IO_Like___sysread_file") + $$.to_s
7
- @contents = "012345678901234567890123456789"
8
- File.open(@filename, "w") { |f| f.write(@contents) }
9
-
10
- @file = File.open(@filename, "r+")
11
- @iowrapper = IOWrapper.open(@file)
12
- end
13
-
14
- after :each do
15
- @iowrapper.close unless @iowrapper.closed?
16
- @file.close unless @file.closed?
17
- File.delete(@filename) if File.exists?(@filename)
18
- end
19
-
20
- it "reads the specified number of bytes from the file" do
21
- @iowrapper.sysread(15).should == @contents.slice(0, 15)
22
- end
23
-
24
- it "reads the specified number of bytes from the file to the buffer" do
25
- buf = "" # empty buffer
26
- @iowrapper.sysread(15, buf).should == buf
27
- buf.should == @contents.slice(0, 15)
28
-
29
- @iowrapper.rewind
30
-
31
- buf = "ABCDE" # small buffer
32
- @iowrapper.sysread(15, buf).should == buf
33
- buf.should == @contents.slice(0, 15)
34
-
35
- @iowrapper.rewind
36
-
37
- buf = "ABCDE" * 5 # large buffer
38
- @iowrapper.sysread(15, buf).should == buf
39
- buf.should == @contents.slice(0, 15)
40
- end
41
-
42
- it "coerces the second argument to string and uses it as a buffer" do
43
- buf = "ABCDE"
44
- (obj = mock("buff")).should_receive(:to_str).and_return(buf)
45
- @iowrapper.sysread(15, obj).should == buf
46
- buf.should == @contents.slice(0, 15)
47
- end
48
-
49
- it "advances the position of the file by the specified number of bytes" do
50
- @iowrapper.sysread(15)
51
- @iowrapper.sysread(5).should == @contents.slice(15, 5)
52
- end
53
-
54
- it "raises IOError when called immediately after a buffered IO#read" do
55
- @iowrapper.read(15)
56
- lambda { @iowrapper.sysread(5) }.should raise_error(IOError)
57
- end
58
-
59
- it "does not raise IOError if called after IO#read followed by IO#write" do
60
- @iowrapper.read(5)
61
- @iowrapper.write("abcde")
62
- lambda { @iowrapper.sysread(5) }.should_not raise_error(IOError)
63
- end
64
-
65
- it "does not raise IOError if called after IO#read followed by IO#syswrite" do
66
- @iowrapper.read(5)
67
- @iowrapper.syswrite("abcde")
68
- lambda { @iowrapper.sysread(5) }.should_not raise_error(IOError)
69
- end
70
-
71
- it "reads updated content after the flushed buffered IO#write" do
72
- @iowrapper.write("abcde")
73
- @iowrapper.flush
74
- @iowrapper.sysread(5).should == @contents.slice(5, 5)
75
- File.open(@filename) do |f|
76
- f.sysread(10).should == "abcde56789"
77
- end
78
- end
79
-
80
- it "raises IOError on write-only stream" do
81
- lambda { IOSpecs.writable_iowrapper.sysread(5) }.should raise_error(IOError)
82
- end
83
-
84
- it "raises IOError on closed stream" do
85
- lambda { IOSpecs.closed_file.sysread(5) }.should raise_error(IOError)
86
- end
87
- end
data/spec/sysseek_spec.rb DELETED
@@ -1,68 +0,0 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
2
- require File.dirname(__FILE__) + '/fixtures/classes'
3
-
4
- describe "IO::Like#sysseek on a file" do
5
- # TODO: This should be made more generic with seek spec
6
- before :each do
7
- @file = File.open(File.dirname(__FILE__) + '/fixtures/readlines.txt', 'r')
8
- @iowrapper = IOWrapper.open(@file)
9
- end
10
-
11
- after :each do
12
- @iowrapper.close unless @iowrapper.closed?
13
- @file.close unless @file.closed?
14
- end
15
-
16
- it "moves the read position relative to the current position with SEEK_CUR" do
17
- @iowrapper.sysseek(10, IO::SEEK_CUR)
18
- @iowrapper.readline.should == "igne une.\n"
19
- end
20
-
21
- it "raises an error when called after buffered reads" do
22
- @iowrapper.readline
23
- lambda { @iowrapper.sysseek(-5, IO::SEEK_CUR) }.should raise_error(IOError)
24
- end
25
-
26
- it "warns if called immediately after a buffered IO#write" do
27
- begin
28
- # copy contents to a separate file
29
- tmpfile = File.open(tmp("tmp_IO_sysseek"), "w")
30
- wrapper = IOWrapper.open(tmpfile)
31
- wrapper.write(@iowrapper.read)
32
- wrapper.seek(0, File::SEEK_SET)
33
-
34
- wrapper.write("abcde")
35
- lambda { wrapper.sysseek(10) }.should complain(/sysseek/)
36
- ensure
37
- wrapper.close
38
- File.unlink(tmpfile.path)
39
- end
40
- end
41
-
42
- it "moves the read position relative to the start with SEEK_SET" do
43
- @iowrapper.sysseek(42, IO::SEEK_SET)
44
- @iowrapper.readline.should == "quí está la línea tres.\n"
45
- end
46
-
47
- it "moves the read position relative to the end with SEEK_END" do
48
- @iowrapper.sysseek(1, IO::SEEK_END)
49
-
50
- # this is the safest way of checking the EOF when
51
- # sys-* methods are invoked
52
- lambda { @iowrapper.sysread(1) }.should raise_error(EOFError)
53
-
54
- @iowrapper.sysseek(-25, IO::SEEK_END)
55
- @iowrapper.sysread(7).should == "cinco.\n"
56
- end
57
-
58
- it "can handle any numerical argument without breaking and can seek past EOF" do
59
- @iowrapper.sysseek(1.2).should == 1
60
- @iowrapper.sysseek(2**10).should == 1024
61
- @iowrapper.sysseek(2**32).should == 4294967296
62
- lambda { @iowrapper.sysseek(2**128) }.should raise_error(RangeError)
63
- end
64
-
65
- it "raises IOError on closed stream" do
66
- lambda { IOSpecs.closed_file.sysseek(0) }.should raise_error(IOError)
67
- end
68
- end
@@ -1,60 +0,0 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
2
- require File.dirname(__FILE__) + '/fixtures/classes'
3
- require File.dirname(__FILE__) + '/shared/write'
4
-
5
- describe "IO::Like#syswrite" do
6
- before :each do
7
- @filename = tmp("IO_Like__syswrite_test")
8
- @content = "012345678901234567890123456789"
9
- File.open(@filename, "w") { |f| f.syswrite(@content) }
10
- @file = File.open(@filename, "r+")
11
- @iowrapper = IOWrapper.open(@file)
12
- end
13
-
14
- after :each do
15
- @iowrapper.close unless @iowrapper.closed?
16
- @file.close unless @file.closed?
17
- File.delete(@filename)
18
- end
19
-
20
- it "returns the number of bytes written" do
21
- @iowrapper.syswrite('').should == 0
22
- @iowrapper.syswrite('abcde').should == 5
23
- end
24
-
25
- it "writes all of the string's bytes but does not buffer them" do
26
- written = @iowrapper.syswrite("abcde")
27
- written.should == 5
28
- File.open(@filename) do |file|
29
- file.sysread(10).should == "abcde56789"
30
- file.seek(0)
31
- @iowrapper.flush
32
- file.sysread(10).should == "abcde56789"
33
- end
34
- end
35
-
36
- not_compliant_on :rubinius do
37
- it "warns if called immediately after a buffered IO#write" do
38
- @iowrapper.write("abcde")
39
- lambda { @iowrapper.syswrite("fghij") }.should complain(/syswrite/)
40
- end
41
- end
42
-
43
- it "does not warn if called after IO#write with intervening IO#sysread" do
44
- @iowrapper.write("abcde")
45
- @iowrapper.sysread(5)
46
- lambda { @iowrapper.syswrite("fghij") }.should_not complain
47
- end
48
-
49
- it "writes to the actual file position when called after buffered IO#read" do
50
- @iowrapper.read(5)
51
- @iowrapper.syswrite("abcde")
52
- File.open(@filename) do |file|
53
- file.sysread(10).should == "01234abcde"
54
- end
55
- end
56
- end
57
-
58
- describe "IO::Like#syswrite" do
59
- it_behaves_like :io_like__write, :syswrite
60
- end
data/spec/tell_spec.rb DELETED
@@ -1,7 +0,0 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
2
- require File.dirname(__FILE__) + '/fixtures/classes'
3
- require File.dirname(__FILE__) + '/shared/pos'
4
-
5
- describe "IO::Like#tell" do
6
- it_behaves_like(:io_like__pos, :tell)
7
- end
data/spec/to_io_spec.rb DELETED
@@ -1,19 +0,0 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
2
- require File.dirname(__FILE__) + '/fixtures/classes'
3
-
4
- describe "IO::Like#to_io" do
5
- it "returns self for open stream" do
6
- IOSpecs.readable_iowrapper do |iowrapper|
7
- iowrapper.to_io.should == iowrapper
8
- end
9
-
10
- IOSpecs.writable_iowrapper do |iowrapper|
11
- iowrapper.to_io.should == iowrapper
12
- end
13
- end
14
-
15
- it "returns self for closed stream" do
16
- io = IOSpecs.closed_file
17
- io.to_io.should == io
18
- end
19
- end
data/spec/tty_spec.rb DELETED
@@ -1,6 +0,0 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
2
- require File.dirname(__FILE__) + '/shared/tty'
3
-
4
- describe "IO::Like#tty?" do
5
- it_behaves_like :io_like__tty, :tty?
6
- end
data/spec/ungetc_spec.rb DELETED
@@ -1,118 +0,0 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
2
- require File.dirname(__FILE__) + '/fixtures/classes'
3
-
4
- describe "IO::Like#ungetc" do
5
- before :each do
6
- @file_name = File.dirname(__FILE__) + '/fixtures/readlines.txt'
7
- @file = File.open(@file_name, 'r')
8
- @iowrapper = ReadableIOWrapper.open(@file)
9
- end
10
-
11
- after :each do
12
- @iowrapper.close unless @iowrapper.closed?
13
- @file.close unless @file.closed?
14
- end
15
-
16
- it "pushes back one character onto stream" do
17
- @iowrapper.getc.should == 86
18
- @iowrapper.ungetc(86)
19
- @iowrapper.getc.should == 86
20
-
21
- @iowrapper.ungetc(10)
22
- @iowrapper.getc.should == 10
23
-
24
- @iowrapper.getc.should == 111
25
- @iowrapper.getc.should == 105
26
- # read the rest of line
27
- @iowrapper.readline.should == "ci la ligne une.\n"
28
- @iowrapper.getc.should == 81
29
- @iowrapper.ungetc(99)
30
- @iowrapper.getc.should == 99
31
- end
32
-
33
- it "pushes back one character when invoked at the end of the stream" do
34
- # read entire content
35
- @iowrapper.read
36
- @iowrapper.ungetc(100)
37
- @iowrapper.getc.should == 100
38
- end
39
-
40
- it "pushes back one character when invoked at the start of the stream" do
41
- @iowrapper.read(0)
42
- @iowrapper.ungetc(100)
43
- @iowrapper.getc.should == 100
44
- end
45
-
46
- it "pushes back one character when invoked on empty stream" do
47
- path = tmp('empty.txt')
48
- File.open(path, "w+") do |empty|
49
- IOWrapper.open(empty) do |iowrapper|
50
- iowrapper.getc().should == nil
51
- iowrapper.ungetc(10)
52
- iowrapper.getc.should == 10
53
- end
54
- end
55
- File.unlink(path)
56
- end
57
-
58
- it "affects EOF state" do
59
- path = tmp('empty.txt')
60
- File.open(path, "w+") do |empty|
61
- IOWrapper.open(empty) do |iowrapper|
62
- iowrapper.eof?.should == true
63
- iowrapper.getc.should == nil
64
- iowrapper.ungetc(100)
65
- iowrapper.eof?.should == false
66
- end
67
- end
68
- File.unlink(path)
69
- end
70
-
71
- it "adjusts the stream position" do
72
- @iowrapper.pos.should == 0
73
-
74
- # read one char
75
- c = @iowrapper.getc
76
- @iowrapper.pos.should == 1
77
- @iowrapper.ungetc(c)
78
- @iowrapper.pos.should == 0
79
-
80
- # read all
81
- @iowrapper.read
82
- pos = @iowrapper.pos
83
- @iowrapper.ungetc(98)
84
- @iowrapper.pos.should == pos - 1
85
- end
86
-
87
- # TODO: file MRI bug
88
- # Another specified behavior that MRI doesn't follow:
89
- # "Has no effect with unbuffered reads (such as IO#sysread)."
90
- #
91
- #it "has no effect with unbuffered reads" do
92
- # length = File.size(@file_name)
93
- # content = @iowrapper.sysread(length)
94
- # @iowrapper.rewind
95
- # @iowrapper.ungetc(100)
96
- # @iowrapper.sysread(length).should == content
97
- #end
98
-
99
- it "makes subsequent unbuffered operations to raise IOError" do
100
- @iowrapper.getc
101
- @iowrapper.ungetc(100)
102
- lambda { @iowrapper.sysread(1) }.should raise_error(IOError)
103
- end
104
-
105
- # WORKS AS DESIGNED:
106
- # Since IO::Like has complete control over the read buffer, it supports
107
- # pushing unlimited data into that buffer at any time on any readable stream.
108
- #
109
- #it "raises IOError when invoked on stream that was not yet read" do
110
- # lambda { @iowrapper.ungetc(100) }.should raise_error(IOError)
111
- #end
112
-
113
- it "raises IOError on closed stream" do
114
- @iowrapper.getc
115
- @iowrapper.close
116
- lambda { @iowrapper.ungetc(100) }.should raise_error(IOError)
117
- end
118
- end