#lang racket/base (require trivial/private/test-common (only-in typed/racket/base ann : -> String Listof List U Bytes)) ;; Ill-typed `regexp:` expressions ;; TODO why can't I catch errors for (ann ... (List String))? WhydoI need #f? (module+ test (test-compile-error #:require trivial/regexp #:exn #rx"Type Checker" (ann (regexp-match: "hi" "hi") (U #f (List String String String))) (ann (regexp-match: #rx"(h)(i)" "hi") (U #f (List String))) (ann (regexp-match: #px"(?<=h)(?=i)" "hi") (U #f (List String String String))) ;;bg; ill-typed in untyped Racket (byte-regexp: #rx#"yolo") (ann (regexp-match: #rx#"hi" "hi") (U #f (List String String))) (ann (regexp-match: #px#"hi" "hi") (U #f (List Bytes Bytes))) (ann (regexp-match: (regexp "he") "hellooo") (U #f (List String))) (ann (let () (define-regexp: rx (regexp "he(l*)(o*)")) (regexp-match: rx "hellooo")) (U #f (List String String String))) ;; `define` doesn't propagate group information (ann (let () (define rx "he(l*)(o*)") (regexp-match: rx "helloooooooo")) (U #f (List String String String))) ;; --- Can't handle |, yet (ann (regexp-match: "this(group)|that" "that") (U #f (List String String))) ;; --- can't handle starred groups (ann (regexp-match: "(a)*(b)" "b") (U #f (List String String))) ) (test-compile-error #:require trivial/regexp racket/port #:exn #rx"Type Checker" ;; -- expected String, given Bytes (with-input-from-string "hello" (lambda () (define m (regexp-match: #rx#"lang" (current-input-port))) (and m (string=? (car m) "lang")))) ;; ---- is raising a type error, which is GOOD, but throwing during test ;;; -- return type assumed to be String, but really is Bytes ;;; (ugly, but at least we catch it statically) ;(with-input-from-file "test/regexp-fail.rkt" ; (lambda () ; (define m (regexp-match: #rx"lang" (current-input-port))) ; (and m (bytes=? #;string=? (car m) #"lang")))) ) ;; 2016-06-13 : these really should be errors, just no-opts ;(test-compile-error ; #:require trivial/regexp ; #:exn #rx"mutation not allowed" ; ;; -- set! problems ; (ann (let-regexp: ([a #rx"(b)(B)"]) ; (set! a #rx"") ; (regexp-match: a "hai")) ; (List String String String)) ; (let () ; (define-regexp: a #rx"h(i)") ; (set! a #rx"hi") ; (regexp-match a "hi")) ; ; (let-regexp: ([a #rx"h(i)"]) ; (set! a #rx"(h)(i)") ; (regexp-match a "hi")) ;) )