structs.test 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. ;;;; structs.test --- Test suite for Guile's structures. -*- Scheme -*-
  2. ;;;; Ludovic Courtès <ludovic.courtes@laas.fr>, 2006-06-12.
  3. ;;;;
  4. ;;;; Copyright (C) 2006, 2007 Free Software Foundation, Inc.
  5. ;;;;
  6. ;;;; This program is free software; you can redistribute it and/or modify
  7. ;;;; it under the terms of the GNU General Public License as published by
  8. ;;;; the Free Software Foundation; either version 2, or (at your option)
  9. ;;;; any later version.
  10. ;;;;
  11. ;;;; This program is distributed in the hope that it will be useful,
  12. ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. ;;;; GNU General Public License for more details.
  15. ;;;;
  16. ;;;; You should have received a copy of the GNU General Public License
  17. ;;;; along with this software; see the file COPYING. If not, write to
  18. ;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  19. ;;;; Boston, MA 02110-1301 USA
  20. (define-module (test-suite test-structs)
  21. :use-module (test-suite lib))
  22. ;;;
  23. ;;; Struct example taken from the reference manual (by Tom Lord).
  24. ;;;
  25. (define ball-root (make-vtable-vtable "pr" 0))
  26. (define (make-ball-type ball-color)
  27. (make-struct ball-root 0
  28. (make-struct-layout "pw")
  29. (lambda (ball port)
  30. (format port "#<a ~A ball owned by ~A>"
  31. (color ball)
  32. (owner ball)))
  33. ball-color))
  34. (define (color ball) (struct-ref (struct-vtable ball) vtable-offset-user))
  35. (define (owner ball) (struct-ref ball 0))
  36. (define (set-owner! ball owner) (struct-set! ball 0 owner))
  37. (define red (make-ball-type 'red))
  38. (define green (make-ball-type 'green))
  39. (define (make-ball type owner) (make-struct type 0 owner))
  40. ;;;
  41. ;;; Test suite.
  42. ;;;
  43. (with-test-prefix "low-level struct procedures"
  44. (pass-if "constructors"
  45. (and (struct-vtable? ball-root)
  46. (struct-vtable? red)
  47. (struct-vtable? green)))
  48. (pass-if "vtables"
  49. (and (eq? (struct-vtable red) ball-root)
  50. (eq? (struct-vtable green) ball-root)
  51. (eq? (struct-vtable (make-ball red "Bob")) red)
  52. ;; end of the vtable tower
  53. (eq? (struct-vtable ball-root) ball-root)))
  54. (pass-if-exception "write-access denied"
  55. exception:struct-set!-denied
  56. ;; The first field of instances of BALL-ROOT is read-only.
  57. (struct-set! red vtable-offset-user "blue"))
  58. (pass-if "write-access granted"
  59. (set-owner! (make-ball red "Bob") "Fred")
  60. #t)
  61. (pass-if "struct-set!"
  62. (let ((ball (make-ball green "Bob")))
  63. (set-owner! ball "Bill")
  64. (string=? (owner ball) "Bill"))))
  65. (with-test-prefix "equal?"
  66. (pass-if "simple structs"
  67. (let* ((vtable (make-vtable-vtable "pr" 0))
  68. (s1 (make-struct vtable 0 "hello"))
  69. (s2 (make-struct vtable 0 "hello")))
  70. (equal? s1 s2)))
  71. (pass-if "more complex structs"
  72. (let ((first (make-ball red (string-copy "Bob")))
  73. (second (make-ball red (string-copy "Bob"))))
  74. (equal? first second)))
  75. (pass-if "not-equal?"
  76. (not (or (equal? (make-ball red "Bob") (make-ball green "Bob"))
  77. (equal? (make-ball red "Bob") (make-ball red "Bill"))))))
  78. ;;
  79. ;; make-struct
  80. ;;
  81. (define exception:bad-tail
  82. (cons 'misc-error "tail array not allowed unless"))
  83. (with-test-prefix "make-struct"
  84. ;; in guile 1.8.1 and earlier, this caused an error throw out of an
  85. ;; SCM_CRITICAL_SECTION_START / SCM_CRITICAL_SECTION_END, which abort()ed
  86. ;; the program
  87. ;;
  88. (pass-if-exception "wrong type for `u' field" exception:wrong-type-arg
  89. (let* ((vv (make-vtable-vtable "" 0))
  90. (v (make-struct vv 0 (make-struct-layout "uw"))))
  91. (make-struct v 0 'x)))
  92. ;; In guile 1.8.1 and earlier, and 1.6.8 and earlier, there was no check
  93. ;; on a tail array being created without an R/W/O type for it. This left
  94. ;; it uninitialized by scm_struct_init(), resulting in garbage getting
  95. ;; into an SCM when struct-ref read it (and attempting to print a garbage
  96. ;; SCM can cause a segv).
  97. ;;
  98. (pass-if-exception "no R/W/O for tail array" exception:bad-tail
  99. (let* ((vv (make-vtable-vtable "" 0))
  100. (v (make-struct vv 0 (make-struct-layout "pw"))))
  101. (make-struct v 123 'x))))
  102. ;;
  103. ;; make-vtable
  104. ;;
  105. (with-test-prefix "make-vtable"
  106. (pass-if "without printer"
  107. (let* ((vtable (make-vtable "pwpr"))
  108. (struct (make-struct vtable 0 'x 'y)))
  109. (and (eq? 'x (struct-ref struct 0))
  110. (eq? 'y (struct-ref struct 1)))))
  111. (pass-if "with printer"
  112. (let ()
  113. (define (print struct port)
  114. (display "hello" port))
  115. (let* ((vtable (make-vtable "pwpr" print))
  116. (struct (make-struct vtable 0 'x 'y))
  117. (str (call-with-output-string
  118. (lambda (port)
  119. (display struct port)))))
  120. (equal? str "hello")))))
  121. ;;; Local Variables:
  122. ;;; coding: latin-1
  123. ;;; End: