rubysl-stringio 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.travis.yml +7 -0
- data/Gemfile +4 -0
- data/LICENSE +25 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/lib/rubysl/stringio.rb +2 -0
- data/lib/rubysl/stringio/stringio.rb +611 -0
- data/lib/rubysl/stringio/version.rb +5 -0
- data/lib/stringio.rb +1 -0
- data/rubysl-stringio.gemspec +24 -0
- data/spec/append_spec.rb +83 -0
- data/spec/binmode_spec.rb +8 -0
- data/spec/bytes_spec.rb +12 -0
- data/spec/chars_spec.rb +12 -0
- data/spec/close_read_spec.rb +30 -0
- data/spec/close_spec.rb +22 -0
- data/spec/close_write_spec.rb +30 -0
- data/spec/closed_read_spec.rb +11 -0
- data/spec/closed_spec.rb +15 -0
- data/spec/closed_write_spec.rb +11 -0
- data/spec/codepoints_spec.rb +11 -0
- data/spec/each_byte_spec.rb +10 -0
- data/spec/each_char_spec.rb +12 -0
- data/spec/each_codepoint_spec.rb +12 -0
- data/spec/each_line_spec.rb +14 -0
- data/spec/each_spec.rb +14 -0
- data/spec/eof_spec.rb +10 -0
- data/spec/external_encoding_spec.rb +12 -0
- data/spec/fcntl_spec.rb +7 -0
- data/spec/fileno_spec.rb +8 -0
- data/spec/fixtures/classes.rb +15 -0
- data/spec/flush_spec.rb +8 -0
- data/spec/fsync_spec.rb +8 -0
- data/spec/getbyte_spec.rb +25 -0
- data/spec/getc_spec.rb +31 -0
- data/spec/gets_spec.rb +245 -0
- data/spec/initialize_copy_spec.rb +95 -0
- data/spec/initialize_spec.rb +193 -0
- data/spec/internal_encoding_spec.rb +12 -0
- data/spec/isatty_spec.rb +6 -0
- data/spec/length_spec.rb +6 -0
- data/spec/lineno_spec.rb +29 -0
- data/spec/lines_spec.rb +16 -0
- data/spec/open_spec.rb +215 -0
- data/spec/path_spec.rb +15 -0
- data/spec/pid_spec.rb +7 -0
- data/spec/pos_spec.rb +27 -0
- data/spec/print_spec.rb +113 -0
- data/spec/printf_spec.rb +60 -0
- data/spec/putc_spec.rb +105 -0
- data/spec/puts_spec.rb +173 -0
- data/spec/read_nonblock_spec.rb +29 -0
- data/spec/read_spec.rb +62 -0
- data/spec/readbyte_spec.rb +21 -0
- data/spec/readchar_spec.rb +19 -0
- data/spec/readline_spec.rb +127 -0
- data/spec/readlines_spec.rb +124 -0
- data/spec/readpartial_spec.rb +29 -0
- data/spec/reopen_spec.rb +303 -0
- data/spec/rewind_spec.rb +23 -0
- data/spec/seek_spec.rb +75 -0
- data/spec/set_encoding_spec.rb +34 -0
- data/spec/shared/codepoints.rb +45 -0
- data/spec/shared/each.rb +162 -0
- data/spec/shared/each_byte.rb +60 -0
- data/spec/shared/each_char.rb +50 -0
- data/spec/shared/eof.rb +24 -0
- data/spec/shared/getc.rb +43 -0
- data/spec/shared/isatty.rb +5 -0
- data/spec/shared/length.rb +12 -0
- data/spec/shared/read.rb +186 -0
- data/spec/shared/readchar.rb +29 -0
- data/spec/shared/sysread.rb +27 -0
- data/spec/shared/tell.rb +12 -0
- data/spec/shared/write.rb +134 -0
- data/spec/size_spec.rb +6 -0
- data/spec/string_spec.rb +49 -0
- data/spec/stringio_spec.rb +8 -0
- data/spec/sync_spec.rb +18 -0
- data/spec/sysread_spec.rb +27 -0
- data/spec/syswrite_spec.rb +18 -0
- data/spec/tell_spec.rb +6 -0
- data/spec/truncate_spec.rb +69 -0
- data/spec/tty_spec.rb +6 -0
- data/spec/ungetbyte_spec.rb +88 -0
- data/spec/ungetc_spec.rb +98 -0
- data/spec/write_nonblock_spec.rb +20 -0
- data/spec/write_spec.rb +18 -0
- 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
|
data/spec/reopen_spec.rb
ADDED
@@ -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
|