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,24 @@
1
+ describe :stringio_eof, :shared => true do
2
+ before(:each) do
3
+ @io = StringIO.new("eof")
4
+ end
5
+
6
+ it "returns true when self's position is greater than or equal to self's size" do
7
+ @io.pos = 3
8
+ @io.send(@method).should be_true
9
+
10
+ @io.pos = 6
11
+ @io.send(@method).should be_true
12
+ end
13
+
14
+ it "returns false when self's position is less than self's size" do
15
+ @io.pos = 0
16
+ @io.send(@method).should be_false
17
+
18
+ @io.pos = 1
19
+ @io.send(@method).should be_false
20
+
21
+ @io.pos = 2
22
+ @io.send(@method).should be_false
23
+ end
24
+ end
@@ -0,0 +1,43 @@
1
+ describe :stringio_getc, :shared => true do
2
+ before(:each) do
3
+ @io = StringIO.new("example")
4
+ end
5
+
6
+ it "increases self's position by one" do
7
+ @io.send(@method)
8
+ @io.pos.should eql(1)
9
+
10
+ @io.send(@method)
11
+ @io.pos.should eql(2)
12
+
13
+ @io.send(@method)
14
+ @io.pos.should eql(3)
15
+ end
16
+
17
+ it "returns nil when called at the end of self" do
18
+ @io.pos = 7
19
+ @io.send(@method).should be_nil
20
+ @io.send(@method).should be_nil
21
+ @io.send(@method).should be_nil
22
+ end
23
+
24
+ it "does not increase self's position when called at the end of file" do
25
+ @io.pos = 7
26
+ @io.send(@method)
27
+ @io.pos.should eql(7)
28
+
29
+ @io.send(@method)
30
+ @io.pos.should eql(7)
31
+ end
32
+ end
33
+
34
+ describe :stringio_getc_not_readable, :shared => true do
35
+ it "raises an IOError" do
36
+ io = StringIO.new("xyz", "w")
37
+ lambda { io.send(@method) }.should raise_error(IOError)
38
+
39
+ io = StringIO.new("xyz")
40
+ io.close_read
41
+ lambda { io.send(@method) }.should raise_error(IOError)
42
+ end
43
+ end
@@ -0,0 +1,5 @@
1
+ describe :stringio_isatty, :shared => true do
2
+ it "returns false" do
3
+ StringIO.new('tty').send(@method).should be_false
4
+ end
5
+ end
@@ -0,0 +1,12 @@
1
+ # -*- encoding: utf-8 -*-
2
+ describe :stringio_length, :shared => true do
3
+ it "returns the length of the wrapped string" do
4
+ StringIO.new("example").send(@method).should == 7
5
+ end
6
+
7
+ with_feature :encoding do
8
+ it "returns the number of bytes" do
9
+ StringIO.new("ありがとう").send(@method).should == 15
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,186 @@
1
+ describe :stringio_read, :shared => true do
2
+ before(:each) do
3
+ @io = StringIO.new("example")
4
+ end
5
+
6
+ it "returns the passed buffer String" do
7
+ ret = @io.send(@method, 7, buffer = "")
8
+ ret.should equal(buffer)
9
+ end
10
+
11
+ it "returns the remaining data when limit is nil" do
12
+ @io.send(@method, nil, buffer = "").should == "example"
13
+ buffer.should == "example"
14
+ end
15
+
16
+ ruby_version_is "1.9" do
17
+ it "truncates buffer when limit is nil and no data reamins" do
18
+ @io.send(@method)
19
+ @io.send(@method, nil, buffer = "abc").should == ""
20
+ buffer.should == ""
21
+ end
22
+ end
23
+
24
+ it "reads length bytes and writes them to the buffer String" do
25
+ @io.send(@method, 7, buffer = "")
26
+ buffer.should == "example"
27
+ end
28
+
29
+ it "calls #to_str to convert the object to a String" do
30
+ obj = mock("to_str")
31
+ obj.should_receive(:to_str).and_return(buffer = "")
32
+
33
+ @io.send(@method, 7, obj)
34
+ buffer.should == "example"
35
+ end
36
+
37
+ it "raises a TypeError if the object does not respond to #to_str" do
38
+ lambda { @io.send(@method, 7, Object.new) }.should raise_error(TypeError)
39
+ end
40
+
41
+ ruby_version_is ""..."1.9" do
42
+ it "raises a TypeError when passed a frozen String as buffer" do
43
+ lambda { @io.send(@method, 7, "".freeze) }.should raise_error(TypeError)
44
+ end
45
+ end
46
+
47
+ ruby_version_is "1.9" do
48
+ it "raises a RuntimeError when passed a frozen String as buffer" do
49
+ lambda { @io.send(@method, 7, "".freeze) }.should raise_error(RuntimeError)
50
+ end
51
+ end
52
+
53
+ with_feature :encoding do
54
+ it "returns a String in ASCII-8BIT ignoring the encoding of the source String and buffer" do
55
+ io = StringIO.new("abc".force_encoding(Encoding::EUC_JP))
56
+ buffer = "".force_encoding(Encoding::ISO_8859_1)
57
+ io.send(@method, 3, buffer).encoding.should == Encoding::ASCII_8BIT
58
+ end
59
+ end
60
+ end
61
+
62
+ describe :stringio_read_length, :shared => true do
63
+ before(:each) do
64
+ @io = StringIO.new("example")
65
+ end
66
+
67
+ it "reads length bytes from the current position and returns them" do
68
+ @io.pos = 3
69
+ @io.send(@method, 4).should == "mple"
70
+ end
71
+
72
+ it "reads at most the whole content" do
73
+ @io.send(@method, 999).should == "example"
74
+ end
75
+ it "updates the position" do
76
+ @io.send(@method, 3)
77
+ @io.pos.should eql(3)
78
+
79
+ @io.send(@method, 999)
80
+ @io.pos.should eql(7)
81
+ end
82
+
83
+ it "calls #to_int to convert the length" do
84
+ obj = mock("to_int")
85
+ obj.should_receive(:to_int).and_return(7)
86
+ @io.send(@method, obj).should == "example"
87
+ end
88
+
89
+ it "raises a TypeError when the length does not respond to #to_int" do
90
+ lambda { @io.send(@method, Object.new) }.should raise_error(TypeError)
91
+ end
92
+
93
+ it "raises a TypeError when length is negative" do
94
+ lambda { @io.send(@method, -2) }.should raise_error(ArgumentError)
95
+ end
96
+
97
+ with_feature :encoding do
98
+ it "returns a String in ASCII-8BIT encoding when passed a length > 0" do
99
+ @io.send(@method, 4).encoding.should == Encoding::ASCII_8BIT
100
+ end
101
+
102
+ it "returns an empty String in ASCII-8BIT encoding when passed length == 0" do
103
+ @io.send(@method, 0).encoding.should == Encoding::ASCII_8BIT
104
+ end
105
+ end
106
+ end
107
+
108
+ describe :stringio_read_no_arguments, :shared => true do
109
+ before(:each) do
110
+ @io = StringIO.new("example")
111
+ end
112
+
113
+ it "reads the whole content starting from the current position" do
114
+ @io.send(@method).should == "example"
115
+
116
+ @io.pos = 3
117
+ @io.send(@method).should == "mple"
118
+ end
119
+
120
+ it "updates the current position" do
121
+ @io.send(@method)
122
+ @io.pos.should eql(7)
123
+ end
124
+
125
+ ruby_bug "readmine#156", "1.8.7" do
126
+ it "returns an empty String when no data remains" do
127
+ @io.send(@method).should == "example"
128
+ @io.send(@method).should == ""
129
+ end
130
+ end
131
+
132
+ with_feature :encoding do
133
+ it "returns a String in the same encoding as the source String" do
134
+ io = StringIO.new("abc".force_encoding(Encoding::EUC_JP))
135
+ io.send(@method).encoding.should == Encoding::EUC_JP
136
+ end
137
+
138
+ it "returns an empty String in ASCII-8BIT encoding" do
139
+ @io.send(@method).should == "example"
140
+ @io.send(@method).encoding.should == Encoding::ASCII_8BIT
141
+ end
142
+ end
143
+ end
144
+
145
+ describe :stringio_read_nil, :shared => true do
146
+ before :each do
147
+ @io = StringIO.new("example")
148
+ end
149
+
150
+ it "returns the remaining content from the current position" do
151
+ @io.send(@method, nil).should == "example"
152
+
153
+ @io.pos = 4
154
+ @io.send(@method, nil).should == "ple"
155
+ end
156
+
157
+ it "updates the current position" do
158
+ @io.send(@method, nil)
159
+ @io.pos.should eql(7)
160
+ end
161
+
162
+ ruby_bug "redmine#156", "1.8.7" do
163
+ it "returns an empty String when no data remains" do
164
+ @io.send(@method, nil).should == "example"
165
+ @io.send(@method, nil).should == ""
166
+ end
167
+ end
168
+
169
+ with_feature :encoding do
170
+ it "returns an empty String in ASCII-8BIT encoding" do
171
+ @io.send(@method).should == "example"
172
+ @io.send(@method).encoding.should == Encoding::ASCII_8BIT
173
+ end
174
+ end
175
+ end
176
+
177
+ describe :stringio_read_not_readable, :shared => true do
178
+ it "raises an IOError" do
179
+ io = StringIO.new("test", "w")
180
+ lambda { io.send(@method) }.should raise_error(IOError)
181
+
182
+ io = StringIO.new("test")
183
+ io.close_read
184
+ lambda { io.send(@method) }.should raise_error(IOError)
185
+ end
186
+ end
@@ -0,0 +1,29 @@
1
+ describe :stringio_readchar, :shared => true do
2
+ before(:each) do
3
+ @io = StringIO.new("example")
4
+ end
5
+
6
+ it "correctly updates the current position" do
7
+ @io.send(@method)
8
+ @io.pos.should == 1
9
+
10
+ @io.send(@method)
11
+ @io.pos.should == 2
12
+ end
13
+
14
+ it "raises an EOFError when self is at the end" do
15
+ @io.pos = 7
16
+ lambda { @io.send(@method) }.should raise_error(EOFError)
17
+ end
18
+ end
19
+
20
+ describe :stringio_readchar_not_readable, :shared => true do
21
+ it "raises an IOError" do
22
+ io = StringIO.new("a b c d e", "w")
23
+ lambda { io.send(@method) }.should raise_error(IOError)
24
+
25
+ io = StringIO.new("a b c d e")
26
+ io.close_read
27
+ lambda { io.send(@method) }.should raise_error(IOError)
28
+ end
29
+ end
@@ -0,0 +1,27 @@
1
+ describe :stringio_sysread_length, :shared => true do
2
+ before(:each) do
3
+ @io = StringIO.new("example")
4
+ end
5
+
6
+ # This was filed as a bug in redmine#156 but since MRI refused to change the
7
+ # 1.8 behavior, it's now considered a version difference by RubySpec since
8
+ # it could have a significant impact on user code.
9
+ ruby_version_is ""..."1.9" do
10
+ it "raises an EOFError when passed 0 and no data remains" do
11
+ @io.send(@method, 8).should == "example"
12
+ lambda { @io.send(@method, 0) }.should raise_error(EOFError)
13
+ end
14
+ end
15
+
16
+ ruby_version_is "1.9" do
17
+ it "returns an empty String when passed 0 and no data remains" do
18
+ @io.send(@method, 8).should == "example"
19
+ @io.send(@method, 0).should == ""
20
+ end
21
+ end
22
+
23
+ it "raises an EOFError when passed length > 0 and no data remains" do
24
+ @io.read.should == "example"
25
+ lambda { @io.sysread(1) }.should raise_error(EOFError)
26
+ end
27
+ end
@@ -0,0 +1,12 @@
1
+ describe :stringio_tell, :shared => true do
2
+ before(:each) do
3
+ @io = StringIOSpecs.build
4
+ end
5
+
6
+ it "returns the current byte offset" do
7
+ @io.getc
8
+ @io.send(@method).should == 1
9
+ @io.read(7)
10
+ @io.send(@method).should == 8
11
+ end
12
+ end
@@ -0,0 +1,134 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ describe :stringio_write, :shared => true do
4
+ before(:each) do
5
+ @io = StringIO.new('12345')
6
+ end
7
+
8
+ it "tries to convert the passed Object to a String using #to_s" do
9
+ obj = mock("to_s")
10
+ obj.should_receive(:to_s).and_return("to_s")
11
+ @io.send(@method, obj)
12
+ @io.string.should == "to_s5"
13
+ end
14
+
15
+ it "raises an IOError if the data String is frozen after creating the StringIO instance" do
16
+ s = "abcdef"
17
+ io = StringIO.new s, "w"
18
+ s.freeze
19
+ lambda { io.write "xyz" }.should raise_error(IOError)
20
+ end
21
+ end
22
+
23
+ describe :stringio_write_string, :shared => true do
24
+ before(:each) do
25
+ @io = StringIO.new('12345')
26
+ end
27
+
28
+ # TODO: RDoc says that #write appends at the current position.
29
+ it "writes the passed String at the current buffer position" do
30
+ @io.pos = 2
31
+ @io.send(@method, 'x').should == 1
32
+ @io.string.should == '12x45'
33
+ @io.send(@method, 7).should == 1
34
+ @io.string.should == '12x75'
35
+ end
36
+
37
+ it "pads self with \\000 when the current position is after the end" do
38
+ @io.pos = 8
39
+ @io.send(@method, 'x')
40
+ @io.string.should == "12345\000\000\000x"
41
+ @io.send(@method, 9)
42
+ @io.string.should == "12345\000\000\000x9"
43
+ end
44
+
45
+ it "returns the number of bytes written" do
46
+ @io.send(@method, '').should == 0
47
+ @io.send(@method, nil).should == 0
48
+ str = "1" * 100
49
+ @io.send(@method, str).should == 100
50
+ end
51
+
52
+ it "updates self's position" do
53
+ @io.send(@method, 'test')
54
+ @io.pos.should eql(4)
55
+ end
56
+
57
+ it "taints self's String when the passed argument is tainted" do
58
+ @io.send(@method, "test".taint)
59
+ @io.string.tainted?.should be_true
60
+ end
61
+
62
+ it "does not taint self when the passed argument is tainted" do
63
+ @io.send(@method, "test".taint)
64
+ @io.tainted?.should be_false
65
+ end
66
+
67
+
68
+ with_feature :encoding do
69
+
70
+ before :each do
71
+ @enc_io = StringIO.new("Hëllø")
72
+ end
73
+
74
+ it "writes binary data into the io" do
75
+ data = "Hëll\xFF"
76
+ data.force_encoding("ASCII-8BIT")
77
+ @enc_io.send(@method, data)
78
+ @enc_io.string.should == "Hëll\xFF\xB8"
79
+ end
80
+
81
+ it "retains the original encoding" do
82
+ data = "Hëll\xFF"
83
+ data.force_encoding("ASCII-8BIT")
84
+ @enc_io.send(@method, data)
85
+ @enc_io.string.encoding.should == Encoding::UTF_8
86
+ end
87
+
88
+ it "returns the number of bytes written" do
89
+ data = "Hëll\xFF"
90
+ data.force_encoding("ASCII-8BIT")
91
+ @enc_io.send(@method, data).should == 6
92
+ end
93
+
94
+ it "pads multibyte characters properly" do
95
+ @enc_io.pos = 8
96
+ @enc_io.send(@method, 'x')
97
+ @enc_io.string.should == "Hëllø\000x"
98
+ @enc_io.send(@method, 9)
99
+ @enc_io.string.should == "Hëllø\000x9"
100
+ end
101
+
102
+ end
103
+
104
+ end
105
+
106
+ describe :stringio_write_not_writable, :shared => true do
107
+ it "raises an IOError" do
108
+ io = StringIO.new("test", "r")
109
+ lambda { io.send(@method, "test") }.should raise_error(IOError)
110
+
111
+ io = StringIO.new("test")
112
+ io.close_write
113
+ lambda { io.send(@method, "test") }.should raise_error(IOError)
114
+ end
115
+ end
116
+
117
+ describe :stringio_write_append, :shared => true do
118
+ before(:each) do
119
+ @io = StringIO.new("example", "a")
120
+ end
121
+
122
+ it "appends the passed argument to the end of self" do
123
+ @io.send(@method, ", just testing")
124
+ @io.string.should == "example, just testing"
125
+
126
+ @io.send(@method, " and more testing")
127
+ @io.string.should == "example, just testing and more testing"
128
+ end
129
+
130
+ it "correctly updates self's position" do
131
+ @io.send(@method, ", testing")
132
+ @io.pos.should eql(16)
133
+ end
134
+ end