#lang scheme/base
(require (prefix-in scheme: (only-in scheme/base eq? eqv? equal?))
srfi/26
"match.ss"
"test-base.ss")
(define match-tests
(test-suite "match.ss"
(test-case "eq? and equal? expand to their normal forms outside of a match pattern"
(check-equal? eq? scheme:eq?)
(check-equal? equal? scheme:equal?))
(test-case "eq? matches (and does not) in the correct situations"
(let ([x 1]
[y "1"])
(check-equal? (match 1 [(eq? 1) "yes"] [_ "no"]) "yes")
(check-equal? (match 1 [(eq? x) "yes"] [_ "no"]) "yes")
(check-equal? (match 2 [(eq? 1) "yes"] [_ "no"]) "no")
(check-equal? (match 2 [(eq? x) "yes"] [_ "no"]) "no")
(check-equal? (match "1" [(eq? "1") "yes"] [_ "no"]) "no")
(check-equal? (match "1" [(eq? y) "yes"] [_ "no"]) "no")
(check-exn exn:fail? (cut match 2 [(eq? x) "yes"]))))
(test-case "equal? matches (and does not) in the correct situations"
(let ([x 1]
[y "1"])
(check-equal? (match 1 [(equal? 1) "yes"] [_ "no"]) "yes")
(check-equal? (match 1 [(equal? x) "yes"] [_ "no"]) "yes")
(check-equal? (match 2 [(equal? 1) "yes"] [_ "no"]) "no")
(check-equal? (match 2 [(equal? x) "yes"] [_ "no"]) "no")
(check-equal? (match "1" [(equal? "1") "yes"] [_ "no"]) "yes")
(check-equal? (match "1" [(equal? y) "yes"] [_ "no"]) "yes")
(check-exn exn:fail? (cut match 2 [(equal? x) "yes"]))))
(test-case "eq? binds correctly"
(let ([num1 123]
[num2 123])
(match num1
[(eq? num2 num2)
(set! num2 1000)])
(check-eq? num2 123)))
(test-case "equal? binds correctly"
(let ([str1 "123"]
[str2 "123"]
[str3 #f])
(check-false (eq? str1 str2))
(check-true (equal? str1 str2))
(match str1
[(equal? str2 str2)
(check-true (eq? str1 str2))
(check-true (equal? str1 str2))
(set! str3 str2)])
(check-false (eq? str1 str2))
(check-true (equal? str1 str2))
(check-true (eq? str1 str3))
(check-true (equal? str1 str3))
(check-false (eq? str2 str3))
(check-true (equal? str2 str3))))))
(provide match-tests)