io-like 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
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