2 # Copyright (C) 2006-2010, Parrot Foundation.
7 use lib qw( . lib ../lib ../../lib );
10 use Parrot::Test tests => 25;
14 t/pmc/stringhandle.t - test the StringHandle PMC
18 % prove t/pmc/stringhandle.t
22 Tests the StringHandle PMC.
26 # L<PDD22/I\/O PMC API/=item new>
27 pir_output_is( <<'CODE', <<'OUT', 'new' );
29 new $P0, ['StringHandle']
30 say "ok 1 - $P0 = new ['StringHandle']"
33 ok 1 - $P0 = new ['StringHandle']
36 # L<PDD22/I\/O PMC API/=item open.*=item close>
37 pir_output_is( <<"CODE", <<'OUT', 'open and close - synchronous' );
39 \$P1 = new ['StringHandle']
41 say 'ok 1 - \$P1.open(\$S1)'
44 say 'ok 2 - \$P1.close()'
46 \$P3 = new ['StringHandle']
47 \$P3.'open'('temp_file', 'rw')
48 say 'ok 3 - \$P3.open(\$S1, \$S2) # rw mode'
52 say 'ok 4 - \$P3.open() # reopening'
56 \$P7 = new ['StringHandle']
57 \$P7.'open'('temp_file', 'w')
58 say 'ok 7 - \$P7.open(\$S1, \$S2) # new file, write mode succeeds'
67 ok 3 - $P3.open($S1, $S2) # rw mode
68 ok 4 - $P3.open() # reopening
69 ok 7 - $P7.open($S1, $S2) # new file, write mode succeeds
72 pir_output_is( <<'CODE', <<'OUT', 'get_bool' );
76 sh = new ['StringHandle']
78 unless sh goto b_false
82 sh.'open'('mockname', 'w')
83 sh.'print'('Some content')
97 # StringHandle doesn't use file descriptor, get_fd always return -1
98 pir_output_is( <<'CODE', <<'OUT', 'get_fd method' );
102 sh = new ['StringHandle']
105 sh.'open'('mockname', 'r')
115 skip 'no asynch calls yet' => 1;
117 pir_output_is( <<'CODE', <<'OUT', 'open and close - asynchronous' );
119 $P1 = # TT #1204 create a callback here
120 $P0 = new ['StringHandle']
123 say 'ok 1 - $P0.open($S1)'
126 say 'ok 2 - $P0.close($P1)'
128 $P0.'open'('README', 'rw')
129 say 'ok 3 - $P0.open($S1, $S2)'
133 say 'ok 4 - $P0.open()'
141 ok 3 - $P0.open($S1, $S2)
146 # L<PDD22/I\/O PMC API/=item read>
148 <<'CODE', <<'OUT', 'read - synchronous' );
150 $P0 = new ['StringHandle']
151 $P0.'open'('README', 'w')
153 $P0.'print'("This is Parrot, version")
159 $S0 = $P0.'read'(14) # bytes
160 if $S0 == 'This is Parrot' goto ok_1
163 say 'ok 1 - $S0 = $P1.read($I2)'
165 $S0 = $P0.'read'(9) # bytes
166 if $S0 == ', version' goto ok_2
169 say 'ok 2 - $S0 = $P1.read($I2) # again on same stream'
172 ok 1 - $S0 = $P1.read($I2)
173 ok 2 - $S0 = $P1.read($I2) # again on same stream
177 <<'CODE', <<'OUT', 'read opcode' );
179 $P0 = new ['StringHandle']
180 $P0.'open'('README', 'w')
182 print $P0, "This is Parrot, version"
187 $S0 = $P0.'read'(14) # bytes
188 if $S0 == 'This is Parrot' goto ok_1
191 say 'ok 1 - $S0 = $P1.read($I2)'
193 $S0 = $P0.'read'(9) # bytes
194 if $S0 == ', version' goto ok_2
197 say 'ok 2 - $S0 = $P1.read($I2) # again on same stream'
200 ok 1 - $S0 = $P1.read($I2)
201 ok 2 - $S0 = $P1.read($I2) # again on same stream
204 # L<PDD22/I\/O PMC API/=item print>
205 pir_output_is( <<"CODE", <<'OUT', 'print - synchronous' );
208 \$P0 = new ['StringHandle']
209 \$P0.'open'('temp_file', 'w')
212 say 'ok 1 - \$P0.print(\$I1)'
213 \$P0.'print'(456.789)
214 say 'ok 2 - \$P0.print(\$N1)'
215 \$P0.'print'("squawk\\n")
216 say 'ok 3 - \$P0.print(\$S1)'
217 \$P1 = new ['Integer']
220 say 'ok 4 - \$P0.print(\$P1)'
224 \$P0.'open'('temp_file', 'r')
226 \$S0 = \$P0.'read'(3) # bytes
227 if \$S0 == "123" goto ok_5
230 say 'ok 5 - read integer back from file'
232 \$S0 = \$P0.'read'(16) # bytes
233 if \$S0 == "456.789squawk\\n42" goto ok_6
238 say 'ok 6 - read string back from file'
243 ok 1 - $P0.print($I1)
244 ok 2 - $P0.print($N1)
245 ok 3 - $P0.print($S1)
246 ok 4 - $P0.print($P1)
247 ok 5 - read integer back from file
248 ok 6 - read string back from file
251 pir_output_is( <<'CODE', <<'OUT', 'puts' );
252 .include 'except_types.pasm'
256 sh = new ['StringHandle']
257 eh = new ['ExceptionHandler']
258 eh.'handle_types'(.EXCEPTION_PIO_ERROR)
261 # puts to SH not opened
264 sh.'puts'('something')
272 # puts to SH opened for reading
275 sh.'open'('mockname', 'r')
276 sh.'puts'('something')
289 # L<PDD22/I\/O PMC API/=item print.*=item readline>
290 pir_output_is( <<"CODE", <<'OUT', 'readline - synchronous' );
292 load_bytecode 'String/Utils.pbc'
294 chomp = get_global ['String';'Utils'], 'chomp'
296 \$P0 = new ['StringHandle']
297 \$P0.'open'('temp_file', 'w')
298 \$P0.'print'("foobarbaz\\n42")
301 \$P0.'open'('temp_file')
303 \$S0 = \$P0.'readline'()
305 if \$S0 == 'foobarbaz' goto ok_1
308 say 'ok 1 - \$S0 = \$P0.readline()'
310 \$S0 = \$P0.'readline'()
312 if \$S0 == '42' goto ok_2
315 say 'ok 2 - \$S0 = \$P0.readline() # again on same stream'
320 ok 1 - $S0 = $P0.readline()
321 ok 2 - $S0 = $P0.readline() # again on same stream
324 pir_output_is( <<'CODE', <<'OUT', 'readline 10,000 lines' );
326 load_bytecode 'String/Utils.pbc'
328 chomp = get_global ['String';'Utils'], 'chomp'
329 .local string test_line
330 .local pmc stringhandle
332 stringhandle = new ['StringHandle']
334 stringhandle.'open'('temp_file', 'w')
339 if counter > 10000 goto end_write_loop
341 stringhandle.'print'(counter)
342 stringhandle.'print'("\n")
346 stringhandle.'close'()
347 stringhandle.'open'('temp_file')
352 # read in the file one line at a time...
353 $I0 = stringhandle.'eof'()
354 if $I0 goto end_read_loop
356 test_line = stringhandle.'readline'()
357 if test_line == "" goto end_read_loop
358 test_line = chomp( test_line )
360 if $I1 == counter goto read_loop
362 ## the following lines provide more extensive debugging
363 ## output on a readline failure
372 if counter > 9000 goto read_something
375 say 'ok 1 - read 10,000 lines'
376 stringhandle.'close'()
379 ok 1 - read 10,000 lines
383 # TT #1204 test reading long chunks, eof, and across newlines
385 # TT #1204 pir_output_is( <<'CODE', <<'OUT', 'print, read, and readline - asynchronous', todo => 'not yet implemented' );
387 # L<PDD22/I\/O PMC API/=item record_separator>
388 pir_output_is( <<'CODE', <<'OUT', 'record_separator', todo => 'not yet implemented' );
390 $P0 = new ['StringHandle']
392 $S0 = $P0.'record_separator'()
393 if $S0 == "\n" goto ok_1
396 say 'ok 1 - $S0 = $P1.record_separator() # default'
399 $P0.'record_separator'($S99)
400 $S0 = $P0.'record_separator'()
401 if $S0 == $S99 goto ok_2
404 say 'ok 2 - $P0.record_separator($S1)'
407 $S0 = $P0.'record_separator'()
411 $S0 = $P0.'readline'()
412 if $S0 == '123abc' goto ok_3
415 say 'ok 3 - $P0.record_separator() # .readline works as expected'
418 ok 1 - $S0 = $P1.record_separator() # default
419 ok 2 - $P0.record_separator($S1)
420 ok 3 - $P0.record_separator() # .readline works as expected
423 # L<PDD22/I\/O PMC API/=item buffer_type>
424 pir_output_is( <<'CODE', <<'OUT', 'buffer_type' );
426 $P0 = new ['StringHandle']
428 $P0.'buffer_type'('unbuffered')
429 $S0 = $P0.'buffer_type'()
430 if $S0 == 'unbuffered' goto ok_1
433 say 'ok 1 - $S0 = $P1.buffer_type() # unbuffered'
435 $P0.'buffer_type'('line-buffered')
436 $S0 = $P0.'buffer_type'()
437 if $S0 == 'line-buffered' goto ok_2
440 say 'ok 2 - $S0 = $P1.buffer_type() # line-buffered'
442 $P0.'buffer_type'('full-buffered')
443 $S0 = $P0.'buffer_type'()
444 if $S0 == 'full-buffered' goto ok_3
447 say 'ok 3 - $S0 = $P1.buffer_type() # full-buffered'
451 ok 1 - $S0 = $P1.buffer_type() # unbuffered
452 ok 2 - $S0 = $P1.buffer_type() # line-buffered
453 ok 3 - $S0 = $P1.buffer_type() # full-buffered
456 # TT #1204 test effects of buffer_type, not just set/get
459 # L<PDD22/I\/O PMC API/=item buffer_size>
460 # NOTES: try setting positive, zero, negative int
461 # perform print and read ops
462 # change buffer size while it contains data
463 # try with all 'buffer_type' modes
465 pir_output_is( <<"CODE", <<'OUT', 'buffer_size' );
467 \$P0 = new ['StringHandle']
469 \$P0.'buffer_type'('full-buffered')
470 \$P0.'buffer_size'(42)
471 say 'ok 1 - \$P0.buffer_size(42) # set buffer size'
473 \$P0.'open'('temp_file', 'w')
474 \$P0.'print'(1234567890)
476 \$I0 = \$P0.'buffer_size'()
478 # The set buffer size is a minimum, the I/O subsystem may scale it upward
479 # to a round block, so test that the buffer size is equal or greater than
481 if \$I0 == 10 goto ok_2
484 say 'ok 2 - \$I0 = \$P0.buffer_size() # get buffer size'
488 \$P0.'open'('temp_file')
489 \$S0 = \$P0.'readline'()
491 if \$S0 == '1234567890' goto ok_3
494 say 'ok 3 - \$S0 = \$P0.readline() # buffer flushed'
500 ok 1 - $P0.buffer_size(42) # set buffer size
501 ok 2 - $I0 = $P0.buffer_size() # get buffer size
502 ok 3 - $S0 = $P0.readline() # buffer flushed
505 # L<PDD22/I\/O PMC API/=item encoding>
506 pir_output_is( <<'CODE', <<'OUT', 'encoding' );
508 $P0 = new ['StringHandle']
510 $P0.'encoding'('utf8')
511 $S0 = $P0.'encoding'()
512 if $S0 == 'utf8' goto ok_1
515 say 'ok 1 - $S0 = $P1.encoding() # utf8'
519 ok 1 - $S0 = $P1.encoding() # utf8
522 pir_output_is( <<"CODE", <<'OUT', 'encoding - read/write' );
524 \$P0 = new ['StringHandle']
525 \$P0.'encoding'('utf8')
527 \$P0.'open'('temp_file', 'w')
529 \$P0.'print'(1234567890)
531 \$S0 = iso-8859-1:"TÖTSCH"
535 \$P0.'open'('temp_file')
537 \$S1 = \$P0.'readline'()
538 if \$S1 == "1234567890\\n" goto ok_1
542 say 'ok 1 - \$S1 = \$P0.readline() # read with utf8 encoding on'
544 \$S2 = \$P0.'readline'()
545 if \$S2 == \$S0 goto ok_2
549 say 'ok 2 - \$S2 = \$P0.readline() # read iso-8859-1 string'
555 ok 1 - $S1 = $P0.readline() # read with utf8 encoding on
556 ok 2 - $S2 = $P0.readline() # read iso-8859-1 string
560 # L<PDD22/I\/O PMC API/=item mode>
561 pir_output_is( <<'CODE', <<'OUT', 'mode' );
563 $P0 = new ['StringHandle']
568 if $S0 == 'r' goto ok_1
571 say 'ok 1 - $S0 = $P0.mode() # get read mode'
577 ok 1 - $S0 = $P0.mode() # get read mode
580 pir_output_is( <<"CODE", <<"OUTPUT", "readall - closed stringhandle" );
588 pio = new ['StringHandle']
589 pio.'open'("temp_file", "w")
592 pio.'open'("temp_file")
593 \$S1 = pio.'readall'('temp_file')
594 if \$S0 == \$S1 goto ok
603 pir_output_is( <<"CODE", <<"OUTPUT", "readall - stringhandle with null content" );
607 sh = new ['StringHandle']
608 sh.'open'('mockname', 'r')
609 # Open sets content to an empty string, flush resets is to null
610 # and that is the case we are testing here.
611 # Also, ensures coverage of the flush method.
622 pir_output_is( <<"CODE", <<"OUTPUT", "readall() - opened stringhandle" );
630 pio = new ['StringHandle']
631 pio.'open'("temp_file", "w")
635 pio.'open'("temp_file", "r")
636 \$S1 = pio.'readall'()
637 if \$S0 == \$S1 goto ok
646 pir_output_is( <<'CODE', <<"OUTPUT", "is_closed" );
650 sh = new ['StringHandle']
653 sh.'open'("foo", "w")
662 pir_output_is( <<'CODE', <<'OUTPUT', 'StringHandle is not a tty' );
666 sh = new ['StringHandle']
675 pir_output_is( <<"CODE", <<"OUTPUT", "readall() - utf8 on closed stringhandle" );
678 ifh = new ['StringHandle']
679 ifh.'encoding'('utf8')
681 \$S0 = ifh.'readall'('temp_file')
684 \$S1 = encodingname \$I0
692 pir_output_is( <<"CODE", <<"OUTPUT", "readall() - utf8 on opened stringhandle" );
695 ifh = new ['StringHandle']
696 ifh.'encoding'('utf8')
697 ifh.'open'('temp_file')
699 \$S0 = ifh.'readall'()
702 \$S1 = encodingname \$I0
710 pir_output_is( <<'CODE', <<'OUTPUT', "clone an uninitialized stringhandle" );
712 $P0 = new ['StringHandle']
721 # L<PDD22/I\/O PMC API/=item get_fd>
722 # NOTES: this is going to be platform dependent
726 # cperl-indent-level: 4
729 # vim: expandtab shiftwidth=4: