io-like 0.3.0 → 0.3.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 (62) hide show
  1. data/.yardopts +1 -0
  2. data/LICENSE +22 -57
  3. data/{LICENSE.rubyspec → LICENSE-rubyspec} +0 -0
  4. data/{NEWS → NEWS.md} +10 -5
  5. data/README.md +269 -0
  6. data/Rakefile +228 -0
  7. data/ruby.1.8.mspec +7 -0
  8. data/spec/binmode_spec.rb +29 -0
  9. data/spec/close_read_spec.rb +64 -0
  10. data/spec/close_spec.rb +36 -0
  11. data/spec/close_write_spec.rb +61 -0
  12. data/spec/closed_spec.rb +16 -0
  13. data/spec/each_byte_spec.rb +38 -0
  14. data/spec/each_line_spec.rb +11 -0
  15. data/spec/each_spec.rb +11 -0
  16. data/spec/eof_spec.rb +11 -0
  17. data/spec/fixtures/classes.rb +96 -0
  18. data/spec/fixtures/gets.txt +9 -0
  19. data/spec/fixtures/numbered_lines.txt +5 -0
  20. data/spec/fixtures/one_byte.txt +1 -0
  21. data/spec/fixtures/paragraphs.txt +7 -0
  22. data/spec/fixtures/readlines.txt +6 -0
  23. data/spec/flush_spec.rb +8 -0
  24. data/spec/getc_spec.rb +44 -0
  25. data/spec/gets_spec.rb +212 -0
  26. data/spec/isatty_spec.rb +6 -0
  27. data/spec/lineno_spec.rb +84 -0
  28. data/spec/output_spec.rb +47 -0
  29. data/spec/pos_spec.rb +53 -0
  30. data/spec/print_spec.rb +97 -0
  31. data/spec/printf_spec.rb +24 -0
  32. data/spec/putc_spec.rb +57 -0
  33. data/spec/puts_spec.rb +99 -0
  34. data/spec/read_spec.rb +162 -0
  35. data/spec/readchar_spec.rb +49 -0
  36. data/spec/readline_spec.rb +60 -0
  37. data/spec/readlines_spec.rb +140 -0
  38. data/spec/readpartial_spec.rb +92 -0
  39. data/spec/rewind_spec.rb +56 -0
  40. data/spec/seek_spec.rb +72 -0
  41. data/spec/shared/each.rb +204 -0
  42. data/spec/shared/eof.rb +116 -0
  43. data/spec/shared/pos.rb +39 -0
  44. data/spec/shared/tty.rb +12 -0
  45. data/spec/shared/write.rb +53 -0
  46. data/spec/sync_spec.rb +56 -0
  47. data/spec/sysread_spec.rb +87 -0
  48. data/spec/sysseek_spec.rb +68 -0
  49. data/spec/syswrite_spec.rb +60 -0
  50. data/spec/tell_spec.rb +7 -0
  51. data/spec/to_io_spec.rb +19 -0
  52. data/spec/tty_spec.rb +6 -0
  53. data/spec/ungetc_spec.rb +118 -0
  54. data/spec/write_spec.rb +61 -0
  55. data/spec_helper.rb +49 -0
  56. metadata +223 -32
  57. data/CONTRIBUTORS +0 -15
  58. data/GPL +0 -676
  59. data/HACKING +0 -123
  60. data/LEGAL +0 -56
  61. data/MANIFEST +0 -10
  62. data/README +0 -150
