v2 / vlib / io / reader_test.v
302 lines · 273 sloc · 5.28 KB · 114ae6d4a297538895253a0ae37bd0411187c19f
Raw
1module io
2
3struct Buf {
4pub:
5 bytes []u8
6mut:
7 i int
8}
9
10fn (mut b Buf) read(mut buf []u8) !int {
11 if !(b.i < b.bytes.len) {
12 return Eof{}
13 }
14 n := copy(mut buf, b.bytes[b.i..])
15 b.i += n
16 return n
17}
18
19fn test_read_all() {
20 buf := Buf{
21 bytes: '123'.repeat(10).bytes()
22 }
23 res := read_all(reader: buf) or {
24 assert false
25 ''.bytes()
26 }
27 assert res == '123'.repeat(10).bytes()
28}
29
30fn test_read_all_huge() {
31 buf := Buf{
32 bytes: '123'.repeat(100000).bytes()
33 }
34 res := read_all(reader: buf) or {
35 assert false
36 ''.bytes()
37 }
38 assert res == '123'.repeat(100000).bytes()
39}
40
41struct ZeroReadAfterDataReader {
42mut:
43 call_count int
44}
45
46fn (mut r ZeroReadAfterDataReader) read(mut buf []u8) !int {
47 match r.call_count {
48 0 {
49 r.call_count++
50 return copy(mut buf, 'hello'.bytes())
51 }
52 1 {
53 r.call_count++
54 return 0
55 }
56 else {
57 return error('unexpected extra read after zero-length read')
58 }
59 }
60}
61
62fn test_read_all_stops_on_zero_length_read_after_partial_data() {
63 mut reader := &ZeroReadAfterDataReader{}
64 res := read_all(reader: reader) or {
65 assert false
66 ''.bytes()
67 }
68 assert res == 'hello'.bytes()
69 assert reader.call_count == 2
70}
71
72struct StringReaderTest {
73 text string
74mut:
75 place int
76}
77
78fn (mut s StringReaderTest) read(mut buf []u8) !int {
79 if s.place >= s.text.len {
80 return Eof{}
81 }
82 read := copy(mut buf, s.text[s.place..].bytes())
83 s.place += read
84 return read
85}
86
87struct ZeroThenDataReader {
88pub:
89 text string
90mut:
91 place int
92 empty_reads int
93}
94
95fn (mut s ZeroThenDataReader) read(mut buf []u8) !int {
96 if buf.len == 0 {
97 return 0
98 }
99 if s.empty_reads == 0 {
100 s.empty_reads++
101 return 0
102 }
103 if s.place >= s.text.len {
104 return Eof{}
105 }
106 read := copy(mut buf, s.text[s.place..].bytes())
107 s.place += read
108 return read
109}
110
111const newline_count = 100000
112
113fn test_stringreadertest() {
114 text := '12345\n'.repeat(newline_count)
115 mut s := StringReaderTest{
116 text: text
117 }
118 mut r := new_buffered_reader(reader: s)
119 for i := 0; true; i++ {
120 if _ := r.read_line() {
121 } else {
122 assert i == newline_count
123 break
124 }
125 }
126 if _ := r.read_line() {
127 assert false
128 }
129 leftover := read_all(reader: r) or {
130 assert false
131 panic('bad')
132 }
133 if leftover.len > 0 {
134 assert false
135 }
136}
137
138fn test_stringreadertest2() {
139 text := '12345\r\n'.repeat(newline_count)
140 mut s := StringReaderTest{
141 text: text
142 }
143 mut r := new_buffered_reader(reader: s)
144 for i := 0; true; i++ {
145 if _ := r.read_line() {
146 } else {
147 assert i == newline_count
148 break
149 }
150 }
151 if _ := r.read_line() {
152 assert false
153 }
154 leftover := read_all(reader: r) or {
155 assert false
156 panic('bad')
157 }
158 if leftover.len > 0 {
159 assert false
160 }
161}
162
163fn test_leftover() {
164 text := 'This is a test\r\nNice try!'
165 mut s := StringReaderTest{
166 text: text
167 }
168 mut r := new_buffered_reader(reader: s)
169 _ := r.read_line() or {
170 assert false
171 panic('bad')
172 }
173 line2 := r.read_line() or {
174 assert false
175 panic('bad')
176 }
177 assert line2 == 'Nice try!'
178 if _ := r.read_line() {
179 assert false
180 panic('bad')
181 }
182 assert r.end_of_stream()
183}
184
185fn test_read_line_strips_crlf_across_buffer_fills() {
186 text := '12345\r\n67890\r\n'
187 mut s := StringReaderTest{
188 text: text
189 }
190 mut r := new_buffered_reader(reader: s, cap: 2)
191 assert r.read_line()! == '12345'
192 assert r.read_line()! == '67890'
193 if _ := r.read_line() {
194 assert false
195 }
196 assert r.end_of_stream()
197}
198
199fn test_totalread_read() {
200 text := 'Some testing text'
201 mut s := StringReaderTest{
202 text: text
203 }
204 mut r := new_buffered_reader(reader: s)
205
206 mut buf := []u8{len: text.len}
207 total := r.read(mut buf) or {
208 assert false
209 panic('bad')
210 }
211
212 assert r.total_read == total
213}
214
215fn test_buffered_reader_retries_zero_length_reads() {
216 text := 'Some testing text'
217 mut s := ZeroThenDataReader{
218 text: text
219 }
220 mut r := new_buffered_reader(reader: s, retries: 2)
221 mut buf := []u8{len: text.len}
222 total := r.read(mut buf) or {
223 assert false
224 panic('bad')
225 }
226
227 assert total == text.len
228 assert buf[..total] == text.bytes()
229 assert r.total_read == total
230}
231
232struct NegativeReader {
233mut:
234 read_count int
235}
236
237fn (mut r NegativeReader) read(mut _ []u8) !int {
238 r.read_count++
239 return -1
240}
241
242fn test_read_all_errors_on_negative_read_count() {
243 mut reader := &NegativeReader{}
244 if _ := read_all(reader: reader) {
245 assert false
246 } else {
247 assert err.msg() == 'io.read_all: reader returned a negative read count (-1)'
248 }
249 assert reader.read_count == 1
250}
251
252fn test_read_any_errors_on_negative_read_count() {
253 mut reader := &NegativeReader{}
254 if _ := read_any(mut reader) {
255 assert false
256 } else {
257 assert err.msg() == 'io.read_any: reader returned a negative read count (-1)'
258 }
259 assert reader.read_count == 1
260}
261
262fn test_totalread_readline() {
263 text := 'Some testing text\nmore_enters'
264 mut s := StringReaderTest{
265 text: text
266 }
267 mut r := new_buffered_reader(reader: s)
268
269 _ := r.read_line() or {
270 assert false
271 panic('bad')
272 }
273 _ := r.read_line() or {
274 assert false
275 panic('bad')
276 }
277
278 assert r.total_read == text.len
279}
280
281fn test_read_line_until_zero_terminated() {
282 text := 'This is a test\0Nice try!\0'
283 mut s := StringReaderTest{
284 text: text
285 }
286 mut r := new_buffered_reader(reader: s)
287 line1 := r.read_line(delim: `\0`) or {
288 assert false
289 panic('bad')
290 }
291 assert line1 == 'This is a test'
292 line2 := r.read_line(delim: `\0`) or {
293 assert false
294 panic('bad')
295 }
296 assert line2 == 'Nice try!'
297 if _ := r.read_line(delim: `\0`) {
298 assert false
299 panic('bad')
300 }
301 assert r.end_of_stream()
302}
303