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,8 @@
1
+ require File.expand_path('../fixtures/classes', __FILE__)
2
+
3
+ describe "StringIO#fsync" do
4
+ it "returns zero" do
5
+ io = StringIO.new("fsync")
6
+ io.fsync.should eql(0)
7
+ end
8
+ end
@@ -0,0 +1,25 @@
1
+ require 'stringio'
2
+ require File.expand_path('../shared/getc', __FILE__)
3
+
4
+ describe "StringIO#getbyte" do
5
+ it_behaves_like :stringio_getc, :getbyte
6
+
7
+ it "returns the 8-bit byte at the current position" do
8
+ io = StringIO.new("example")
9
+
10
+ io.send(@method).should == 101
11
+ io.send(@method).should == 120
12
+ io.send(@method).should == 97
13
+ end
14
+
15
+ it "retrieves bytes at a time rather than characters" do
16
+ io = StringIO.new("\xc3\x91")
17
+
18
+ io.getbyte.should == 0xc3
19
+ io.getbyte.should == 0x91
20
+ end
21
+ end
22
+
23
+ describe "StringIO#getbyte when self is not readable" do
24
+ it_behaves_like :stringio_getc_not_readable, :getbyte
25
+ end
data/spec/getc_spec.rb ADDED
@@ -0,0 +1,31 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../../../spec_helper', __FILE__)
3
+ require 'stringio'
4
+ require File.expand_path('../shared/getc', __FILE__)
5
+
6
+ describe "StringIO#getc" do
7
+ it_behaves_like :stringio_getc, :getc
8
+
9
+ it "returns the charactor at the current position" do
10
+ io = StringIO.new("example")
11
+
12
+ io.send(@method).should == ?e
13
+ io.send(@method).should == ?x
14
+ io.send(@method).should == ?a
15
+ end
16
+
17
+ with_feature :encoding do
18
+ it "increments #pos by the byte size of the character in multibyte strings" do
19
+ io = StringIO.new("föóbar")
20
+
21
+ io.send(@method); io.pos.should == 1 # "f" has byte size 1
22
+ io.send(@method); io.pos.should == 3 # "ö" has byte size 2
23
+ io.send(@method); io.pos.should == 5 # "ó" has byte size 2
24
+ io.send(@method); io.pos.should == 6 # "b" has byte size 1
25
+ end
26
+ end
27
+ end
28
+
29
+ describe "StringIO#getc when self is not readable" do
30
+ it_behaves_like :stringio_getc_not_readable, :getc
31
+ end
data/spec/gets_spec.rb ADDED
@@ -0,0 +1,245 @@
1
+ require "stringio"
2
+
3
+ describe "StringIO#gets when passed [separator]" do
4
+ before(:each) do
5
+ @io = StringIO.new("this>is>an>example")
6
+ end
7
+
8
+ it "returns the data read till the next occurence of the passed separator" do
9
+ @io.gets(">").should == "this>"
10
+ @io.gets(">").should == "is>"
11
+ @io.gets(">").should == "an>"
12
+ @io.gets(">").should == "example"
13
+ end
14
+
15
+ it "sets $_ to the read content" do
16
+ @io.gets(">")
17
+ $_.should == "this>"
18
+ @io.gets(">")
19
+ $_.should == "is>"
20
+ @io.gets(">")
21
+ $_.should == "an>"
22
+ @io.gets(">")
23
+ $_.should == "example"
24
+ @io.gets(">")
25
+ $_.should be_nil
26
+ end
27
+
28
+ it "accepts string as separator" do
29
+ @io.gets("is>")
30
+ $_.should == "this>"
31
+ @io.gets("an>")
32
+ $_.should == "is>an>"
33
+ @io.gets("example")
34
+ $_.should == "example"
35
+ @io.gets("ple")
36
+ $_.should be_nil
37
+ end
38
+
39
+ it "updates self's lineno by one" do
40
+ @io.gets(">")
41
+ @io.lineno.should eql(1)
42
+
43
+ @io.gets(">")
44
+ @io.lineno.should eql(2)
45
+
46
+ @io.gets(">")
47
+ @io.lineno.should eql(3)
48
+ end
49
+
50
+ ruby_bug "", "1.8.8" do
51
+ it "returns the next paragraph when the passed separator is an empty String" do
52
+ io = StringIO.new("this is\n\nan example")
53
+ io.gets("").should == "this is\n\n"
54
+ io.gets("").should == "an example"
55
+ end
56
+ end
57
+
58
+ it "returns the remaining content starting at the current position when passed nil" do
59
+ io = StringIO.new("this is\n\nan example")
60
+ io.pos = 5
61
+ io.gets(nil).should == "is\n\nan example"
62
+ end
63
+
64
+ it "tries to convert the passed separator to a String using #to_str" do
65
+ obj = mock('to_str')
66
+ obj.should_receive(:to_str).and_return(">")
67
+ @io.gets(obj).should == "this>"
68
+ end
69
+ end
70
+
71
+ describe "StringIO#gets when passed no argument" do
72
+ before(:each) do
73
+ @io = StringIO.new("this is\nan example\nfor StringIO#gets")
74
+ end
75
+
76
+ it "returns the data read till the next occurence of $/ or till eof" do
77
+ @io.gets.should == "this is\n"
78
+
79
+ begin
80
+ old_sep, $/ = $/, " "
81
+ @io.gets.should == "an "
82
+ @io.gets.should == "example\nfor "
83
+ @io.gets.should == "StringIO#gets"
84
+ ensure
85
+ $/ = old_sep
86
+ end
87
+ end
88
+
89
+ it "sets $_ to the read content" do
90
+ @io.gets
91
+ $_.should == "this is\n"
92
+ @io.gets
93
+ $_.should == "an example\n"
94
+ @io.gets
95
+ $_.should == "for StringIO#gets"
96
+ @io.gets
97
+ $_.should be_nil
98
+ end
99
+
100
+ it "updates self's position" do
101
+ @io.gets
102
+ @io.pos.should eql(8)
103
+
104
+ @io.gets
105
+ @io.pos.should eql(19)
106
+
107
+ @io.gets
108
+ @io.pos.should eql(36)
109
+ end
110
+
111
+ it "updates self's lineno" do
112
+ @io.gets
113
+ @io.lineno.should eql(1)
114
+
115
+ @io.gets
116
+ @io.lineno.should eql(2)
117
+
118
+ @io.gets
119
+ @io.lineno.should eql(3)
120
+ end
121
+
122
+ it "returns nil if self is at the end" do
123
+ @io.pos = 36
124
+ @io.gets.should be_nil
125
+ @io.gets.should be_nil
126
+ end
127
+ end
128
+
129
+ ruby_version_is "1.9" do
130
+ describe "StringIO#gets when passed [limit]" do
131
+ before(:each) do
132
+ @io = StringIO.new("this>is>an>example")
133
+ end
134
+
135
+ it "returns the data read until the limit is met" do
136
+ @io.gets(4).should == "this"
137
+ @io.gets(3).should == ">is"
138
+ @io.gets(5).should == ">an>e"
139
+ @io.gets(6).should == "xample"
140
+ end
141
+
142
+ it "sets $_ to the read content" do
143
+ @io.gets(4)
144
+ $_.should == "this"
145
+ @io.gets(3)
146
+ $_.should == ">is"
147
+ @io.gets(5)
148
+ $_.should == ">an>e"
149
+ @io.gets(6)
150
+ $_.should == "xample"
151
+ @io.gets(3)
152
+ $_.should be_nil
153
+ end
154
+
155
+ it "updates self's lineno by one" do
156
+ @io.gets(3)
157
+ @io.lineno.should eql(1)
158
+
159
+ @io.gets(3)
160
+ @io.lineno.should eql(2)
161
+
162
+ @io.gets(3)
163
+ @io.lineno.should eql(3)
164
+ end
165
+
166
+ it "tries to convert the passed limit to an Integer using #to_int" do
167
+ obj = mock('to_int')
168
+ obj.should_receive(:to_int).and_return(4)
169
+ @io.gets(obj).should == "this"
170
+ end
171
+
172
+ it "returns a blank string when passed a limit of 0" do
173
+ @io.gets(0).should == ""
174
+ end
175
+ end
176
+
177
+ describe "StringIO#gets when passed [separator] and [limit]" do
178
+ before(:each) do
179
+ @io = StringIO.new("this>is>an>example")
180
+ end
181
+
182
+ it "returns the data read until the limit is consumed or the separator is met" do
183
+ @io.gets('>', 8).should == "this>"
184
+ @io.gets('>', 2).should == "is"
185
+ @io.gets('>', 10).should == ">"
186
+ @io.gets('>', 6).should == "an>"
187
+ @io.gets('>', 5).should == "examp"
188
+ end
189
+
190
+ it "sets $_ to the read content" do
191
+ @io.gets('>', 8)
192
+ $_.should == "this>"
193
+ @io.gets('>', 2)
194
+ $_.should == "is"
195
+ @io.gets('>', 10)
196
+ $_.should == ">"
197
+ @io.gets('>', 6)
198
+ $_.should == "an>"
199
+ @io.gets('>', 5)
200
+ $_.should == "examp"
201
+ end
202
+
203
+ it "updates self's lineno by one" do
204
+ @io.gets('>', 3)
205
+ @io.lineno.should eql(1)
206
+
207
+ @io.gets('>', 3)
208
+ @io.lineno.should eql(2)
209
+
210
+ @io.gets('>', 3)
211
+ @io.lineno.should eql(3)
212
+ end
213
+
214
+ it "tries to convert the passed separator to a String using #to_str" do
215
+ obj = mock('to_str')
216
+ obj.should_receive(:to_str).and_return('>')
217
+ @io.gets(obj, 5).should == "this>"
218
+ end
219
+
220
+ it "does not raise TypeError if passed separator is nil" do
221
+ @io.gets(nil, 5).should == "this>"
222
+ end
223
+
224
+ it "tries to convert the passed limit to an Integer using #to_int" do
225
+ obj = mock('to_int')
226
+ obj.should_receive(:to_int).and_return(5)
227
+ @io.gets('>', obj).should == "this>"
228
+ end
229
+
230
+ it "raises a TypeError if both separator and limit are nil" do
231
+ lambda { @io.gets nil, nil }.should raise_error(TypeError)
232
+ end
233
+ end
234
+ end
235
+
236
+ describe "StringIO#gets when in write-only mode" do
237
+ it "raises an IOError" do
238
+ io = StringIO.new("xyz", "w")
239
+ lambda { io.gets }.should raise_error(IOError)
240
+
241
+ io = StringIO.new("xyz")
242
+ io.close_read
243
+ lambda { io.gets }.should raise_error(IOError)
244
+ end
245
+ end
@@ -0,0 +1,95 @@
1
+ require 'stringio'
2
+
3
+ describe "StringIO#initialize_copy" do
4
+ before(:each) do
5
+ @io = StringIO.new("StringIO example")
6
+ @orig_io = StringIO.new("Original StringIO")
7
+ end
8
+
9
+ it "is private" do
10
+ StringIO.should have_private_instance_method(:initialize_copy)
11
+ end
12
+
13
+ it "returns self" do
14
+ @io.send(:initialize_copy, @orig_io).should equal(@io)
15
+ end
16
+
17
+ it "tries to convert the passed argument to a StringIO using #to_strio" do
18
+ obj = mock('to_strio')
19
+ obj.should_receive(:to_strio).and_return(StringIO.new("converted"))
20
+ @io.send(:initialize_copy, obj)
21
+ @io.string.should == "converted"
22
+ end
23
+
24
+ it "copies the passed StringIO's content to self" do
25
+ @io.send(:initialize_copy, @orig_io)
26
+ @io.string.should == "Original StringIO"
27
+ end
28
+
29
+ it "copies the passed StringIO's position to self" do
30
+ @orig_io.pos = 5
31
+ @io.send(:initialize_copy, @orig_io)
32
+ @io.pos.should eql(5)
33
+ end
34
+
35
+ it "taints self when the passed StringIO is tainted" do
36
+ @orig_io.taint
37
+ @io.send(:initialize_copy, @orig_io)
38
+ @io.tainted?.should be_true
39
+ end
40
+
41
+ it "copies the passed StringIO's mode to self" do
42
+ orig_io = StringIO.new("read-only", "r")
43
+ @io.send(:initialize_copy, orig_io)
44
+ @io.closed_read?.should be_false
45
+ @io.closed_write?.should be_true
46
+
47
+ orig_io = StringIO.new("write-only", "w")
48
+ @io.send(:initialize_copy, orig_io)
49
+ @io.closed_read?.should be_true
50
+ @io.closed_write?.should be_false
51
+
52
+ orig_io = StringIO.new("read-write", "r+")
53
+ @io.send(:initialize_copy, orig_io)
54
+ @io.closed_read?.should be_false
55
+ @io.closed_write?.should be_false
56
+
57
+ orig_io = StringIO.new("read-write", "w+")
58
+ @io.send(:initialize_copy, orig_io)
59
+ @io.closed_read?.should be_false
60
+ @io.closed_write?.should be_false
61
+ end
62
+
63
+ it "copies the passed StringIO's append mode" do
64
+ orig_io = StringIO.new("read-write", "a")
65
+ @io.send(:initialize_copy, orig_io)
66
+
67
+ @io.pos = 0
68
+ @io << " test"
69
+
70
+ @io.string.should == "read-write test"
71
+ end
72
+
73
+ it "does not truncate self's content when the copied StringIO was in truncate mode" do
74
+ orig_io = StringIO.new("original StringIO", "w+")
75
+ orig_io.write("not truncated") # make sure the content is not empty
76
+
77
+ @io.send(:initialize_copy, orig_io)
78
+ @io.string.should == "not truncated"
79
+ end
80
+
81
+ it "makes both StringIO objects to share position, eof status" do
82
+ @io.send(:initialize_copy, @orig_io)
83
+ @orig_io.pos.should == 0
84
+ @io.getc
85
+ @io.pos.should == 1
86
+ @orig_io.pos.should == 1
87
+ @orig_io.read(1).should == "r"
88
+ @io.read(1).should == "i"
89
+ @orig_io.pos.should == 3
90
+ @orig_io.pos.should == 3
91
+ @io.gets(nil)
92
+ @io.eof?.should == true
93
+ @orig_io.eof?.should == true
94
+ end
95
+ end
@@ -0,0 +1,193 @@
1
+ require 'stringio'
2
+
3
+ describe "StringIO#initialize when passed [Object, mode]" do
4
+ before(:each) do
5
+ @io = StringIO.allocate
6
+ end
7
+
8
+ it "uses the passed Object as the StringIO backend" do
9
+ @io.send(:initialize, str = "example", "r")
10
+ @io.string.should equal(str)
11
+ end
12
+
13
+ it "sets the mode based on the passed mode" do
14
+ io = StringIO.allocate
15
+ io.send(:initialize, "example", "r")
16
+ io.closed_read?.should be_false
17
+ io.closed_write?.should be_true
18
+
19
+ io = StringIO.allocate
20
+ io.send(:initialize, "example", "rb")
21
+ io.closed_read?.should be_false
22
+ io.closed_write?.should be_true
23
+
24
+ io = StringIO.allocate
25
+ io.send(:initialize, "example", "r+")
26
+ io.closed_read?.should be_false
27
+ io.closed_write?.should be_false
28
+
29
+ io = StringIO.allocate
30
+ io.send(:initialize, "example", "rb+")
31
+ io.closed_read?.should be_false
32
+ io.closed_write?.should be_false
33
+
34
+ io = StringIO.allocate
35
+ io.send(:initialize, "example", "w")
36
+ io.closed_read?.should be_true
37
+ io.closed_write?.should be_false
38
+
39
+ io = StringIO.allocate
40
+ io.send(:initialize, "example", "wb")
41
+ io.closed_read?.should be_true
42
+ io.closed_write?.should be_false
43
+
44
+ io = StringIO.allocate
45
+ io.send(:initialize, "example", "w+")
46
+ io.closed_read?.should be_false
47
+ io.closed_write?.should be_false
48
+
49
+ io = StringIO.allocate
50
+ io.send(:initialize, "example", "wb+")
51
+ io.closed_read?.should be_false
52
+ io.closed_write?.should be_false
53
+
54
+ io = StringIO.allocate
55
+ io.send(:initialize, "example", "a")
56
+ io.closed_read?.should be_true
57
+ io.closed_write?.should be_false
58
+
59
+ io = StringIO.allocate
60
+ io.send(:initialize, "example", "ab")
61
+ io.closed_read?.should be_true
62
+ io.closed_write?.should be_false
63
+
64
+ io = StringIO.allocate
65
+ io.send(:initialize, "example", "a+")
66
+ io.closed_read?.should be_false
67
+ io.closed_write?.should be_false
68
+
69
+ io = StringIO.allocate
70
+ io.send(:initialize, "example", "ab+")
71
+ io.closed_read?.should be_false
72
+ io.closed_write?.should be_false
73
+ end
74
+
75
+ it "allows passing the mode as an Integer" do
76
+ io = StringIO.allocate
77
+ io.send(:initialize, "example", IO::RDONLY)
78
+ io.closed_read?.should be_false
79
+ io.closed_write?.should be_true
80
+
81
+ io = StringIO.allocate
82
+ io.send(:initialize, "example", IO::RDWR)
83
+ io.closed_read?.should be_false
84
+ io.closed_write?.should be_false
85
+
86
+ io = StringIO.allocate
87
+ io.send(:initialize, "example", IO::WRONLY)
88
+ io.closed_read?.should be_true
89
+ io.closed_write?.should be_false
90
+
91
+ io = StringIO.allocate
92
+ io.send(:initialize, "example", IO::WRONLY | IO::TRUNC)
93
+ io.closed_read?.should be_true
94
+ io.closed_write?.should be_false
95
+
96
+ io = StringIO.allocate
97
+ io.send(:initialize, "example", IO::RDWR | IO::TRUNC)
98
+ io.closed_read?.should be_false
99
+ io.closed_write?.should be_false
100
+
101
+ io = StringIO.allocate
102
+ io.send(:initialize, "example", IO::WRONLY | IO::APPEND)
103
+ io.closed_read?.should be_true
104
+ io.closed_write?.should be_false
105
+
106
+ io = StringIO.allocate
107
+ io.send(:initialize, "example", IO::RDWR | IO::APPEND)
108
+ io.closed_read?.should be_false
109
+ io.closed_write?.should be_false
110
+ end
111
+
112
+ ruby_version_is "" ... "1.9" do
113
+ it "raises a TypeError when passed a frozen String in truncate mode as StringIO backend" do
114
+ io = StringIO.allocate
115
+ lambda { io.send(:initialize, "example".freeze, IO::TRUNC) }.should raise_error(TypeError)
116
+ end
117
+ end
118
+
119
+ ruby_version_is "1.9" do
120
+ it "raises a RuntimeError when passed a frozen String in truncate mode as StringIO backend" do
121
+ io = StringIO.allocate
122
+ lambda { io.send(:initialize, "example".freeze, IO::TRUNC) }.should raise_error(RuntimeError)
123
+ end
124
+ end
125
+
126
+ it "tries to convert the passed mode to a String using #to_str" do
127
+ obj = mock('to_str')
128
+ obj.should_receive(:to_str).and_return("r")
129
+ @io.send(:initialize, "example", obj)
130
+
131
+ @io.closed_read?.should be_false
132
+ @io.closed_write?.should be_true
133
+ end
134
+
135
+ it "raises an Errno::EACCES error when passed a frozen string with a write-mode" do
136
+ (str = "example").freeze
137
+ lambda { @io.send(:initialize, str, "r+") }.should raise_error(Errno::EACCES)
138
+ lambda { @io.send(:initialize, str, "w") }.should raise_error(Errno::EACCES)
139
+ lambda { @io.send(:initialize, str, "a") }.should raise_error(Errno::EACCES)
140
+ end
141
+ end
142
+
143
+ describe "StringIO#initialize when passed [Object]" do
144
+ before(:each) do
145
+ @io = StringIO.allocate
146
+ end
147
+
148
+ it "uses the passed Object as the StringIO backend" do
149
+ @io.send(:initialize, str = "example")
150
+ @io.string.should equal(str)
151
+ end
152
+
153
+ it "sets the mode to read-write" do
154
+ @io.send(:initialize, "example")
155
+ @io.closed_read?.should be_false
156
+ @io.closed_write?.should be_false
157
+ end
158
+
159
+ it "tries to convert the passed Object to a String using #to_str" do
160
+ obj = mock('to_str')
161
+ obj.should_receive(:to_str).and_return("example")
162
+ @io.send(:initialize, obj)
163
+ @io.string.should == "example"
164
+ end
165
+
166
+ it "automatically sets the mode to read-only when passed a frozen string" do
167
+ (str = "example").freeze
168
+ @io.send(:initialize, str)
169
+ @io.closed_read?.should be_false
170
+ @io.closed_write?.should be_true
171
+ end
172
+ end
173
+
174
+ describe "StringIO#initialize when passed no arguments" do
175
+ before(:each) do
176
+ @io = StringIO.allocate
177
+ end
178
+
179
+ it "is private" do
180
+ StringIO.should have_private_instance_method(:initialize)
181
+ end
182
+
183
+ it "sets the mode to read-write" do
184
+ @io.send(:initialize, "example")
185
+ @io.closed_read?.should be_false
186
+ @io.closed_write?.should be_false
187
+ end
188
+
189
+ it "uses an empty String as the StringIO backend" do
190
+ @io.send(:initialize)
191
+ @io.string.should == ""
192
+ end
193
+ end