350 lines
14 KiB
Scheme
350 lines
14 KiB
Scheme
|
|
(load-relative "loadtest.ss")
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;
|
|
;; url.ss tests
|
|
;;
|
|
|
|
(require (lib "url.ss" "net")
|
|
(lib "uri-codec.ss" "net")
|
|
(lib "string.ss"))
|
|
|
|
(test "%Pq" uri-decode "%Pq")
|
|
(test "%P" uri-decode "%P")
|
|
(test "a=hel%2blo+%e7%88%b8" alist->form-urlencoded '((a . "hel+lo \u7238")))
|
|
(test '((a . "hel+lo \u7238")) form-urlencoded->alist (alist->form-urlencoded '((a . "hel+lo \u7238"))))
|
|
(test "a=hel%2blo;b=good-bye" alist->form-urlencoded '((a . "hel+lo") (b . "good-bye")))
|
|
(parameterize ([current-alist-separator-mode 'semi])
|
|
(test "a=hel%2blo;b=good-bye" alist->form-urlencoded '((a . "hel+lo") (b . "good-bye"))))
|
|
(parameterize ([current-alist-separator-mode 'amp])
|
|
(test "a=hel%2blo&b=good-bye" alist->form-urlencoded '((a . "hel+lo") (b . "good-bye"))))
|
|
(test '((a . "hel+lo") (b . "good-bye")) form-urlencoded->alist (alist->form-urlencoded '((a . "hel+lo") (b . "good-bye"))))
|
|
(parameterize ([current-alist-separator-mode 'amp])
|
|
(test '((a . "hel+lo") (b . "good-bye")) form-urlencoded->alist (alist->form-urlencoded '((a . "hel+lo") (b . "good-bye")))))
|
|
(test '((a . "hel+lo") (b . "good-bye")) form-urlencoded->alist
|
|
(parameterize ([current-alist-separator-mode 'amp])
|
|
(alist->form-urlencoded '((a . "hel+lo") (b . "good-bye")))))
|
|
(parameterize ([current-alist-separator-mode 'semi])
|
|
(test '((a . "hel+lo&b=good-bye")) form-urlencoded->alist
|
|
(parameterize ([current-alist-separator-mode 'amp])
|
|
(alist->form-urlencoded '((a . "hel+lo") (b . "good-bye"))))))
|
|
(parameterize ([current-alist-separator-mode 'amp])
|
|
(test '((a . "hel+lo;b=good-bye")) form-urlencoded->alist
|
|
(parameterize ([current-alist-separator-mode 'semi])
|
|
(alist->form-urlencoded '((a . "hel+lo") (b . "good-bye"))))))
|
|
(test "aNt=hi" alist->form-urlencoded '((aNt . "hi")))
|
|
(test '((aNt . "hi")) form-urlencoded->alist (alist->form-urlencoded '((aNt . "hi"))))
|
|
(test "aNt=hi" alist->form-urlencoded (form-urlencoded->alist "aNt=hi"))
|
|
|
|
(test 'amp-or-semi current-alist-separator-mode)
|
|
(err/rt-test (current-alist-separator-mode 'bad))
|
|
|
|
(let ([with-censor (load-relative "censor.ss")])
|
|
(with-censor
|
|
(lambda ()
|
|
;; Test all ASCII chars
|
|
(let ([p (let loop ([n 0])
|
|
(if (= n 128)
|
|
null
|
|
(let ([s (string (char-downcase (integer->char n)))])
|
|
(cons (cons (string->symbol s) s)
|
|
(loop (add1 n))))))])
|
|
(test p form-urlencoded->alist (alist->form-urlencoded p))
|
|
(let ([l (apply string-append (map cdr p))])
|
|
(test l uri-decode (uri-encode l)))))))
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;
|
|
;; tests adapted from Noel Welsh's original test suite
|
|
;;
|
|
|
|
(let ()
|
|
(define-syntax (for stx)
|
|
(syntax-case stx (code)
|
|
[(_ (i from to) e)
|
|
(and (identifier? (syntax code))
|
|
(number? (syntax-e (syntax from)))
|
|
(number? (syntax-e (syntax to))))
|
|
(syntax (let loop ([i from])
|
|
e
|
|
(unless (= i to)
|
|
(loop (+ i 1)))))]))
|
|
|
|
|
|
(test "hello" uri-encode "hello")
|
|
(test "hello%20there" uri-encode "hello there")
|
|
|
|
(let ((pad (lambda (str)
|
|
(if (= (string-length str) 1)
|
|
(string-append "0" str)
|
|
str))))
|
|
(for (code 0 127)
|
|
(if (or (= code 45) (= code 33) (= code 95)
|
|
(= code 46) (= code 126) (= code 42)
|
|
(= code 39) (= code 40) (= code 41)
|
|
(and (<= 48 code) (<= code 57)) ; 0-9
|
|
(and (<= 65 code) (<= code 90)) ; A-Z
|
|
(and (<= 97 code) (<= code 122))) ; a-z
|
|
(test (string (integer->char code)) uri-encode (string (integer->char code)))
|
|
(test (string-append "%" (pad (number->string code 16)))
|
|
uri-encode
|
|
(string (integer->char code))))))
|
|
|
|
|
|
(test "" alist->form-urlencoded '())
|
|
(test "key=hello+there" alist->form-urlencoded '((key . "hello there")))
|
|
(test "key1=hi;key2=hello" alist->form-urlencoded '((key1 . "hi") (key2 . "hello")))
|
|
(test "key1=hello+there" alist->form-urlencoded '((key1 . "hello there")))
|
|
|
|
(test "hello" uri-decode "hello")
|
|
(test "hello there" uri-decode "hello%20there")
|
|
|
|
(let* ((pad (lambda (str)
|
|
(if (= (string-length str) 1)
|
|
(string-append "0" str)
|
|
str)))
|
|
(uppercase (lambda (str)
|
|
(string-uppercase! str)
|
|
str))
|
|
(lowercase (lambda (str)
|
|
(string-lowercase! str)
|
|
str))
|
|
(hexcode (lambda (code)
|
|
(string-append "%"
|
|
(pad (number->string code 16))))))
|
|
|
|
;; each of the next three of these were going from 0 to 255 in Noel's
|
|
;; original test suite. Those fail here, however.
|
|
|
|
(for (code 0 127)
|
|
(test (string (integer->char code)) uri-decode (uppercase (hexcode code))))
|
|
(for (code 0 127)
|
|
(test (string (integer->char code)) uri-decode (lowercase (hexcode code)))))
|
|
|
|
(for (code 0 127)
|
|
(test (string (integer->char code)) uri-decode (string (integer->char code))))
|
|
|
|
;; form-urlencoded->alist
|
|
(test '() form-urlencoded->alist "")
|
|
(test '((key . "value")) form-urlencoded->alist "key=value")
|
|
(test '((key . "hello there")) form-urlencoded->alist "key=hello+there")
|
|
(test '((key . "a value")) form-urlencoded->alist "key=a%20value")
|
|
(test '((key . "")) form-urlencoded->alist "key")
|
|
(test '((key1 . "value 1") (key2 . "value 2")) form-urlencoded->alist "key1=value+1&key2=value+2"))
|
|
|
|
;;
|
|
;; end Noel's original tests
|
|
;;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
(let ()
|
|
(define (test-s->u vec str)
|
|
(define (string->url/vec str) (url->vec (string->url str)))
|
|
(define (url/vec->string vec) (url->string (vec->url vec)))
|
|
(test vec string->url/vec str)
|
|
(test str url/vec->string vec))
|
|
|
|
(define (test-c-u/r expected base relative)
|
|
(define (combine-url/relative-vec x y)
|
|
(url->vec (combine-url/relative (vec->url x) y)))
|
|
(test (url->vec expected) combine-url/relative-vec (url->vec base) relative))
|
|
|
|
(define (vec->url vec)
|
|
(make-url
|
|
(vector-ref vec 0)
|
|
(vector-ref vec 1)
|
|
(vector-ref vec 2)
|
|
(vector-ref vec 3)
|
|
(map (lambda (x) (if (string? x)
|
|
x
|
|
(make-path/param (vector-ref x 0) (vector-ref x 1))))
|
|
(vector-ref vec 4))
|
|
(vector-ref vec 5)
|
|
(vector-ref vec 6)))
|
|
|
|
(define (url->vec url)
|
|
(vector (url-scheme url)
|
|
(url-user url)
|
|
(url-host url)
|
|
(url-port url)
|
|
(map (lambda (x) (if (string? x)
|
|
x
|
|
(vector (path/param-path x) (path/param-param x))))
|
|
(url-path url))
|
|
(url-query url)
|
|
(url-fragment url)))
|
|
|
|
(test-s->u (vector #f #f #f #f '("") '() #f)
|
|
"/")
|
|
(test-s->u (vector #f #f #f #f '() '() #f)
|
|
"")
|
|
(test-s->u (vector "http" #f "www.drscheme.org" #f '("") '() #f)
|
|
"http://www.drscheme.org/")
|
|
(test-s->u (vector "http" #f "www.drscheme.org" #f (list "a" "b" "c") '() #f)
|
|
"http://www.drscheme.org/a/b/c")
|
|
(test-s->u (vector "http" "robby" "www.drscheme.org" #f (list "a" "b" "c") '() #f)
|
|
"http://robby@www.drscheme.org/a/b/c")
|
|
(test-s->u (vector "http" #f "www.drscheme.org" 8080 (list "a" "b" "c") '() #f)
|
|
"http://www.drscheme.org:8080/a/b/c")
|
|
(test-s->u (vector "http" #f "www.drscheme.org" #f (list "a" "b" "c") '() "joe")
|
|
"http://www.drscheme.org/a/b/c#joe")
|
|
(test-s->u (vector "http" #f "www.drscheme.org" #f (list "a" "b" "c") '((tim . "")) #f)
|
|
"http://www.drscheme.org/a/b/c?tim=")
|
|
(test-s->u (vector "http" #f "www.drscheme.org" #f (list "a" "b" "c") '((tim . "")) "joe")
|
|
"http://www.drscheme.org/a/b/c?tim=#joe")
|
|
(test-s->u (vector "http" #f "www.drscheme.org" #f (list "a" "b" "c") '((tim . "tim")) "joe")
|
|
"http://www.drscheme.org/a/b/c?tim=tim#joe")
|
|
(test-s->u (vector "http" #f "www.drscheme.org" #f (list "a" "b" "c") '((tam . "tom")) "joe")
|
|
"http://www.drscheme.org/a/b/c?tam=tom#joe")
|
|
(test-s->u (vector "http" #f "www.drscheme.org" #f (list "a" "b" "c") '((tam . "tom") (pam . "pom")) "joe")
|
|
"http://www.drscheme.org/a/b/c?tam=tom;pam=pom#joe")
|
|
(parameterize ([current-alist-separator-mode 'semi])
|
|
(test-s->u (vector "http" #f "www.drscheme.org" #f (list "a" "b" "c") '((tam . "tom") (pam . "pom")) "joe")
|
|
"http://www.drscheme.org/a/b/c?tam=tom;pam=pom#joe"))
|
|
(parameterize ([current-alist-separator-mode 'amp])
|
|
(test-s->u (vector "http" #f "www.drscheme.org" #f (list "a" "b" "c") '((tam . "tom") (pam . "pom")) "joe")
|
|
"http://www.drscheme.org/a/b/c?tam=tom&pam=pom#joe"))
|
|
(test-s->u (vector "http" #f "www.drscheme.org" #f (list "a" "b" #("c" "b")) '() #f)
|
|
"http://www.drscheme.org/a/b/c;b")
|
|
(test-s->u (vector "http" #f "www.drscheme.org" #f (list #("a" "x") "b" #("c" "b")) '() #f)
|
|
"http://www.drscheme.org/a;x/b/c;b")
|
|
|
|
;; test unquoting for %
|
|
(test-s->u (vector "http" #f "www.drscheme.org" #f (list "a" "b" "c") '((ti#m . "")) "jo e")
|
|
"http://www.drscheme.org/a/b/c?ti%23m=#jo%20e")
|
|
(test-s->u (vector "http" #f "www.drscheme.org" #f (list #("a " " a") " b " " c ") '() #f)
|
|
"http://www.drscheme.org/a ; a/ b / c ")
|
|
(test-s->u (vector "http" "robb y" "www.drscheme.org" #f '("") '() #f)
|
|
"http://robb%20y@www.drscheme.org/")
|
|
|
|
(let ([empty-url (make-url #f #f #f #f '() '() #f)])
|
|
(test-c-u/r (string->url "http://www.drscheme.org")
|
|
empty-url
|
|
"http://www.drscheme.org")
|
|
(test-c-u/r (string->url "http://www.drscheme.org")
|
|
(string->url "http://www.drscheme.org")
|
|
""))
|
|
|
|
(test-c-u/r (string->url "http://www.mzscheme.org")
|
|
(string->url "http://www.drscheme.org/")
|
|
"http://www.mzscheme.org")
|
|
(test-c-u/r (string->url "http://www.drscheme.org/index.html")
|
|
(string->url "http://www.drscheme.org/")
|
|
"index.html")
|
|
(test-c-u/r (string->url "http://www.drscheme.org/index.html")
|
|
(string->url "http://www.drscheme.org/")
|
|
"/index.html")
|
|
(test-c-u/r (string->url "http://www.drscheme.org/index.html")
|
|
(string->url "http://www.drscheme.org/a/b/c/")
|
|
"/index.html")
|
|
(test-c-u/r (string->url "http://www.drscheme.org/a/b/index.html")
|
|
(string->url "http://www.drscheme.org/a/b/c")
|
|
"index.html")
|
|
(test-c-u/r (string->url "http://www.drscheme.org/a/b/c/index.html")
|
|
(string->url "http://www.drscheme.org/a/b/c/")
|
|
"index.html")
|
|
(test-c-u/r (string->url "http://www.drscheme.org/a/b/d/index.html")
|
|
(string->url "http://www.drscheme.org/a/b/c")
|
|
"d/index.html")
|
|
(test-c-u/r (string->url "http://www.drscheme.org/a/b/c/d/index.html")
|
|
(string->url "http://www.drscheme.org/a/b/c/")
|
|
"d/index.html")
|
|
|
|
(test-c-u/r (string->url "file:///a/b/c/d/index.html")
|
|
(string->url "file:///a/b/c/")
|
|
"d/index.html")
|
|
(test-c-u/r (string->url "file:///a/b/d/index.html")
|
|
(string->url "file:///a/b/c")
|
|
"d/index.html")
|
|
)
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;
|
|
;; other net tests
|
|
;;
|
|
|
|
(require (lib "base64.ss" "net")
|
|
(lib "qp.ss" "net")
|
|
(lib "port.ss"))
|
|
|
|
(define tricky-strings
|
|
(let ([dir (collection-path "tests" "mzscheme")])
|
|
(list (make-bytes 200 32)
|
|
(make-bytes 200 9)
|
|
(make-bytes 200 (char->integer #\x))
|
|
(list->bytes
|
|
(let loop ([i 0])
|
|
(if (= i 256)
|
|
null
|
|
(cons i (loop (add1 i))))))
|
|
;; Something that doesn't end with a LF:
|
|
(bytes-append
|
|
(with-input-from-file (build-path dir "net.ss") (lambda () (read-bytes 500)))
|
|
#"xxx")
|
|
;; CRLF:
|
|
(regexp-replace
|
|
#rx#"\n"
|
|
(with-input-from-file (build-path dir "net.ss") (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)
|
|
(unless (<= (bytes-length l) max-w)
|
|
(test encode "line too long" l))
|
|
(let ([m (regexp-match-positions line-rx l)])
|
|
(unless (and m
|
|
(= (bytes-length l) (cdar m)))
|
|
(test encode 'bad-line l)))
|
|
(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 file line-rx max-w)
|
|
;; This "test" is really just a progress report:
|
|
(test #t list? (list file encode))
|
|
(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)
|
|
(parameterize ([current-pseudo-random-generator (make-pseudo-random-generator)])
|
|
(random-seed 17)
|
|
(let ([dir (collection-path "tests" "mzscheme")])
|
|
(for-each (lambda (p)
|
|
(when (regexp-match #rx"[.]ss$" (path->string p))
|
|
(unless (or (positive? (random 10)) ; check random 1/10 of files
|
|
(equal? (path->string p) "flat.ss"))
|
|
(check-same-file encode decode (build-path dir p) line-rx max-w))))
|
|
(directory-list dir)))))
|
|
|
|
(check-same-all (lambda (i o) (qp-encode-stream i o))
|
|
qp-decode-stream
|
|
#rx#"^(|[\t \41-\176]*[\41-\176]+)$"
|
|
76)
|
|
|
|
(check-same-all base64-encode-stream
|
|
base64-decode-stream
|
|
#rx#"^[0-9a-zA-Z+=/]*$"
|
|
72)
|
|
|
|
(report-errs)
|