srfi-9.test 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772
  1. ;;;; srfi-9.test --- Test suite for Guile's SRFI-9 functions. -*- scheme -*-
  2. ;;;; Martin Grabmueller, 2001-05-10
  3. ;;;;
  4. ;;;; Copyright (C) 2001, 2006, 2007, 2010, 2011, 2012,
  5. ;;;; 2013 Free Software Foundation, Inc.
  6. ;;;;
  7. ;;;; This library is free software; you can redistribute it and/or
  8. ;;;; modify it under the terms of the GNU Lesser General Public
  9. ;;;; License as published by the Free Software Foundation; either
  10. ;;;; version 3 of the License, or (at your option) any later version.
  11. ;;;;
  12. ;;;; This library is distributed in the hope that it will be useful,
  13. ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. ;;;; Lesser General Public License for more details.
  16. ;;;;
  17. ;;;; You should have received a copy of the GNU Lesser General Public
  18. ;;;; License along with this library; if not, write to the Free Software
  19. ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. (define-module (test-suite test-numbers)
  21. #:use-module (test-suite lib)
  22. #:use-module ((system base compile) #:select (compile))
  23. #:use-module (srfi srfi-26)
  24. #:use-module (srfi srfi-9)
  25. #:use-module (srfi srfi-9 gnu))
  26. (define-record-type :qux (make-qux) qux?)
  27. (define-record-type :foo (make-foo x) foo?
  28. (x foo-x)
  29. (y foo-y set-foo-y!)
  30. (z foo-z set-foo-z!))
  31. (define-record-type :bar (make-bar i j) bar?
  32. (i bar-i)
  33. (j bar-j set-bar-j!))
  34. (define f (make-foo 1))
  35. (set-foo-y! f 2)
  36. (define b (make-bar 123 456))
  37. (define exception:syntax-error-wrong-num-args
  38. (cons 'syntax-error "Wrong number of arguments"))
  39. (with-test-prefix "constructor"
  40. ;; Constructors are defined using `define-integrable', meaning that direct
  41. ;; calls as in `(make-foo)' lead to a compile-time psyntax error, hence the
  42. ;; distinction below.
  43. (pass-if-exception "foo 0 args (inline)" exception:syntax-error-wrong-num-args
  44. (compile '(make-foo) #:env (current-module)))
  45. (pass-if-exception "foo 2 args (inline)" exception:syntax-error-wrong-num-args
  46. (compile '(make-foo 1 2) #:env (current-module)))
  47. (pass-if-exception "foo 0 args" exception:wrong-num-args
  48. (let ((make-foo make-foo))
  49. (make-foo)))
  50. (pass-if-exception "foo 2 args" exception:wrong-num-args
  51. (let ((make-foo make-foo))
  52. (make-foo 1 2))))
  53. (with-test-prefix "predicate"
  54. (pass-if "pass"
  55. (foo? f))
  56. (pass-if "fail wrong record type"
  57. (eq? #f (foo? b)))
  58. (pass-if "fail number"
  59. (eq? #f (foo? 123))))
  60. (with-test-prefix "getter"
  61. (pass-if "foo-x"
  62. (= 1 (foo-x f)))
  63. (pass-if "foo-y"
  64. (= 2 (foo-y f)))
  65. (pass-if-exception "foo-x on number" exception:wrong-type-arg
  66. (foo-x 999))
  67. (pass-if-exception "foo-y on number" exception:wrong-type-arg
  68. (foo-y 999))
  69. ;; prior to guile 1.6.9 and 1.8.1 this wan't enforced
  70. (pass-if-exception "foo-x on bar" exception:wrong-type-arg
  71. (foo-x b))
  72. (pass-if-exception "foo-y on bar" exception:wrong-type-arg
  73. (foo-y b)))
  74. (with-test-prefix "setter"
  75. (pass-if "set-foo-y!"
  76. (set-foo-y! f #t)
  77. (eq? #t (foo-y f)))
  78. (pass-if-exception "set-foo-y! on number" exception:wrong-type-arg
  79. (set-foo-y! 999 #t))
  80. ;; prior to guile 1.6.9 and 1.8.1 this wan't enforced
  81. (pass-if-exception "set-foo-y! on bar" exception:wrong-type-arg
  82. (set-foo-y! b 99)))
  83. (with-test-prefix "functional setters"
  84. (pass-if "set-field"
  85. (let ((s (make-foo (make-bar 1 2))))
  86. (and (equal? (set-field s (foo-x bar-j) 3)
  87. (make-foo (make-bar 1 3)))
  88. (equal? (set-field s (foo-z) 'bar)
  89. (let ((s2 (make-foo (make-bar 1 2))))
  90. (set-foo-z! s2 'bar)
  91. s2))
  92. (equal? s (make-foo (make-bar 1 2))))))
  93. (pass-if-exception "set-field on wrong struct type" exception:wrong-type-arg
  94. (let ((s (make-bar (make-foo 5) 2)))
  95. (set-field s (foo-x bar-j) 3)))
  96. (pass-if-exception "set-field on number" exception:wrong-type-arg
  97. (set-field 4 (foo-x bar-j) 3))
  98. (pass-if-equal "set-field with unknown first getter"
  99. '(syntax-error set-fields "unknown getter"
  100. (set-field s (blah) 3)
  101. blah)
  102. (catch 'syntax-error
  103. (lambda ()
  104. (compile '(let ((s (make-bar (make-foo 5) 2)))
  105. (set-field s (blah) 3))
  106. #:env (current-module))
  107. #f)
  108. (lambda (key whom what src form subform)
  109. (list key whom what form subform))))
  110. (pass-if-equal "set-field with unknown second getter"
  111. '(syntax-error set-fields "unknown getter"
  112. (set-field s (bar-j blah) 3)
  113. blah)
  114. (catch 'syntax-error
  115. (lambda ()
  116. (compile '(let ((s (make-bar (make-foo 5) 2)))
  117. (set-field s (bar-j blah) 3))
  118. #:env (current-module))
  119. #f)
  120. (lambda (key whom what src form subform)
  121. (list key whom what form subform))))
  122. (pass-if "set-fields"
  123. (let ((s (make-foo (make-bar 1 2))))
  124. (and (equal? (set-field s (foo-x bar-j) 3)
  125. (make-foo (make-bar 1 3)))
  126. (equal? (set-fields s
  127. ((foo-x bar-j) 3)
  128. ((foo-z) 'bar))
  129. (let ((s2 (make-foo (make-bar 1 3))))
  130. (set-foo-z! s2 'bar)
  131. s2))
  132. (equal? s (make-foo (make-bar 1 2))))))
  133. (pass-if-exception "set-fields on wrong struct type" exception:wrong-type-arg
  134. (let ((s (make-bar (make-foo 5) 2)))
  135. (set-fields 4
  136. ((foo-x bar-j) 3)
  137. ((foo-y) 'bar))))
  138. (pass-if-exception "set-fields on number" exception:wrong-type-arg
  139. (set-fields 4
  140. ((foo-x bar-j) 3)
  141. ((foo-z) 'bar)))
  142. (pass-if-equal "set-fields with unknown first getter"
  143. '(syntax-error set-fields "unknown getter"
  144. (set-fields s ((bar-i foo-x) 1) ((blah) 3))
  145. blah)
  146. (catch 'syntax-error
  147. (lambda ()
  148. (compile '(let ((s (make-bar (make-foo 5) 2)))
  149. (set-fields s ((bar-i foo-x) 1) ((blah) 3)))
  150. #:env (current-module))
  151. #f)
  152. (lambda (key whom what src form subform)
  153. (list key whom what form subform))))
  154. (pass-if-equal "set-fields with unknown second getter"
  155. '(syntax-error set-fields "unknown getter"
  156. (set-fields s ((bar-i foo-x) 1) ((blah) 3))
  157. blah)
  158. (catch 'syntax-error
  159. (lambda ()
  160. (compile '(let ((s (make-bar (make-foo 5) 2)))
  161. (set-fields s ((bar-i foo-x) 1) ((blah) 3)))
  162. #:env (current-module))
  163. #f)
  164. (lambda (key whom what src form subform)
  165. (list key whom what form subform))))
  166. (pass-if-equal "set-fields with duplicate field path"
  167. '(syntax-error set-fields "duplicate field path"
  168. (set-fields s
  169. ((bar-i foo-x) 1)
  170. ((bar-i foo-z) 2)
  171. ((bar-i foo-x) 3))
  172. (bar-i foo-x))
  173. (catch 'syntax-error
  174. (lambda ()
  175. (compile '(let ((s (make-bar (make-foo 5) 2)))
  176. (set-fields s
  177. ((bar-i foo-x) 1)
  178. ((bar-i foo-z) 2)
  179. ((bar-i foo-x) 3)))
  180. #:env (current-module))
  181. #f)
  182. (lambda (key whom what src form subform)
  183. (list key whom what form subform))))
  184. (pass-if-equal "set-fields with one path as a prefix of another"
  185. '(syntax-error set-fields
  186. "one field path is a prefix of another"
  187. (set-fields s
  188. ((bar-i foo-x) 1)
  189. ((bar-i foo-z) 2)
  190. ((bar-i) 3))
  191. (bar-i))
  192. (catch 'syntax-error
  193. (lambda ()
  194. (compile '(let ((s (make-bar (make-foo 5) 2)))
  195. (set-fields s
  196. ((bar-i foo-x) 1)
  197. ((bar-i foo-z) 2)
  198. ((bar-i) 3)))
  199. #:env (current-module))
  200. #f)
  201. (lambda (key whom what src form subform)
  202. (list key whom what form subform)))))
  203. (with-test-prefix "side-effecting arguments"
  204. (pass-if "predicate"
  205. (let ((x 0))
  206. (and (foo? (begin (set! x (+ x 1)) f))
  207. (= x 1)))))
  208. (with-test-prefix "non-toplevel"
  209. (define-record-type :frotz (make-frotz a b) frotz?
  210. (a frotz-a) (b frotz-b set-frotz-b!))
  211. (pass-if "construction"
  212. (let ((frotz (make-frotz 1 2)))
  213. (and (= (frotz-a frotz) 1)
  214. (= (frotz-b frotz) 2))))
  215. (with-test-prefix "functional setters"
  216. (let ()
  217. (define-record-type foo (make-foo x) foo?
  218. (x foo-x)
  219. (y foo-y set-foo-y!)
  220. (z foo-z set-foo-z!))
  221. (define-record-type :bar (make-bar i j) bar?
  222. (i bar-i)
  223. (j bar-j set-bar-j!))
  224. (pass-if "set-field"
  225. (let ((s (make-foo (make-bar 1 2))))
  226. (and (equal? (set-field s (foo-x bar-j) 3)
  227. (make-foo (make-bar 1 3)))
  228. (equal? (set-field s (foo-z) 'bar)
  229. (let ((s2 (make-foo (make-bar 1 2))))
  230. (set-foo-z! s2 'bar)
  231. s2))
  232. (equal? s (make-foo (make-bar 1 2)))))))
  233. (pass-if "set-fieldss "
  234. (let ((s (make-foo (make-bar 1 2))))
  235. (and (equal? (set-field s (foo-x bar-j) 3)
  236. (make-foo (make-bar 1 3)))
  237. (equal? (set-fields s
  238. ((foo-x bar-j) 3)
  239. ((foo-z) 'bar))
  240. (let ((s2 (make-foo (make-bar 1 3))))
  241. (set-foo-z! s2 'bar)
  242. s2))
  243. (equal? s (make-foo (make-bar 1 2))))))))
  244. (define-immutable-record-type :baz
  245. (make-baz x y z)
  246. baz?
  247. (x baz-x set-baz-x)
  248. (y baz-y set-baz-y)
  249. (z baz-z set-baz-z))
  250. (define-immutable-record-type :address
  251. (make-address street city country)
  252. address?
  253. (street address-street)
  254. (city address-city)
  255. (country address-country))
  256. (define-immutable-record-type :person
  257. (make-person age email address)
  258. person?
  259. (age person-age)
  260. (email person-email)
  261. (address person-address))
  262. (with-test-prefix "define-immutable-record-type"
  263. (pass-if "get"
  264. (let ((b (make-baz 1 2 3)))
  265. (and (= (baz-x b) 1)
  266. (= (baz-y b) 2)
  267. (= (baz-z b) 3))))
  268. (pass-if "get non-inlined"
  269. (let ((b (make-baz 1 2 3)))
  270. (equal? (map (cute apply <> (list b))
  271. (list baz-x baz-y baz-z))
  272. '(1 2 3))))
  273. (pass-if "set"
  274. (let* ((b0 (make-baz 1 2 3))
  275. (b1 (set-baz-x b0 11))
  276. (b2 (set-baz-y b1 22))
  277. (b3 (set-baz-z b2 33)))
  278. (and (= (baz-x b0) 1)
  279. (= (baz-x b1) 11) (= (baz-x b2) 11) (= (baz-x b3) 11)
  280. (= (baz-y b0) 2) (= (baz-y b1) 2)
  281. (= (baz-y b2) 22) (= (baz-y b3) 22)
  282. (= (baz-z b0) 3) (= (baz-z b1) 3) (= (baz-z b2) 3)
  283. (= (baz-z b3) 33))))
  284. (pass-if "set non-inlined"
  285. (let ((set (compose (cut set-baz-x <> 1)
  286. (cut set-baz-y <> 2)
  287. (cut set-baz-z <> 3))))
  288. (equal? (set (make-baz 0 0 0)) (make-baz 1 2 3))))
  289. (pass-if "set-field"
  290. (let ((p (make-person 30 "foo@example.com"
  291. (make-address "Foo" "Paris" "France"))))
  292. (and (equal? (set-field p (person-address address-street) "Bar")
  293. (make-person 30 "foo@example.com"
  294. (make-address "Bar" "Paris" "France")))
  295. (equal? (set-field p (person-email) "bar@example.com")
  296. (make-person 30 "bar@example.com"
  297. (make-address "Foo" "Paris" "France")))
  298. (equal? p (make-person 30 "foo@example.com"
  299. (make-address "Foo" "Paris" "France"))))))
  300. (pass-if "set-fields"
  301. (let ((p (make-person 30 "foo@example.com"
  302. (make-address "Foo" "Paris" "France"))))
  303. (and (equal? (set-fields p
  304. ((person-email) "bar@example.com")
  305. ((person-address address-country) "Catalonia")
  306. ((person-address address-city) "Barcelona"))
  307. (make-person 30 "bar@example.com"
  308. (make-address "Foo" "Barcelona" "Catalonia")))
  309. (equal? (set-fields p
  310. ((person-email) "bar@example.com")
  311. ((person-age) 20))
  312. (make-person 20 "bar@example.com"
  313. (make-address "Foo" "Paris" "France")))
  314. (equal? p (make-person 30 "foo@example.com"
  315. (make-address "Foo" "Paris" "France"))))))
  316. (with-test-prefix "non-toplevel"
  317. (pass-if "get"
  318. (let ()
  319. (define-immutable-record-type bar
  320. (make-bar x y z)
  321. bar?
  322. (x bar-x)
  323. (y bar-y)
  324. (z bar-z set-bar-z))
  325. (let ((b (make-bar 1 2 3)))
  326. (and (= (bar-x b) 1)
  327. (= (bar-y b) 2)
  328. (= (bar-z b) 3)))))
  329. (pass-if "get non-inlined"
  330. (let ()
  331. (define-immutable-record-type bar
  332. (make-bar x y z)
  333. bar?
  334. (x bar-x)
  335. (y bar-y)
  336. (z bar-z set-bar-z))
  337. (let ((b (make-bar 1 2 3)))
  338. (equal? (map (cute apply <> (list b))
  339. (list bar-x bar-y bar-z))
  340. '(1 2 3)))))
  341. (pass-if "set"
  342. (let ()
  343. (define-immutable-record-type bar
  344. (make-bar x y z)
  345. bar?
  346. (x bar-x set-bar-x)
  347. (y bar-y set-bar-y)
  348. (z bar-z set-bar-z))
  349. (let* ((b0 (make-bar 1 2 3))
  350. (b1 (set-bar-x b0 11))
  351. (b2 (set-bar-y b1 22))
  352. (b3 (set-bar-z b2 33)))
  353. (and (= (bar-x b0) 1)
  354. (= (bar-x b1) 11) (= (bar-x b2) 11) (= (bar-x b3) 11)
  355. (= (bar-y b0) 2) (= (bar-y b1) 2)
  356. (= (bar-y b2) 22) (= (bar-y b3) 22)
  357. (= (bar-z b0) 3) (= (bar-z b1) 3) (= (bar-z b2) 3)
  358. (= (bar-z b3) 33)))))
  359. (pass-if "set non-inlined"
  360. (let ()
  361. (define-immutable-record-type bar
  362. (make-bar x y z)
  363. bar?
  364. (x bar-x set-bar-x)
  365. (y bar-y set-bar-y)
  366. (z bar-z set-bar-z))
  367. (let ((set (compose (cut set-bar-x <> 1)
  368. (cut set-bar-y <> 2)
  369. (cut set-bar-z <> 3))))
  370. (equal? (set (make-bar 0 0 0)) (make-bar 1 2 3)))))
  371. (pass-if "set-field"
  372. (let ()
  373. (define-immutable-record-type address
  374. (make-address street city country)
  375. address?
  376. (street address-street)
  377. (city address-city)
  378. (country address-country))
  379. (define-immutable-record-type :person
  380. (make-person age email address)
  381. person?
  382. (age person-age)
  383. (email person-email)
  384. (address person-address))
  385. (let ((p (make-person 30 "foo@example.com"
  386. (make-address "Foo" "Paris" "France"))))
  387. (and (equal? (set-field p (person-address address-street) "Bar")
  388. (make-person 30 "foo@example.com"
  389. (make-address "Bar" "Paris" "France")))
  390. (equal? (set-field p (person-email) "bar@example.com")
  391. (make-person 30 "bar@example.com"
  392. (make-address "Foo" "Paris" "France")))
  393. (equal? p (make-person 30 "foo@example.com"
  394. (make-address "Foo" "Paris" "France")))))))
  395. (pass-if "set-fields"
  396. (let ()
  397. (define-immutable-record-type address
  398. (make-address street city country)
  399. address?
  400. (street address-street)
  401. (city address-city)
  402. (country address-country))
  403. (define-immutable-record-type :person
  404. (make-person age email address)
  405. person?
  406. (age person-age)
  407. (email person-email)
  408. (address person-address))
  409. (let ((p (make-person 30 "foo@example.com"
  410. (make-address "Foo" "Paris" "France"))))
  411. (and (equal? (set-fields p
  412. ((person-email) "bar@example.com")
  413. ((person-address address-country) "Catalonia")
  414. ((person-address address-city) "Barcelona"))
  415. (make-person 30 "bar@example.com"
  416. (make-address "Foo" "Barcelona" "Catalonia")))
  417. (equal? (set-fields p
  418. ((person-email) "bar@example.com")
  419. ((person-age) 20))
  420. (make-person 20 "bar@example.com"
  421. (make-address "Foo" "Paris" "France")))
  422. (equal? p (make-person 30 "foo@example.com"
  423. (make-address "Foo" "Paris" "France")))))))
  424. (pass-if-equal "set-fields with unknown first getter"
  425. '(syntax-error set-fields "unknown getter"
  426. (set-fields s ((bar-i foo-x) 1) ((blah) 3))
  427. blah)
  428. (catch 'syntax-error
  429. (lambda ()
  430. (compile '(let ()
  431. (define-immutable-record-type foo
  432. (make-foo x)
  433. foo?
  434. (x foo-x)
  435. (y foo-y set-foo-y)
  436. (z foo-z set-foo-z))
  437. (define-immutable-record-type :bar
  438. (make-bar i j)
  439. bar?
  440. (i bar-i)
  441. (j bar-j set-bar-j))
  442. (let ((s (make-bar (make-foo 5) 2)))
  443. (set-fields s ((bar-i foo-x) 1) ((blah) 3))))
  444. #:env (current-module))
  445. #f)
  446. (lambda (key whom what src form subform)
  447. (list key whom what form subform))))
  448. (pass-if-equal "set-fields with unknown second getter"
  449. '(syntax-error set-fields "unknown getter"
  450. (set-fields s ((bar-i foo-x) 1) ((blah) 3))
  451. blah)
  452. (catch 'syntax-error
  453. (lambda ()
  454. (compile '(let ()
  455. (define-immutable-record-type foo
  456. (make-foo x)
  457. foo?
  458. (x foo-x)
  459. (y foo-y set-foo-y)
  460. (z foo-z set-foo-z))
  461. (define-immutable-record-type :bar
  462. (make-bar i j)
  463. bar?
  464. (i bar-i)
  465. (j bar-j set-bar-j))
  466. (let ((s (make-bar (make-foo 5) 2)))
  467. (set-fields s ((bar-i foo-x) 1) ((blah) 3))))
  468. #:env (current-module))
  469. #f)
  470. (lambda (key whom what src form subform)
  471. (list key whom what form subform))))
  472. (pass-if-equal "set-fields with duplicate field path"
  473. '(syntax-error set-fields "duplicate field path"
  474. (set-fields s
  475. ((bar-i foo-x) 1)
  476. ((bar-i foo-z) 2)
  477. ((bar-i foo-x) 3))
  478. (bar-i foo-x))
  479. (catch 'syntax-error
  480. (lambda ()
  481. (compile '(let ()
  482. (define-immutable-record-type foo
  483. (make-foo x)
  484. foo?
  485. (x foo-x)
  486. (y foo-y set-foo-y)
  487. (z foo-z set-foo-z))
  488. (define-immutable-record-type :bar
  489. (make-bar i j)
  490. bar?
  491. (i bar-i)
  492. (j bar-j set-bar-j))
  493. (let ((s (make-bar (make-foo 5) 2)))
  494. (set-fields s
  495. ((bar-i foo-x) 1)
  496. ((bar-i foo-z) 2)
  497. ((bar-i foo-x) 3))))
  498. #:env (current-module))
  499. #f)
  500. (lambda (key whom what src form subform)
  501. (list key whom what form subform))))
  502. (pass-if-equal "set-fields with one path as a prefix of another"
  503. '(syntax-error set-fields
  504. "one field path is a prefix of another"
  505. (set-fields s
  506. ((bar-i foo-x) 1)
  507. ((bar-i foo-z) 2)
  508. ((bar-i) 3))
  509. (bar-i))
  510. (catch 'syntax-error
  511. (lambda ()
  512. (compile '(let ()
  513. (define-immutable-record-type foo
  514. (make-foo x)
  515. foo?
  516. (x foo-x)
  517. (y foo-y set-foo-y)
  518. (z foo-z set-foo-z))
  519. (define-immutable-record-type :bar
  520. (make-bar i j)
  521. bar?
  522. (i bar-i)
  523. (j bar-j set-bar-j))
  524. (let ((s (make-bar (make-foo 5) 2)))
  525. (set-fields s
  526. ((bar-i foo-x) 1)
  527. ((bar-i foo-z) 2)
  528. ((bar-i) 3))))
  529. #:env (current-module))
  530. #f)
  531. (lambda (key whom what src form subform)
  532. (list key whom what form subform))))
  533. (pass-if-equal "incompatible field paths"
  534. '(syntax-error set-fields
  535. "\
  536. field paths (bar-i bar-j) and (bar-i foo-x) require one object \
  537. to belong to two different record types (bar and foo)"
  538. (set-fields s
  539. ((bar-i foo-x) 1)
  540. ((bar-i bar-j) 2)
  541. ((bar-j) 3))
  542. #f)
  543. (catch 'syntax-error
  544. (lambda ()
  545. (compile '(let ()
  546. (define-immutable-record-type foo
  547. (make-foo x)
  548. foo?
  549. (x foo-x)
  550. (y foo-y set-foo-y)
  551. (z foo-z set-foo-z))
  552. (define-immutable-record-type bar
  553. (make-bar i j)
  554. bar?
  555. (i bar-i)
  556. (j bar-j set-bar-j))
  557. (let ((s (make-bar (make-foo 5) 2)))
  558. (set-fields s
  559. ((bar-i foo-x) 1)
  560. ((bar-i bar-j) 2)
  561. ((bar-j) 3))))
  562. #:env (current-module))
  563. #f)
  564. (lambda (key whom what src form subform)
  565. (list key whom what form subform))))))
  566. (with-test-prefix "record type definition error reporting"
  567. (pass-if-equal "invalid type name"
  568. '(syntax-error define-immutable-record-type
  569. "expected type name"
  570. (define-immutable-record-type
  571. (foobar x y)
  572. foobar?
  573. (x foobar-x)
  574. (y foobar-y))
  575. (foobar x y))
  576. (catch 'syntax-error
  577. (lambda ()
  578. (compile '(define-immutable-record-type
  579. (foobar x y)
  580. foobar?
  581. (x foobar-x)
  582. (y foobar-y))
  583. #:env (current-module))
  584. #f)
  585. (lambda (key whom what src form subform)
  586. (list key whom what form subform))))
  587. (pass-if-equal "invalid constructor spec"
  588. '(syntax-error define-immutable-record-type
  589. "invalid constructor spec"
  590. (define-immutable-record-type :foobar
  591. (make-foobar x y 3)
  592. foobar?
  593. (x foobar-x)
  594. (y foobar-y))
  595. (make-foobar x y 3))
  596. (catch 'syntax-error
  597. (lambda ()
  598. (compile '(define-immutable-record-type :foobar
  599. (make-foobar x y 3)
  600. foobar?
  601. (x foobar-x)
  602. (y foobar-y))
  603. #:env (current-module))
  604. #f)
  605. (lambda (key whom what src form subform)
  606. (list key whom what form subform))))
  607. (pass-if-equal "invalid predicate name"
  608. '(syntax-error define-immutable-record-type
  609. "expected predicate name"
  610. (define-immutable-record-type :foobar
  611. (foobar x y)
  612. (x foobar-x)
  613. (y foobar-y))
  614. (x foobar-x))
  615. (catch 'syntax-error
  616. (lambda ()
  617. (compile '(define-immutable-record-type :foobar
  618. (foobar x y)
  619. (x foobar-x)
  620. (y foobar-y))
  621. #:env (current-module))
  622. #f)
  623. (lambda (key whom what src form subform)
  624. (list key whom what form subform))))
  625. (pass-if-equal "invalid field spec"
  626. '(syntax-error define-record-type
  627. "invalid field spec"
  628. (define-record-type :foobar
  629. (make-foobar x y)
  630. foobar?
  631. (x)
  632. (y foobar-y))
  633. (x))
  634. (catch 'syntax-error
  635. (lambda ()
  636. (compile '(define-record-type :foobar
  637. (make-foobar x y)
  638. foobar?
  639. (x)
  640. (y foobar-y))
  641. #:env (current-module))
  642. #f)
  643. (lambda (key whom what src form subform)
  644. (list key whom what form subform))))
  645. (pass-if-equal "unknown field in constructor spec"
  646. '(syntax-error define-record-type
  647. "unknown field in constructor spec"
  648. (define-record-type :foobar
  649. (make-foobar x z)
  650. foobar?
  651. (x foobar-x)
  652. (y foobar-y))
  653. z)
  654. (catch 'syntax-error
  655. (lambda ()
  656. (compile '(define-record-type :foobar
  657. (make-foobar x z)
  658. foobar?
  659. (x foobar-x)
  660. (y foobar-y))
  661. #:env (current-module))
  662. #f)
  663. (lambda (key whom what src form subform)
  664. (list key whom what form subform)))))
  665. (with-test-prefix "record compatibility"
  666. (pass-if "record?"
  667. (record? (make-foo 1)))
  668. (pass-if "record-constructor"
  669. (equal? ((record-constructor :foo) 1)
  670. (make-foo 1))))
  671. ;;; Local Variables:
  672. ;;; mode: scheme
  673. ;;; eval: (put 'set-fields 'scheme-indent-function 1)
  674. ;;; End: