test-ports.scm 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. ;;; Copyright (C) 2023, 2024 Igalia, S.L.
  2. ;;;
  3. ;;; Licensed under the Apache License, Version 2.0 (the "License");
  4. ;;; you may not use this file except in compliance with the License.
  5. ;;; You may obtain a copy of the License at
  6. ;;;
  7. ;;; http://www.apache.org/licenses/LICENSE-2.0
  8. ;;;
  9. ;;; Unless required by applicable law or agreed to in writing, software
  10. ;;; distributed under the License is distributed on an "AS IS" BASIS,
  11. ;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. ;;; See the License for the specific language governing permissions and
  13. ;;; limitations under the License.
  14. ;;; Commentary:
  15. ;;;
  16. ;;; Port tests.
  17. ;;;
  18. ;;; Code:
  19. (use-modules (srfi srfi-64)
  20. (test utils))
  21. (test-begin "test-ports")
  22. (test-call "#vu8(100 120)"
  23. (lambda ()
  24. (let ((p (open-output-bytevector)))
  25. (write-u8 100 p)
  26. (write-u8 120 p)
  27. (get-output-bytevector p))))
  28. (test-call "#vu8(100 120 130 140)"
  29. (lambda ()
  30. (let ((p (open-output-bytevector)))
  31. (write-bytevector #vu8(100 120) p)
  32. (write-bytevector #vu8(130 140) p)
  33. (get-output-bytevector p))))
  34. (test-call "#vu8(104 101 108 108 111 44 32 119 111 114 108 100)"
  35. (lambda ()
  36. (let ((p (open-output-bytevector)))
  37. (write-string "hello, world" p)
  38. (get-output-bytevector p))))
  39. (test-call "#(1 1 2 3 #<eof> #<eof> #<eof>)"
  40. (lambda ()
  41. (let* ((p (open-input-bytevector #vu8(1 2 3)))
  42. (a (peek-u8 p))
  43. (b (read-u8 p))
  44. (c (read-u8 p))
  45. (d (read-u8 p))
  46. (e (read-u8 p))
  47. (f (peek-u8 p))
  48. (g (read-u8 p)))
  49. (vector a b c d e f g))))
  50. (test-call "#(#vu8() #vu8(1) #vu8(1 2) #vu8(1 2 3) #vu8(1 2 3))"
  51. (lambda ()
  52. (define (read-n n)
  53. (read-bytevector n (open-input-bytevector #vu8(1 2 3))))
  54. (vector (read-n 0)
  55. (read-n 1)
  56. (read-n 2)
  57. (read-n 3)
  58. (read-n 4))))
  59. (test-call "#<eof>"
  60. (lambda ()
  61. (read-bytevector 1 (open-input-bytevector #vu8()))))
  62. (test-call "#(#\\h #\\h #\\e #\\l #\\l #\\o #<eof> #<eof> #<eof>)"
  63. (lambda ()
  64. (let* ((p (open-input-bytevector #vu8(104 101 108 108 111)))
  65. (a (peek-char p))
  66. (b (read-char p))
  67. (c (read-char p))
  68. (d (read-char p))
  69. (e (read-char p))
  70. (f (read-char p))
  71. (g (read-char p))
  72. (h (peek-char p))
  73. (i (read-char p)))
  74. (vector a b c d e f g h i))))
  75. (test-call "#(\"\" \"h\" \"he\" \"hel\" \"hell\" \"hello\" \"hello\")"
  76. (lambda ()
  77. (define (read-n n)
  78. (read-string n (open-input-bytevector #vu8(104 101 108 108 111))))
  79. (vector (read-n 0)
  80. (read-n 1)
  81. (read-n 2)
  82. (read-n 3)
  83. (read-n 4)
  84. (read-n 5)
  85. (read-n 6))))
  86. (test-call "#(43 43 70 #(101 101 421) 70)"
  87. (lambda ()
  88. (let* ((p (make-parameter 42 1+))
  89. (a (p))
  90. (b (p 69))
  91. (c (p))
  92. (d (parameterize ((p 100))
  93. (let* ((a (p))
  94. (b (p 420))
  95. (c (p)))
  96. (vector a b c))))
  97. (e (p)))
  98. (vector a b c d e))))
  99. (test-call "#(\"foo\" \"bar\" \"baz\" \"asdfa\" #<eof> #<eof>)"
  100. (lambda ()
  101. (let* ((p (open-input-string "foo\nbar\r\nbaz\rasdfa"))
  102. (a (read-line p))
  103. (b (read-line p))
  104. (c (read-line p))
  105. (d (read-line p))
  106. (e (read-line p))
  107. (f (read-line p)))
  108. (vector a b c d e f))))
  109. (with-additional-imports ((only (hoot ports) port-line port-column)
  110. (only (hoot syntax) syntax-case with-syntax
  111. syntax generate-temporaries))
  112. (test-call "#(#((0 . 0) \"foo\" (1 . 0)) #((1 . 0) #\\b (1 . 1)) #((1 . 1) #\\a (1 . 2)) #((1 . 2) #\\r (1 . 3)) #((1 . 3) #\\return (1 . 0)) #((1 . 0) #\\newline (2 . 0)) #((2 . 0) \"baz\" (3 . 0)) #((3 . 0) \"as\" (3 . 2)) #((3 . 2) \"df\" (3 . 4)) #((3 . 4) \"a\" (3 . 5)))"
  113. (lambda ()
  114. (define p (open-input-string "foo\nbar\r\nbaz\rasdfa"))
  115. (define (pos)
  116. (cons (port-line p) (port-column p)))
  117. (define-syntax <<
  118. (lambda (stx)
  119. (syntax-case stx ()
  120. ((_ exp ...)
  121. (with-syntax (((t ...) (generate-temporaries #'(exp ...))))
  122. #'(let* ((t (let* ((before (pos))
  123. (val exp)
  124. (after (pos)))
  125. (vector before val after)))
  126. ...)
  127. (vector t ...)))))))
  128. (<< (read-line p)
  129. (read-char p)
  130. (read-char p)
  131. (read-char p)
  132. (read-char p)
  133. (read-char p)
  134. (read-line p)
  135. (read-string 2 p)
  136. (read-string 2 p)
  137. (read-line p)))))
  138. ;; Apologies for the wall of text, but this tests that input that
  139. ;; exceeds the default buffer size (1024) comes through correctly.
  140. (test-call "\"This paper would not have happened if Sussman had not been forced to\\nthink about lambda calculus by having to teach 6.031, not would it\\nhave happened had not Steele been forced to understand PLASMA by\\nmorbid curiosity.\\n\\nThis work developed out of an initial attempt to understand the\\nactorness of actors. Steele thought he understood it, but couldn't\\nexplain it; Sussamn suggested the experimental approach of actually\\nbuilding an \\\"ACTORS interpreter\\\". This interpreter attempted to\\nintermix the user of actors and LISP lambda expressions in a clean\\nmanner. When it was completed, we discovered that the \\\"actors\\\" and\\nthe lambda expressions were identical in implementation. Once we had\\ndiscovered this, all the rest fell into place, and it was only natural\\nto begin thinking about actors in terms of lambda calculus. The\\noriginal interpreter was call-by-name for various reasons having to do\\nwith 6.031; we subsequently experimentally discovered how call-by-name\\nscrews iteration, and rewrote it to use call-by-value. Note well that\\nwe did not bring forth a clean implementation in one brilliant flash\\nof understanding; we used an experimental and highly empirical\\napproach to bootstrap our knowledge.\""
  141. (lambda ()
  142. (let ((p (open-input-string
  143. "This paper would not have happened if Sussman had not been forced to
  144. think about lambda calculus by having to teach 6.031, not would it
  145. have happened had not Steele been forced to understand PLASMA by
  146. morbid curiosity.
  147. This work developed out of an initial attempt to understand the
  148. actorness of actors. Steele thought he understood it, but couldn't
  149. explain it; Sussamn suggested the experimental approach of actually
  150. building an \"ACTORS interpreter\". This interpreter attempted to
  151. intermix the user of actors and LISP lambda expressions in a clean
  152. manner. When it was completed, we discovered that the \"actors\" and
  153. the lambda expressions were identical in implementation. Once we had
  154. discovered this, all the rest fell into place, and it was only natural
  155. to begin thinking about actors in terms of lambda calculus. The
  156. original interpreter was call-by-name for various reasons having to do
  157. with 6.031; we subsequently experimentally discovered how call-by-name
  158. screws iteration, and rewrote it to use call-by-value. Note well that
  159. we did not bring forth a clean implementation in one brilliant flash
  160. of understanding; we used an experimental and highly empirical
  161. approach to bootstrap our knowledge.")))
  162. (list->string
  163. (let lp ((char (read-char p)))
  164. (if (eof-object? char)
  165. '()
  166. (cons char (lp (read-char p)))))))))
  167. (test-call "#f"
  168. (lambda (str)
  169. (let ((port (open-input-string str)))
  170. (call-with-port port read-char)
  171. (input-port-open? port)))
  172. "foo")
  173. ;; We cannot test file ports against d8 because it lacks a sufficient
  174. ;; filesystem API.
  175. (define input-fixture
  176. (in-vicinity (getenv "HOOT_TEST_DATA_DIR") "fixtures/hello"))
  177. (parameterize ((use-d8? #f))
  178. (test-call
  179. "(hello and welcome back to scheme)"
  180. (lambda ()
  181. (call-with-input-file ,input-fixture
  182. (lambda (port)
  183. (let loop ()
  184. (match (read port)
  185. ((? eof-object?) '())
  186. (x (cons x (loop)))))))))
  187. (with-additional-imports
  188. ((only (hoot ports) seek))
  189. (test-call
  190. "welcome"
  191. (lambda ()
  192. (call-with-input-file ,input-fixture
  193. (lambda (port)
  194. (seek port 10 'cur)
  195. (read port))))))
  196. ;; Not guaranteed to be a unique name, but 'mkstemp' opens a port
  197. ;; which we don't want since we need Hoot to open the port.
  198. (let ((tmp "/tmp/tmp-hoot-port-test"))
  199. (define-syntax-rule (test-output-file expected expr)
  200. (unwind-protect
  201. (lambda ()
  202. (test-call expected expr))
  203. (lambda ()
  204. (false-if-exception
  205. (delete-file tmp)))))
  206. (test-output-file
  207. "#t"
  208. (lambda ()
  209. (call-with-output-file ,tmp (lambda (port) #t))
  210. (file-exists? ,tmp)))
  211. (test-output-file
  212. "deleted"
  213. (lambda ()
  214. (call-with-output-file ,tmp (lambda (port) #t))
  215. (and (file-exists? ,tmp)
  216. (begin
  217. (delete-file ,tmp)
  218. (file-exists? ,tmp)
  219. 'deleted))))
  220. (test-output-file
  221. "HELLO"
  222. (lambda ()
  223. (call-with-output-file ,tmp
  224. (lambda (port)
  225. (write 'HELLO port)))
  226. (call-with-input-file ,tmp read)))))
  227. (test-end* "test-ports")