r6rs-hashtables.test 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. ;;; r6rs-hashtables.test --- Test suite for R6RS (rnrs hashtables)
  2. ;; Copyright (C) 2010 Free Software Foundation, Inc.
  3. ;;
  4. ;; This library is free software; you can redistribute it and/or
  5. ;; modify it under the terms of the GNU Lesser General Public
  6. ;; License as published by the Free Software Foundation; either
  7. ;; version 3 of the Lice6nse, or (at your option) any later version.
  8. ;;
  9. ;; This library is distributed in the hope that it will be useful,
  10. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. ;; Lesser General Public License for more details.
  13. ;;
  14. ;; You should have received a copy of the GNU Lesser General Public
  15. ;; License along with this library; if not, write to the Free Software
  16. ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. (define-module (test-suite test-rnrs-hashtable)
  18. :use-module (ice-9 receive)
  19. :use-module ((rnrs hashtables) :version (6))
  20. :use-module ((rnrs exceptions) :version (6))
  21. :use-module (srfi srfi-1)
  22. :use-module (test-suite lib))
  23. (with-test-prefix "make-eq-hashtable"
  24. (pass-if "eq hashtable compares keys with eq?"
  25. (let ((eq-hashtable (make-eq-hashtable)))
  26. (hashtable-set! eq-hashtable (list 'foo) #t)
  27. (hashtable-set! eq-hashtable 'sym #t)
  28. (and (not (hashtable-contains? eq-hashtable (list 'foo)))
  29. (hashtable-contains? eq-hashtable 'sym)))))
  30. (with-test-prefix "make-eqv-hashtable"
  31. (pass-if "eqv hashtable compares keys with eqv?"
  32. (let ((eqv-hashtable (make-eqv-hashtable)))
  33. (hashtable-set! eqv-hashtable (list 'foo) #t)
  34. (hashtable-set! eqv-hashtable 4 #t)
  35. (and (not (hashtable-contains? eqv-hashtable (list 'foo)))
  36. (hashtable-contains? eqv-hashtable 4)))))
  37. (with-test-prefix "make-hashtable"
  38. (pass-if "hashtable compares keys with custom equality function"
  39. (let* ((abs-eqv? (lambda (x y) (eqv? (abs x) (abs y))))
  40. (abs-hashtable (make-hashtable abs abs-eqv?)))
  41. (hashtable-set! abs-hashtable -4 #t)
  42. (and (not (hashtable-contains? abs-hashtable 6))
  43. (hashtable-contains? abs-hashtable 4))))
  44. (pass-if "hash function value used modulo capacity"
  45. (let* ((constant-hash (lambda (x) most-positive-fixnum))
  46. (constant-hashtable (make-hashtable constant-hash eq?)))
  47. (hashtable-set! constant-hashtable 'foo 'bar)
  48. (hashtable-contains? constant-hashtable 'foo))))
  49. (with-test-prefix "hashtable?"
  50. (pass-if "hashtable? is #t on hashtables"
  51. (let ((hashtable (make-eq-hashtable)))
  52. (hashtable? hashtable)))
  53. (pass-if "hashtable? is #f on non-hashtables"
  54. (let ((not-hashtable (list)))
  55. (not (hashtable? not-hashtable)))))
  56. (with-test-prefix "hashtable-size"
  57. (pass-if "hashtable-size returns current size"
  58. (let ((hashtable (make-eq-hashtable)))
  59. (and (eqv? (hashtable-size hashtable) 0)
  60. (hashtable-set! hashtable 'foo #t)
  61. (eqv? (hashtable-size hashtable) 1)))))
  62. (with-test-prefix "hashtable-ref"
  63. (pass-if "hashtable-ref returns value for bound key"
  64. (let ((hashtable (make-eq-hashtable)))
  65. (hashtable-set! hashtable 'sym 'foo)
  66. (eq? (hashtable-ref hashtable 'sym 'bar) 'foo)))
  67. (pass-if "hashtable-ref returns default for unbound key"
  68. (let ((hashtable (make-eq-hashtable)))
  69. (eq? (hashtable-ref hashtable 'sym 'bar) 'bar))))
  70. (with-test-prefix "hashtable-set!"
  71. (pass-if "hashtable-set! returns unspecified"
  72. (let ((hashtable (make-eq-hashtable)))
  73. (unspecified? (hashtable-set! hashtable 'foo 'bar))))
  74. (pass-if "hashtable-set! allows storing #f"
  75. (let ((hashtable (make-eq-hashtable)))
  76. (hashtable-set! hashtable 'foo #f)
  77. (not (hashtable-ref hashtable 'foo 'bar)))))
  78. (with-test-prefix "hashtable-delete!"
  79. (pass-if "hashtable-delete! removes association"
  80. (let ((hashtable (make-eq-hashtable)))
  81. (hashtable-set! hashtable 'foo 'bar)
  82. (and (unspecified? (hashtable-delete! hashtable 'foo))
  83. (not (hashtable-ref hashtable 'foo #f))))))
  84. (with-test-prefix "hashtable-contains?"
  85. (pass-if "hashtable-contains? returns #t when association present"
  86. (let ((hashtable (make-eq-hashtable)))
  87. (hashtable-set! hashtable 'foo 'bar)
  88. (let ((contains (hashtable-contains? hashtable 'foo)))
  89. (and (boolean? contains) contains))))
  90. (pass-if "hashtable-contains? returns #f when association not present"
  91. (let ((hashtable (make-eq-hashtable)))
  92. (not (hashtable-contains? hashtable 'foo)))))
  93. (with-test-prefix "hashtable-update!"
  94. (pass-if "hashtable-update! adds return value of proc on bound key"
  95. (let ((hashtable (make-eq-hashtable)))
  96. (hashtable-set! hashtable 'foo 0)
  97. (hashtable-update! hashtable 'foo (lambda (x) (+ x 1)) 100)
  98. (eqv? (hashtable-ref hashtable 'foo #f) 1)))
  99. (pass-if "hashtable-update! adds default value on unbound key"
  100. (let ((hashtable (make-eq-hashtable)))
  101. (hashtable-update! hashtable 'foo (lambda (x) (+ x 1)) 100)
  102. (eqv? (hashtable-ref hashtable 'foo #f) 101))))
  103. (with-test-prefix "hashtable-copy"
  104. (pass-if "hashtable-copy produces copy of hashtable"
  105. (let ((hashtable (make-eq-hashtable)))
  106. (hashtable-set! hashtable 'foo 1)
  107. (hashtable-set! hashtable 'bar 2)
  108. (let ((copied-table (hashtable-copy hashtable)))
  109. (and (eqv? (hashtable-ref hashtable 'foo #f) 1)
  110. (eqv? (hashtable-ref hashtable 'bar #f) 2)))))
  111. (pass-if "hashtable-copy with mutability #f produces immutable copy"
  112. (let ((copied-table (hashtable-copy (make-eq-hashtable) #f)))
  113. (guard (exc (else #t))
  114. (hashtable-set! copied-table 'foo 1)
  115. #f))))
  116. (with-test-prefix "hashtable-clear!"
  117. (pass-if "hashtable-clear! removes all values from hashtable"
  118. (let ((hashtable (make-eq-hashtable)))
  119. (hashtable-set! hashtable 'foo 1)
  120. (hashtable-set! hashtable 'bar 2)
  121. (and (unspecified? (hashtable-clear! hashtable))
  122. (eqv? (hashtable-size hashtable) 0)))))
  123. (with-test-prefix "hashtable-keys"
  124. (pass-if "hashtable-keys returns all keys"
  125. (let ((hashtable (make-eq-hashtable)))
  126. (hashtable-set! hashtable 'foo #t)
  127. (hashtable-set! hashtable 'bar #t)
  128. (let ((keys (vector->list (hashtable-keys hashtable))))
  129. (and (memq 'foo keys) (memq 'bar keys) #t)))))
  130. (with-test-prefix "hashtable-entries"
  131. (pass-if "hashtable-entries returns all entries"
  132. (let ((hashtable (make-eq-hashtable)))
  133. (hashtable-set! hashtable 'foo 1)
  134. (hashtable-set! hashtable 'bar 2)
  135. (receive
  136. (keys values)
  137. (hashtable-entries hashtable)
  138. (let f ((counter 0) (success #t))
  139. (if (or (not success) (= counter 2))
  140. success
  141. (case (vector-ref keys counter)
  142. ((foo) (f (+ counter 1) (eqv? (vector-ref values counter) 1)))
  143. ((bar) (f (+ counter 1) (eqv? (vector-ref values counter) 2)))
  144. (else f 0 #f))))))))
  145. (with-test-prefix "hashtable-equivalence-function"
  146. (pass-if "hashtable-equivalence-function returns eqv function"
  147. (let* ((abs-eqv? (lambda (x y) (eqv? (abs x) (abs y))))
  148. (abs-hashtable (make-hashtable abs abs-eqv?)))
  149. (eq? (hashtable-equivalence-function abs-hashtable) abs-eqv?))))
  150. (with-test-prefix "hashtable-hash-function"
  151. (pass-if "hashtable-hash-function returns hash function"
  152. (let ((abs-hashtable (make-hashtable abs eqv?)))
  153. (eq? (hashtable-hash-function abs-hashtable) abs)))
  154. (pass-if "hashtable-hash-function returns #f on eq table"
  155. (eq? #f (hashtable-hash-function (make-eq-hashtable))))
  156. (pass-if "hashtable-hash-function returns #f on eqv table"
  157. (eq? #f (hashtable-hash-function (make-eqv-hashtable)))))
  158. (with-test-prefix "hashtable-mutable?"
  159. (pass-if "hashtable-mutable? is #t on mutable hashtables"
  160. (hashtable-mutable? (hashtable-copy (make-eq-hashtable) #t)))
  161. (pass-if "hashtable-mutable? is #f on immutable hashtables"
  162. (not (hashtable-mutable? (hashtable-copy (make-eq-hashtable) #f)))))