rubysl-stringio 1.0.0

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