r6rs-hashtables.test 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  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 (srfi srfi-1)
  21. :use-module (test-suite lib))
  22. (with-test-prefix "make-eq-hashtable"
  23. (pass-if "eq hashtable compares keys with eq?"
  24. (let ((eq-hashtable (make-eq-hashtable)))
  25. (hashtable-set! eq-hashtable (list 'foo) #t)
  26. (hashtable-set! eq-hashtable 'sym #t)
  27. (and (not (hashtable-contains? eq-hashtable (list 'foo)))
  28. (hashtable-contains? eq-hashtable 'sym)))))
  29. (with-test-prefix "make-eqv-hashtable"
  30. (pass-if "eqv hashtable compares keys with eqv?"
  31. (let ((eqv-hashtable (make-eqv-hashtable)))
  32. (hashtable-set! eqv-hashtable (list 'foo) #t)
  33. (hashtable-set! eqv-hashtable 4 #t)
  34. (and (not (hashtable-contains? eqv-hashtable (list 'foo)))
  35. (hashtable-contains? eqv-hashtable 4)))))
  36. (with-test-prefix "make-hashtable"
  37. (pass-if "hashtable compares keys with custom equality function"
  38. (let* ((abs-eqv? (lambda (x y) (eqv? (abs x) (abs y))))
  39. (abs-hashtable (make-hashtable abs abs-eqv?)))
  40. (hashtable-set! abs-hashtable -4 #t)
  41. (and (not (hashtable-contains? abs-hashtable 6))
  42. (hashtable-contains? abs-hashtable 4))))
  43. (pass-if "hash function value used modulo capacity"
  44. (let* ((constant-hash (lambda (x) most-positive-fixnum))
  45. (constant-hashtable (make-hashtable constant-hash eq?)))
  46. (hashtable-set! constant-hashtable 'foo 'bar)
  47. (hashtable-contains? constant-hashtable 'foo))))
  48. (with-test-prefix "hashtable?"
  49. (pass-if "hashtable? is #t on hashtables"
  50. (let ((hashtable (make-eq-hashtable)))
  51. (hashtable? hashtable)))
  52. (pass-if "hashtable? is #f on non-hashtables"
  53. (let ((not-hashtable (list)))
  54. (not (hashtable? not-hashtable)))))
  55. (with-test-prefix "hashtable-size"
  56. (pass-if "hashtable-size returns current size"
  57. (let ((hashtable (make-eq-hashtable)))
  58. (and (eqv? (hashtable-size hashtable) 0)
  59. (hashtable-set! hashtable 'foo #t)
  60. (eqv? (hashtable-size hashtable) 1)))))
  61. (with-test-prefix "hashtable-ref"
  62. (pass-if "hashtable-ref returns value for bound key"
  63. (let ((hashtable (make-eq-hashtable)))
  64. (hashtable-set! hashtable 'sym 'foo)
  65. (eq? (hashtable-ref hashtable 'sym 'bar) 'foo)))
  66. (pass-if "hashtable-ref returns default for unbound key"
  67. (let ((hashtable (make-eq-hashtable)))
  68. (eq? (hashtable-ref hashtable 'sym 'bar) 'bar))))
  69. (with-test-prefix "hashtable-set!"
  70. (pass-if "hashtable-set! returns unspecified"
  71. (let ((hashtable (make-eq-hashtable)))
  72. (unspecified? (hashtable-set! hashtable 'foo 'bar))))
  73. (pass-if "hashtable-set! allows storing #f"
  74. (let ((hashtable (make-eq-hashtable)))
  75. (hashtable-set! hashtable 'foo #f)
  76. (not (hashtable-ref hashtable 'foo 'bar)))))
  77. (with-test-prefix "hashtable-delete!"
  78. (pass-if "hashtable-delete! removes association"
  79. (let ((hashtable (make-eq-hashtable)))
  80. (hashtable-set! hashtable 'foo 'bar)
  81. (and (unspecified? (hashtable-delete! hashtable 'foo))
  82. (not (hashtable-ref hashtable 'foo #f))))))
  83. (with-test-prefix "hashtable-contains?"
  84. (pass-if "hashtable-contains? returns #t when association present"
  85. (let ((hashtable (make-eq-hashtable)))
  86. (hashtable-set! hashtable 'foo 'bar)
  87. (let ((contains (hashtable-contains? hashtable 'foo)))
  88. (and (boolean? contains) contains))))
  89. (pass-if "hashtable-contains? returns #f when association not present"
  90. (let ((hashtable (make-eq-hashtable)))
  91. (not (hashtable-contains? hashtable 'foo)))))
  92. (with-test-prefix "hashtable-update!"
  93. (pass-if "hashtable-update! adds return value of proc on bound key"
  94. (let ((hashtable (make-eq-hashtable)))
  95. (hashtable-set! hashtable 'foo 0)
  96. (hashtable-update! hashtable 'foo (lambda (x) (+ x 1)) 100)
  97. (eqv? (hashtable-ref hashtable 'foo #f) 1)))
  98. (pass-if "hashtable-update! adds default value on unbound key"
  99. (let ((hashtable (make-eq-hashtable)))
  100. (hashtable-update! hashtable 'foo (lambda (x) (+ x 1)) 100)
  101. (eqv? (hashtable-ref hashtable 'foo #f) 101))))
  102. (with-test-prefix "hashtable-copy"
  103. (pass-if "hashtable-copy produces copy of hashtable"
  104. (let ((hashtable (make-eq-hashtable)))
  105. (hashtable-set! hashtable 'foo 1)
  106. (hashtable-set! hashtable 'bar 2)
  107. (let ((copied-table (hashtable-copy hashtable)))
  108. (and (eqv? (hashtable-ref hashtable 'foo #f) 1)
  109. (eqv? (hashtable-ref hashtable 'bar #f) 2)))))
  110. (pass-if "hashtable-copy with mutability #f produces immutable copy"
  111. (let ((copied-table (hashtable-copy (make-eq-hashtable) #f)))
  112. (hashtable-set! copied-table 'foo 1)
  113. (not (hashtable-ref copied-table 'foo #f)))))
  114. (with-test-prefix "hashtable-clear!"
  115. (pass-if "hashtable-clear! removes all values from hashtable"
  116. (let ((hashtable (make-eq-hashtable)))
  117. (hashtable-set! hashtable 'foo 1)
  118. (hashtable-set! hashtable 'bar 2)
  119. (and (unspecified? (hashtable-clear! hashtable))
  120. (eqv? (hashtable-size hashtable) 0)))))
  121. (with-test-prefix "hashtable-keys"
  122. (pass-if "hashtable-keys returns all keys"
  123. (let ((hashtable (make-eq-hashtable)))
  124. (hashtable-set! hashtable 'foo #t)
  125. (hashtable-set! hashtable 'bar #t)
  126. (let ((keys (vector->list (hashtable-keys hashtable))))
  127. (and (memq 'foo keys) (memq 'bar keys) #t)))))
  128. (with-test-prefix "hashtable-entries"
  129. (pass-if "hashtable-entries returns all entries"
  130. (let ((hashtable (make-eq-hashtable)))
  131. (hashtable-set! hashtable 'foo 1)
  132. (hashtable-set! hashtable 'bar 2)
  133. (receive
  134. (keys values)
  135. (hashtable-entries hashtable)
  136. (let f ((counter 0) (success #t))
  137. (if (or (not success) (= counter 2))
  138. success
  139. (case (vector-ref keys counter)
  140. ((foo) (f (+ counter 1) (eqv? (vector-ref values counter) 1)))
  141. ((bar) (f (+ counter 1) (eqv? (vector-ref values counter) 2)))
  142. (else f 0 #f))))))))
  143. (with-test-prefix "hashtable-equivalence-function"
  144. (pass-if "hashtable-equivalence-function returns eqv function"
  145. (let* ((abs-eqv? (lambda (x y) (eqv? (abs x) (abs y))))
  146. (abs-hashtable (make-hashtable abs abs-eqv?)))
  147. (eq? (hashtable-equivalence-function abs-hashtable) abs-eqv?))))
  148. (with-test-prefix "hashtable-hash-function"
  149. (pass-if "hashtable-hash-function returns hash function"
  150. (let ((abs-hashtable (make-hashtable abs eqv?)))
  151. (eq? (hashtable-hash-function abs-hashtable) abs))))
  152. (with-test-prefix "hashtable-mutable?"
  153. (pass-if "hashtable-mutable? is #t on mutable hashtables"
  154. (hashtable-mutable? (hashtable-copy (make-eq-hashtable) #t)))
  155. (pass-if "hashtable-mutable? is #f on immutable hashtables"
  156. (not (hashtable-mutable? (hashtable-copy (make-eq-hashtable) #f)))))