rubysl-stringio 1.0.0

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 +17 -0
  3. data/.travis.yml +7 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE +25 -0
  6. data/README.md +29 -0
  7. data/Rakefile +1 -0
  8. data/lib/rubysl/stringio.rb +2 -0
  9. data/lib/rubysl/stringio/stringio.rb +611 -0
  10. data/lib/rubysl/stringio/version.rb +5 -0
  11. data/lib/stringio.rb +1 -0
  12. data/rubysl-stringio.gemspec +24 -0
  13. data/spec/append_spec.rb +83 -0
  14. data/spec/binmode_spec.rb +8 -0
  15. data/spec/bytes_spec.rb +12 -0
  16. data/spec/chars_spec.rb +12 -0
  17. data/spec/close_read_spec.rb +30 -0
  18. data/spec/close_spec.rb +22 -0
  19. data/spec/close_write_spec.rb +30 -0
  20. data/spec/closed_read_spec.rb +11 -0
  21. data/spec/closed_spec.rb +15 -0
  22. data/spec/closed_write_spec.rb +11 -0
  23. data/spec/codepoints_spec.rb +11 -0
  24. data/spec/each_byte_spec.rb +10 -0
  25. data/spec/each_char_spec.rb +12 -0
  26. data/spec/each_codepoint_spec.rb +12 -0
  27. data/spec/each_line_spec.rb +14 -0
  28. data/spec/each_spec.rb +14 -0
  29. data/spec/eof_spec.rb +10 -0
  30. data/spec/external_encoding_spec.rb +12 -0
  31. data/spec/fcntl_spec.rb +7 -0
  32. data/spec/fileno_spec.rb +8 -0
  33. data/spec/fixtures/classes.rb +15 -0
  34. data/spec/flush_spec.rb +8 -0
  35. data/spec/fsync_spec.rb +8 -0
  36. data/spec/getbyte_spec.rb +25 -0
  37. data/spec/getc_spec.rb +31 -0
  38. data/spec/gets_spec.rb +245 -0
  39. data/spec/initialize_copy_spec.rb +95 -0
  40. data/spec/initialize_spec.rb +193 -0
  41. data/spec/internal_encoding_spec.rb +12 -0
  42. data/spec/isatty_spec.rb +6 -0
  43. data/spec/length_spec.rb +6 -0
  44. data/spec/lineno_spec.rb +29 -0
  45. data/spec/lines_spec.rb +16 -0
  46. data/spec/open_spec.rb +215 -0
  47. data/spec/path_spec.rb +15 -0
  48. data/spec/pid_spec.rb +7 -0
  49. data/spec/pos_spec.rb +27 -0
  50. data/spec/print_spec.rb +113 -0
  51. data/spec/printf_spec.rb +60 -0
  52. data/spec/putc_spec.rb +105 -0
  53. data/spec/puts_spec.rb +173 -0
  54. data/spec/read_nonblock_spec.rb +29 -0
  55. data/spec/read_spec.rb +62 -0
  56. data/spec/readbyte_spec.rb +21 -0
  57. data/spec/readchar_spec.rb +19 -0
  58. data/spec/readline_spec.rb +127 -0
  59. data/spec/readlines_spec.rb +124 -0
  60. data/spec/readpartial_spec.rb +29 -0
  61. data/spec/reopen_spec.rb +303 -0
  62. data/spec/rewind_spec.rb +23 -0
  63. data/spec/seek_spec.rb +75 -0
  64. data/spec/set_encoding_spec.rb +34 -0
  65. data/spec/shared/codepoints.rb +45 -0
  66. data/spec/shared/each.rb +162 -0
  67. data/spec/shared/each_byte.rb +60 -0
  68. data/spec/shared/each_char.rb +50 -0
  69. data/spec/shared/eof.rb +24 -0
  70. data/spec/shared/getc.rb +43 -0
  71. data/spec/shared/isatty.rb +5 -0
  72. data/spec/shared/length.rb +12 -0
  73. data/spec/shared/read.rb +186 -0
  74. data/spec/shared/readchar.rb +29 -0
  75. data/spec/shared/sysread.rb +27 -0
  76. data/spec/shared/tell.rb +12 -0
  77. data/spec/shared/write.rb +134 -0
  78. data/spec/size_spec.rb +6 -0
  79. data/spec/string_spec.rb +49 -0
  80. data/spec/stringio_spec.rb +8 -0
  81. data/spec/sync_spec.rb +18 -0
  82. data/spec/sysread_spec.rb +27 -0
  83. data/spec/syswrite_spec.rb +18 -0
  84. data/spec/tell_spec.rb +6 -0
  85. data/spec/truncate_spec.rb +69 -0
  86. data/spec/tty_spec.rb +6 -0
  87. data/spec/ungetbyte_spec.rb +88 -0
  88. data/spec/ungetc_spec.rb +98 -0
  89. data/spec/write_nonblock_spec.rb +20 -0
  90. data/spec/write_spec.rb +18 -0
  91. metadata +267 -0
