#lang scheme (require net/base64 net/qp tests/eli-tester) (define tricky-strings (let ([dir (collection-path "tests" "racket")]) (list (make-bytes 200 32) (make-bytes 200 9) (make-bytes 200 (char->integer #\x)) (make-bytes 201 (char->integer #\x)) (make-bytes 202 (char->integer #\x)) (make-bytes 203 (char->integer #\x)) (make-bytes 204 (char->integer #\x)) (list->bytes (for/list ([i (in-range 256)]) i)) ;; Something that doesn't end with a LF: (bytes-append (with-input-from-file (build-path dir "net.rktl") (lambda () (read-bytes 500))) #"xxx") ;; CRLF: (regexp-replace #rx#"\r?\n" (with-input-from-file (build-path dir "net.rktl") (lambda () (read-bytes 500))) #"\r\n")))) (define (check-same encode decode port line-rx max-w) (let ([p (open-output-bytes)]) (copy-port port p) (let ([bytes (get-output-bytes p)] [r (open-output-bytes)]) (encode (open-input-bytes bytes) r) (let ([p (open-input-bytes (get-output-bytes r))]) (let loop () (let ([l (read-bytes-line p 'any)]) (unless (eof-object? l) (test ; #:failure-message (format "line too long; ~s" encode) (<= (bytes-length l) max-w)) (let ([m (regexp-match-positions line-rx l)]) (test ; #:failure-message (format "bad line; ~s" encode) (and m (= (bytes-length l) (cdar m))))) (loop)))) (let ([q (open-output-bytes)]) (decode (open-input-bytes (get-output-bytes r)) q) (unless (equal? (get-output-bytes q) bytes) (with-output-to-file "/tmp/x0" (lambda () (display (get-output-bytes r))) 'truncate) (with-output-to-file "/tmp/x1" (lambda () (display (get-output-bytes q))) 'truncate) (with-output-to-file "/tmp/x2" (lambda () (display bytes)) 'truncate) (error 'decode "failed"))))))) (define ((check-same-file encode decode line-rx max-w) file) (call-with-input-file file (lambda (p) (check-same encode decode p line-rx max-w)))) (define (check-same-all encode decode line-rx max-w) (for-each (lambda (tricky-string) (check-same encode decode (open-input-bytes tricky-string) line-rx max-w)) tricky-strings) (let* ([dir (collection-path "tests" "racket")] [files (filter-map (lambda (f) ;; check 1/4 of the files, randomly (let ([p (build-path dir f)]) (and (zero? (random 4)) (not (regexp-match #rx"^flat.*\\.rktl$" (path-element->string f))) (file-exists? p) p))) (directory-list dir))]) (for-each (check-same-file encode decode line-rx max-w) files))) (provide tests) (module+ main (tests)) (define (tests) (test do (check-same-all (lambda (i o) (qp-encode-stream i o)) qp-decode-stream #rx#"^(|[\t \41-\176]*[\41-\176]+)$" 76) do (check-same-all base64-encode-stream base64-decode-stream #rx#"^[0-9a-zA-Z+=/]*$" 72))) #| Use this to compare base64 encode/decode against the unix utilities (require net/base64 scheme/system) (define (base64-encode* bstr) (let ([o (open-output-bytes)]) (parameterize ([current-output-port o] [current-input-port (open-input-bytes bstr)]) (system "base64-encode")) (let* ([o (get-output-bytes o)] [o (regexp-replace #rx#"(.)(?:\r?\n)?$" o #"\\1\r\n")] [o (regexp-replace* #rx#"\r?\n" o #"\r\n")]) o))) (define (base64-decode* bstr) (let ([o (open-output-bytes)]) (parameterize ([current-output-port o] [current-input-port (open-input-bytes bstr)]) (system "base64-decode")) (get-output-bytes o))) (define (check-base64-encode bstr) (equal? (base64-encode bstr) (base64-encode* bstr))) (define (check-base64-decode bstr) (equal? (base64-decode bstr) (base64-decode* bstr))) (define (check-base64-both bstr) (let ([en (base64-encode bstr)]) (and (equal? en (base64-encode* bstr)) (equal? (base64-decode en) (base64-decode* en))))) |#