; input-output-port.scm - Tests for ; ; Copyright (c) 2009 Higepon(Taro Minowa) ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions ; are met: ; ; 1. Redistributions of source code must retain the above copyright ; notice, this list of conditions and the following disclaimer. ; ; 2. Redistributions in binary form must reproduce the above copyright ; notice, this list of conditions and the following disclaimer in the ; documentation and/or other materials provided with the distribution. ; ; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED ; TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ; ; $Id: test.ss 621 2008-11-09 06:22:47Z higepon $ (import (rnrs) (rnrs mutable-strings) (mosh) (mosh process) (mosh shell) (mosh test)) ;; N.B rm and cp should be written in pure scheme (define (rm file-name) (when (file-exists? file-name) (delete-file file-name))) (define (cp from to) (call-with-port (open-file-output-port to (file-options no-fail) (buffer-mode none)) (lambda (out) (call-with-port (open-file-input-port from (file-options no-fail) (buffer-mode none)) (lambda (in) (let ([bv (get-bytevector-all in)]) ; (format #t "cp bv length = ~a\n" (bytevector-length bv)) (put-bytevector out bv) (close-port in) (close-port out))))))) ;;(cp "./test-trueest.txt" "./test-trueest.txt.dat") ;; (define (cp from to) ;; (let-values ([(pid cin cout cerr) (spawn "cp" (list from to) (list #f #f #f))]) ;; (waitpid pid) ;; #f)) (define-syntax test-positions (syntax-rules () [(_ make) (begin (let* ([p (make "custom" (lambda (? start count) 0) (lambda () 0) #f (lambda () 'ok))]) (test-true (port-has-port-position? p)) (test-false (port-has-set-port-position!? p)) (test-equal (port-position p) 0) (close-port p)) (let* ([p (make "custom" (lambda (? start count) 0) #f (lambda (pos) 'ok) (lambda () 'ok))]) (test-false (port-has-port-position? p)) (test-true (port-has-set-port-position!? p)) (set-port-position! p 0) (close-port p)) (let* ([p (make "custom" (lambda (? start count) 0) #f #f (lambda () 'ok))]) (test-false (port-has-port-position? p)) (test-false (port-has-set-port-position!? p)) (close-port p)))])) (define (with-all-buffer-mode file proc) (let ([tmp-file (format "~a.temp" file)]) (for-each (lambda (mode) (cp file tmp-file) (proc mode tmp-file)) (list (buffer-mode none) (buffer-mode block) (buffer-mode line))))) (define (with-all-buffer-mode-simple proc) (for-each (lambda (mode) (proc mode)) (list (buffer-mode none) (buffer-mode block) (buffer-mode line)))) ;; binary-port (with-all-buffer-mode "./tests/test.txt" (lambda (mode file) (let ([port (open-file-input/output-port file (file-options no-fail no-truncate) mode)]) (define (write-and-back c) (put-u8 port c) (set-port-position! port (- (port-position port) 1))) (test-true (input-port? port)) (test-true (port-has-set-port-position!? port)) (test-true (port-has-port-position? port)) (test-equal (get-u8 port) #x2f) (test-equal (port-position port) 1) ;; write! (put-u8 port #x2e) ;; write! (write-and-back #xfb) (test-equal (get-u8 port) #xfb) (test-equal (port-position port) 3) (set-port-position! port 8193) ;; over the buffer boundary (test-equal (port-position port) 8193) (test-equal (get-u8 port) 46) (set-port-position! port 8190) (test-equal (port-position port) 8190) (test-equal (get-u8 port) 32) (test-equal (lookahead-u8 port) 110) (test-equal (port-position port) 8191) (test-equal (get-u8 port) 110) (set-port-position! port 8190) ;; read over the boundary (test-equal (get-bytevector-n port 30) #vu8(32 110 50 46 116 111 70 108 111 110 117 109 40 41 41 59 10 32 32 32 32 125 32 101 108 115 101 32 123 10)) (test-equal (port-position port) 8220) ;; read over the boundary and size > buffer-size (set-port-position! port 4000) (let ([bv1 (make-bytevector 10000)] [bv2 (get-bytevector-n port 10000)]) (test-equal (bytevector-u8-ref bv2 0) 123) (test-equal (bytevector-u8-ref bv2 9999) 108) (set-port-position! port 4000) (test-equal (get-bytevector-n! port bv1 0 10000) 10000) ;; write! (put-u8 port #xfc) (test-equal bv1 bv2)) ;; read-some (set-port-position! port 4000) (let ([bv (get-bytevector-some port)]) (test-true (> (bytevector-length bv) 0)) ;; yeah wrote data is here (test-equal (bytevector-u8-ref bv 0) 123)) ;; read-all (set-port-position! port 4000) (let ([bv (get-bytevector-all port)]) (test-equal (bytevector-length bv) 34861) (test-equal (bytevector-u8-ref bv 0) 123) (test-equal (bytevector-u8-ref bv 34860) 10)) (test-equal (port-position port) 38861) (set-port-position! port 4000) (put-bytevector port (make-bytevector 9000 #x13)) (close-port port)) ;; check the written data (let ([port (open-file-input/output-port file (file-options no-fail no-truncate) mode)]) #f (test-equal (get-u8 port) #x2f) (test-equal (port-position port) 1) (test-equal (get-u8 port) #x2e) (test-equal (port-position port) 2) (test-equal (get-u8 port) #xfb) (set-port-position! port 14000) (test-equal (get-u8 port) #xfc) (set-port-position! port 4000) (let ([bv (get-bytevector-n port 9000)]) (test-true (bytevector? bv)) (test-equal (bytevector-length bv) 9000) (test-true (for-all (lambda (x) (= #x13 x)) (bytevector->u8-list bv))) )) )) ;; textual port (with-all-buffer-mode "./tests/utf16.txt" (lambda (mode file) (let ([port (open-file-input/output-port file (file-options no-fail no-truncate) mode (make-transcoder (utf-16-codec)))]) (test-true (input-port? port)) (test-equal (read port) "あいう") ; rmosh can't handle this ;(test-equal (read-char port) #\newline) (test-true (port-eof? port)) (close-port port)))) ;; test utilitiy (define (empty-file-exists? path) (let ([port (open-file-input-port path (file-options))]) (let ([ret (eof-object? (get-u8 port))]) (close-port port) ret))) #| file-options (file-options) If file exists: raise &file-already-exists If does not exist: create new file |# (test-error i/o-file-already-exists-error? (open-file-input/output-port "./tests/utf16.txt")) (test-error i/o-file-already-exists-error? (open-file-input/output-port "./tests/utf16.txt" (file-options))) (with-all-buffer-mode-simple (lambda (mode) (test-error i/o-file-already-exists-error? (open-file-input/output-port "./tests/utf16.txt" (file-options) mode)))) (with-all-buffer-mode-simple (lambda (mode) (test-error i/o-file-already-exists-error? (open-file-input/output-port "./tests/utf16.txt" (file-options) mode (make-transcoder (utf-16-codec)))))) (with-all-buffer-mode-simple (lambda (mode) (let ([port (open-file-input/output-port "./not-exists")]) (close-port port) (test-true (empty-file-exists? "./not-exists")) (rm "./not-exists")))) (with-all-buffer-mode-simple (lambda (mode) (let ([port (open-file-input/output-port "./not-exists" (file-options))]) (close-port port) (test-true (empty-file-exists? "./not-exists")) (rm "./not-exists")))) (with-all-buffer-mode-simple (lambda (mode) (let ([port (open-file-input/output-port "./not-exists" (file-options) mode)]) (close-port port) (test-true (empty-file-exists? "./not-exists")) (rm "./not-exists")))) (with-all-buffer-mode-simple (lambda (mode) (let ([port (open-file-input/output-port "./not-exists" (file-options) mode (make-transcoder (utf-16-codec)))]) (close-port port) (test-true (empty-file-exists? "./not-exists")) (rm "./not-exists")))) #| (file-options no-create) If file exists: truncate If does not exist: raise &file-does-not-exist |# (with-all-buffer-mode "tests/utf16.txt" (lambda (mode file) (let ([port (open-file-input/output-port file (file-options no-create))]) (close-port port) (test-true (empty-file-exists? file))))) (with-all-buffer-mode "tests/utf16.txt" (lambda (mode file) (let ([port (open-file-input/output-port file (file-options no-create) mode)]) (close-port port) (test-true (empty-file-exists? file))))) (with-all-buffer-mode "tests/utf16.txt" (lambda (mode file) (let ([port (open-file-input/output-port file (file-options no-create) mode (make-transcoder (utf-16-codec)))]) (close-port port) (test-true (empty-file-exists? file))))) (with-all-buffer-mode-simple (lambda (mode) (test-error i/o-file-does-not-exist-error? (open-file-input/output-port "./not-exists" (file-options no-create))))) (with-all-buffer-mode-simple (lambda (mode) (test-error i/o-file-does-not-exist-error? (open-file-input/output-port "./not-exists" (file-options no-create) mode)))) (with-all-buffer-mode-simple (lambda (mode) (test-error i/o-file-does-not-exist-error? (open-file-input/output-port "./not-exists" (file-options no-create) mode (make-transcoder (utf-16-codec)))))) #| (file-options no-fail) If file exists: truncate If does not exist: create new file |# (with-all-buffer-mode "tests/utf16.txt" (lambda (mode file) (let ([port (open-file-input/output-port file (file-options no-fail))]) (close-port port) (test-true (empty-file-exists? file))))) (with-all-buffer-mode "tests/utf16.txt" (lambda (mode file) (let ([port (open-file-input/output-port file (file-options no-fail) mode)]) (close-port port) (test-true (empty-file-exists? file))))) (with-all-buffer-mode "tests/utf16.txt" (lambda (mode file) (let ([port (open-file-input/output-port file (file-options no-fail) mode (make-transcoder (utf-16-codec)))]) (close-port port) (test-true (empty-file-exists? file))))) (with-all-buffer-mode-simple (lambda (mode) (let ([port (open-file-input/output-port "./not-exists" (file-options no-fail))]) (close-port port) (test-true (empty-file-exists? "./not-exists")) (rm "./not-exists")))) (with-all-buffer-mode-simple (lambda (mode) (let ([port (open-file-input/output-port "./not-exists" (file-options no-fail) mode)]) (close-port port) (test-true (empty-file-exists? "./not-exists")) (rm "./not-exists")))) (with-all-buffer-mode-simple (lambda (mode) (let ([port (open-file-input/output-port "./not-exists" (file-options no-fail) mode (make-transcoder (utf-16-codec)))]) (close-port port) (test-true (empty-file-exists? "./not-exists")) (rm "./not-exists")))) #| (file-options no-truncate) If file exists: raise &file-already-exists If does not exist: create new file |# (test-error i/o-file-already-exists-error? (open-file-input/output-port "./tests/utf16.txt" (file-options no-truncate))) (with-all-buffer-mode-simple (lambda (mode) (test-error i/o-file-already-exists-error? (open-file-input/output-port "./tests/utf16.txt" (file-options no-truncate) mode)))) (with-all-buffer-mode-simple (lambda (mode) (test-error i/o-file-already-exists-error? (open-file-input/output-port "./tests/utf16.txt" (file-options no-truncate) mode (make-transcoder (utf-16-codec)))))) (with-all-buffer-mode-simple (lambda (mode) (let ([port (open-file-input/output-port "./not-exists" (file-options no-truncate))]) (close-port port) (test-true (empty-file-exists? "./not-exists")) (rm "./not-exists")))) (with-all-buffer-mode-simple (lambda (mode) (let ([port (open-file-input/output-port "./not-exists" (file-options no-truncate) mode)]) (close-port port) (test-true (empty-file-exists? "./not-exists")) (rm "./not-exists")))) (with-all-buffer-mode-simple (lambda (mode) (let ([port (open-file-input/output-port "./not-exists" (file-options no-truncate) mode (make-transcoder (utf-16-codec)))]) (close-port port) (test-true (empty-file-exists? "./not-exists")) (rm "./not-exists")))) #| (file-options no-create no-fail) If file exists: truncate If does not exist: [N.B.] R6RS say nothing about this case, we choose raise &file-does-not-exist |# (with-all-buffer-mode "tests/utf16.txt" (lambda (mode file) (let ([port (open-file-input/output-port file (file-options no-create no-fail))]) (close-port port) (test-true (empty-file-exists? file))))) (with-all-buffer-mode "tests/utf16.txt" (lambda (mode file) (let ([port (open-file-input/output-port file (file-options no-create no-fail) mode)]) (close-port port) (test-true (empty-file-exists? file))))) (with-all-buffer-mode "tests/utf16.txt" (lambda (mode file) (let ([port (open-file-input/output-port file (file-options no-create no-fail) mode (make-transcoder (utf-16-codec)))]) (close-port port) (test-true (empty-file-exists? file))))) (with-all-buffer-mode-simple (lambda (mode) (test-error i/o-file-does-not-exist-error? (open-file-input/output-port "./not-exists" (file-options no-create no-fail))))) (with-all-buffer-mode-simple (lambda (mode) (test-error i/o-file-does-not-exist-error? (open-file-input/output-port "./not-exists" (file-options no-create no-fail) mode)))) (with-all-buffer-mode-simple (lambda (mode) (test-error i/o-file-does-not-exist-error? (open-file-input/output-port "./not-exists" (file-options no-create no-fail) mode (make-transcoder (utf-16-codec)))))) #| (file-options no-fail no-truncate) If file exists: set port position to 0 (overwriting) If does not exist: create new file |# (with-all-buffer-mode "tests/utf16.txt" (lambda (mode file) (let ([port (open-file-input/output-port file (file-options no-fail no-truncate))]) (close-port port) (test-false (empty-file-exists? file))))) (with-all-buffer-mode "tests/utf16.txt" (lambda (mode file) (let ([port (open-file-input/output-port file (file-options no-fail no-truncate) mode)]) (close-port port) (test-false (empty-file-exists? file))))) (with-all-buffer-mode "tests/utf16.txt" (lambda (mode file) (let ([port (open-file-input/output-port file (file-options no-fail no-truncate) mode (make-transcoder (utf-16-codec)))]) (close-port port) (test-false (empty-file-exists? file))))) (with-all-buffer-mode-simple (lambda (mode) (let ([port (open-file-input/output-port "./not-exists" (file-options no-fail no-truncate))]) (close-port port) (test-true (empty-file-exists? "./not-exists")) (rm "./not-exists")))) (with-all-buffer-mode-simple (lambda (mode) (let ([port (open-file-input/output-port "./not-exists" (file-options no-fail no-truncate) mode)]) (close-port port) (test-true (empty-file-exists? "./not-exists")) (rm "./not-exists")))) (with-all-buffer-mode-simple (lambda (mode) (let ([port (open-file-input/output-port "./not-exists" (file-options no-fail no-truncate) mode (make-transcoder (utf-16-codec)))]) (close-port port) (test-true (empty-file-exists? "./not-exists")) (rm "./not-exists")))) #| (file-options no-create no-truncate) If file exists: set port position to 0 (overwriting) If does not exist: raise &file-does-not-exist |# (with-all-buffer-mode "tests/utf16.txt" (lambda (mode file) (let ([port (open-file-input/output-port file (file-options no-create no-truncate))]) (close-port port) (test-false (empty-file-exists? file))))) (with-all-buffer-mode "tests/utf16.txt" (lambda (mode file) (let ([port (open-file-input/output-port file (file-options no-create no-truncate) mode)]) (close-port port) (test-false (empty-file-exists? file))))) (with-all-buffer-mode "tests/utf16.txt" (lambda (mode file) (let ([port (open-file-input/output-port file (file-options no-create no-truncate) mode (make-transcoder (utf-16-codec)))]) (close-port port) (test-false (empty-file-exists? file))))) (with-all-buffer-mode-simple (lambda (mode) (test-error i/o-file-does-not-exist-error? (open-file-input/output-port "./not-exists" (file-options no-create no-truncate))))) (with-all-buffer-mode-simple (lambda (mode) (test-error i/o-file-does-not-exist-error? (open-file-input/output-port "./not-exists" (file-options no-create no-truncate) mode)))) (with-all-buffer-mode-simple (lambda (mode) (test-error i/o-file-does-not-exist-error? (open-file-input/output-port "./not-exists" (file-options no-create no-truncate) mode (make-transcoder (utf-16-codec)))))) #| (file-options no-create no-fail no-truncate) If file exists: set port position to 0 (overwriting) If does not exist: [N.B.] R6RS say nothing about this case, we choose raise &file-does-not-exist |# (with-all-buffer-mode "tests/utf16.txt" (lambda (mode file) (let ([port (open-file-input/output-port file (file-options no-create no-truncate no-fail))]) (close-port port) (test-false (empty-file-exists? file))))) (with-all-buffer-mode "tests/utf16.txt" (lambda (mode file) (let ([port (open-file-input/output-port file (file-options no-create no-truncate no-fail) mode)]) (close-port port) (test-false (empty-file-exists? file))))) (with-all-buffer-mode "tests/utf16.txt" (lambda (mode file) (let ([port (open-file-input/output-port file (file-options no-create no-truncate no-fail) mode (make-transcoder (utf-16-codec)))]) (close-port port) (test-false (empty-file-exists? file))))) (with-all-buffer-mode-simple (lambda (mode) (test-error i/o-file-does-not-exist-error? (open-file-input/output-port "./not-exists" (file-options no-create no-fail no-truncate))))) (with-all-buffer-mode-simple (lambda (mode) (test-error i/o-file-does-not-exist-error? (open-file-input/output-port "./not-exists" (file-options no-create no-fail no-truncate) mode)))) (with-all-buffer-mode-simple (lambda (mode) (test-error i/o-file-does-not-exist-error? (open-file-input/output-port "./not-exists" (file-options no-create no-fail no-truncate) mode (make-transcoder (utf-16-codec)))))) ;; custom (let* ([save #f] [p (make-custom-binary-input/output-port "custom in" (lambda (bv start end) (bytevector-u8-set! bv start 7) 1) (lambda (bv start end) (set! save (bytevector-u8-ref bv start)) 1) #f #f #f)]) (put-u8 p 10) (flush-output-port p) (test-equal save 10) (test-equal (get-u8 p) 7) (close-port p)) (test-positions make-custom-binary-input-port) (let* ([save #f] [p (make-custom-textual-input/output-port "custom in" (lambda (str start end) (string-set! str start #\!) 1) (lambda (str start end) (set! save (string-ref str start)) 1) #f #f #f)]) (put-char p #\q) (flush-output-port p) (test-equal save #\q) (test-equal #\! (get-char p)) (close-port p)) (test-results)