@@ -0,0 +1,19 @@
1
+ require 'stringio'
2
+ require File.expand_path('../shared/readchar', __FILE__)
3
+
4
+ describe "StringIO#readchar" do
5
+ it_behaves_like :stringio_readchar, :readchar
6
+
7
+ it "reads the next 8-bit byte from self's current position" do
8
+ io = StringIO.new("example")
9
+
10
+ io.send(@method).should == ?e
11
+
12
+ io.pos = 4
13
+ io.send(@method).should == ?p
14
+ end
15
+ end
16
+
17
+ describe "StringIO#readchar when self is not readable" do
18
+ it_behaves_like :stringio_readchar_not_readable, :readchar
19
+ end
@@ -0,0 +1,127 @@
1
+ require File.expand_path('../fixtures/classes', __FILE__)
2
+
3
+
4
+ describe "StringIO#readline when passed [separator]" do
5
+ before(:each) do
6
+ @io = StringIO.new("this>is>an>example")
7
+ end
8
+
9
+ it "returns the data read till the next occurence of the passed separator" do
10
+ @io.readline(">").should == "this>"
11
+ @io.readline(">").should == "is>"
12
+ @io.readline(">").should == "an>"
13
+ @io.readline(">").should == "example"
14
+ end
15
+
16
+ ruby_bug "http://redmine.ruby-lang.org/issues/show/159", "1.8.7.17" do
17
+ it "sets $_ to the read content" do
18
+ @io.readline(">")
19
+ $_.should == "this>"
20
+ @io.readline(">")
21
+ $_.should == "is>"
22
+ @io.readline(">")
23
+ $_.should == "an>"
24
+ @io.readline(">")
25
+ $_.should == "example"
26
+ end
27
+ end
28
+
29
+ it "updates self's lineno by one" do
30
+ @io.readline(">")
31
+ @io.lineno.should eql(1)
32
+
33
+ @io.readline(">")
34
+ @io.lineno.should eql(2)
35
+
36
+ @io.readline(">")
37
+ @io.lineno.should eql(3)
38
+ end
39
+
40
+ ruby_bug "", "1.8.8" do
41
+ it "returns the next paragraph when the passed separator is an empty String" do
42
+ io = StringIO.new("this is\n\nan example")
43
+ io.readline("").should == "this is\n\n"
44
+ io.readline("").should == "an example"
45
+ end
46
+ end
47
+
48
+ it "returns the remaining content starting at the current position when passed nil" do
49
+ io = StringIO.new("this is\n\nan example")
50
+ io.pos = 5
51
+ io.readline(nil).should == "is\n\nan example"
52
+ end
53
+
54
+ it "tries to convert the passed separator to a String using #to_str" do
55
+ obj = mock('to_str')
56
+ obj.should_receive(:to_str).and_return(">")
57
+ @io.readline(obj).should == "this>"
58
+ end
59
+ end
60
+
61
+ describe "StringIO#readline when passed no argument" do
62
+ before(:each) do
63
+ @io = StringIO.new("this is\nan example\nfor StringIO#readline")
64
+ end
65
+
66
+ it "returns the data read till the next occurence of $/ or till eof" do
67
+ @io.readline.should == "this is\n"
68
+
69
+ begin
70
+ old_sep, $/ = $/, " "
71
+ @io.readline.should == "an "
72
+ @io.readline.should == "example\nfor "
73
+ @io.readline.should == "StringIO#readline"
74
+ ensure
75
+ $/ = old_sep
76
+ end
77
+ end
78
+
79
+ ruby_bug "http://redmine.ruby-lang.org/issues/show/159", "1.8.7.17" do
80
+ it "sets $_ to the read content" do
81
+ @io.readline
82
+ $_.should == "this is\n"
83
+ @io.readline
84
+ $_.should == "an example\n"
85
+ @io.readline
86
+ $_.should == "for StringIO#readline"
87
+ end
88
+ end
89
+
90
+ it "updates self's position" do
91
+ @io.readline
92
+ @io.pos.should eql(8)
93
+
94
+ @io.readline
95
+ @io.pos.should eql(19)
96
+
97
+ @io.readline
98
+ @io.pos.should eql(40)
99
+ end
100
+
101
+ it "updates self's lineno" do
102
+ @io.readline
103
+ @io.lineno.should eql(1)
104
+
105
+ @io.readline
106
+ @io.lineno.should eql(2)
107
+
108
+ @io.readline
109
+ @io.lineno.should eql(3)
110
+ end
111
+
112
+ it "raises an IOError if self is at the end" do
113
+ @io.pos = 40
114
+ lambda { @io.readline }.should raise_error(IOError)
115
+ end
116
+ end
117
+
118
+ describe "StringIO#readline when in write-only mode" do
119
+ it "raises an IOError" do
120
+ io = StringIO.new("xyz", "w")
121
+ lambda { io.readline }.should raise_error(IOError)
122
+
123
+ io = StringIO.new("xyz")
124
+ io.close_read
125
+ lambda { io.readline }.should raise_error(IOError)
126
+ end
127
+ end
@@ -0,0 +1,124 @@
1
+ require File.expand_path('../fixtures/classes', __FILE__)
2
+
3
+ describe "StringIO#readlines when passed [separator]" do
4
+ before(:each) do
5
+ @io = StringIO.new("this>is>an>example")
6
+ end
7
+
8
+ it "returns an Array containing lines based on the passed separator" do
9
+ @io.readlines(">").should == ["this>", "is>", "an>", "example"]
10
+ end
11
+
12
+ it "updates self's position based on the number of read bytes" do
13
+ @io.readlines(">")
14
+ @io.pos.should eql(18)
15
+ end
16
+
17
+ it "updates self's lineno based on the number of read lines" do
18
+ @io.readlines(">")
19
+ @io.lineno.should eql(4)
20
+ end
21
+
22
+ it "does not change $_" do
23
+ $_ = "test"
24
+ @io.readlines(">")
25
+ $_.should == "test"
26
+ end
27
+
28
+ ruby_bug "", "1.8.8" do
29
+ it "returns an Array containing all paragraphs when the passed separator is an empty String" do
30
+ io = StringIO.new("this is\n\nan example")
31
+ io.readlines("").should == ["this is\n\n", "an example"]
32
+ end
33
+ end
34
+
35
+ it "returns the remaining content as one line starting at the current position when passed nil" do
36
+ io = StringIO.new("this is\n\nan example")
37
+ io.pos = 5
38
+ io.readlines(nil).should == ["is\n\nan example"]
39
+ end
40
+
41
+ it "tries to convert the passed separator to a String using #to_str" do
42
+ obj = mock('to_str')
43
+ obj.stub!(:to_str).and_return(">")
44
+ @io.readlines(obj).should == ["this>", "is>", "an>", "example"]
45
+ end
46
+ end
47
+
48
+ ruby_version_is "1.9" do
49
+ describe "StringIO#readlines" do
50
+ before :each do
51
+ @io = StringIO.new("ab\ncd")
52
+ ScratchPad.record []
53
+ end
54
+
55
+ it "returns at most limit characters when limit is positive" do
56
+ @io.readlines.should == ["ab\n", "cd"]
57
+ end
58
+
59
+ it "calls #to_int to convert the limit" do
60
+ limit = mock("stringio each limit")
61
+ limit.should_receive(:to_int).at_least(1).times.and_return(5)
62
+
63
+ @io.readlines(limit)
64
+ end
65
+
66
+ it "calls #to_int to convert the limit when passed separator and limit" do
67
+ limit = mock("stringio each limit")
68
+ limit.should_receive(:to_int).at_least(1).times.and_return(6)
69
+
70
+ @io.readlines($/, limit)
71
+ end
72
+
73
+ it "raises an ArgumentError when limit is 0" do
74
+ lambda { @io.readlines(0) }.should raise_error(ArgumentError)
75
+ end
76
+ end
77
+ end
78
+
79
+ describe "StringIO#readlines when passed no argument" do
80
+ before(:each) do
81
+ @io = StringIO.new("this is\nan example\nfor StringIO#readlines")
82
+ end
83
+
84
+ it "returns an Array containing lines based on $/" do
85
+ begin
86
+ old_sep, $/ = $/, " "
87
+ @io.readlines.should == ["this ", "is\nan ", "example\nfor ", "StringIO#readlines"]
88
+ ensure
89
+ $/ = old_sep
90
+ end
91
+ end
92
+
93
+ it "updates self's position based on the number of read bytes" do
94
+ @io.readlines
95
+ @io.pos.should eql(41)
96
+ end
97
+
98
+ it "updates self's lineno based on the number of read lines" do
99
+ @io.readlines
100
+ @io.lineno.should eql(3)
101
+ end
102
+
103
+ it "does not change $_" do
104
+ $_ = "test"
105
+ @io.readlines(">")
106
+ $_.should == "test"
107
+ end
108
+
109
+ it "returns an empty Array when self is at the end" do
110
+ @io.pos = 41
111
+ @io.readlines.should == []
112
+ end
113
+ end
114
+
115
+ describe "StringIO#readlines when in write-only mode" do
116
+ it "raises an IOError" do
117
+ io = StringIO.new("xyz", "w")
118
+ lambda { io.readlines }.should raise_error(IOError)
119
+
120
+ io = StringIO.new("xyz")
121
+ io.close_read
122
+ lambda { io.readlines }.should raise_error(IOError)
123
+ end
124
+ end
@@ -0,0 +1,29 @@
1
+ require "stringio"
2
+ require File.expand_path('../shared/read', __FILE__)
3
+ require File.expand_path('../shared/sysread', __FILE__)
4
+
5
+ ruby_version_is "1.9" do
6
+ describe "StringIO#readpartial when passed length, buffer" do
7
+ it_behaves_like :stringio_read, :readpartial
8
+ end
9
+
10
+ describe "StringIO#readpartial when passed length" do
11
+ it_behaves_like :stringio_read_length, :readpartial
12
+ end
13
+
14
+ describe "StringIO#readpartial when passed no arguments" do
15
+ it_behaves_like :stringio_read_no_arguments, :readpartial
16
+ end
17
+
18
+ describe "StringIO#readpartial when self is not readable" do
19
+ it_behaves_like :stringio_read_not_readable, :readpartial
20
+ end
21
+
22
+ describe "StringIO#readpartial when passed nil" do
23
+ it_behaves_like :stringio_read_nil, :readpartial
24
+ end
25
+
26
+ describe "StringIO#readpartial when passed length" do
27
+ it_behaves_like :stringio_sysread_length, :readpartial
28
+ end
29
+ end
@@ -0,0 +1,303 @@
1
+ require File.expand_path('../fixtures/classes', __FILE__)
2
+
3
+ describe "StringIO#reopen when passed [Object, Integer]" do
4
+ before(:each) do
5
+ @io = StringIO.new("example")
6
+ end
7
+
8
+ it "reopens self with the passed Object in the passed mode" do
9
+ @io.reopen("reopened", IO::RDONLY)
10
+ @io.closed_read?.should be_false
11
+ @io.closed_write?.should be_true
12
+ @io.string.should == "reopened"
13
+
14
+ @io.reopen("reopened, twice", IO::WRONLY)
15
+ @io.closed_read?.should be_true
16
+ @io.closed_write?.should be_false
17
+ @io.string.should == "reopened, twice"
18
+
19
+ @io.reopen("reopened, another time", IO::RDWR)
20
+ @io.closed_read?.should be_false
21
+ @io.closed_write?.should be_false
22
+ @io.string.should == "reopened, another time"
23
+ end
24
+
25
+ # NOTE: WEIRD!
26
+ it "does not taint self when the passed Object was tainted" do
27
+ @io.reopen("reopened".taint, IO::RDONLY)
28
+ @io.tainted?.should be_false
29
+
30
+ @io.reopen("reopened".taint, IO::WRONLY)
31
+ @io.tainted?.should be_false
32
+ end
33
+
34
+ it "tries to convert the passed Object to a String using #to_str" do
35
+ obj = mock("to_str")
36
+ obj.should_receive(:to_str).and_return("to_str")
37
+ @io.reopen(obj, IO::RDWR)
38
+ @io.string.should == "to_str"
39
+ end
40
+
41
+ it "raises a TypeError when the passed Object can't be converted to a String" do
42
+ lambda { @io.reopen(Object.new, IO::RDWR) }.should raise_error(TypeError)
43
+ end
44
+
45
+ it "raises an Errno::EACCES when trying to reopen self with a frozen String in write-mode" do
46
+ lambda { @io.reopen("burn".freeze, IO::WRONLY) }.should raise_error(Errno::EACCES)
47
+ lambda { @io.reopen("burn".freeze, IO::WRONLY | IO::APPEND) }.should raise_error(Errno::EACCES)
48
+ end
49
+
50
+ ruby_version_is "" ... "1.9" do
51
+ it "raises a TypeError when trying to reopen self with a frozen String in truncate-mode" do
52
+ lambda { @io.reopen("burn".freeze, IO::RDONLY | IO::TRUNC) }.should raise_error(TypeError)
53
+ end
54
+ end
55
+
56
+ ruby_version_is "1.9" do
57
+ it "raises a RuntimeError when trying to reopen self with a frozen String in truncate-mode" do
58
+ lambda { @io.reopen("burn".freeze, IO::RDONLY | IO::TRUNC) }.should raise_error(RuntimeError)
59
+ end
60
+ end
61
+
62
+ it "does not raise IOError when passed a frozen String in read-mode" do
63
+ @io.reopen("burn".freeze, IO::RDONLY)
64
+ @io.string.should == "burn"
65
+ end
66
+ end
67
+
68
+ describe "StringIO#reopen when passed [Object, Object]" do
69
+ before(:each) do
70
+ @io = StringIO.new("example")
71
+ end
72
+
73
+ it "reopens self with the passed Object in the passed mode" do
74
+ @io.reopen("reopened", "r")
75
+ @io.closed_read?.should be_false
76
+ @io.closed_write?.should be_true
77
+ @io.string.should == "reopened"
78
+
79
+ @io.reopen("reopened, twice", "r+")
80
+ @io.closed_read?.should be_false
81
+ @io.closed_write?.should be_false
82
+ @io.string.should == "reopened, twice"
83
+
84
+ @io.reopen("reopened, another", "w+")
85
+ @io.closed_read?.should be_false
86
+ @io.closed_write?.should be_false
87
+ @io.string.should == ""
88
+
89
+ @io.reopen("reopened, another time", "r+")
90
+ @io.closed_read?.should be_false
91
+ @io.closed_write?.should be_false
92
+ @io.string.should == "reopened, another time"
93
+ end
94
+
95
+ it "truncates the passed String when opened in truncate mode" do
96
+ @io.reopen(str = "reopened", "w")
97
+ str.should == ""
98
+ end
99
+
100
+ # NOTE: WEIRD!
101
+ it "does not taint self when the passed Object was tainted" do
102
+ @io.reopen("reopened".taint, "r")
103
+ @io.tainted?.should be_false
104
+
105
+ @io.reopen("reopened".taint, "w")
106
+ @io.tainted?.should be_false
107
+ end
108
+
109
+ it "tries to convert the passed Object to a String using #to_str" do
110
+ obj = mock("to_str")
111
+ obj.should_receive(:to_str).and_return("to_str")
112
+ @io.reopen(obj, "r")
113
+ @io.string.should == "to_str"
114
+ end
115
+
116
+ it "raises a TypeError when the passed Object can't be converted to a String using #to_str" do
117
+ lambda { @io.reopen(Object.new, "r") }.should raise_error(TypeError)
118
+ end
119
+
120
+ ruby_bug "#", "1.8.7" do
121
+ it "resets self's position to 0" do
122
+ @io.read(5)
123
+ @io.reopen("reopened")
124
+ @io.pos.should eql(0)
125
+ end
126
+
127
+ it "resets self's line number to 0" do
128
+ @io.gets
129
+ @io.reopen("reopened")
130
+ @io.lineno.should eql(0)
131
+ end
132
+ end
133
+
134
+ it "tries to convert the passed mode Object to an Integer using #to_str" do
135
+ obj = mock("to_str")
136
+ obj.should_receive(:to_str).and_return("r")
137
+ @io.reopen("reopened", obj)
138
+ @io.closed_read?.should be_false
139
+ @io.closed_write?.should be_true
140
+ @io.string.should == "reopened"
141
+ end
142
+
143
+ it "raises an Errno::EACCES error when trying to reopen self with a frozen String in write-mode" do
144
+ lambda { @io.reopen("burn".freeze, 'w') }.should raise_error(Errno::EACCES)
145
+ lambda { @io.reopen("burn".freeze, 'w+') }.should raise_error(Errno::EACCES)
146
+ lambda { @io.reopen("burn".freeze, 'a') }.should raise_error(Errno::EACCES)
147
+ lambda { @io.reopen("burn".freeze, "r+") }.should raise_error(Errno::EACCES)
148
+ end
149
+
150
+ it "does not raise IOError if a frozen string is passed in read mode" do
151
+ @io.reopen("burn".freeze, "r")
152
+ @io.string.should == "burn"
153
+ end
154
+ end
155
+
156
+ describe "StringIO#reopen when passed [String]" do
157
+ before(:each) do
158
+ @io = StringIO.new("example")
159
+ end
160
+
161
+ it "reopens self with the passed String in read-write mode" do
162
+ @io.close
163
+
164
+ @io.reopen("reopened")
165
+
166
+ @io.closed_write?.should be_false
167
+ @io.closed_read?.should be_false
168
+
169
+ @io.string.should == "reopened"
170
+ end
171
+
172
+ # NOTE: WEIRD!
173
+ it "does not taint self when the passed Object was tainted" do
174
+ @io.reopen("reopened".taint)
175
+ @io.tainted?.should be_false
176
+ end
177
+
178
+ ruby_bug "#", "1.8.7" do
179
+ it "resets self's position to 0" do
180
+ @io.read(5)
181
+ @io.reopen("reopened")
182
+ @io.pos.should eql(0)
183
+ end
184
+
185
+ it "resets self's line number to 0" do
186
+ @io.gets
187
+ @io.reopen("reopened")
188
+ @io.lineno.should eql(0)
189
+ end
190
+ end
191
+ end
192
+
193
+ describe "StringIO#reopen when passed [Object]" do
194
+ before(:each) do
195
+ @io = StringIO.new("example")
196
+ end
197
+
198
+ it "raises a TypeError when passed an Object that can't be converted to a StringIO" do
199
+ lambda { @io.reopen(Object.new) }.should raise_error(TypeError)
200
+ end
201
+
202
+ it "does not try to convert the passed Object to a String using #to_str" do
203
+ obj = mock("not to_str")
204
+ obj.should_not_receive(:to_str)
205
+ lambda { @io.reopen(obj) }.should raise_error(TypeError)
206
+ end
207
+
208
+ it "tries to convert the passed Object to a StringIO using #to_strio" do
209
+ obj = mock("to_strio")
210
+ obj.should_receive(:to_strio).and_return(StringIO.new("to_strio"))
211
+ @io.reopen(obj)
212
+ @io.string.should == "to_strio"
213
+ end
214
+
215
+ # NOTE: WEIRD!
216
+ it "taints self when the passed Object was tainted" do
217
+ @io.reopen(StringIO.new("reopened").taint)
218
+ @io.tainted?.should be_true
219
+ end
220
+ end
221
+
222
+ describe "StringIO#reopen when passed no arguments" do
223
+ before(:each) do
224
+ @io = StringIO.new("example\nsecond line")
225
+ end
226
+
227
+ it "resets self's mode to read-write" do
228
+ @io.close
229
+ @io.reopen
230
+ @io.closed_read?.should be_false
231
+ @io.closed_write?.should be_false
232
+ end
233
+
234
+ ruby_bug "#", "1.8.7" do
235
+ it "resets self's position to 0" do
236
+ @io.read(5)
237
+ @io.reopen
238
+ @io.pos.should eql(0)
239
+ end
240
+
241
+ it "resets self's line number to 0" do
242
+ @io.gets
243
+ @io.reopen
244
+ @io.lineno.should eql(0)
245
+ end
246
+ end
247
+ end
248
+
249
+ # NOTE: Some reopen specs disabled due to MRI bugs. See:
250
+ # http://rubyforge.org/tracker/index.php?func=detail&aid=13919&group_id=426&atid=1698
251
+ # for details.
252
+ describe "StringIO#reopen" do
253
+ before(:each) do
254
+ @io = StringIO.new('hello','a')
255
+ end
256
+
257
+ # TODO: find out if this is really a bug
258
+ ruby_bug "#", "1.8.6.114" do
259
+ it "reopens a stream when given a String argument" do
260
+ @io.reopen('goodbye').should == @io
261
+ @io.string.should == 'goodbye'
262
+ @io << 'x'
263
+ @io.string.should == 'xoodbye'
264
+ end
265
+
266
+ it "reopens a stream in append mode when flagged as such" do
267
+ @io.reopen('goodbye', 'a').should == @io
268
+ @io.string.should == 'goodbye'
269
+ @io << 'x'
270
+ @io.string.should == 'goodbyex'
271
+ end
272
+
273
+ it "reopens and truncate when reopened in write mode" do
274
+ @io.reopen('goodbye', 'wb').should == @io
275
+ @io.string.should == ''
276
+ @io << 'x'
277
+ @io.string.should == 'x'
278
+ end
279
+
280
+ it "truncates the given string, not a copy" do
281
+ str = 'goodbye'
282
+ @io.reopen(str, 'w')
283
+ @io.string.should == ''
284
+ str.should == ''
285
+ end
286
+ end
287
+
288
+ it "taints self if the provided StringIO argument is tainted" do
289
+ new_io = StringIO.new("tainted")
290
+ new_io.taint
291
+ @io.reopen(new_io)
292
+ @io.tainted?.should == true
293
+ end
294
+
295
+ it "does not truncate the content even when the StringIO argument is in the truncate mode" do
296
+ orig_io = StringIO.new("Original StringIO", IO::RDWR|IO::TRUNC)
297
+ orig_io.write("BLAH") # make sure the content is not empty
298
+
299
+ @io.reopen(orig_io)
300
+ @io.string.should == "BLAH"
301
+ end
302
+
303
+ end