mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-17 17:20:29 +02:00
597 lines
18 KiB
Scheme
597 lines
18 KiB
Scheme
;;;; srfi-1.test --- Test suite for Guile's SRFI-1 functions. -*- scheme -*-
|
|
;;;;
|
|
;;;; Copyright 2003, 2004 Free Software Foundation, Inc.
|
|
;;;;
|
|
;;;; This program is free software; you can redistribute it and/or modify
|
|
;;;; it under the terms of the GNU General Public License as published by
|
|
;;;; the Free Software Foundation; either version 2, or (at your option)
|
|
;;;; any later version.
|
|
;;;;
|
|
;;;; This program is distributed in the hope that it will be useful,
|
|
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
;;;; GNU General Public License for more details.
|
|
;;;;
|
|
;;;; You should have received a copy of the GNU General Public License
|
|
;;;; along with this software; see the file COPYING. If not, write to
|
|
;;;; the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
|
;;;; Boston, MA 02111-1307 USA
|
|
;;;;
|
|
;;;; As a special exception, the Free Software Foundation gives permission
|
|
;;;; for additional uses of the text contained in its release of GUILE.
|
|
;;;;
|
|
;;;; The exception is that, if you link the GUILE library with other files
|
|
;;;; to produce an executable, this does not by itself cause the
|
|
;;;; resulting executable to be covered by the GNU General Public License.
|
|
;;;; Your use of that executable is in no way restricted on account of
|
|
;;;; linking the GUILE library code into it.
|
|
;;;;
|
|
;;;; This exception does not however invalidate any other reasons why
|
|
;;;; the executable file might be covered by the GNU General Public License.
|
|
;;;;
|
|
;;;; This exception applies only to the code released by the
|
|
;;;; Free Software Foundation under the name GUILE. If you copy
|
|
;;;; code from other Free Software Foundation releases into a copy of
|
|
;;;; GUILE, as the General Public License permits, the exception does
|
|
;;;; not apply to the code that you add in this way. To avoid misleading
|
|
;;;; anyone as to the status of such modified files, you must delete
|
|
;;;; this exception notice from them.
|
|
;;;;
|
|
;;;; If you write modifications of your own for GUILE, it is your choice
|
|
;;;; whether to permit this exception to apply to your modifications.
|
|
;;;; If you do not wish that, delete this exception notice.
|
|
|
|
(use-modules (srfi srfi-1)
|
|
(test-suite lib))
|
|
|
|
(define (ref-delete x lst . proc)
|
|
"Reference implemenation of srfi-1 `delete'."
|
|
(set! proc (if (null? proc) equal? (car proc)))
|
|
(do ((ret '())
|
|
(lst lst (cdr lst)))
|
|
((null? lst)
|
|
(reverse! ret))
|
|
(if (not (proc x (car lst)))
|
|
(set! ret (cons (car lst) ret)))))
|
|
|
|
;;
|
|
;; alist-copy
|
|
;;
|
|
|
|
(with-test-prefix "alist-copy"
|
|
|
|
;; return a list which is the pairs making up alist A, the spine and cells
|
|
(define (alist-pairs a)
|
|
(let more ((a a)
|
|
(result a))
|
|
(if (pair? a)
|
|
(more (cdr a) (cons a result))
|
|
result)))
|
|
|
|
;; return a list of the elements common to lists X and Y, compared with eq?
|
|
(define (common-elements x y)
|
|
(if (null? x)
|
|
'()
|
|
(if (memq (car x) y)
|
|
(cons (car x) (common-elements (cdr x) y))
|
|
(common-elements (cdr x) y))))
|
|
|
|
;; validate an alist-copy of OLD to NEW
|
|
;; lists must be equal, and must comprise new pairs
|
|
(define (valid-alist-copy? old new)
|
|
(and (equal? old new)
|
|
(null? (common-elements old new))))
|
|
|
|
(pass-if-exception "too few args" exception:wrong-num-args
|
|
(alist-copy))
|
|
|
|
(pass-if-exception "too many args" exception:wrong-num-args
|
|
(alist-copy '() '()))
|
|
|
|
(let ((old '()))
|
|
(pass-if old (valid-alist-copy? old (alist-copy old))))
|
|
|
|
(let ((old '((1 . 2))))
|
|
(pass-if old (valid-alist-copy? old (alist-copy old))))
|
|
|
|
(let ((old '((1 . 2) (3 . 4))))
|
|
(pass-if old (valid-alist-copy? old (alist-copy old))))
|
|
|
|
(let ((old '((1 . 2) (3 . 4) (5 . 6))))
|
|
(pass-if old (valid-alist-copy? old (alist-copy old)))))
|
|
|
|
;;
|
|
;; append-map
|
|
;;
|
|
|
|
(with-test-prefix "append-map"
|
|
|
|
(with-test-prefix "one list"
|
|
|
|
(pass-if "()"
|
|
(equal? '() (append-map noop '(()))))
|
|
|
|
(pass-if "(1)"
|
|
(equal? '(1) (append-map noop '((1)))))
|
|
|
|
(pass-if "(1 2)"
|
|
(equal? '(1 2) (append-map noop '((1 2)))))
|
|
|
|
(pass-if "() ()"
|
|
(equal? '() (append-map noop '(() ()))))
|
|
|
|
(pass-if "() (1)"
|
|
(equal? '(1) (append-map noop '(() (1)))))
|
|
|
|
(pass-if "() (1 2)"
|
|
(equal? '(1 2) (append-map noop '(() (1 2)))))
|
|
|
|
(pass-if "(1) (2)"
|
|
(equal? '(1 2) (append-map noop '((1) (2)))))
|
|
|
|
(pass-if "(1 2) ()"
|
|
(equal? '(1 2) (append-map noop '(() (1 2))))))
|
|
|
|
(with-test-prefix "two lists"
|
|
|
|
(pass-if "() / 9"
|
|
(equal? '() (append-map noop '(()) '(9))))
|
|
|
|
(pass-if "(1) / 9"
|
|
(equal? '(1) (append-map noop '((1)) '(9))))
|
|
|
|
(pass-if "() () / 9 9"
|
|
(equal? '() (append-map noop '(() ()) '(9 9))))
|
|
|
|
(pass-if "(1) (2) / 9"
|
|
(equal? '(1) (append-map noop '((1) (2)) '(9))))
|
|
|
|
(pass-if "(1) (2) / 9 9"
|
|
(equal? '(1 2) (append-map noop '((1) (2)) '(9 9))))))
|
|
|
|
;;
|
|
;; count
|
|
;;
|
|
|
|
(with-test-prefix "count"
|
|
(pass-if-exception "no args" exception:wrong-num-args
|
|
(count))
|
|
|
|
(pass-if-exception "one arg" exception:wrong-num-args
|
|
(count noop))
|
|
|
|
(with-test-prefix "one list"
|
|
(define (or1 x)
|
|
x)
|
|
|
|
(pass-if "empty list" (= 0 (count or1 '())))
|
|
|
|
(pass-if-exception "pred arg count 0" exception:wrong-num-args
|
|
(count (lambda () x) '(1 2 3)))
|
|
(pass-if-exception "pred arg count 2" exception:wrong-num-args
|
|
(count (lambda (x y) x) '(1 2 3)))
|
|
|
|
(pass-if-exception "improper 1" exception:wrong-type-arg
|
|
(count or1 1))
|
|
(pass-if-exception "improper 2" exception:wrong-type-arg
|
|
(count or1 '(1 . 2)))
|
|
(pass-if-exception "improper 3" exception:wrong-type-arg
|
|
(count or1 '(1 2 . 3)))
|
|
|
|
(pass-if "" (= 0 (count or1 '(#f))))
|
|
(pass-if "" (= 1 (count or1 '(#t))))
|
|
|
|
(pass-if "" (= 0 (count or1 '(#f #f))))
|
|
(pass-if "" (= 1 (count or1 '(#f #t))))
|
|
(pass-if "" (= 1 (count or1 '(#t #f))))
|
|
(pass-if "" (= 2 (count or1 '(#t #t))))
|
|
|
|
(pass-if "" (= 0 (count or1 '(#f #f #f))))
|
|
(pass-if "" (= 1 (count or1 '(#f #f #t))))
|
|
(pass-if "" (= 1 (count or1 '(#t #f #f))))
|
|
(pass-if "" (= 2 (count or1 '(#t #f #t))))
|
|
(pass-if "" (= 3 (count or1 '(#t #t #t)))))
|
|
|
|
(with-test-prefix "two lists"
|
|
(define (or2 x y)
|
|
(or x y))
|
|
|
|
(pass-if "arg order"
|
|
(= 1 (count (lambda (x y)
|
|
(and (= 1 x)
|
|
(= 2 y)))
|
|
'(1) '(2))))
|
|
|
|
(pass-if "empty lists" (= 0 (count or2 '() '())))
|
|
|
|
(pass-if-exception "pred arg count 0" exception:wrong-num-args
|
|
(count (lambda () #t) '(1 2 3) '(1 2 3)))
|
|
(pass-if-exception "pred arg count 1" exception:wrong-num-args
|
|
(count (lambda (x) x) '(1 2 3) '(1 2 3)))
|
|
(pass-if-exception "pred arg count 3" exception:wrong-num-args
|
|
(count (lambda (x y z) x) '(1 2 3) '(1 2 3)))
|
|
|
|
(pass-if-exception "improper first 1" exception:wrong-type-arg
|
|
(count or2 1 '(1 2 3)))
|
|
(pass-if-exception "improper first 2" exception:wrong-type-arg
|
|
(count or2 '(1 . 2) '(1 2 3)))
|
|
(pass-if-exception "improper first 3" exception:wrong-type-arg
|
|
(count or2 '(1 2 . 3) '(1 2 3)))
|
|
|
|
(pass-if-exception "improper second 1" exception:wrong-type-arg
|
|
(count or2 '(1 2 3) 1))
|
|
(pass-if-exception "improper second 2" exception:wrong-type-arg
|
|
(count or2 '(1 2 3) '(1 . 2)))
|
|
(pass-if-exception "improper second 3" exception:wrong-type-arg
|
|
(count or2 '(1 2 3) '(1 2 . 3)))
|
|
|
|
(pass-if "" (= 0 (count or2 '(#f) '(#f))))
|
|
(pass-if "" (= 1 (count or2 '(#t) '(#f))))
|
|
(pass-if "" (= 1 (count or2 '(#f) '(#t))))
|
|
|
|
(pass-if "" (= 0 (count or2 '(#f #f) '(#f #f))))
|
|
(pass-if "" (= 1 (count or2 '(#t #f) '(#t #f))))
|
|
(pass-if "" (= 2 (count or2 '(#t #t) '(#f #f))))
|
|
(pass-if "" (= 2 (count or2 '(#t #f) '(#f #t))))
|
|
|
|
(with-test-prefix "stop shortest"
|
|
(pass-if "" (= 2 (count or2 '(#t #f #t) '(#f #t))))
|
|
(pass-if "" (= 2 (count or2 '(#t #f #t #t) '(#f #t))))
|
|
(pass-if "" (= 2 (count or2 '(#t #f) '(#f #t #t))))
|
|
(pass-if "" (= 2 (count or2 '(#t #f) '(#f #t #t #t))))))
|
|
|
|
(with-test-prefix "three lists"
|
|
(define (or3 x y z)
|
|
(or x y z))
|
|
|
|
(pass-if "arg order"
|
|
(= 1 (count (lambda (x y z)
|
|
(and (= 1 x)
|
|
(= 2 y)
|
|
(= 3 z)))
|
|
'(1) '(2) '(3))))
|
|
|
|
(pass-if "empty lists" (= 0 (count or3 '() '() '())))
|
|
|
|
;; currently bad pred argument gives wrong-num-args when 3 or more
|
|
;; lists, as opposed to wrong-type-arg for 1 or 2 lists
|
|
(pass-if-exception "pred arg count 0" exception:wrong-num-args
|
|
(count (lambda () #t) '(1 2 3) '(1 2 3) '(1 2 3)))
|
|
(pass-if-exception "pred arg count 2" exception:wrong-num-args
|
|
(count (lambda (x y) x) '(1 2 3) '(1 2 3)'(1 2 3) ))
|
|
(pass-if-exception "pred arg count 4" exception:wrong-num-args
|
|
(count (lambda (w x y z) x) '(1 2 3) '(1 2 3) '(1 2 3)))
|
|
|
|
(pass-if-exception "improper first 1" exception:wrong-type-arg
|
|
(count or3 1 '(1 2 3) '(1 2 3)))
|
|
(pass-if-exception "improper first 2" exception:wrong-type-arg
|
|
(count or3 '(1 . 2) '(1 2 3) '(1 2 3)))
|
|
(pass-if-exception "improper first 3" exception:wrong-type-arg
|
|
(count or3 '(1 2 . 3) '(1 2 3) '(1 2 3)))
|
|
|
|
(pass-if-exception "improper second 1" exception:wrong-type-arg
|
|
(count or3 '(1 2 3) 1 '(1 2 3)))
|
|
(pass-if-exception "improper second 2" exception:wrong-type-arg
|
|
(count or3 '(1 2 3) '(1 . 2) '(1 2 3)))
|
|
(pass-if-exception "improper second 3" exception:wrong-type-arg
|
|
(count or3 '(1 2 3) '(1 2 . 3) '(1 2 3)))
|
|
|
|
(pass-if-exception "improper third 1" exception:wrong-type-arg
|
|
(count or3 '(1 2 3) '(1 2 3) 1))
|
|
(pass-if-exception "improper third 2" exception:wrong-type-arg
|
|
(count or3 '(1 2 3) '(1 2 3) '(1 . 2)))
|
|
(pass-if-exception "improper third 3" exception:wrong-type-arg
|
|
(count or3 '(1 2 3) '(1 2 3) '(1 2 . 3)))
|
|
|
|
(pass-if "" (= 0 (count or3 '(#f) '(#f) '(#f))))
|
|
(pass-if "" (= 1 (count or3 '(#t) '(#f) '(#f))))
|
|
(pass-if "" (= 1 (count or3 '(#f) '(#t) '(#f))))
|
|
(pass-if "" (= 1 (count or3 '(#f) '(#f) '(#t))))
|
|
|
|
(pass-if "" (= 0 (count or3 '(#f #f) '(#f #f) '(#f #f))))
|
|
|
|
(pass-if "" (= 1 (count or3 '(#t #f) '(#f #f) '(#f #f))))
|
|
(pass-if "" (= 1 (count or3 '(#f #t) '(#f #f) '(#f #f))))
|
|
(pass-if "" (= 1 (count or3 '(#f #f) '(#t #f) '(#f #f))))
|
|
(pass-if "" (= 1 (count or3 '(#f #f) '(#f #t) '(#f #f))))
|
|
(pass-if "" (= 1 (count or3 '(#f #f) '(#f #f) '(#t #f))))
|
|
(pass-if "" (= 1 (count or3 '(#f #f) '(#f #f) '(#f #t))))
|
|
|
|
(pass-if "" (= 2 (count or3 '(#t #t) '(#f #f) '(#f #f))))
|
|
(pass-if "" (= 2 (count or3 '(#f #f) '(#t #t) '(#f #f))))
|
|
(pass-if "" (= 2 (count or3 '(#f #f) '(#f #f) '(#t #t))))
|
|
(pass-if "" (= 2 (count or3 '(#f #f) '(#t #f) '(#f #t))))
|
|
|
|
(with-test-prefix "stop shortest"
|
|
(pass-if "" (= 0 (count or3 '() '(#t #t #t) '(#t #t))))
|
|
(pass-if "" (= 0 (count or3 '(#t #t #t) '() '(#t #t))))
|
|
(pass-if "" (= 0 (count or3 '(#t #t #t) '(#t #t) '())))
|
|
|
|
(pass-if "" (= 1 (count or3 '(#t) '(#t #t #t) '(#t #t))))
|
|
(pass-if "" (= 1 (count or3 '(#t #t #t) '(#t) '(#t #t))))
|
|
(pass-if "" (= 1 (count or3 '(#t #t #t) '(#t #t) '(#t)))))))
|
|
|
|
;;
|
|
;; delete and delete!
|
|
;;
|
|
|
|
(let ()
|
|
;; Call (PROC lst) for all lists of length up to 6, with all combinations
|
|
;; of elements to be retained or deleted. Elements to retain are numbers,
|
|
;; 0 upwards. Elements to be deleted are #f.
|
|
(define (test-lists proc)
|
|
(do ((n 0 (1+ n)))
|
|
((>= n 6))
|
|
(do ((limit (ash 1 n))
|
|
(i 0 (1+ i)))
|
|
((>= i limit))
|
|
(let ((lst '()))
|
|
(do ((bit 0 (1+ bit)))
|
|
((>= bit n))
|
|
(set! lst (cons (if (logbit? bit i) bit #f) lst)))
|
|
(proc lst)))))
|
|
|
|
(define (common-tests delete-proc)
|
|
(pass-if-exception "too few args" exception:wrong-num-args
|
|
(delete-proc 0))
|
|
|
|
(pass-if "empty"
|
|
(eq? '() (delete-proc 0 '())))
|
|
|
|
(pass-if "equal? (the default)"
|
|
(equal? '((1) (3))
|
|
(delete-proc '(2) '((1) (2) (3)))))
|
|
|
|
(pass-if "eq?"
|
|
(equal? '((1) (2) (3))
|
|
(delete-proc '(2) '((1) (2) (3)) eq?)))
|
|
|
|
(pass-if "called arg order"
|
|
(equal? '(1 2 3)
|
|
(delete-proc 3 '(1 2 3 4 5) <))))
|
|
|
|
(with-test-prefix "delete"
|
|
(common-tests delete)
|
|
|
|
(test-lists
|
|
(lambda (lst)
|
|
(let ((lst-copy (list-copy lst)))
|
|
(with-test-prefix lst-copy
|
|
(pass-if "result"
|
|
(equal? (delete #f lst)
|
|
(ref-delete #f lst)))
|
|
(pass-if "non-destructive"
|
|
(equal? lst-copy lst)))))))
|
|
|
|
(with-test-prefix "delete!"
|
|
(common-tests delete!)
|
|
|
|
(test-lists
|
|
(lambda (lst)
|
|
(pass-if lst
|
|
(equal? (delete! #f lst)
|
|
(ref-delete #f lst)))))))
|
|
|
|
;;
|
|
;; filter-map
|
|
;;
|
|
|
|
(with-test-prefix "filter-map"
|
|
|
|
(with-test-prefix "one list"
|
|
(pass-if "(1)"
|
|
(equal? '(1) (filter-map noop '(1))))
|
|
|
|
(pass-if "(#f)"
|
|
(equal? '() (filter-map noop '(#f))))
|
|
|
|
(pass-if "(1 2)"
|
|
(equal? '(1 2) (filter-map noop '(1 2))))
|
|
|
|
(pass-if "(#f 2)"
|
|
(equal? '(2) (filter-map noop '(#f 2))))
|
|
|
|
(pass-if "(#f #f)"
|
|
(equal? '() (filter-map noop '(#f #f))))
|
|
|
|
(pass-if "(1 2 3)"
|
|
(equal? '(1 2 3) (filter-map noop '(1 2 3))))
|
|
|
|
(pass-if "(#f 2 3)"
|
|
(equal? '(2 3) (filter-map noop '(#f 2 3))))
|
|
|
|
(pass-if "(1 #f 3)"
|
|
(equal? '(1 3) (filter-map noop '(1 #f 3))))
|
|
|
|
(pass-if "(1 2 #f)"
|
|
(equal? '(1 2) (filter-map noop '(1 2 #f)))))
|
|
|
|
(with-test-prefix "two lists"
|
|
(pass-if "(1 2 3) (4 5 6)"
|
|
(equal? '(1 2 3) (filter-map noop '(1 2 3) '(4 5 6))))
|
|
|
|
(pass-if "(#f 2 3) (4 5)"
|
|
(equal? '(2) (filter-map noop '(#f 2 3) '(4 5))))
|
|
|
|
(pass-if "(4 #f) (1 2 3)"
|
|
(equal? '(4) (filter-map noop '(4 #f) '(1 2 3))))))
|
|
|
|
;;
|
|
;; list-copy
|
|
;;
|
|
|
|
(with-test-prefix "list-copy"
|
|
|
|
;; improper lists can be copied
|
|
(pass-if "empty" (equal? '() (list-copy '())))
|
|
(pass-if "one" (equal? '(1) (list-copy '(1))))
|
|
(pass-if "two" (equal? '(1 2) (list-copy '(1 2))))
|
|
(pass-if "three" (equal? '(1 2 3) (list-copy '(1 2 3))))
|
|
(pass-if "four" (equal? '(1 2 3 4) (list-copy '(1 2 3 4))))
|
|
(pass-if "five" (equal? '(1 2 3 4 5) (list-copy '(1 2 3 4 5))))
|
|
|
|
;; improper lists can be copied
|
|
(pass-if "one improper" (equal? 1 (list-copy 1)))
|
|
(pass-if "two improper" (equal? '(1 . 2) (list-copy '(1 . 2))))
|
|
(pass-if "three improper" (equal? '(1 2 . 3) (list-copy '(1 2 . 3))))
|
|
(pass-if "four improper" (equal? '(1 2 3 . 4) (list-copy '(1 2 3 . 4))))
|
|
(pass-if "five improper" (equal? '(1 2 3 4 . 5) (list-copy '(1 2 3 4 . 5)))))
|
|
|
|
;;
|
|
;; map
|
|
;;
|
|
|
|
(with-test-prefix "map"
|
|
|
|
(with-test-prefix "two lists"
|
|
|
|
(pass-if "empty / empty"
|
|
(equal? '() (map + '() '())))
|
|
|
|
(pass-if "empty / (1)"
|
|
(equal? '() (map + '() '(1))))
|
|
|
|
(pass-if "empty / (1 2)"
|
|
(equal? '() (map + '() '(1 2))))
|
|
|
|
(pass-if "(1) / empty"
|
|
(equal? '() (map + '(1) '())))
|
|
|
|
(pass-if "(1) / (2)"
|
|
(equal? '(3) (map + '(1) '(2))))
|
|
|
|
(pass-if "(1) / (2 3)"
|
|
(equal? '(3) (map + '(1) '(2 3))))
|
|
|
|
(pass-if "(1 2) / empty"
|
|
(equal? '() (map + '(1 2) '())))
|
|
|
|
(pass-if "(1 2) / (3)"
|
|
(equal? '(4) (map + '(1 2) '(3))))
|
|
|
|
(pass-if "(1 2) / (3 4)"
|
|
(equal? '(4 6) (map + '(1 2) '(3 4)))))
|
|
|
|
(with-test-prefix "three lists"
|
|
|
|
(pass-if "empty / empty / empty"
|
|
(equal? '() (map + '() '() '())))
|
|
|
|
(pass-if "(1) / (2) / ()"
|
|
(equal? '() (map + '(1) '(2) '())))
|
|
|
|
(pass-if "(1) / (2) / (3)"
|
|
(equal? '(6) (map + '(1) '(2) '(3))))
|
|
|
|
(pass-if "(1 2) / (3 4) / (5 6)"
|
|
(equal? '(9 12) (map + '(1 2) '(3 4) '(5 6))))))
|
|
|
|
;;
|
|
;; map!
|
|
;;
|
|
|
|
(with-test-prefix "map!"
|
|
|
|
(pass-if-exception "no args" exception:wrong-num-args
|
|
(map!))
|
|
|
|
(pass-if-exception "no lists" exception:wrong-num-args
|
|
(map! 1+))
|
|
|
|
(with-test-prefix "one list"
|
|
|
|
(pass-if "empty"
|
|
(equal? '() (map! 1+ (list))))
|
|
|
|
(pass-if "(1)"
|
|
(equal? '(2) (map! 1+ (list 1))))
|
|
|
|
(pass-if "(1 2)"
|
|
(equal? '(2 3) (map! 1+ (list 1 2)))))
|
|
|
|
(with-test-prefix "two lists"
|
|
|
|
(pass-if "empty / empty"
|
|
(equal? '() (map! + (list) (list))))
|
|
|
|
(pass-if "empty / (1)"
|
|
(equal? '() (map! + (list) (list 1))))
|
|
|
|
(pass-if "empty / (1 2)"
|
|
(equal? '() (map! + (list) (list 1 2))))
|
|
|
|
(pass-if "(1) / empty"
|
|
(equal? '() (map! + (list 1) (list))))
|
|
|
|
(pass-if "(1) / (2)"
|
|
(equal? '(3) (map! + (list 1) (list 2))))
|
|
|
|
(pass-if "(1) / (2 3)"
|
|
(equal? '(3) (map! + (list 1) (list 2 3))))
|
|
|
|
(pass-if "(1 2) / empty"
|
|
(equal? '() (map! + (list 1 2) (list))))
|
|
|
|
(pass-if "(1 2) / (3)"
|
|
(equal? '(4) (map! + (list 1 2) (list 3))))
|
|
|
|
(pass-if "(1 2) / (3 4)"
|
|
(equal? '(4 6) (map! + (list 1 2) (list 3 4)))))
|
|
|
|
(with-test-prefix "three lists"
|
|
|
|
(pass-if "empty / empty / empty"
|
|
(equal? '() (map! + (list) (list) (list))))
|
|
|
|
(pass-if "(1) / (2) / ()"
|
|
(equal? '() (map! + (list 1) (list 2) (list))))
|
|
|
|
(pass-if "(1) / (2) / (3)"
|
|
(equal? '(6) (map! + (list 1) (list 2) (list 3))))
|
|
|
|
(pass-if "(1 2) / (3 4) / (5 6)"
|
|
(equal? '(9 12) (map! + (list 1 2) (list 3 4) (list 5 6))))))
|
|
|
|
;;
|
|
;; partition
|
|
;;
|
|
|
|
(define (test-partition pred list kept-good dropped-good)
|
|
(call-with-values (lambda ()
|
|
(partition pred list))
|
|
(lambda (kept dropped)
|
|
(and (equal? kept kept-good)
|
|
(equal? dropped dropped-good)))))
|
|
|
|
(with-test-prefix "partition"
|
|
|
|
(pass-if "with dropped tail"
|
|
(test-partition even? '(1 2 3 4 5 6 7)
|
|
'(2 4 6) '(1 3 5 7)))
|
|
|
|
(pass-if "with kept tail"
|
|
(test-partition even? '(1 2 3 4 5 6)
|
|
'(2 4 6) '(1 3 5)))
|
|
|
|
(pass-if "with everything dropped"
|
|
(test-partition even? '(1 3 5 7)
|
|
'() '(1 3 5 7)))
|
|
|
|
(pass-if "with everything kept"
|
|
(test-partition even? '(2 4 6)
|
|
'(2 4 6) '()))
|
|
|
|
(pass-if "with empty list"
|
|
(test-partition even? '()
|
|
'() '()))
|
|
|
|
(pass-if "with reasonably long list"
|
|
;; the old implementation from SRFI-1 reference implementation
|
|
;; would signal a stack-overflow for a list of only 500 elements!
|
|
(call-with-values (lambda ()
|
|
(partition even?
|
|
(make-list 10000 1)))
|
|
(lambda (even odd)
|
|
(and (= (length odd) 10000)
|
|
(= (length even) 0))))))
|
|
|