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.
- 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
|