737 lines
22 KiB
Scheme
Executable File
737 lines
22 KiB
Scheme
Executable File
|
|
(library (tests io)
|
|
(export run-tests)
|
|
(import (ikarus)(tests framework))
|
|
|
|
|
|
(define-syntax test
|
|
(syntax-rules ()
|
|
[(_ name body)
|
|
(begin
|
|
(printf "running ~s ... " 'name)
|
|
body
|
|
(printf "ok\n"))]))
|
|
|
|
(define (make-n-byte-custom-binary-input-port n)
|
|
(assert (<= 0 n 256))
|
|
(make-custom-binary-input-port "test0"
|
|
(let ([c 0])
|
|
(lambda (bv i count)
|
|
(if (< c n)
|
|
(begin
|
|
(bytevector-u8-set! bv i c)
|
|
(set! c (+ c 1))
|
|
1)
|
|
0)))
|
|
#f #f #f))
|
|
|
|
(define (make-n-byte-bytevector-binary-input-port n)
|
|
(assert (<= 0 n 256))
|
|
(let ([bv (make-bytevector n)])
|
|
(let f ([i 0])
|
|
(unless (= i n)
|
|
(bytevector-u8-set! bv i i)
|
|
(f (+ i 1))))
|
|
(open-bytevector-input-port bv)))
|
|
|
|
(define (make-ascii-range-bytevector)
|
|
(let ([bv (make-bytevector 128)])
|
|
(let f ([i 0])
|
|
(unless (= i 128)
|
|
(bytevector-u8-set! bv i i)
|
|
(f (+ i 1))))
|
|
bv))
|
|
|
|
(define (make-ascii-range-bytevector+utf8-bom)
|
|
(let ([bv (make-bytevector (+ 128 3))])
|
|
(bytevector-u8-set! bv 0 #xEF)
|
|
(bytevector-u8-set! bv 1 #xBB)
|
|
(bytevector-u8-set! bv 2 #xBF)
|
|
(let f ([i 0])
|
|
(unless (= i 128)
|
|
(bytevector-u8-set! bv (+ i 3) i)
|
|
(f (+ i 1))))
|
|
bv))
|
|
|
|
(define (test-get-u8-1 p n)
|
|
(let f ([i 0])
|
|
(let ([x (get-u8 p)])
|
|
(cond
|
|
[(eof-object? x)
|
|
(unless (= i n)
|
|
(error 'test0 "premature termination" i))]
|
|
[(= x i) (f (+ i 1))]
|
|
[else
|
|
(error 'test0 "incorrect value returned" x)]))))
|
|
|
|
(define (test-get-char-1 p n)
|
|
(let f ([i 0])
|
|
(let ([x (get-char p)])
|
|
(cond
|
|
[(eof-object? x)
|
|
(unless (= i n)
|
|
(error 'test0 "premature termination" i))]
|
|
[(= (char->integer x) i) (f (+ i 1))]
|
|
[else
|
|
(error 'test0 "incorrect value returned" x)]))))
|
|
|
|
|
|
(define (test-peek-u8-1 p n)
|
|
(let f ([i 0])
|
|
(let* ([px (lookahead-u8 p)]
|
|
[x (get-u8 p)])
|
|
(cond
|
|
[(not (eqv? px x)) (error #f "peek invalid" px x)]
|
|
[(eof-object? x)
|
|
(unless (= i n)
|
|
(error #f "premature termination" i))]
|
|
[(= x i) (f (+ i 1))]
|
|
[else
|
|
(error #f "incorrect value returned" x i)]))))
|
|
|
|
(define (test-peek-char-1 p n)
|
|
(let f ([i 0])
|
|
(let* ([px (lookahead-char p)]
|
|
[x (get-char p)])
|
|
(cond
|
|
[(not (eqv? px x)) (error #f "peek invalid" px x)]
|
|
[(eof-object? x)
|
|
(unless (= i n)
|
|
(error #f "premature termination" i))]
|
|
[(= (char->integer x) i) (f (+ i 1))]
|
|
[else
|
|
(error #f "incorrect value returned" x i)]))))
|
|
|
|
(define (test-binary-port-eof?-1 p n)
|
|
(let f ([i 0])
|
|
(cond
|
|
[(port-eof? p)
|
|
(unless (= i n)
|
|
(error #f "premature termination" i))
|
|
(assert (eof-object? (lookahead-u8 p)))
|
|
(assert (eof-object? (get-u8 p)))]
|
|
[(= (get-u8 p) i) (f (+ i 1))]
|
|
[else
|
|
(error #f "incorrect value returned" i)])))
|
|
|
|
(define (test-textual-port-eof?-1 p n)
|
|
(let f ([i 0])
|
|
(cond
|
|
[(port-eof? p)
|
|
(unless (= i n)
|
|
(error #f "premature termination" i))
|
|
(assert (eof-object? (lookahead-char p)))
|
|
(assert (eof-object? (get-char p)))]
|
|
[(= (char->integer (get-char p)) i) (f (+ i 1))]
|
|
[else
|
|
(error #f "incorrect value returned" i)])))
|
|
|
|
(define (test-custom-binary-input-ports)
|
|
(test "reading 256 bytes in ascending order"
|
|
(test-get-u8-1 (make-n-byte-custom-binary-input-port 256) 256))
|
|
|
|
(test "reading 256 bytes in ascending order 2 at a time"
|
|
(test-get-u8-1
|
|
(make-custom-binary-input-port "test0"
|
|
(let ([c 0])
|
|
(lambda (bv i count)
|
|
(if (< c 256)
|
|
(begin
|
|
(assert (>= count 2))
|
|
(bytevector-u8-set! bv i c)
|
|
(bytevector-u8-set! bv (+ i 1) (+ c 1))
|
|
(set! c (+ c 2))
|
|
2)
|
|
0)))
|
|
#f #f #f)
|
|
256))
|
|
|
|
(test "peeking 256 bytes in ascending order"
|
|
(test-peek-u8-1 (make-n-byte-custom-binary-input-port 256) 256))
|
|
|
|
(test "custom-binary-port port-eof?"
|
|
(test-binary-port-eof?-1 (make-n-byte-custom-binary-input-port 256) 256))
|
|
|
|
;;;
|
|
(test "reading 256 bytes from bytevector-input-port"
|
|
(test-get-u8-1 (make-n-byte-bytevector-binary-input-port 256) 256))
|
|
|
|
(test "peeking 256 bytes from bytevector-input-port"
|
|
(test-peek-u8-1 (make-n-byte-bytevector-binary-input-port 256) 256))
|
|
|
|
(test "bytevector-binary-port port-eof?"
|
|
(test-binary-port-eof?-1 (make-n-byte-bytevector-binary-input-port 256) 256))
|
|
|
|
;;;
|
|
|
|
(test "reading 256 latin1 chars from bytevector-input-port"
|
|
(test-get-char-1
|
|
(transcoded-port (make-n-byte-bytevector-binary-input-port 256)
|
|
(make-transcoder (latin-1-codec) 'none 'raise))
|
|
256))
|
|
|
|
(test "peeking 256 bytes from latin1 transcoded port"
|
|
(test-peek-char-1
|
|
(transcoded-port (make-n-byte-bytevector-binary-input-port 256)
|
|
(make-transcoder (latin-1-codec) 'none 'raise))
|
|
256))
|
|
|
|
(test "latin1 transcoded port port-eof?"
|
|
(test-textual-port-eof?-1
|
|
(transcoded-port (make-n-byte-bytevector-binary-input-port 256)
|
|
(make-transcoder (latin-1-codec) 'none 'raise))
|
|
256))
|
|
|
|
;;;
|
|
|
|
(test "reading 128 utf8 chars from bytevector-input-port"
|
|
(test-get-char-1
|
|
(open-bytevector-input-port (make-ascii-range-bytevector)
|
|
(make-transcoder (utf-8-codec) 'none 'raise))
|
|
128))
|
|
|
|
(test "peeking 128 chars from utf8 port"
|
|
(test-peek-char-1
|
|
(open-bytevector-input-port (make-ascii-range-bytevector)
|
|
(make-transcoder (utf-8-codec) 'none 'raise))
|
|
128))
|
|
|
|
(test "utf8 transcoded port port-eof?"
|
|
(test-textual-port-eof?-1
|
|
(open-bytevector-input-port (make-ascii-range-bytevector)
|
|
(make-transcoder (utf-8-codec) 'none 'raise))
|
|
128)))
|
|
|
|
(define (make-utf8-bytevector-range1)
|
|
(u8-list->bytevector
|
|
(let f ([i 0] [j #x7F])
|
|
(cond
|
|
[(> i j) '()]
|
|
[else
|
|
(cons* i (f (+ i 1) j))]))))
|
|
|
|
|
|
|
|
(define (make-utf8-bytevector-range2)
|
|
(u8-list->bytevector
|
|
(let f ([i #x80] [j #x7FF])
|
|
(cond
|
|
[(> i j) '()]
|
|
[else
|
|
(cons* (fxior #b11000000 (fxsra i 6))
|
|
(fxior #b10000000 (fxand i #b111111))
|
|
(f (+ i 1) j))]))))
|
|
|
|
(define (make-utf8-bytevector-range3)
|
|
(u8-list->bytevector
|
|
(let f ([i #x800] [j #xFFFF])
|
|
(cond
|
|
[(> i j) '()]
|
|
[(fx= i #xD800) (f #xE000 j)]
|
|
[else
|
|
(cons* (fxior #b11100000 (fxsra i 12))
|
|
(fxior #b10000000 (fxand (fxsra i 6) #b111111))
|
|
(fxior #b10000000 (fxand i #b111111))
|
|
(f (+ i 1) j))]))))
|
|
|
|
(define (make-utf8-bytevector-range4)
|
|
(u8-list->bytevector
|
|
(let f ([i #x10000] [j #x10FFFF])
|
|
(cond
|
|
[(> i j) '()]
|
|
[else
|
|
(cons* (fxior #b11110000 (fxsra i 18))
|
|
(fxior #b10000000 (fxand (fxsra i 12) #b111111))
|
|
(fxior #b10000000 (fxand (fxsra i 6) #b111111))
|
|
(fxior #b10000000 (fxand i #b111111))
|
|
(f (+ i 1) j))]))))
|
|
|
|
(define (make-utf8-string-range1)
|
|
(list->string
|
|
(let f ([i 0] [j #x7F])
|
|
(cond
|
|
[(> i j) '()]
|
|
[else
|
|
(cons (integer->char i)
|
|
(f (+ i 1) j))]))))
|
|
|
|
(define (make-utf8-string-range2)
|
|
(list->string
|
|
(let f ([i #x80] [j #x7FF])
|
|
(cond
|
|
[(> i j) '()]
|
|
[else
|
|
(cons (integer->char i)
|
|
(f (+ i 1) j))]))))
|
|
|
|
(define (make-utf8-string-range3)
|
|
(list->string
|
|
(let f ([i #x800] [j #xFFFF])
|
|
(cond
|
|
[(> i j) '()]
|
|
[(fx= i #xD800) (f #xE000 j)]
|
|
[else
|
|
(cons (integer->char i)
|
|
(f (+ i 1) j))]))))
|
|
|
|
(define (make-utf8-string-range4)
|
|
(list->string
|
|
(let f ([i #x10000] [j #x10FFFF])
|
|
(cond
|
|
[(> i j) '()]
|
|
[else
|
|
(cons (integer->char i)
|
|
(f (+ i 1) j))]))))
|
|
|
|
(define (test-port-string-output p str)
|
|
(let f ([i 0])
|
|
(let ([x (get-char p)])
|
|
(cond
|
|
[(eof-object? x)
|
|
(unless (= i (string-length str))
|
|
(error #f "premature eof"))]
|
|
[(= i (string-length str))
|
|
(error #f "too many chars")]
|
|
[(char=? x (string-ref str i))
|
|
(f (+ i 1))]
|
|
[else
|
|
(error #f
|
|
(format
|
|
"mismatch at index ~a, got char ~a (code #x~x), \
|
|
expected char ~a (code #x~x)"
|
|
i
|
|
x
|
|
(char->integer x)
|
|
(string-ref str i)
|
|
(char->integer (string-ref str i))))]))))
|
|
|
|
|
|
(define (test-port-string-peeking-output p str)
|
|
(let f ([i 0])
|
|
(let ([x (lookahead-char p)])
|
|
(cond
|
|
[(eof-object? x)
|
|
(unless (= i (string-length str))
|
|
(error #f "premature eof"))]
|
|
[(= i (string-length str))
|
|
(error #f "too many chars")]
|
|
[(not (char=? x (get-char p)))
|
|
(error #f "peek not same as get")]
|
|
[(char=? x (string-ref str i))
|
|
(f (+ i 1))]
|
|
[else
|
|
(error #f "mismatch" x (string-ref str i) i)]))))
|
|
|
|
|
|
(define (invalid-code? n) (not (valid-code? n)))
|
|
(define (valid-code? n)
|
|
(cond
|
|
[(< n 0) #f]
|
|
[(<= n #xD7FF) #t]
|
|
[(< n #xE000) #f]
|
|
[(<= n #x10FFFF) #t]
|
|
[else (error 'valid-code? "out of range" n)]))
|
|
|
|
|
|
|
|
(define (make-u16le-bv min max)
|
|
(u8-list->bytevector
|
|
(let f ([i min])
|
|
(cond
|
|
[(> i max) '()]
|
|
[(invalid-code? i) (f (+ i 1))]
|
|
[(< i #x10000)
|
|
(cons*
|
|
(fxand i #xFF)
|
|
(fxsra i 8)
|
|
(f (+ i 1)))]
|
|
[else
|
|
(let ([ii (fx- i #x10000)])
|
|
(let ([w1 (fxior #xD800 (fxand #x3FF (fxsra ii 10)))]
|
|
[w2 (fxior #xDC00 (fxand #x3FF ii))])
|
|
(cons*
|
|
(fxand w1 #xFF)
|
|
(fxsra w1 8)
|
|
(fxand w2 #xFF)
|
|
(fxsra w2 8)
|
|
(f (+ i 1)))))]))))
|
|
|
|
(define (make-string-slice min max)
|
|
(list->string
|
|
(let f ([i min])
|
|
(cond
|
|
[(> i max) '()]
|
|
[(invalid-code? i) (f (+ i 1))]
|
|
[else (cons (integer->char i) (f (+ i 1)))]))))
|
|
|
|
|
|
(define (make-u16le-range1)
|
|
(make-u16le-bv 0 #x7FFF))
|
|
(define (make-u16le-range2)
|
|
(make-u16le-bv #x8000 #x10FFFF))
|
|
(define (make-utf16-string-range1)
|
|
(make-string-slice 0 #x7FFF))
|
|
(define (make-utf16-string-range2)
|
|
(make-string-slice #x8000 #x10FFFF))
|
|
|
|
(define (run-exhaustive-tests)
|
|
|
|
(test "utf8 range 1"
|
|
(test-port-string-output
|
|
(open-bytevector-input-port (make-utf8-bytevector-range1)
|
|
(make-transcoder (utf-8-codec) 'none 'raise))
|
|
(make-utf8-string-range1)))
|
|
|
|
(test "utf8 range 2"
|
|
(test-port-string-output
|
|
(open-bytevector-input-port (make-utf8-bytevector-range2)
|
|
(make-transcoder (utf-8-codec) 'none 'raise))
|
|
(make-utf8-string-range2)))
|
|
|
|
(test "utf8 range 3"
|
|
(test-port-string-output
|
|
(open-bytevector-input-port (make-utf8-bytevector-range3)
|
|
(make-transcoder (utf-8-codec) 'none 'raise))
|
|
(make-utf8-string-range3)))
|
|
|
|
(test "utf8 range 4"
|
|
(test-port-string-output
|
|
(open-bytevector-input-port (make-utf8-bytevector-range4)
|
|
(make-transcoder (utf-8-codec) 'none 'raise))
|
|
(make-utf8-string-range4)))
|
|
|
|
|
|
(test "utf16 range 1"
|
|
(test-port-string-output
|
|
(open-bytevector-input-port (make-u16le-range1)
|
|
(make-transcoder (utf-16-codec) 'none 'raise))
|
|
(make-utf16-string-range1)))
|
|
|
|
|
|
(test "utf16 range 2"
|
|
(test-port-string-output
|
|
(open-bytevector-input-port (make-u16le-range2)
|
|
(make-transcoder (utf-16-codec) 'none 'raise))
|
|
(make-utf16-string-range2)))
|
|
|
|
|
|
(test "utf8 peek range 1"
|
|
(test-port-string-peeking-output
|
|
(open-bytevector-input-port (make-utf8-bytevector-range1)
|
|
(make-transcoder (utf-8-codec) 'none 'raise))
|
|
(make-utf8-string-range1)))
|
|
|
|
(test "utf8 peek range 2"
|
|
(test-port-string-peeking-output
|
|
(open-bytevector-input-port (make-utf8-bytevector-range2)
|
|
(make-transcoder (utf-8-codec) 'none 'raise))
|
|
(make-utf8-string-range2)))
|
|
|
|
(test "utf8 peek range 3"
|
|
(test-port-string-peeking-output
|
|
(open-bytevector-input-port (make-utf8-bytevector-range3)
|
|
(make-transcoder (utf-8-codec) 'none 'raise))
|
|
(make-utf8-string-range3)))
|
|
|
|
(test "utf8 peek range 4"
|
|
(test-port-string-peeking-output
|
|
(open-bytevector-input-port (make-utf8-bytevector-range4)
|
|
(make-transcoder (utf-8-codec) 'none 'raise))
|
|
(make-utf8-string-range4)))
|
|
|
|
(test "utf16 peek range 1"
|
|
(test-port-string-peeking-output
|
|
(open-bytevector-input-port (make-u16le-range1)
|
|
(make-transcoder (utf-16-codec) 'none 'raise))
|
|
(make-utf16-string-range1)))
|
|
|
|
(test "utf16 peek range 2"
|
|
(test-port-string-peeking-output
|
|
(open-bytevector-input-port (make-u16le-range2)
|
|
(make-transcoder (utf-16-codec) 'none 'raise))
|
|
(make-utf16-string-range2)))
|
|
|
|
(test "utf8 range 1 string"
|
|
(test-port-string-output
|
|
(open-string-input-port (make-utf8-string-range1))
|
|
(make-utf8-string-range1)))
|
|
|
|
(test "utf8 range 2 string"
|
|
(test-port-string-output
|
|
(open-string-input-port (make-utf8-string-range2))
|
|
(make-utf8-string-range2)))
|
|
|
|
(test "utf8 range 3 string"
|
|
(test-port-string-output
|
|
(open-string-input-port (make-utf8-string-range3))
|
|
(make-utf8-string-range3)))
|
|
|
|
(test "utf8 range 4 string"
|
|
(test-port-string-output
|
|
(open-string-input-port (make-utf8-string-range4))
|
|
(make-utf8-string-range4)))
|
|
|
|
(test "utf8 peek range 2 string"
|
|
(test-port-string-peeking-output
|
|
(open-string-input-port (make-utf8-string-range2))
|
|
(make-utf8-string-range2)))
|
|
|
|
(test "utf8 peek range 3 string"
|
|
(test-port-string-peeking-output
|
|
(open-string-input-port (make-utf8-string-range3))
|
|
(make-utf8-string-range3)))
|
|
|
|
(test "utf8 peek range 4 string"
|
|
(test-port-string-peeking-output
|
|
(open-string-input-port (make-utf8-string-range4))
|
|
(make-utf8-string-range4))))
|
|
|
|
|
|
(define (run-interactive-tests)
|
|
(display "now write something on the keyboard ...\n")
|
|
(printf "you typed ~s\n"
|
|
(list->string
|
|
(let ([p (standard-input-port)])
|
|
(let f ()
|
|
(let ([x (get-u8 p)])
|
|
(if (eof-object? x)
|
|
'()
|
|
(cons (integer->char x) (f))))))))
|
|
|
|
(display "let's do it again ...\n")
|
|
(printf "you typed ~s\n"
|
|
(list->string
|
|
(let ([p (transcoded-port (standard-input-port)
|
|
(make-transcoder (utf-8-codec)))])
|
|
(let f ()
|
|
(let ([x (get-char p)])
|
|
(if (eof-object? x)
|
|
'()
|
|
(cons x (f)))))))))
|
|
|
|
(define (file-size-char-by-char filename)
|
|
(with-input-from-file filename
|
|
(lambda ()
|
|
(let f ([i 0])
|
|
(let ([x (get-char (current-input-port))])
|
|
(if (eof-object? x)
|
|
i
|
|
(f (+ i 1))))))))
|
|
|
|
|
|
(define (file->bytevector filename)
|
|
(let ([p (open-file-input-port filename (file-options) 'block #f)])
|
|
(u8-list->bytevector
|
|
(let f ()
|
|
(let ([x (get-u8 p)])
|
|
(if (eof-object? x)
|
|
(begin (close-input-port p) '())
|
|
(cons x (f))))))))
|
|
|
|
(define (bytevector->binary-port bv p)
|
|
(let f ([i 0])
|
|
(unless (fx= i (bytevector-length bv))
|
|
(put-u8 p (bytevector-u8-ref bv i))
|
|
(f (fx+ i 1)))))
|
|
|
|
(define (bytevector->textual-port bv p)
|
|
(let f ([i 0])
|
|
(unless (fx= i (bytevector-length bv))
|
|
(put-char p (integer->char (bytevector-u8-ref bv i)))
|
|
(f (fx+ i 1)))))
|
|
|
|
(define (test-input-files)
|
|
(assert (= (file-size-char-by-char (src-file "tests/SRFI-1.ss")) 56573))
|
|
(assert (= (file-size (src-file "tests/SRFI-1.ss")) 56573))
|
|
(let ([bv (file->bytevector (src-file "tests/SRFI-1.ss"))])
|
|
(let-values ([(p extract) (open-bytevector-output-port #f)])
|
|
(bytevector->binary-port bv p)
|
|
(let ([bv2 (extract)])
|
|
(assert (bytevector=? bv bv2))
|
|
(assert (bytevector=? #vu8() (extract))))))
|
|
|
|
(let ([bv (file->bytevector (src-file "tests/SRFI-1.ss"))])
|
|
(let-values ([(p extract) (open-bytevector-output-port
|
|
(native-transcoder))])
|
|
(bytevector->textual-port bv p)
|
|
(let ([bv2 (extract)])
|
|
(assert (bytevector=? bv bv2))
|
|
(assert (bytevector=? #vu8() (extract))))))
|
|
|
|
(let ([bv (file->bytevector (src-file "tests/SRFI-1.ss"))])
|
|
(let-values ([(p extract) (open-bytevector-output-port
|
|
(make-transcoder (latin-1-codec)))])
|
|
(bytevector->textual-port bv p)
|
|
(let ([bv2 (extract)])
|
|
(assert (bytevector=? bv bv2))
|
|
(assert (bytevector=? #vu8() (extract))))))
|
|
|
|
(let ([bv (file->bytevector (src-file "tests/SRFI-1.ss"))])
|
|
(let-values ([(p extract) (open-string-output-port)])
|
|
(bytevector->textual-port bv p)
|
|
(let ([str (extract)])
|
|
(assert (bytevector=? bv (string->utf8 str)))
|
|
(assert (string=? "" (extract))))))
|
|
|
|
(let ([p (standard-output-port)])
|
|
(bytevector->binary-port
|
|
(string->utf8 "HELLO THERE\n")
|
|
p)
|
|
(flush-output-port p))
|
|
|
|
(let ([p (current-output-port)])
|
|
(bytevector->textual-port
|
|
(string->utf8 "HELLO THERE\n")
|
|
p)
|
|
(flush-output-port p))
|
|
|
|
(let ([p (current-output-port)])
|
|
(put-string p "HELLO THERE\n")
|
|
(flush-output-port p)))
|
|
|
|
(define (test-custom-binary-output-ports)
|
|
(define ls '())
|
|
(let ([p (make-custom-binary-output-port "foo"
|
|
(lambda (bv i c)
|
|
(let f ([i i] [c c])
|
|
(unless (fx= c 0)
|
|
(set! ls (cons (bytevector-u8-ref bv i) ls))
|
|
(f (fx+ i 1) (fx- c 1))))
|
|
c)
|
|
#f
|
|
#f
|
|
#f)])
|
|
(let f ([i 0])
|
|
(unless (fx= i 10000)
|
|
(put-u8 p (mod i 37))
|
|
(f (+ i 1))))
|
|
(flush-output-port p)
|
|
(let f ([i 0] [ls (reverse ls)])
|
|
(unless (null? ls)
|
|
(assert (fx= (mod i 37) (car ls)))
|
|
(f (fx+ i 1) (cdr ls))))))
|
|
|
|
|
|
(define (test-partial-reads)
|
|
(define (make-test-string)
|
|
(list->string
|
|
(let f ([i 0])
|
|
(cond
|
|
[(fx=? i #x110000) '()]
|
|
[(fx=? i #xD800) (f #xE000)]
|
|
[else (cons (integer->char i) (f (+ i 1)))]))))
|
|
(define (make-slow-input-port bv transcoder)
|
|
(let ([n 0])
|
|
(transcoded-port
|
|
(make-custom-binary-input-port "foo"
|
|
(lambda (buffer i cnt)
|
|
(cond
|
|
[(fx=? n (bytevector-length bv)) 0]
|
|
[else
|
|
(let ([u8 (bytevector-u8-ref bv n)])
|
|
; (printf "got [~s] #b~b\n" n u8)
|
|
(bytevector-u8-set! buffer i u8))
|
|
(set! n (+ n 1))
|
|
1]))
|
|
#f #f #f)
|
|
transcoder)))
|
|
(define (test name codec s->bv bv->s)
|
|
(printf "testing partial reads for ~s codec ... " name)
|
|
(let ([s (make-test-string)])
|
|
(assert (string=? s (bv->s (s->bv s))))
|
|
(let ([r (call-with-port
|
|
(make-slow-input-port (s->bv s)
|
|
(make-transcoder codec
|
|
(eol-style none) (error-handling-mode raise)))
|
|
get-string-all)])
|
|
(unless (string=? r s)
|
|
(if (= (string-length r) (string-length s))
|
|
(error #f "test failed")
|
|
(error #f "length mismatch"
|
|
(string-length s) (string-length r))))))
|
|
(printf "ok\n"))
|
|
(test 'utf8 (utf-8-codec)
|
|
string->utf8
|
|
utf8->string)
|
|
(test 'utf16 (utf-16-codec)
|
|
(lambda (x) (string->utf16 x 'little))
|
|
(lambda (x) (utf16->string x 'little))))
|
|
|
|
(define-tests test-input-ports
|
|
[eof-object?
|
|
(get-line (open-string-input-port ""))]
|
|
[(lambda (x) (equal? x "abcd"))
|
|
(get-line (open-string-input-port "abcd"))]
|
|
[(lambda (x) (equal? x ""))
|
|
(get-line (open-string-input-port "\nabcd"))]
|
|
[(lambda (x) (equal? x "abcd"))
|
|
(get-line (open-string-input-port "abcd\nefg"))])
|
|
|
|
(define (test-has-port-position)
|
|
(define-syntax check
|
|
(syntax-rules ()
|
|
[(_ e)
|
|
(begin ;;; evaluating e twice
|
|
(assert (not (port-has-port-position? e)))
|
|
(assert
|
|
(guard (con
|
|
[(assertion-violation? con) #t]
|
|
[else #f])
|
|
(begin (port-position e) #f))))]))
|
|
(check (make-custom-binary-input-port "foo" (lambda a 0) #f #f #f))
|
|
(check (make-custom-binary-output-port "foo" (lambda a 0) #f #f #f))
|
|
(check (make-custom-textual-input-port "foo" (lambda a 0) #f #f #f))
|
|
(check (make-custom-textual-output-port "foo" (lambda a 0) #f #f #f)))
|
|
|
|
|
|
(define (test-put-bytevector)
|
|
(call-with-values open-bytevector-output-port
|
|
(lambda (p e)
|
|
(do ((i 0 (+ i 1))) ((= i 86))
|
|
(put-bytevector p '#vu8(0))
|
|
(put-u8 p 0))
|
|
(assert (equal? (e) (make-bytevector (* 86 2) 0)))))
|
|
|
|
(call-with-values open-bytevector-output-port
|
|
(lambda (p e)
|
|
(do ((i 0 (+ i 1))) ((= i 86))
|
|
(put-u8 p 0)
|
|
(put-u8 p 0))
|
|
(assert (equal? (e) (make-bytevector (* 86 2) 0)))))
|
|
|
|
(call-with-values open-bytevector-output-port
|
|
(lambda (p e)
|
|
(do ((i 0 (+ i 1))) ((= i 86))
|
|
(put-bytevector p '#vu8(0))
|
|
(put-bytevector p '#vu8(0)))
|
|
(assert (equal? (e) (make-bytevector (* 86 2) 0))))))
|
|
|
|
(define (test-get-bytevector-n)
|
|
(let ((p (open-bytevector-input-port '#vu8(1 2 3 4 5 6 7 8 9)))
|
|
(buf (make-bytevector 10 #xff)))
|
|
(let ([buf1
|
|
(begin
|
|
(printf "going to read 5 bytes: ~s\n" (get-bytevector-n! p buf 0 5))
|
|
(printf "result: ~s\n" buf)
|
|
(bytevector-copy buf))])
|
|
(printf "going to read 1 byte: ~s\n" (get-bytevector-n! p buf 5 1))
|
|
(printf "result: ~s\n" buf)
|
|
(unless (bytevector=? buf '#vu8(1 2 3 4 5 6 #xff #xff #xff #xff))
|
|
(error 'test "the data is not correct" buf1 buf)))))
|
|
|
|
(define (run-tests)
|
|
(test-get-bytevector-n)
|
|
(test-custom-binary-input-ports)
|
|
(test-custom-binary-output-ports)
|
|
(run-exhaustive-tests)
|
|
(test-input-files)
|
|
(test-partial-reads)
|
|
(test-input-ports)
|
|
(test-has-port-position)
|
|
(test-put-bytevector))
|
|
|
|
)
|
|
|
|
|
|
|