match.test 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. ;;;; match.test --- (ice-9 match) -*- mode: scheme; coding: utf-8; -*-
  2. ;;;;
  3. ;;;; Copyright (C) 2010, 2011, 2012 Free Software Foundation, Inc.
  4. ;;;;
  5. ;;;; This library is free software; you can redistribute it and/or
  6. ;;;; modify it under the terms of the GNU Lesser General Public
  7. ;;;; License as published by the Free Software Foundation; either
  8. ;;;; version 3 of the License, or (at your option) any later version.
  9. ;;;;
  10. ;;;; This library is distributed in the hope that it will be useful,
  11. ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. ;;;; Lesser General Public License for more details.
  14. ;;;;
  15. ;;;; You should have received a copy of the GNU Lesser General Public
  16. ;;;; License along with this library; if not, write to the Free Software
  17. ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  18. (define-module (test-match)
  19. #:use-module (ice-9 match)
  20. #:use-module (srfi srfi-9)
  21. #:use-module (test-suite lib))
  22. (define exception:match-error
  23. (cons 'match-error "^.*$"))
  24. (define-record-type rtd-2-slots
  25. (make-2-slot-record a b)
  26. two-slot-record?
  27. (a slot-first)
  28. (b slot-second))
  29. (define-record-type rtd-3-slots
  30. (make-3-slot-record a b c)
  31. three-slot-record?
  32. (a slot-one)
  33. (b slot-two)
  34. (c slot-three))
  35. (with-test-prefix "matches"
  36. (pass-if "wildcard"
  37. (match "hello" (_ #t)))
  38. (pass-if "symbol"
  39. (match 'foo ('foo #t)))
  40. (pass-if "string"
  41. (match "bar" ("bar" #t)))
  42. (pass-if "number"
  43. (match 777 (777 #t)))
  44. (pass-if "char"
  45. (match #\g (#\g #t)))
  46. (pass-if "sexp"
  47. (match '(a b c) ('(a b c) #t)))
  48. (pass-if "predicate"
  49. (match '(a 1 2)
  50. (('a (and (? odd?) one) (? even?))
  51. (= one 1))))
  52. (pass-if "list"
  53. (let ((lst '(a b c)))
  54. (match lst
  55. ((x y z)
  56. (equal? (list x y z) lst)))))
  57. (pass-if "list rest..."
  58. (let ((lst '(a b c)))
  59. (match lst
  60. ((x rest ...)
  61. (and (eq? x 'a) (equal? rest '(b c)))))))
  62. (pass-if "list . rest"
  63. (let ((lst '(a b c)))
  64. (match lst
  65. ((x . rest)
  66. (and (eq? x 'a) (equal? rest '(b c)))))))
  67. (pass-if "list ..1"
  68. (match '(a b c)
  69. ((x ..1)
  70. (equal? x '(a b c)))))
  71. (pass-if "list ..1, with predicate"
  72. (match '(a b c)
  73. (((and x (? symbol?)) ..1)
  74. (equal? x '(a b c)))))
  75. (pass-if "list ..1, nested"
  76. (match '((1 2) (3 4))
  77. (((x ..1) ..1)
  78. (equal? x '((1 2) (3 4))))))
  79. (pass-if "tree"
  80. (let ((tree '(one (two 2) (three 3 (and 4 (and 5))))))
  81. (match tree
  82. (('one ('two x) ('three y ('and z '(and 5))))
  83. (equal? (list x y z) '(2 3 4))))))
  84. (pass-if "and, unique names"
  85. (let ((tree '(1 2)))
  86. (match tree
  87. ((and (a 2) (1 b))
  88. (equal? 3 (+ a b))))))
  89. (pass-if "and, same names"
  90. (let ((a '(1 2)))
  91. (match a
  92. ((and (a 2) (1 b))
  93. (equal? 3 (+ a b))))))
  94. (with-test-prefix "records"
  95. (pass-if "all slots, bind"
  96. (let ((r (make-3-slot-record 1 2 3)))
  97. (match r
  98. (($ rtd-3-slots a b c)
  99. (equal? (list a b c) '(1 2 3))))))
  100. (pass-if "all slots, literals"
  101. (let ((r (make-3-slot-record 1 2 3)))
  102. (match r
  103. (($ rtd-3-slots 1 2 3)
  104. #t))))
  105. (pass-if "2 slots"
  106. (let ((r (make-3-slot-record 1 2 3)))
  107. (match r
  108. (($ rtd-3-slots x y)
  109. (equal? (list x y) '(1 2))))))
  110. (pass-if "RTD correctly checked"
  111. (let ((r (make-2-slot-record 1 2)))
  112. (match r
  113. (($ rtd-3-slots a b)
  114. #f)
  115. (($ rtd-2-slots a b)
  116. (equal? (list a b) '(1 2))))))
  117. (pass-if "getter"
  118. (match (make-2-slot-record 1 2)
  119. (($ rtd-2-slots (get! first) (get! second))
  120. (equal? (list (first) (second)) '(1 2)))))
  121. (pass-if "setter"
  122. (let ((r (make-2-slot-record 1 2)))
  123. (match r
  124. (($ rtd-2-slots (set! set-first!) (set! set-second!))
  125. (set-first! 'one)
  126. (set-second! 'two)
  127. (equal? (list (slot-first r) (slot-second r))
  128. '(one two))))))))
  129. (with-test-prefix "doesn't match"
  130. (pass-if-exception "tree"
  131. exception:match-error
  132. (match '(a (b c))
  133. ((foo (bar)) #t)))
  134. (pass-if-exception "list ..1"
  135. exception:match-error
  136. (match '()
  137. ((x ..1) #f)))
  138. (pass-if-exception "list ..1, with predicate"
  139. exception:match-error
  140. (match '(a 0)
  141. (((and x (? symbol?)) ..1)
  142. (equal? x '(a b c)))))
  143. (with-test-prefix "records"
  144. (pass-if "not a record"
  145. (match "hello"
  146. (($ rtd-2-slots) #f)
  147. (_ #t)))
  148. (pass-if-exception "too many slots"
  149. exception:out-of-range
  150. (let ((r (make-3-slot-record 1 2 3)))
  151. (match r
  152. (($ rtd-3-slots a b c d)
  153. #f))))))
  154. ;;;
  155. ;;; Upstream tests, from Chibi-Scheme (3-clause BSD license).
  156. ;;;
  157. (let-syntax ((load (syntax-rules ()
  158. ((_ file) #t)))
  159. (test (syntax-rules ()
  160. ((_ name expected expr)
  161. (pass-if name
  162. (equal? expected expr)))))
  163. (test-begin (syntax-rules ()
  164. ((_ name) #t)))
  165. (test-end (syntax-rules ()
  166. ((_) #t))))
  167. (with-test-prefix "upstream tests"
  168. (include-from-path "tests/match.test.upstream")))