1 ;;;; srfi-1.test --- Test suite for Guile's SRFI-1 functions. -*- scheme -*-
3 ;;;; Copyright 2003, 2004, 2005 Free Software Foundation, Inc.
5 ;;;; This program is free software; you can redistribute it and/or modify
6 ;;;; it under the terms of the GNU General Public License as published by
7 ;;;; the Free Software Foundation; either version 2, or (at your option)
8 ;;;; any later version.
10 ;;;; This program is distributed in the hope that it will be useful,
11 ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ;;;; GNU General Public License for more details.
15 ;;;; You should have received a copy of the GNU General Public License
16 ;;;; along with this software; see the file COPYING. If not, write to
17 ;;;; the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18 ;;;; Boston, MA 02111-1307 USA
20 (use-modules (srfi srfi-1)
23 (define (ref-delete x lst . proc)
24 "Reference implemenation of srfi-1 `delete'."
25 (set! proc (if (null? proc) equal? (car proc)))
30 (if (not (proc x (car lst)))
31 (set! ret (cons (car lst) ret)))))
33 (define (ref-delete-duplicates lst . proc)
34 "Reference implemenation of srfi-1 `delete-duplicates'."
35 (set! proc (if (null? proc) equal? (car proc)))
41 (let ((elem (car lst)))
42 (set! keep (cons elem keep))
43 (set! lst (ref-delete elem lst proc))))))
50 (with-test-prefix "alist-copy"
52 ;; return a list which is the pairs making up alist A, the spine and cells
53 (define (alist-pairs a)
57 (more (cdr a) (cons a result))
60 ;; return a list of the elements common to lists X and Y, compared with eq?
61 (define (common-elements x y)
65 (cons (car x) (common-elements (cdr x) y))
66 (common-elements (cdr x) y))))
68 ;; validate an alist-copy of OLD to NEW
69 ;; lists must be equal, and must comprise new pairs
70 (define (valid-alist-copy? old new)
72 (null? (common-elements old new))))
74 (pass-if-exception "too few args" exception:wrong-num-args
77 (pass-if-exception "too many args" exception:wrong-num-args
81 (pass-if old (valid-alist-copy? old (alist-copy old))))
83 (let ((old '((1 . 2))))
84 (pass-if old (valid-alist-copy? old (alist-copy old))))
86 (let ((old '((1 . 2) (3 . 4))))
87 (pass-if old (valid-alist-copy? old (alist-copy old))))
89 (let ((old '((1 . 2) (3 . 4) (5 . 6))))
90 (pass-if old (valid-alist-copy? old (alist-copy old)))))
96 (with-test-prefix "alist-delete"
98 (pass-if "equality call arg order"
100 (alist-delete 'k '((ak . 123))
102 (if (and (eq? k 'k) (eq? ak 'ak))
106 (pass-if "delete keys greater than 5"
107 (equal? '((4 . x) (5 . y))
108 (alist-delete 5 '((4 . x) (5 . y) (6 . z)) <)))
111 (equal? '() (alist-delete 'x '())))
114 (equal? '() (alist-delete 'y '((y . 1)))))
117 (equal? '((n . 1)) (alist-delete 'y '((n . 1)))))
120 (equal? '() (alist-delete 'y '((y . 1) (y . 2)))))
123 (equal? '((n . 1)) (alist-delete 'y '((n . 1) (y . 2)))))
126 (equal? '((n . 2)) (alist-delete 'y '((y . 1) (n . 2)))))
129 (equal? '((n . 1) (n . 2)) (alist-delete 'y '((n . 1) (n . 2)))))
132 (equal? '() (alist-delete 'y '((y . 1) (y . 2) (y . 3)))))
135 (equal? '((n . 1)) (alist-delete 'y '((n . 1) (y . 2) (y . 3)))))
138 (equal? '((n . 2)) (alist-delete 'y '((y . 1) (n . 2) (y . 3)))))
141 (equal? '((n . 1) (n . 2)) (alist-delete 'y '((n . 1) (n . 2) (y . 3)))))
144 (equal? '( (n . 3)) (alist-delete 'y '((y . 1) (y . 2) (n . 3)))))
147 (equal? '((n . 1) (n . 3)) (alist-delete 'y '((n . 1) (y . 2) (n . 3)))))
150 (equal? '((n . 2) (n . 3)) (alist-delete 'y '((y . 1) (n . 2) (n . 3)))))
153 (equal? '((n . 1) (n . 2) (n . 3)) (alist-delete 'y '((n . 1) (n . 2) (n . 3))))))
159 (with-test-prefix "append-map"
161 (with-test-prefix "one list"
164 (equal? '() (append-map noop '(()))))
167 (equal? '(1) (append-map noop '((1)))))
170 (equal? '(1 2) (append-map noop '((1 2)))))
173 (equal? '() (append-map noop '(() ()))))
176 (equal? '(1) (append-map noop '(() (1)))))
179 (equal? '(1 2) (append-map noop '(() (1 2)))))
182 (equal? '(1 2) (append-map noop '((1) (2)))))
185 (equal? '(1 2) (append-map noop '(() (1 2))))))
187 (with-test-prefix "two lists"
190 (equal? '() (append-map noop '(()) '(9))))
193 (equal? '(1) (append-map noop '((1)) '(9))))
195 (pass-if "() () / 9 9"
196 (equal? '() (append-map noop '(() ()) '(9 9))))
198 (pass-if "(1) (2) / 9"
199 (equal? '(1) (append-map noop '((1) (2)) '(9))))
201 (pass-if "(1) (2) / 9 9"
202 (equal? '(1 2) (append-map noop '((1) (2)) '(9 9))))))
208 (with-test-prefix "break"
210 (define (test-break lst want-v1 want-v2)
213 (break negative? lst))
214 (lambda (got-v1 got-v2)
215 (and (equal? got-v1 want-v1)
216 (equal? got-v2 want-v2)))))
219 (test-break '() '() '()))
222 (test-break '(1) '(1) '()))
225 (test-break '(-1) '() '(-1)))
228 (test-break '(1 2) '(1 2) '()))
231 (test-break '(-1 1) '() '(-1 1)))
234 (test-break '(1 -1) '(1) '(-1)))
237 (test-break '(-1 -2) '() '(-1 -2)))
240 (test-break '(1 2 3) '(1 2 3) '()))
243 (test-break '(-1 1 2) '() '(-1 1 2)))
246 (test-break '(1 -1 2) '(1) '(-1 2)))
249 (test-break '(-1 -2 1) '() '(-1 -2 1)))
252 (test-break '(1 2 -1) '(1 2) '(-1)))
255 (test-break '(-1 1 -2) '() '(-1 1 -2)))
258 (test-break '(1 -1 -2) '(1) '(-1 -2)))
261 (test-break '(-1 -2 -3) '() '(-1 -2 -3))))
264 ;; concatenate and concatenate!
268 (define (common-tests concatenate-proc unmodified?)
269 (define (try lstlst want)
270 (let ((lstlst-copy (copy-tree lstlst))
271 (got (concatenate-proc lstlst)))
273 (if (not (equal? lstlst lstlst-copy))
274 (error "input lists modified")))
277 (pass-if-exception "too few args" exception:wrong-num-args
280 (pass-if-exception "too many args" exception:wrong-num-args
281 (concatenate-proc '() '()))
286 (pass-if (try '((1)) '(1)))
287 (pass-if (try '((1 2)) '(1 2)))
288 (pass-if (try '(() (1)) '(1)))
289 (pass-if (try '(() () (1)) '(1)))
291 (pass-if (try '((1) (2)) '(1 2)))
292 (pass-if (try '(() (1 2)) '(1 2)))
294 (pass-if (try '((1) 2) '(1 . 2)))
295 (pass-if (try '((1) (2) 3) '(1 2 . 3)))
296 (pass-if (try '((1) (2) (3 . 4)) '(1 2 3 . 4)))
299 (with-test-prefix "concatenate"
300 (common-tests concatenate #t))
302 (with-test-prefix "concatenate!"
303 (common-tests concatenate! #f)))
309 (with-test-prefix "count"
310 (pass-if-exception "no args" exception:wrong-num-args
313 (pass-if-exception "one arg" exception:wrong-num-args
316 (with-test-prefix "one list"
320 (pass-if "empty list" (= 0 (count or1 '())))
322 (pass-if-exception "pred arg count 0" exception:wrong-type-arg
323 (count (lambda () x) '(1 2 3)))
324 (pass-if-exception "pred arg count 2" exception:wrong-type-arg
325 (count (lambda (x y) x) '(1 2 3)))
327 (pass-if-exception "improper 1" exception:wrong-type-arg
329 (pass-if-exception "improper 2" exception:wrong-type-arg
330 (count or1 '(1 . 2)))
331 (pass-if-exception "improper 3" exception:wrong-type-arg
332 (count or1 '(1 2 . 3)))
334 (pass-if (= 0 (count or1 '(#f))))
335 (pass-if (= 1 (count or1 '(#t))))
337 (pass-if (= 0 (count or1 '(#f #f))))
338 (pass-if (= 1 (count or1 '(#f #t))))
339 (pass-if (= 1 (count or1 '(#t #f))))
340 (pass-if (= 2 (count or1 '(#t #t))))
342 (pass-if (= 0 (count or1 '(#f #f #f))))
343 (pass-if (= 1 (count or1 '(#f #f #t))))
344 (pass-if (= 1 (count or1 '(#t #f #f))))
345 (pass-if (= 2 (count or1 '(#t #f #t))))
346 (pass-if (= 3 (count or1 '(#t #t #t)))))
348 (with-test-prefix "two lists"
353 (= 1 (count (lambda (x y)
358 (pass-if "empty lists" (= 0 (count or2 '() '())))
360 (pass-if-exception "pred arg count 0" exception:wrong-type-arg
361 (count (lambda () #t) '(1 2 3) '(1 2 3)))
362 (pass-if-exception "pred arg count 1" exception:wrong-type-arg
363 (count (lambda (x) x) '(1 2 3) '(1 2 3)))
364 (pass-if-exception "pred arg count 3" exception:wrong-type-arg
365 (count (lambda (x y z) x) '(1 2 3) '(1 2 3)))
367 (pass-if-exception "improper first 1" exception:wrong-type-arg
368 (count or2 1 '(1 2 3)))
369 (pass-if-exception "improper first 2" exception:wrong-type-arg
370 (count or2 '(1 . 2) '(1 2 3)))
371 (pass-if-exception "improper first 3" exception:wrong-type-arg
372 (count or2 '(1 2 . 3) '(1 2 3)))
374 (pass-if-exception "improper second 1" exception:wrong-type-arg
375 (count or2 '(1 2 3) 1))
376 (pass-if-exception "improper second 2" exception:wrong-type-arg
377 (count or2 '(1 2 3) '(1 . 2)))
378 (pass-if-exception "improper second 3" exception:wrong-type-arg
379 (count or2 '(1 2 3) '(1 2 . 3)))
381 (pass-if (= 0 (count or2 '(#f) '(#f))))
382 (pass-if (= 1 (count or2 '(#t) '(#f))))
383 (pass-if (= 1 (count or2 '(#f) '(#t))))
385 (pass-if (= 0 (count or2 '(#f #f) '(#f #f))))
386 (pass-if (= 1 (count or2 '(#t #f) '(#t #f))))
387 (pass-if (= 2 (count or2 '(#t #t) '(#f #f))))
388 (pass-if (= 2 (count or2 '(#t #f) '(#f #t))))
390 (with-test-prefix "stop shortest"
391 (pass-if (= 2 (count or2 '(#t #f #t) '(#f #t))))
392 (pass-if (= 2 (count or2 '(#t #f #t #t) '(#f #t))))
393 (pass-if (= 2 (count or2 '(#t #f) '(#f #t #t))))
394 (pass-if (= 2 (count or2 '(#t #f) '(#f #t #t #t))))))
396 (with-test-prefix "three lists"
401 (= 1 (count (lambda (x y z)
407 (pass-if "empty lists" (= 0 (count or3 '() '() '())))
409 ;; currently bad pred argument gives wrong-num-args when 3 or more
410 ;; lists, as opposed to wrong-type-arg for 1 or 2 lists
411 (pass-if-exception "pred arg count 0" exception:wrong-num-args
412 (count (lambda () #t) '(1 2 3) '(1 2 3) '(1 2 3)))
413 (pass-if-exception "pred arg count 2" exception:wrong-num-args
414 (count (lambda (x y) x) '(1 2 3) '(1 2 3)'(1 2 3) ))
415 (pass-if-exception "pred arg count 4" exception:wrong-num-args
416 (count (lambda (w x y z) x) '(1 2 3) '(1 2 3) '(1 2 3)))
418 (pass-if-exception "improper first 1" exception:wrong-type-arg
419 (count or3 1 '(1 2 3) '(1 2 3)))
420 (pass-if-exception "improper first 2" exception:wrong-type-arg
421 (count or3 '(1 . 2) '(1 2 3) '(1 2 3)))
422 (pass-if-exception "improper first 3" exception:wrong-type-arg
423 (count or3 '(1 2 . 3) '(1 2 3) '(1 2 3)))
425 (pass-if-exception "improper second 1" exception:wrong-type-arg
426 (count or3 '(1 2 3) 1 '(1 2 3)))
427 (pass-if-exception "improper second 2" exception:wrong-type-arg
428 (count or3 '(1 2 3) '(1 . 2) '(1 2 3)))
429 (pass-if-exception "improper second 3" exception:wrong-type-arg
430 (count or3 '(1 2 3) '(1 2 . 3) '(1 2 3)))
432 (pass-if-exception "improper third 1" exception:wrong-type-arg
433 (count or3 '(1 2 3) '(1 2 3) 1))
434 (pass-if-exception "improper third 2" exception:wrong-type-arg
435 (count or3 '(1 2 3) '(1 2 3) '(1 . 2)))
436 (pass-if-exception "improper third 3" exception:wrong-type-arg
437 (count or3 '(1 2 3) '(1 2 3) '(1 2 . 3)))
439 (pass-if (= 0 (count or3 '(#f) '(#f) '(#f))))
440 (pass-if (= 1 (count or3 '(#t) '(#f) '(#f))))
441 (pass-if (= 1 (count or3 '(#f) '(#t) '(#f))))
442 (pass-if (= 1 (count or3 '(#f) '(#f) '(#t))))
444 (pass-if (= 0 (count or3 '(#f #f) '(#f #f) '(#f #f))))
446 (pass-if (= 1 (count or3 '(#t #f) '(#f #f) '(#f #f))))
447 (pass-if (= 1 (count or3 '(#f #t) '(#f #f) '(#f #f))))
448 (pass-if (= 1 (count or3 '(#f #f) '(#t #f) '(#f #f))))
449 (pass-if (= 1 (count or3 '(#f #f) '(#f #t) '(#f #f))))
450 (pass-if (= 1 (count or3 '(#f #f) '(#f #f) '(#t #f))))
451 (pass-if (= 1 (count or3 '(#f #f) '(#f #f) '(#f #t))))
453 (pass-if (= 2 (count or3 '(#t #t) '(#f #f) '(#f #f))))
454 (pass-if (= 2 (count or3 '(#f #f) '(#t #t) '(#f #f))))
455 (pass-if (= 2 (count or3 '(#f #f) '(#f #f) '(#t #t))))
456 (pass-if (= 2 (count or3 '(#f #f) '(#t #f) '(#f #t))))
458 (with-test-prefix "stop shortest"
459 (pass-if (= 0 (count or3 '() '(#t #t #t) '(#t #t))))
460 (pass-if (= 0 (count or3 '(#t #t #t) '() '(#t #t))))
461 (pass-if (= 0 (count or3 '(#t #t #t) '(#t #t) '())))
463 (pass-if (= 1 (count or3 '(#t) '(#t #t #t) '(#t #t))))
464 (pass-if (= 1 (count or3 '(#t #t #t) '(#t) '(#t #t))))
465 (pass-if (= 1 (count or3 '(#t #t #t) '(#t #t) '(#t)))))))
468 ;; delete and delete!
472 ;; Call (PROC lst) for all lists of length up to 6, with all combinations
473 ;; of elements to be retained or deleted. Elements to retain are numbers,
474 ;; 0 upwards. Elements to be deleted are #f.
475 (define (test-lists proc)
478 (do ((limit (ash 1 n))
482 (do ((bit 0 (1+ bit)))
484 (set! lst (cons (if (logbit? bit i) bit #f) lst)))
487 (define (common-tests delete-proc)
488 (pass-if-exception "too few args" exception:wrong-num-args
491 (pass-if-exception "too many args" exception:wrong-num-args
492 (delete-proc 0 '() equal? 99))
495 (eq? '() (delete-proc 0 '())))
497 (pass-if "equal? (the default)"
499 (delete-proc '(2) '((1) (2) (3)))))
502 (equal? '((1) (2) (3))
503 (delete-proc '(2) '((1) (2) (3)) eq?)))
505 (pass-if "called arg order"
507 (delete-proc 3 '(1 2 3 4 5) <))))
509 (with-test-prefix "delete"
510 (common-tests delete)
514 (let ((lst-copy (list-copy lst)))
515 (with-test-prefix lst-copy
517 (equal? (delete #f lst)
518 (ref-delete #f lst)))
519 (pass-if "non-destructive"
520 (equal? lst-copy lst)))))))
522 (with-test-prefix "delete!"
523 (common-tests delete!)
528 (equal? (delete! #f lst)
529 (ref-delete #f lst)))))))
532 ;; delete-duplicates and delete-duplicates!
536 ;; Call (PROC lst) for all lists of length 1 <= n <= 4, with all
537 ;; combinations of numbers 1 to n in the elements
538 (define (test-lists proc)
541 (do ((limit (integer-expt n n))
546 (rem i (quotient rem n)))
548 (set! lst (cons (remainder rem n) lst)))
551 (define (common-tests delete-duplicates-proc)
552 (pass-if-exception "too few args" exception:wrong-num-args
553 (delete-duplicates-proc))
555 (pass-if-exception "too many args" exception:wrong-num-args
556 (delete-duplicates-proc '() equal? 99))
559 (eq? '() (delete-duplicates-proc '())))
561 (pass-if "equal? (the default)"
563 (delete-duplicates-proc '((2) (2) (2)))))
566 (equal? '((2) (2) (2))
567 (delete-duplicates-proc '((2) (2) (2)) eq?)))
569 (pass-if "called arg order"
571 (delete-duplicates-proc '(1 2 3 4 5)
578 (with-test-prefix "delete-duplicates"
579 (common-tests delete-duplicates)
583 (let ((lst-copy (list-copy lst)))
584 (with-test-prefix lst-copy
586 (equal? (delete-duplicates lst)
587 (ref-delete-duplicates lst)))
588 (pass-if "non-destructive"
589 (equal? lst-copy lst)))))))
591 (with-test-prefix "delete-duplicates!"
592 (common-tests delete-duplicates!)
597 (equal? (delete-duplicates! lst)
598 (ref-delete-duplicates lst)))))))
604 (with-test-prefix "drop"
607 (null? (drop '() 0)))
634 (pass-if "'(a b c) 1"
635 (let ((lst '(a b c)))
639 (pass-if "circular '(a) 0"
640 (let ((lst (circular-list 'a)))
644 (pass-if "circular '(a) 1"
645 (let ((lst (circular-list 'a)))
649 (pass-if "circular '(a) 2"
650 (let ((lst (circular-list 'a)))
654 (pass-if "circular '(a b) 1"
655 (let ((lst (circular-list 'a)))
659 (pass-if "circular '(a b) 2"
660 (let ((lst (circular-list 'a)))
664 (pass-if "circular '(a b) 5"
665 (let ((lst (circular-list 'a)))
669 (pass-if "'(a . b) 1"
673 (pass-if "'(a b . c) 1"
675 (drop '(a b . c) 2))))
681 (with-test-prefix "drop-right"
683 (pass-if-exception "() -1" exception:out-of-range
685 (pass-if (equal? '() (drop-right '() 0)))
686 (pass-if-exception "() 1" exception:wrong-type-arg
689 (pass-if-exception "(1) -1" exception:out-of-range
690 (drop-right '(1) -1))
691 (pass-if (equal? '(1) (drop-right '(1) 0)))
692 (pass-if (equal? '() (drop-right '(1) 1)))
693 (pass-if-exception "(1) 2" exception:wrong-type-arg
696 (pass-if-exception "(4 5) -1" exception:out-of-range
697 (drop-right '(4 5) -1))
698 (pass-if (equal? '(4 5) (drop-right '(4 5) 0)))
699 (pass-if (equal? '(4) (drop-right '(4 5) 1)))
700 (pass-if (equal? '() (drop-right '(4 5) 2)))
701 (pass-if-exception "(4 5) 3" exception:wrong-type-arg
702 (drop-right '(4 5) 3))
704 (pass-if-exception "(4 5 6) -1" exception:out-of-range
705 (drop-right '(4 5 6) -1))
706 (pass-if (equal? '(4 5 6) (drop-right '(4 5 6) 0)))
707 (pass-if (equal? '(4 5) (drop-right '(4 5 6) 1)))
708 (pass-if (equal? '(4) (drop-right '(4 5 6) 2)))
709 (pass-if (equal? '() (drop-right '(4 5 6) 3)))
710 (pass-if-exception "(4 5 6) 4" exception:wrong-type-arg
711 (drop-right '(4 5 6) 4)))
717 (with-test-prefix "filter-map"
719 (with-test-prefix "one list"
720 (pass-if-exception "'x" exception:wrong-type-arg
721 (filter-map noop 'x))
723 (pass-if-exception "'(1 . x)" exception:wrong-type-arg
724 (filter-map noop '(1 . x)))
727 (equal? '(1) (filter-map noop '(1))))
730 (equal? '() (filter-map noop '(#f))))
733 (equal? '(1 2) (filter-map noop '(1 2))))
736 (equal? '(2) (filter-map noop '(#f 2))))
739 (equal? '() (filter-map noop '(#f #f))))
742 (equal? '(1 2 3) (filter-map noop '(1 2 3))))
745 (equal? '(2 3) (filter-map noop '(#f 2 3))))
748 (equal? '(1 3) (filter-map noop '(1 #f 3))))
751 (equal? '(1 2) (filter-map noop '(1 2 #f)))))
753 (with-test-prefix "two lists"
754 (pass-if-exception "'x '(1 2 3)" exception:wrong-type-arg
755 (filter-map noop 'x '(1 2 3)))
757 (pass-if-exception "'(1 2 3) 'x" exception:wrong-type-arg
758 (filter-map noop '(1 2 3) 'x))
760 (pass-if-exception "'(1 . x) '(1 2 3)" exception:wrong-type-arg
761 (filter-map noop '(1 . x) '(1 2 3)))
763 (pass-if-exception "'(1 2 3) '(1 . x)" exception:wrong-type-arg
764 (filter-map noop '(1 2 3) '(1 . x)))
766 (pass-if "(1 2 3) (4 5 6)"
767 (equal? '(5 7 9) (filter-map + '(1 2 3) '(4 5 6))))
769 (pass-if "(#f 2 3) (4 5)"
770 (equal? '(2) (filter-map noop '(#f 2 3) '(4 5))))
772 (pass-if "(4 #f) (1 2 3)"
773 (equal? '(4) (filter-map noop '(4 #f) '(1 2 3))))
775 (pass-if "() (1 2 3)"
776 (equal? '() (filter-map noop '() '(1 2 3))))
778 (pass-if "(1 2 3) ()"
779 (equal? '() (filter-map noop '(1 2 3) '()))))
781 (with-test-prefix "three lists"
782 (pass-if-exception "'x '(1 2 3) '(1 2 3)" exception:wrong-type-arg
783 (filter-map noop 'x '(1 2 3) '(1 2 3)))
785 (pass-if-exception "'(1 2 3) 'x '(1 2 3)" exception:wrong-type-arg
786 (filter-map noop '(1 2 3) 'x '(1 2 3)))
788 (pass-if-exception "'(1 2 3) '(1 2 3) 'x" exception:wrong-type-arg
789 (filter-map noop '(1 2 3) '(1 2 3) 'x))
791 (pass-if-exception "'(1 . x) '(1 2 3) '(1 2 3)" exception:wrong-type-arg
792 (filter-map noop '(1 . x) '(1 2 3) '(1 2 3)))
794 (pass-if-exception "'(1 2 3) '(1 . x) '(1 2 3)" exception:wrong-type-arg
795 (filter-map noop '(1 2 3) '(1 . x) '(1 2 3)))
797 (pass-if-exception "'(1 2 3) '(1 2 3) '(1 . x)" exception:wrong-type-arg
798 (filter-map noop '(1 2 3) '(1 2 3) '(1 . x)))
800 (pass-if "(1 2 3) (4 5 6) (7 8 9)"
801 (equal? '(12 15 18) (filter-map + '(1 2 3) '(4 5 6) '(7 8 9))))
803 (pass-if "(#f 2 3) (4 5) (7 8 9)"
804 (equal? '(2) (filter-map noop '(#f 2 3) '(4 5) '(7 8 9))))
806 (pass-if "(#f 2 3) (7 8 9) (4 5)"
807 (equal? '(2) (filter-map noop '(#f 2 3) '(7 8 9) '(4 5))))
809 (pass-if "(4 #f) (1 2 3) (7 8 9)"
810 (equal? '(4) (filter-map noop '(4 #f) '(1 2 3) '(7 8 9))))))
816 (with-test-prefix "find"
817 (pass-if (eqv? #f (find odd? '())))
818 (pass-if (eqv? #f (find odd? '(0))))
819 (pass-if (eqv? #f (find odd? '(0 2))))
820 (pass-if (eqv? 1 (find odd? '(1))))
821 (pass-if (eqv? 1 (find odd? '(0 1))))
822 (pass-if (eqv? 1 (find odd? '(0 1 2))))
823 (pass-if (eqv? 1 (find odd? '(2 0 1))))
824 (pass-if (eqv? 1 (find (lambda (x) (= 1 x)) '(2 0 1)))))
830 (with-test-prefix "find-tail"
831 (pass-if (let ((lst '()))
832 (eq? #f (find-tail odd? lst))))
833 (pass-if (let ((lst '(0)))
834 (eq? #f (find-tail odd? lst))))
835 (pass-if (let ((lst '(0 2)))
836 (eq? #f (find-tail odd? lst))))
837 (pass-if (let ((lst '(1)))
838 (eq? lst (find-tail odd? lst))))
839 (pass-if (let ((lst '(1 2)))
840 (eq? lst (find-tail odd? lst))))
841 (pass-if (let ((lst '(2 1)))
842 (eq? (cdr lst) (find-tail odd? lst))))
843 (pass-if (let ((lst '(2 1 0)))
844 (eq? (cdr lst) (find-tail odd? lst))))
845 (pass-if (let ((lst '(2 0 1)))
846 (eq? (cddr lst) (find-tail odd? lst))))
847 (pass-if (let ((lst '(2 0 1)))
848 (eq? (cddr lst) (find-tail (lambda (x) (= 1 x)) lst)))))
854 (with-test-prefix "length+"
855 (pass-if-exception "too few args" exception:wrong-num-args
857 (pass-if-exception "too many args" exception:wrong-num-args
859 (pass-if (= 0 (length+ '())))
860 (pass-if (= 1 (length+ '(x))))
861 (pass-if (= 2 (length+ '(x y))))
862 (pass-if (= 3 (length+ '(x y z))))
863 (pass-if (not (length+ (circular-list 1))))
864 (pass-if (not (length+ (circular-list 1 2))))
865 (pass-if (not (length+ (circular-list 1 2 3)))))
871 (with-test-prefix "list="
874 (eq? #t (list= eqv?)))
876 (with-test-prefix "one list"
879 (eq? #t (list= eqv? '())))
881 (eq? #t (list= eqv? '(1))))
883 (eq? #t (list= eqv? '(2)))))
885 (with-test-prefix "two lists"
887 (pass-if "empty / empty"
888 (eq? #t (list= eqv? '() '())))
890 (pass-if "one / empty"
891 (eq? #f (list= eqv? '(1) '())))
893 (pass-if "empty / one"
894 (eq? #f (list= eqv? '() '(1))))
896 (pass-if "one / one same"
897 (eq? #t (list= eqv? '(1) '(1))))
899 (pass-if "one / one diff"
900 (eq? #f (list= eqv? '(1) '(2))))
902 (pass-if "called arg order"
905 (set! good (and good (= (1+ x) y)))
910 (with-test-prefix "three lists"
912 (pass-if "empty / empty / empty"
913 (eq? #t (list= eqv? '() '() '())))
915 (pass-if "one / empty / empty"
916 (eq? #f (list= eqv? '(1) '() '())))
918 (pass-if "one / one / empty"
919 (eq? #f (list= eqv? '(1) '(1) '())))
921 (pass-if "one / diff / empty"
922 (eq? #f (list= eqv? '(1) '(2) '())))
924 (pass-if "one / one / one"
925 (eq? #t (list= eqv? '(1) '(1) '(1))))
927 (pass-if "two / two / diff"
928 (eq? #f (list= eqv? '(1 2) '(1 2) '(1 99))))
930 (pass-if "two / two / two"
931 (eq? #t (list= eqv? '(1 2) '(1 2) '(1 2))))
933 (pass-if "called arg order"
936 (set! good (and good (= (1+ x) y)))
938 '(1 4) '(2 5) '(3 6))
945 (with-test-prefix "list-copy"
946 (pass-if (equal? '() (list-copy '())))
947 (pass-if (equal? '(1 2) (list-copy '(1 2))))
948 (pass-if (equal? '(1 2 3) (list-copy '(1 2 3))))
949 (pass-if (equal? '(1 2 3 4) (list-copy '(1 2 3 4))))
950 (pass-if (equal? '(1 2 3 4 5) (list-copy '(1 2 3 4 5))))
952 ;; improper lists can be copied
953 (pass-if (equal? 1 (list-copy 1)))
954 (pass-if (equal? '(1 . 2) (list-copy '(1 . 2))))
955 (pass-if (equal? '(1 2 . 3) (list-copy '(1 2 . 3))))
956 (pass-if (equal? '(1 2 3 . 4) (list-copy '(1 2 3 . 4))))
957 (pass-if (equal? '(1 2 3 4 . 5) (list-copy '(1 2 3 4 . 5)))))
963 (with-test-prefix "lset="
965 ;; in guile 1.6.7 and earlier, lset= incorrectly demanded at least one
968 (eq? #t (lset= eq?)))
970 (with-test-prefix "one arg"
973 (eq? #t (lset= eqv? '())))
976 (eq? #t (lset= eqv? '(1))))
979 (eq? #t (lset= eqv? '(1 2)))))
981 (with-test-prefix "two args"
984 (eq? #t (lset= eqv? '() '())))
987 (eq? #t (lset= eqv? '(1) '(1))))
990 (eq? #f (lset= eqv? '(1) '(2))))
993 (eq? #f (lset= eqv? '(1) '(1 2))))
995 (pass-if "(1 2) (2 1)"
996 (eq? #t (lset= eqv? '(1 2) '(2 1))))
998 (pass-if "called arg order"
1000 (lset= (lambda (x y)
1001 (if (not (= x (1- y)))
1007 (with-test-prefix "three args"
1010 (eq? #t (lset= eqv? '() '() '())))
1012 (pass-if "(1) (1) (1)"
1013 (eq? #t (lset= eqv? '(1) '(1) '(1))))
1015 (pass-if "(1) (1) (2)"
1016 (eq? #f (lset= eqv? '(1) '(1) '(2))))
1018 (pass-if "(1) (1) (1 2)"
1019 (eq? #f (lset= eqv? '(1) '(1) '(1 2))))
1021 (pass-if "(1 2 3) (3 2 1) (1 3 2)"
1022 (eq? #t (lset= eqv? '(1 2 3) '(3 2 1) '(1 3 2))))
1024 (pass-if "called arg order"
1026 (lset= (lambda (x y)
1027 (if (not (= x (1- y)))
1030 '(1 1) '(2 2) '(3 3))
1037 (with-test-prefix "lset-adjoin"
1039 ;; in guile 1.6.7 and earlier, lset-adjoin didn't actually use the given
1040 ;; `=' procedure, all comparisons were just with `equal?
1042 (with-test-prefix "case-insensitive ="
1044 (pass-if "(\"x\") \"X\""
1045 (equal? '("x") (lset-adjoin string-ci=? '("x") "X"))))
1047 (pass-if "called arg order"
1049 (lset-adjoin (lambda (x y)
1050 (set! good (and (= x 1) (= y 2)))
1055 (pass-if "(1 1) 1 1"
1056 (equal? '(1 1) (lset-adjoin = '(1 1) 1 1)))
1058 ;; duplicates among args are cast out
1060 (equal? '(1 2) (lset-adjoin = '(2) 1 1))))
1066 (with-test-prefix "lset-union"
1069 (eq? '() (lset-union eq?)))
1072 (equal? '(1 2 3) (lset-union eq? '(1 2 3))))
1075 (equal? '() (lset-union eq? '() '())))
1077 (pass-if "'() '(1 2 3)"
1078 (equal? '(1 2 3) (lset-union eq? '() '(1 2 3))))
1080 (pass-if "'(1 2 3) '()"
1081 (equal? '(1 2 3) (lset-union eq? '(1 2 3) '())))
1083 (pass-if "'(1 2 3) '(4 3 5)"
1084 (equal? '(5 4 1 2 3) (lset-union eq? '(1 2 3) '(4 3 5))))
1086 (pass-if "'(1 2 3) '(4) '(3 5))"
1087 (equal? '(5 4 1 2 3) (lset-union eq? '(1 2 3) '(4) '(3 5))))
1089 ;; in guile 1.6.7 and earlier, `=' was called with the arguments the wrong
1091 (pass-if "called arg order"
1093 (lset-union (lambda (x y)
1094 (set! good (and (= x 1) (= y 2)))
1103 (with-test-prefix "member"
1105 (pass-if-exception "no args" exception:wrong-num-args
1108 (pass-if-exception "one arg" exception:wrong-num-args
1111 (pass-if "1 (1 2 3)"
1112 (let ((lst '(1 2 3)))
1113 (eq? lst (member 1 lst))))
1115 (pass-if "2 (1 2 3)"
1116 (let ((lst '(1 2 3)))
1117 (eq? (cdr lst) (member 2 lst))))
1119 (pass-if "3 (1 2 3)"
1120 (let ((lst '(1 2 3)))
1121 (eq? (cddr lst) (member 3 lst))))
1123 (pass-if "4 (1 2 3)"
1124 (let ((lst '(1 2 3)))
1125 (eq? #f (member 4 lst))))
1127 (pass-if "called arg order"
1129 (member 1 '(2) (lambda (x y)
1130 (set! good (and (eqv? 1 x)
1138 (with-test-prefix "take"
1141 (null? (take '() 0)))
1144 (null? (take '(a) 0)))
1147 (null? (take '() 0)))
1149 (pass-if "'(a b c) 0"
1150 (null? (take '() 0)))
1155 (and (equal? '(a) got)
1156 (not (eq? lst got)))))
1162 (pass-if "'(a b c) 1"
1169 (and (equal? '(a b) got)
1170 (not (eq? lst got)))))
1172 (pass-if "'(a b c) 2"
1176 (pass-if "circular '(a) 0"
1178 (take (circular-list 'a) 0)))
1180 (pass-if "circular '(a) 1"
1182 (take (circular-list 'a) 1)))
1184 (pass-if "circular '(a) 2"
1186 (take (circular-list 'a) 2)))
1188 (pass-if "circular '(a b) 5"
1189 (equal? '(a b a b a)
1190 (take (circular-list 'a 'b) 5)))
1192 (pass-if "'(a . b) 1"
1196 (pass-if "'(a b . c) 1"
1198 (take '(a b . c) 1)))
1200 (pass-if "'(a b . c) 2"
1202 (take '(a b . c) 2))))
1208 (define (test-partition pred list kept-good dropped-good)
1209 (call-with-values (lambda ()
1210 (partition pred list))
1211 (lambda (kept dropped)
1212 (and (equal? kept kept-good)
1213 (equal? dropped dropped-good)))))
1215 (with-test-prefix "partition"
1217 (pass-if "with dropped tail"
1218 (test-partition even? '(1 2 3 4 5 6 7)
1219 '(2 4 6) '(1 3 5 7)))
1221 (pass-if "with kept tail"
1222 (test-partition even? '(1 2 3 4 5 6)
1225 (pass-if "with everything dropped"
1226 (test-partition even? '(1 3 5 7)
1229 (pass-if "with everything kept"
1230 (test-partition even? '(2 4 6)
1233 (pass-if "with empty list"
1234 (test-partition even? '()
1237 (pass-if "with reasonably long list"
1238 ;; the old implementation from SRFI-1 reference implementation
1239 ;; would signal a stack-overflow for a list of only 500 elements!
1240 (call-with-values (lambda ()
1242 (make-list 10000 1)))
1244 (and (= (length odd) 10000)
1245 (= (length even) 0))))))
1251 (define (test-partition! pred list kept-good dropped-good)
1252 (call-with-values (lambda ()
1253 (partition! pred list))
1254 (lambda (kept dropped)
1255 (and (equal? kept kept-good)
1256 (equal? dropped dropped-good)))))
1258 (with-test-prefix "partition!"
1260 (pass-if "with dropped tail"
1261 (test-partition! even? (list 1 2 3 4 5 6 7)
1262 '(2 4 6) '(1 3 5 7)))
1264 (pass-if "with kept tail"
1265 (test-partition! even? (list 1 2 3 4 5 6)
1268 (pass-if "with everything dropped"
1269 (test-partition! even? (list 1 3 5 7)
1272 (pass-if "with everything kept"
1273 (test-partition! even? (list 2 4 6)
1276 (pass-if "with empty list"
1277 (test-partition! even? '()
1280 (pass-if "with reasonably long list"
1281 ;; the old implementation from SRFI-1 reference implementation
1282 ;; would signal a stack-overflow for a list of only 500 elements!
1283 (call-with-values (lambda ()
1285 (make-list 10000 1)))
1287 (and (= (length odd) 10000)
1288 (= (length even) 0))))))
1294 (with-test-prefix "reduce"
1298 (ret (reduce (lambda (x prev)
1299 (set! calls (cons (list x prev) calls))
1302 (and (equal? calls '())
1307 (ret (reduce (lambda (x prev)
1308 (set! calls (cons (list x prev) calls))
1311 (and (equal? calls '())
1314 (pass-if "two elems"
1316 (ret (reduce (lambda (x prev)
1317 (set! calls (cons (list x prev) calls))
1320 (and (equal? calls '((3 2)))
1323 (pass-if "three elems"
1325 (ret (reduce (lambda (x prev)
1326 (set! calls (cons (list x prev) calls))
1329 (and (equal? calls '((4 3)
1333 (pass-if "four elems"
1335 (ret (reduce (lambda (x prev)
1336 (set! calls (cons (list x prev) calls))
1339 (and (equal? calls '((5 4)
1348 (with-test-prefix "reduce-right"
1352 (ret (reduce-right (lambda (x prev)
1353 (set! calls (cons (list x prev) calls))
1356 (and (equal? calls '())
1361 (ret (reduce-right (lambda (x prev)
1362 (set! calls (cons (list x prev) calls))
1365 (and (equal? calls '())
1368 (pass-if "two elems"
1370 (ret (reduce-right (lambda (x prev)
1371 (set! calls (cons (list x prev) calls))
1374 (and (equal? calls '((2 3)))
1377 (pass-if "three elems"
1379 (ret (reduce-right (lambda (x prev)
1380 (set! calls (cons (list x prev) calls))
1383 (and (equal? calls '((2 3)
1387 (pass-if "four elems"
1389 (ret (reduce-right (lambda (x prev)
1390 (set! calls (cons (list x prev) calls))
1393 (and (equal? calls '((2 3)
1402 (with-test-prefix "remove"
1404 (pass-if (equal? '() (remove odd? '())))
1405 (pass-if (equal? '() (remove odd? '(1))))
1406 (pass-if (equal? '(2) (remove odd? '(2))))
1408 (pass-if (equal? '() (remove odd? '(1 3))))
1409 (pass-if (equal? '(2) (remove odd? '(2 3))))
1410 (pass-if (equal? '(2) (remove odd? '(1 2))))
1411 (pass-if (equal? '(2 4) (remove odd? '(2 4))))
1413 (pass-if (equal? '() (remove odd? '(1 3 5))))
1414 (pass-if (equal? '(2) (remove odd? '(2 3 5))))
1415 (pass-if (equal? '(2) (remove odd? '(1 2 5))))
1416 (pass-if (equal? '(2 4) (remove odd? '(2 4 5))))
1418 (pass-if (equal? '(6) (remove odd? '(1 3 6))))
1419 (pass-if (equal? '(2 6) (remove odd? '(2 3 6))))
1420 (pass-if (equal? '(2 6) (remove odd? '(1 2 6))))
1421 (pass-if (equal? '(2 4 6) (remove odd? '(2 4 6)))))
1427 (with-test-prefix "remove!"
1429 (pass-if (equal? '() (remove! odd? '())))
1430 (pass-if (equal? '() (remove! odd? (list 1))))
1431 (pass-if (equal? '(2) (remove! odd? (list 2))))
1433 (pass-if (equal? '() (remove! odd? (list 1 3))))
1434 (pass-if (equal? '(2) (remove! odd? (list 2 3))))
1435 (pass-if (equal? '(2) (remove! odd? (list 1 2))))
1436 (pass-if (equal? '(2 4) (remove! odd? (list 2 4))))
1438 (pass-if (equal? '() (remove! odd? (list 1 3 5))))
1439 (pass-if (equal? '(2) (remove! odd? (list 2 3 5))))
1440 (pass-if (equal? '(2) (remove! odd? (list 1 2 5))))
1441 (pass-if (equal? '(2 4) (remove! odd? (list 2 4 5))))
1443 (pass-if (equal? '(6) (remove! odd? (list 1 3 6))))
1444 (pass-if (equal? '(2 6) (remove! odd? (list 2 3 6))))
1445 (pass-if (equal? '(2 6) (remove! odd? (list 1 2 6))))
1446 (pass-if (equal? '(2 4 6) (remove! odd? (list 2 4 6)))))
1452 (with-test-prefix "split-at"
1454 (define (equal-values? lst thunk)
1455 (call-with-values thunk
1459 (pass-if-exception "() -1" exception:out-of-range
1461 (pass-if (equal-values? '(() ())
1462 (lambda () (split-at '() 0))))
1463 (pass-if-exception "() 1" exception:wrong-type-arg
1466 (pass-if-exception "(1) -1" exception:out-of-range
1468 (pass-if (equal-values? '(() (1)) (lambda () (split-at '(1) 0))))
1469 (pass-if (equal-values? '((1) ()) (lambda () (split-at '(1) 1))))
1470 (pass-if-exception "(1) 2" exception:wrong-type-arg
1473 (pass-if-exception "(4 5) -1" exception:out-of-range
1474 (split-at '(4 5) -1))
1475 (pass-if (equal-values? '(() (4 5)) (lambda () (split-at '(4 5) 0))))
1476 (pass-if (equal-values? '((4) (5)) (lambda () (split-at '(4 5) 1))))
1477 (pass-if (equal-values? '((4 5) ()) (lambda () (split-at '(4 5) 2))))
1478 (pass-if-exception "(4 5) 3" exception:wrong-type-arg
1479 (split-at '(4 5) 3))
1481 (pass-if-exception "(4 5 6) -1" exception:out-of-range
1482 (split-at '(4 5 6) -1))
1483 (pass-if (equal-values? '(() (4 5 6)) (lambda () (split-at '(4 5 6) 0))))
1484 (pass-if (equal-values? '((4) (5 6)) (lambda () (split-at '(4 5 6) 1))))
1485 (pass-if (equal-values? '((4 5) (6)) (lambda () (split-at '(4 5 6) 2))))
1486 (pass-if (equal-values? '((4 5 6) ()) (lambda () (split-at '(4 5 6) 3))))
1487 (pass-if-exception "(4 5 6) 4" exception:wrong-type-arg
1488 (split-at '(4 5 6) 4)))
1494 (with-test-prefix "split-at!"
1496 (define (equal-values? lst thunk)
1497 (call-with-values thunk
1501 (pass-if-exception "() -1" exception:out-of-range
1503 (pass-if (equal-values? '(() ())
1504 (lambda () (split-at! '() 0))))
1505 (pass-if-exception "() 1" exception:wrong-type-arg
1508 (pass-if-exception "(1) -1" exception:out-of-range
1509 (split-at! (list 1) -1))
1510 (pass-if (equal-values? '(() (1)) (lambda () (split-at! (list 1) 0))))
1511 (pass-if (equal-values? '((1) ()) (lambda () (split-at! (list 1) 1))))
1512 (pass-if-exception "(1) 2" exception:wrong-type-arg
1513 (split-at! (list 1) 2))
1515 (pass-if-exception "(4 5) -1" exception:out-of-range
1516 (split-at! (list 4 5) -1))
1517 (pass-if (equal-values? '(() (4 5)) (lambda () (split-at! (list 4 5) 0))))
1518 (pass-if (equal-values? '((4) (5)) (lambda () (split-at! (list 4 5) 1))))
1519 (pass-if (equal-values? '((4 5) ()) (lambda () (split-at! (list 4 5) 2))))
1520 (pass-if-exception "(4 5) 3" exception:wrong-type-arg
1521 (split-at! (list 4 5) 3))
1523 (pass-if-exception "(4 5 6) -1" exception:out-of-range
1524 (split-at! (list 4 5 6) -1))
1525 (pass-if (equal-values? '(() (4 5 6)) (lambda () (split-at! (list 4 5 6) 0))))
1526 (pass-if (equal-values? '((4) (5 6)) (lambda () (split-at! (list 4 5 6) 1))))
1527 (pass-if (equal-values? '((4 5) (6)) (lambda () (split-at! (list 4 5 6) 2))))
1528 (pass-if (equal-values? '((4 5 6) ()) (lambda () (split-at! (list 4 5 6) 3))))
1529 (pass-if-exception "(4 5 6) 4" exception:wrong-type-arg
1530 (split-at! (list 4 5 6) 4)))
1536 (with-test-prefix "span"
1538 (define (test-span lst want-v1 want-v2)
1541 (span positive? lst))
1542 (lambda (got-v1 got-v2)
1543 (and (equal? got-v1 want-v1)
1544 (equal? got-v2 want-v2)))))
1547 (test-span '() '() '()))
1550 (test-span '(1) '(1) '()))
1553 (test-span '(-1) '() '(-1)))
1556 (test-span '(1 2) '(1 2) '()))
1559 (test-span '(-1 1) '() '(-1 1)))
1562 (test-span '(1 -1) '(1) '(-1)))
1565 (test-span '(-1 -2) '() '(-1 -2)))
1568 (test-span '(1 2 3) '(1 2 3) '()))
1571 (test-span '(-1 1 2) '() '(-1 1 2)))
1574 (test-span '(1 -1 2) '(1) '(-1 2)))
1577 (test-span '(-1 -2 1) '() '(-1 -2 1)))
1580 (test-span '(1 2 -1) '(1 2) '(-1)))
1583 (test-span '(-1 1 -2) '() '(-1 1 -2)))
1586 (test-span '(1 -1 -2) '(1) '(-1 -2)))
1589 (test-span '(-1 -2 -3) '() '(-1 -2 -3))))
1595 (with-test-prefix "take-right"
1597 (pass-if-exception "() -1" exception:out-of-range
1598 (take-right '() -1))
1599 (pass-if (equal? '() (take-right '() 0)))
1600 (pass-if-exception "() 1" exception:wrong-type-arg
1603 (pass-if-exception "(1) -1" exception:out-of-range
1604 (take-right '(1) -1))
1605 (pass-if (equal? '() (take-right '(1) 0)))
1606 (pass-if (equal? '(1) (take-right '(1) 1)))
1607 (pass-if-exception "(1) 2" exception:wrong-type-arg
1608 (take-right '(1) 2))
1610 (pass-if-exception "(4 5) -1" exception:out-of-range
1611 (take-right '(4 5) -1))
1612 (pass-if (equal? '() (take-right '(4 5) 0)))
1613 (pass-if (equal? '(5) (take-right '(4 5) 1)))
1614 (pass-if (equal? '(4 5) (take-right '(4 5) 2)))
1615 (pass-if-exception "(4 5) 3" exception:wrong-type-arg
1616 (take-right '(4 5) 3))
1618 (pass-if-exception "(4 5 6) -1" exception:out-of-range
1619 (take-right '(4 5 6) -1))
1620 (pass-if (equal? '() (take-right '(4 5 6) 0)))
1621 (pass-if (equal? '(6) (take-right '(4 5 6) 1)))
1622 (pass-if (equal? '(5 6) (take-right '(4 5 6) 2)))
1623 (pass-if (equal? '(4 5 6) (take-right '(4 5 6) 3)))
1624 (pass-if-exception "(4 5 6) 4" exception:wrong-type-arg
1625 (take-right '(4 5 6) 4)))