exceptions.test 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. ;;;; exceptions.test --- tests for Guile's exception handling -*- scheme -*-
  2. ;;;; Copyright (C) 2001, 2003, 2004, 2006 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 2.1 of the License, 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. (use-modules (test-suite lib))
  18. (define-macro (throw-test title result . exprs)
  19. `(pass-if ,title
  20. (equal? ,result
  21. (letrec ((stack '())
  22. (push (lambda (val)
  23. (set! stack (cons val stack)))))
  24. (begin ,@exprs)
  25. ;;(display ,title)
  26. ;;(display ": ")
  27. ;;(write (reverse stack))
  28. ;;(newline)
  29. (reverse stack)))))
  30. (with-test-prefix "throw/catch"
  31. (with-test-prefix "wrong type argument"
  32. (pass-if-exception "(throw 1)"
  33. exception:wrong-type-arg
  34. (throw 1)))
  35. (with-test-prefix "wrong number of arguments"
  36. (pass-if-exception "(throw)"
  37. exception:wrong-num-args
  38. (throw))
  39. (pass-if-exception "throw 1 / catch 0"
  40. exception:wrong-num-args
  41. (catch 'a
  42. (lambda () (throw 'a))
  43. (lambda () #f)))
  44. (pass-if-exception "throw 2 / catch 1"
  45. exception:wrong-num-args
  46. (catch 'a
  47. (lambda () (throw 'a 2))
  48. (lambda (x) #f)))
  49. (pass-if-exception "throw 1 / catch 2"
  50. exception:wrong-num-args
  51. (catch 'a
  52. (lambda () (throw 'a))
  53. (lambda (x y) #f)))
  54. (pass-if-exception "throw 3 / catch 2"
  55. exception:wrong-num-args
  56. (catch 'a
  57. (lambda () (throw 'a 2 3))
  58. (lambda (y x) #f)))
  59. (pass-if-exception "throw 1 / catch 2+"
  60. exception:wrong-num-args
  61. (catch 'a
  62. (lambda () (throw 'a))
  63. (lambda (x y . rest) #f))))
  64. (with-test-prefix "with lazy handler"
  65. (pass-if "lazy fluid state"
  66. (equal? '(inner outer arg)
  67. (let ((fluid-parm (make-fluid))
  68. (inner-val #f))
  69. (fluid-set! fluid-parm 'outer)
  70. (catch 'misc-exc
  71. (lambda ()
  72. (with-fluids ((fluid-parm 'inner))
  73. (throw 'misc-exc 'arg)))
  74. (lambda (key . args)
  75. (list inner-val
  76. (fluid-ref fluid-parm)
  77. (car args)))
  78. (lambda (key . args)
  79. (set! inner-val (fluid-ref fluid-parm))))))))
  80. (throw-test "normal catch"
  81. '(1 2)
  82. (catch 'a
  83. (lambda ()
  84. (push 1)
  85. (throw 'a))
  86. (lambda (key . args)
  87. (push 2))))
  88. (throw-test "catch and lazy catch"
  89. '(1 2 3 4)
  90. (catch 'a
  91. (lambda ()
  92. (push 1)
  93. (lazy-catch 'a
  94. (lambda ()
  95. (push 2)
  96. (throw 'a))
  97. (lambda (key . args)
  98. (push 3))))
  99. (lambda (key . args)
  100. (push 4))))
  101. (throw-test "catch with rethrowing lazy catch handler"
  102. '(1 2 3 4)
  103. (catch 'a
  104. (lambda ()
  105. (push 1)
  106. (lazy-catch 'a
  107. (lambda ()
  108. (push 2)
  109. (throw 'a))
  110. (lambda (key . args)
  111. (push 3)
  112. (apply throw key args))))
  113. (lambda (key . args)
  114. (push 4))))
  115. (throw-test "catch with pre-unwind handler"
  116. '(1 3 2)
  117. (catch 'a
  118. (lambda ()
  119. (push 1)
  120. (throw 'a))
  121. (lambda (key . args)
  122. (push 2))
  123. (lambda (key . args)
  124. (push 3))))
  125. (throw-test "catch with rethrowing pre-unwind handler"
  126. '(1 3 2)
  127. (catch 'a
  128. (lambda ()
  129. (push 1)
  130. (throw 'a))
  131. (lambda (key . args)
  132. (push 2))
  133. (lambda (key . args)
  134. (push 3)
  135. (apply throw key args))))
  136. (throw-test "catch with throw handler"
  137. '(1 2 3 4)
  138. (catch 'a
  139. (lambda ()
  140. (push 1)
  141. (with-throw-handler 'a
  142. (lambda ()
  143. (push 2)
  144. (throw 'a))
  145. (lambda (key . args)
  146. (push 3))))
  147. (lambda (key . args)
  148. (push 4))))
  149. (throw-test "catch with rethrowing throw handler"
  150. '(1 2 3 4)
  151. (catch 'a
  152. (lambda ()
  153. (push 1)
  154. (with-throw-handler 'a
  155. (lambda ()
  156. (push 2)
  157. (throw 'a))
  158. (lambda (key . args)
  159. (push 3)
  160. (apply throw key args))))
  161. (lambda (key . args)
  162. (push 4))))
  163. (throw-test "effect of lazy-catch unwinding on throw to another key"
  164. '(1 2 3 5 7)
  165. (catch 'a
  166. (lambda ()
  167. (push 1)
  168. (lazy-catch 'b
  169. (lambda ()
  170. (push 2)
  171. (catch 'a
  172. (lambda ()
  173. (push 3)
  174. (throw 'b))
  175. (lambda (key . args)
  176. (push 4))))
  177. (lambda (key . args)
  178. (push 5)
  179. (throw 'a)))
  180. (push 6))
  181. (lambda (key . args)
  182. (push 7))))
  183. (throw-test "effect of with-throw-handler not-unwinding on throw to another key"
  184. '(1 2 3 5 4 6)
  185. (catch 'a
  186. (lambda ()
  187. (push 1)
  188. (with-throw-handler 'b
  189. (lambda ()
  190. (push 2)
  191. (catch 'a
  192. (lambda ()
  193. (push 3)
  194. (throw 'b))
  195. (lambda (key . args)
  196. (push 4))))
  197. (lambda (key . args)
  198. (push 5)
  199. (throw 'a)))
  200. (push 6))
  201. (lambda (key . args)
  202. (push 7))))
  203. (throw-test "lazy-catch chaining"
  204. '(1 2 3 4 6 8)
  205. (catch 'a
  206. (lambda ()
  207. (push 1)
  208. (lazy-catch 'a
  209. (lambda ()
  210. (push 2)
  211. (lazy-catch 'a
  212. (lambda ()
  213. (push 3)
  214. (throw 'a))
  215. (lambda (key . args)
  216. (push 4)))
  217. (push 5))
  218. (lambda (key . args)
  219. (push 6)))
  220. (push 7))
  221. (lambda (key . args)
  222. (push 8))))
  223. (throw-test "with-throw-handler chaining"
  224. '(1 2 3 4 6 8)
  225. (catch 'a
  226. (lambda ()
  227. (push 1)
  228. (with-throw-handler 'a
  229. (lambda ()
  230. (push 2)
  231. (with-throw-handler 'a
  232. (lambda ()
  233. (push 3)
  234. (throw 'a))
  235. (lambda (key . args)
  236. (push 4)))
  237. (push 5))
  238. (lambda (key . args)
  239. (push 6)))
  240. (push 7))
  241. (lambda (key . args)
  242. (push 8))))
  243. (throw-test "with-throw-handler inside lazy-catch"
  244. '(1 2 3 4 6 8)
  245. (catch 'a
  246. (lambda ()
  247. (push 1)
  248. (lazy-catch 'a
  249. (lambda ()
  250. (push 2)
  251. (with-throw-handler 'a
  252. (lambda ()
  253. (push 3)
  254. (throw 'a))
  255. (lambda (key . args)
  256. (push 4)))
  257. (push 5))
  258. (lambda (key . args)
  259. (push 6)))
  260. (push 7))
  261. (lambda (key . args)
  262. (push 8))))
  263. (throw-test "lazy-catch inside with-throw-handler"
  264. '(1 2 3 4 6 8)
  265. (catch 'a
  266. (lambda ()
  267. (push 1)
  268. (with-throw-handler 'a
  269. (lambda ()
  270. (push 2)
  271. (lazy-catch 'a
  272. (lambda ()
  273. (push 3)
  274. (throw 'a))
  275. (lambda (key . args)
  276. (push 4)))
  277. (push 5))
  278. (lambda (key . args)
  279. (push 6)))
  280. (push 7))
  281. (lambda (key . args)
  282. (push 8))))
  283. (throw-test "throw handlers throwing to each other recursively"
  284. '(1 2 3 4 8 6 10 12)
  285. (catch #t
  286. (lambda ()
  287. (push 1)
  288. (with-throw-handler 'a
  289. (lambda ()
  290. (push 2)
  291. (with-throw-handler 'b
  292. (lambda ()
  293. (push 3)
  294. (with-throw-handler 'c
  295. (lambda ()
  296. (push 4)
  297. (throw 'b)
  298. (push 5))
  299. (lambda (key . args)
  300. (push 6)
  301. (throw 'a)))
  302. (push 7))
  303. (lambda (key . args)
  304. (push 8)
  305. (throw 'c)))
  306. (push 9))
  307. (lambda (key . args)
  308. (push 10)
  309. (throw 'b)))
  310. (push 11))
  311. (lambda (key . args)
  312. (push 12))))
  313. (throw-test "repeat of previous test but with lazy-catch"
  314. '(1 2 3 4 8 12)
  315. (catch #t
  316. (lambda ()
  317. (push 1)
  318. (lazy-catch 'a
  319. (lambda ()
  320. (push 2)
  321. (lazy-catch 'b
  322. (lambda ()
  323. (push 3)
  324. (lazy-catch 'c
  325. (lambda ()
  326. (push 4)
  327. (throw 'b)
  328. (push 5))
  329. (lambda (key . args)
  330. (push 6)
  331. (throw 'a)))
  332. (push 7))
  333. (lambda (key . args)
  334. (push 8)
  335. (throw 'c)))
  336. (push 9))
  337. (lambda (key . args)
  338. (push 10)
  339. (throw 'b)))
  340. (push 11))
  341. (lambda (key . args)
  342. (push 12))))
  343. (throw-test "throw handler throwing to lexically inside catch"
  344. '(1 2 7 5 4 6 9)
  345. (with-throw-handler 'a
  346. (lambda ()
  347. (push 1)
  348. (catch 'b
  349. (lambda ()
  350. (push 2)
  351. (throw 'a)
  352. (push 3))
  353. (lambda (key . args)
  354. (push 4))
  355. (lambda (key . args)
  356. (push 5)))
  357. (push 6))
  358. (lambda (key . args)
  359. (push 7)
  360. (throw 'b)
  361. (push 8)))
  362. (push 9))
  363. (throw-test "reuse of same throw handler after lexically inside catch"
  364. '(0 1 2 7 5 4 6 7 10)
  365. (catch 'b
  366. (lambda ()
  367. (push 0)
  368. (with-throw-handler 'a
  369. (lambda ()
  370. (push 1)
  371. (catch 'b
  372. (lambda ()
  373. (push 2)
  374. (throw 'a)
  375. (push 3))
  376. (lambda (key . args)
  377. (push 4))
  378. (lambda (key . args)
  379. (push 5)))
  380. (push 6)
  381. (throw 'a))
  382. (lambda (key . args)
  383. (push 7)
  384. (throw 'b)
  385. (push 8)))
  386. (push 9))
  387. (lambda (key . args)
  388. (push 10))))
  389. (throw-test "again but with two chained throw handlers"
  390. '(0 1 11 2 13 7 5 4 12 13 7 10)
  391. (catch 'b
  392. (lambda ()
  393. (push 0)
  394. (with-throw-handler 'a
  395. (lambda ()
  396. (push 1)
  397. (with-throw-handler 'a
  398. (lambda ()
  399. (push 11)
  400. (catch 'b
  401. (lambda ()
  402. (push 2)
  403. (throw 'a)
  404. (push 3))
  405. (lambda (key . args)
  406. (push 4))
  407. (lambda (key . args)
  408. (push 5)))
  409. (push 12)
  410. (throw 'a))
  411. (lambda (key . args)
  412. (push 13)))
  413. (push 6))
  414. (lambda (key . args)
  415. (push 7)
  416. (throw 'b)))
  417. (push 9))
  418. (lambda (key . args)
  419. (push 10))))
  420. )
  421. (with-test-prefix "false-if-exception"
  422. (pass-if (false-if-exception #t))
  423. (pass-if (not (false-if-exception #f)))
  424. (pass-if (not (false-if-exception (error "xxx"))))
  425. ;; Not yet working.
  426. ;;
  427. ;; (with-test-prefix "in empty environment"
  428. ;; ;; an environment with no bindings at all
  429. ;; (define empty-environment
  430. ;; (make-module 1))
  431. ;;
  432. ;; (pass-if "#t"
  433. ;; (eval `(,false-if-exception #t)
  434. ;; empty-environment))
  435. ;; (pass-if "#f"
  436. ;; (not (eval `(,false-if-exception #f)
  437. ;; empty-environment)))
  438. ;; (pass-if "exception"
  439. ;; (not (eval `(,false-if-exception (,error "xxx"))
  440. ;; empty-environment))))
  441. )