test-ports.scm 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. ;;; Copyright (C) 2023, 2024, 2025y 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. (with-additional-imports ((only (hoot numbers) 1+))
  87. (test-call "#(43 43 70 #(101 101 421) 70)"
  88. (lambda ()
  89. (let* ((p (make-parameter 42 1+))
  90. (a (p))
  91. (b (p 69))
  92. (c (p))
  93. (d (parameterize ((p 100))
  94. (let* ((a (p))
  95. (b (p 420))
  96. (c (p)))
  97. (vector a b c))))
  98. (e (p)))
  99. (vector a b c d e)))))
  100. (test-call "#(\"foo\" \"bar\" \"baz\" \"asdfa\" #<eof> #<eof>)"
  101. (lambda ()
  102. (let* ((p (open-input-string "foo\nbar\r\nbaz\rasdfa"))
  103. (a (read-line p))
  104. (b (read-line p))
  105. (c (read-line p))
  106. (d (read-line p))
  107. (e (read-line p))
  108. (f (read-line p)))
  109. (vector a b c d e f))))
  110. (with-additional-imports ((only (hoot ports) port-line port-column)
  111. (only (hoot syntax) syntax-case with-syntax
  112. syntax generate-temporaries))
  113. (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)))"
  114. (lambda ()
  115. (define p (open-input-string "foo\nbar\r\nbaz\rasdfa"))
  116. (define (pos)
  117. (cons (port-line p) (port-column p)))
  118. (define-syntax <<
  119. (lambda (stx)
  120. (syntax-case stx ()
  121. ((_ exp ...)
  122. (with-syntax (((t ...) (generate-temporaries #'(exp ...))))
  123. #'(let* ((t (let* ((before (pos))
  124. (val exp)
  125. (after (pos)))
  126. (vector before val after)))
  127. ...)
  128. (vector t ...)))))))
  129. (<< (read-line p)
  130. (read-char p)
  131. (read-char p)
  132. (read-char p)
  133. (read-char p)
  134. (read-char p)
  135. (read-line p)
  136. (read-string 2 p)
  137. (read-string 2 p)
  138. (read-line p)))))
  139. ;; Apologies for the wall of text, but this tests that input that
  140. ;; exceeds the default buffer size (1024) comes through correctly.
  141. (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.\""
  142. (lambda ()
  143. (let ((p (open-input-string
  144. "This paper would not have happened if Sussman had not been forced to
  145. think about lambda calculus by having to teach 6.031, not would it
  146. have happened had not Steele been forced to understand PLASMA by
  147. morbid curiosity.
  148. This work developed out of an initial attempt to understand the
  149. actorness of actors. Steele thought he understood it, but couldn't
  150. explain it; Sussamn suggested the experimental approach of actually
  151. building an \"ACTORS interpreter\". This interpreter attempted to
  152. intermix the user of actors and LISP lambda expressions in a clean
  153. manner. When it was completed, we discovered that the \"actors\" and
  154. the lambda expressions were identical in implementation. Once we had
  155. discovered this, all the rest fell into place, and it was only natural
  156. to begin thinking about actors in terms of lambda calculus. The
  157. original interpreter was call-by-name for various reasons having to do
  158. with 6.031; we subsequently experimentally discovered how call-by-name
  159. screws iteration, and rewrote it to use call-by-value. Note well that
  160. we did not bring forth a clean implementation in one brilliant flash
  161. of understanding; we used an experimental and highly empirical
  162. approach to bootstrap our knowledge.")))
  163. (list->string
  164. (let lp ((char (read-char p)))
  165. (if (eof-object? char)
  166. '()
  167. (cons char (lp (read-char p)))))))))
  168. (test-call "#f"
  169. (lambda (str)
  170. (let ((port (open-input-string str)))
  171. (call-with-port port read-char)
  172. (input-port-open? port)))
  173. "foo")
  174. ;; We cannot test file ports against d8 because it lacks a sufficient
  175. ;; filesystem API.
  176. (define input-fixture
  177. (in-vicinity (getenv "HOOT_TEST_DATA_DIR") "fixtures/hello"))
  178. (parameterize ((use-d8? #f))
  179. (with-additional-imports ((ice-9 match)
  180. (scheme read)
  181. (scheme file))
  182. (test-call
  183. "(hello and welcome back to scheme)"
  184. (lambda ()
  185. (call-with-input-file ,input-fixture
  186. (lambda (port)
  187. (let loop ()
  188. (match (read port)
  189. ((? eof-object?) '())
  190. (x (cons x (loop))))))))))
  191. (with-additional-imports
  192. ((only (hoot ports) seek)
  193. (scheme read)
  194. (scheme file))
  195. (test-call
  196. "welcome"
  197. (lambda ()
  198. (call-with-input-file ,input-fixture
  199. (lambda (port)
  200. (seek port 10 'cur)
  201. (read port))))))
  202. ;; Not guaranteed to be a unique name, but 'mkstemp' opens a port
  203. ;; which we don't want since we need Hoot to open the port.
  204. (let ((tmp "/tmp/tmp-hoot-port-test"))
  205. (define-syntax-rule (test-output-file expected expr)
  206. (unwind-protect
  207. (lambda ()
  208. (test-call expected expr))
  209. (lambda ()
  210. (false-if-exception
  211. (delete-file tmp)))))
  212. (with-additional-imports ((scheme file))
  213. (test-output-file
  214. "#t"
  215. (lambda ()
  216. (call-with-output-file ,tmp (lambda (port) #t))
  217. (file-exists? ,tmp)))
  218. (test-output-file
  219. "deleted"
  220. (lambda ()
  221. (call-with-output-file ,tmp (lambda (port) #t))
  222. (and (file-exists? ,tmp)
  223. (begin
  224. (delete-file ,tmp)
  225. (file-exists? ,tmp)
  226. 'deleted))))
  227. (with-additional-imports ((scheme write)
  228. (scheme read))
  229. (test-output-file
  230. "HELLO"
  231. (lambda ()
  232. (call-with-output-file ,tmp
  233. (lambda (port)
  234. (write 'HELLO port)))
  235. (call-with-input-file ,tmp read)))))))
  236. (test-end* "test-ports")