@@ -0,0 +1,212 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require File.dirname(__FILE__) + '/fixtures/classes'
3
+
4
+ describe "IO::Like#gets" do
5
+ it "returns the next line of string that were separated by $/" do
6
+ IOSpecs.readable_iowrapper do |f|
7
+ IOSpecs.lines.each { |line| line.should == f.gets }
8
+ end
9
+ end
10
+
11
+ it "returns tainted strings" do
12
+ IOSpecs.readable_iowrapper do |f|
13
+ while (line = f.gets(nil))
14
+ line.tainted?.should == true
15
+ end
16
+ end
17
+
18
+ IOSpecs.readable_iowrapper do |f|
19
+ while (line = f.gets(""))
20
+ line.tainted?.should == true
21
+ end
22
+ end
23
+
24
+ IOSpecs.readable_iowrapper do |f|
25
+ while (line = f.gets)
26
+ line.tainted?.should == true
27
+ end
28
+ end
29
+
30
+ IOSpecs.readable_iowrapper do |f|
31
+ while (line = f.gets("la"))
32
+ line.tainted?.should == true
33
+ end
34
+ end
35
+ end
36
+
37
+ it "updates lineno with each invocation" do
38
+ count = 1
39
+ IOSpecs.readable_iowrapper do |f|
40
+ while (line = f.gets(nil))
41
+ f.lineno.should == count
42
+ count += 1
43
+ end
44
+ end
45
+
46
+ count = 1
47
+ IOSpecs.readable_iowrapper do |f|
48
+ while (line = f.gets(""))
49
+ f.lineno.should == count
50
+ count += 1
51
+ end
52
+ end
53
+
54
+ count = 1
55
+ IOSpecs.readable_iowrapper do |f|
56
+ while (line = f.gets)
57
+ f.lineno.should == count
58
+ count += 1
59
+ end
60
+ end
61
+
62
+ count = 1
63
+ IOSpecs.readable_iowrapper do |f|
64
+ while (line = f.gets("la"))
65
+ f.lineno.should == count
66
+ count += 1
67
+ end
68
+ end
69
+ end
70
+
71
+ it "updates $. with each invocation" do
72
+ count = 1
73
+ IOSpecs.readable_iowrapper do |f|
74
+ while (line = f.gets(nil))
75
+ $..should == count
76
+ count += 1
77
+ end
78
+ end
79
+
80
+ count = 1
81
+ IOSpecs.readable_iowrapper do |f|
82
+ while (line = f.gets(""))
83
+ $..should == count
84
+ count += 1
85
+ end
86
+ end
87
+
88
+ count = 1
89
+ IOSpecs.readable_iowrapper do |f|
90
+ while (line = f.gets)
91
+ $..should == count
92
+ count += 1
93
+ end
94
+ end
95
+
96
+ count = 1
97
+ IOSpecs.readable_iowrapper do |f|
98
+ while (line = f.gets("la"))
99
+ $..should == count
100
+ count += 1
101
+ end
102
+ end
103
+ end
104
+
105
+ # MRI LIMITATION:
106
+ # $_ will not cross out of the implementation of gets since its value is
107
+ # limited to the local scope in managed code.
108
+ #
109
+ #it "assigns the returned line to $_" do
110
+ # IOSpecs.readable_iowrapper do |f|
111
+ # IOSpecs.lines.each do |line|
112
+ # f.gets
113
+ # $line.should == line
114
+ # end
115
+ # end
116
+ #end
117
+
118
+ it "returns nil if called at the end of the stream" do
119
+ IOSpecs.readable_iowrapper do |f|
120
+ IOSpecs.lines.length.times { f.gets }
121
+ f.gets.should == nil
122
+ end
123
+ end
124
+
125
+ it "returns the entire content if the separator is nil" do
126
+ IOSpecs.readable_iowrapper do |f|
127
+ f.gets(nil).should == IOSpecs.lines.join('')
128
+ end
129
+ end
130
+
131
+ it "reads and returns all data available before a SystemCallError is raised when the separator is nil" do
132
+ file = File.open(IOSpecs.gets_fixtures)
133
+ # Overrride file.sysread to raise SystemCallError every other time it's
134
+ # called.
135
+ class << file
136
+ alias :sysread_orig :sysread
137
+ def sysread(length)
138
+ if @error_raised then
139
+ @error_raised = false
140
+ sysread_orig(length)
141
+ else
142
+ @error_raised = true
143
+ raise SystemCallError, 'Test Error'
144
+ end
145
+ end
146
+ end
147
+
148
+ ReadableIOWrapper.open(file) do |iowrapper|
149
+ lambda { iowrapper.gets(nil) }.should raise_error(SystemCallError)
150
+ iowrapper.gets(nil).should == IOSpecs.lines.join('')
151
+ end
152
+ file.close
153
+ end
154
+
155
+ # Two successive newlines in the input separate paragraphs.
156
+ # When there are more than two successive newlines, only two are kept.
157
+ it "returns the next paragraph if the separator's length is 0" do
158
+ a = "Voici la ligne une.\nQui \303\250 la linea due.\n\n"
159
+ b = "Aqu\303\255 est\303\241 la l\303\255nea tres.\nIst hier Linie vier.\n\n"
160
+ c = "Est\303\241 aqui a linha cinco.\nHere is line six.\n"
161
+
162
+ IOSpecs.readable_iowrapper do |f|
163
+ f.gets("").should == a
164
+ f.gets("").should == b
165
+ f.gets("").should == c
166
+ end
167
+ end
168
+
169
+ # This could probably be added to the previous test using pos, but right now
170
+ # this doesn't pass and the previous test does.
171
+ it "reads until the beginning of the next paragraph when the separator's length is 0" do
172
+ # Leverage the fact that there are three newlines between the first and
173
+ # second paragraph.
174
+ IOSpecs.readable_iowrapper do |f|
175
+ f.gets('')
176
+
177
+ # This should return 'A', the first character of the next paragraph, not
178
+ # $/.
179
+ f.read(1).should == 'A'
180
+ end
181
+ end
182
+
183
+ it "raises an IOError if the stream is not opened for reading" do
184
+ path = tmp("gets_spec")
185
+ lambda do
186
+ File.open(path, 'w') do |f|
187
+ WritableIOWrapper.open(f) { |iowrapper| iowrapper.gets }
188
+ end
189
+ end.should raise_error(IOError)
190
+ File.unlink(path) if File.exist?(path)
191
+ end
192
+
193
+ it "raises IOError on closed stream" do
194
+ lambda { IOSpecs.closed_file.gets }.should raise_error(IOError)
195
+ end
196
+
197
+ it "accepts a separator" do
198
+ path = tmp("gets_specs")
199
+ f = File.open(path, "w")
200
+ f.print("A\n\n\nB\n")
201
+ f.close
202
+ f = File.open(path, "r")
203
+ iowrapper = ReadableIOWrapper.open(f)
204
+ iowrapper.gets("\n\n")
205
+ b = iowrapper.gets("\n\n")
206
+ iowrapper.gets("\n\n")
207
+ iowrapper.close
208
+ f.close
209
+ b.should == "\nB\n"
210
+ File.unlink(path)
211
+ end
212
+ end
@@ -0,0 +1,6 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require File.dirname(__FILE__) + '/shared/tty'
3
+
4
+ describe "IO::Like#isatty" do
5
+ it_behaves_like :io_like__tty, :isatty
6
+ end
@@ -0,0 +1,84 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require File.dirname(__FILE__) + '/fixtures/classes'
3
+
4
+ describe "IO::Like#lineno" do
5
+ it "raises IOError on closed stream" do
6
+ lambda { IOSpecs.closed_file.lineno }.should raise_error(IOError)
7
+ end
8
+
9
+ it "returns the current line number" do
10
+ IOSpecs.readable_iowrapper do |f|
11
+ f.lineno.should == 0
12
+ while (f.gets)
13
+ f.lineno.should > 0
14
+ end
15
+ f.rewind
16
+ f.lineno.should == 0
17
+ end
18
+ end
19
+ end
20
+
21
+ describe "IO::Like#lineno=" do
22
+ it "raises IOError on closed stream" do
23
+ lambda { IOSpecs.closed_file.lineno = 5 }.should raise_error(IOError)
24
+ end
25
+
26
+ it "invokes to_int on non-numeric arguments" do
27
+ (obj = mock('123')).should_receive(:to_int).and_return(123)
28
+ IOSpecs.readable_iowrapper do |f|
29
+ f.lineno = obj
30
+ f.lineno.should == 123
31
+
32
+ f.lineno = 1.5
33
+ f.lineno.should == 1
34
+
35
+ f.lineno = 92233.72036854775808
36
+ f.lineno.should == 92233
37
+ end
38
+ end
39
+
40
+ it "raises TypeError on nil argument" do
41
+ IOSpecs.readable_iowrapper do |f|
42
+ lambda { f.lineno = nil }.should raise_error(TypeError)
43
+ end
44
+ end
45
+
46
+ it "sets the current line number to the given value" do
47
+ IOSpecs.readable_iowrapper do |f|
48
+ count = 500
49
+ f.lineno = count - 1
50
+ while (f.gets)
51
+ f.lineno.should == count
52
+ count += 1
53
+ end
54
+ f.rewind
55
+ f.lineno.should == 0
56
+ end
57
+ end
58
+
59
+ it "does not change $." do
60
+ orig_value = $.
61
+ IOSpecs.readable_iowrapper do |f|
62
+ numbers = [-2**30, -2**16, -2**8, -100, -10, -1, 0, 1, 10, 2**8, 2**16, 2**30]
63
+ numbers.each { |num|
64
+ f.lineno = num
65
+ f.lineno.should == num
66
+ $..should == orig_value
67
+ }
68
+ end
69
+ end
70
+
71
+ it "does not change $. until next read" do
72
+ $. = 0
73
+ IOSpecs.readable_iowrapper do |f|
74
+ $..should == 0
75
+ count = 500
76
+ f.lineno = count - 1
77
+ $..should == 0
78
+ while (f.gets)
79
+ $..should == count
80
+ count += 1
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,47 @@
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#<<" do
6
+ before :each do
7
+ @filename = tmp("IO_Like__write_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 a reference to the stream" do
21
+ (@iowrapper << 'abcde').should == @iowrapper
22
+ end
23
+
24
+ it "writes all of the string's bytes without buffering if mode is sync" do
25
+ @iowrapper.sync = true
26
+ @iowrapper << "abcde"
27
+ File.open(@filename) do |file|
28
+ file.read(10).should == "abcde56789"
29
+ end
30
+ end
31
+
32
+ it "does not raise IOError on read-only stream if writing zero bytes" do
33
+ lambda do
34
+ IOSpecs.readable_iowrapper do |iowrapper|
35
+ iowrapper << ""
36
+ end
37
+ end.should_not raise_error
38
+ end
39
+
40
+ it "does not raise IOError on closed stream if writing zero bytes" do
41
+ lambda { IOSpecs.closed_file << "" }.should_not raise_error
42
+ end
43
+ end
44
+
45
+ describe "IO::Like#<<" do
46
+ it_behaves_like :io_like__write, :<<
47
+ end
@@ -0,0 +1,53 @@
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#pos" do
6
+ it_behaves_like(:io_like__pos, :pos)
7
+ end
8
+
9
+ describe "IO::Like#pos=" do
10
+ before :each do
11
+ @fname = 'test.txt'
12
+ File.open(@fname, 'w') { |f| f.write("123") }
13
+ end
14
+
15
+ after :each do
16
+ File.unlink(@fname)
17
+ end
18
+
19
+ it "sets the offset" do
20
+ File.open(@fname) do |f|
21
+ ReadableIOWrapper.open(f) do |iowrapper|
22
+ val1 = iowrapper.read(1)
23
+ iowrapper.pos = 0
24
+ iowrapper.read(1).should == val1
25
+ end
26
+ end
27
+ end
28
+
29
+ it "can handle any numerical argument without breaking" do
30
+ File.open(@fname) do |f|
31
+ ReadableIOWrapper.open(f) do |iowrapper|
32
+ iowrapper.pos = 1.2
33
+ iowrapper.pos.should == 1
34
+
35
+ iowrapper.pos = 2**32
36
+ iowrapper.pos.should == 2**32
37
+
38
+ iowrapper.pos = 1.23423423432e12
39
+ iowrapper.pos.should == Integer(1.23423423432e12)
40
+
41
+ iowrapper.pos = Float::EPSILON
42
+ iowrapper.pos.should == 0
43
+
44
+ lambda { iowrapper.pos = 2**128 }.should raise_error(RangeError)
45
+ end
46
+ end
47
+ end
48
+
49
+ it "raises IOError on closed stream" do
50
+ lambda { IOSpecs.closed_file.pos = 0 }.should raise_error(IOError)
51
+ end
52
+ end
53
+
@@ -0,0 +1,97 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require File.dirname(__FILE__) + '/fixtures/classes'
3
+
4
+ describe "IO::Like#print" do
5
+ before :each do
6
+ @old_record_separator = $\
7
+ @old_field_separator = $,
8
+ @filename = tmp('IO_Like__print_test')
9
+ @file = File.open(@filename, 'w')
10
+ @file.sync = true
11
+ @iowrapper = WritableIOWrapper.open(@file)
12
+ @iowrapper.sync = true
13
+ end
14
+
15
+ after :each do
16
+ $\ = @old_record_separator
17
+ $, = @old_field_separator
18
+ @iowrapper.close unless @iowrapper.closed?
19
+ @file.close unless @file.closed?
20
+ end
21
+
22
+ it "returns nil" do
23
+ @iowrapper.print('hello').should == nil
24
+ end
25
+
26
+ # MRI LIMITATION:
27
+ # $_ will not cross into the implementation of print since its value is
28
+ # limited to the local scope in managed code.
29
+ #
30
+ #it "writes $_ by default" do
31
+ # $_ = 'hello'
32
+ # @iowrapper.print()
33
+ # @iowrapper.close
34
+ # @file.close
35
+ # File.read(@filename).should == "hello\n"
36
+ #end
37
+
38
+ it "coerces arguments to strings using to_s" do
39
+ data = 'abcdefgh9876'
40
+ (obj = mock('test')).should_receive(:to_s).and_return(data)
41
+ @iowrapper.print(obj)
42
+ File.read(@filename).should == data
43
+ end
44
+
45
+ it "writes nil arguments as \"nil\"" do
46
+ @iowrapper.print(nil)
47
+ File.read(@filename).should == "nil"
48
+ end
49
+
50
+ it "appends $\\ to the output" do
51
+ $\ = '->'
52
+ data = 'abcdefgh9876'
53
+ @iowrapper.print(data)
54
+ File.read(@filename).should == "#{data}#{$\}"
55
+ end
56
+
57
+ it "does not append $\\ to the output when it is nil" do
58
+ $\ = nil
59
+ data = 'abcdefgh9876'
60
+ @iowrapper.print(data)
61
+ File.read(@filename).should == data
62
+ end
63
+
64
+ it "writes $, between arguments" do
65
+ $, = '->'
66
+ data1 = 'abcdefgh9876'
67
+ data2 = '12345678zyxw'
68
+ @iowrapper.print(data1, data2)
69
+ File.read(@filename).should == "#{data1}#{$,}#{data2}"
70
+ end
71
+
72
+ it "does not write $, between arguments when it is nil" do
73
+ $, = nil
74
+ data1 = 'abcdefgh9876'
75
+ data2 = '12345678zyxw'
76
+ @iowrapper.print(data1, data2)
77
+ File.read(@filename).should == "#{data1}#{data2}"
78
+ end
79
+
80
+ it "does not check if the file is writable if writing zero bytes" do
81
+ lambda { IOSpecs.readable_iowrapper.print("") }.should_not raise_error
82
+ end
83
+
84
+ it "checks if the file is writable if writing more than zero bytes" do
85
+ lambda do
86
+ IOSpecs.readable_iowrapper.print("hello")
87
+ end.should raise_error(IOError)
88
+ end
89
+
90
+ it "does not raise IOError on closed stream if writing zero bytes" do
91
+ lambda { IOSpecs.closed_file.print("") }.should_not raise_error
92
+ end
93
+
94
+ it "raises IOError on closed stream if writing more than zero bytes" do
95
+ lambda { IOSpecs.closed_file.print("hello") }.should raise_error(IOError)
96
+ end
97
+ end