;;;; srfi-1.test --- Test suite for Guile's SRFI-1 functions. -*- scheme -*-
;;;;
-;;;; Copyright 2003, 2004, 2005 Free Software Foundation, Inc.
+;;;; Copyright 2003, 2004, 2005, 2006 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
;;;;
;;;; 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
+;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;;;; Boston, MA 02110-1301 USA
+
+(define-module (test-srfi-1)
+ #:use-module (test-suite lib)
+ #:use-module (srfi srfi-1))
-(use-modules (srfi srfi-1)
- (test-suite lib))
(define (ref-delete x lst . proc)
"Reference implemenation of srfi-1 `delete'."
(pass-if "(1) (2) / 9 9"
(equal? '(1 2) (append-map noop '((1) (2)) '(9 9))))))
-
+
+;;
+;; append-reverse
+;;
+
+(with-test-prefix "append-reverse"
+
+ ;; return a list which is the cars and cdrs of LST
+ (define (list-contents lst)
+ (if (null? lst)
+ '()
+ (cons* (car lst) (cdr lst) (list-contents (cdr lst)))))
+
+ (define (valid-append-reverse revhead tail want)
+ (let ((revhead-contents (list-contents revhead))
+ (got (append-reverse revhead tail)))
+ (and (equal? got want)
+ ;; revhead unchanged
+ (equal? revhead-contents (list-contents revhead)))))
+
+ (pass-if-exception "too few args (0)" exception:wrong-num-args
+ (append-reverse))
+
+ (pass-if-exception "too few args (1)" exception:wrong-num-args
+ (append-reverse '(x)))
+
+ (pass-if-exception "too many args (3)" exception:wrong-num-args
+ (append-reverse '() '() #f))
+
+ (pass-if (valid-append-reverse '() '() '()))
+ (pass-if (valid-append-reverse '() '(1 2 3) '(1 2 3)))
+
+ (pass-if (valid-append-reverse '(1) '() '(1)))
+ (pass-if (valid-append-reverse '(1) '(2) '(1 2)))
+ (pass-if (valid-append-reverse '(1) '(2 3) '(1 2 3)))
+
+ (pass-if (valid-append-reverse '(1 2) '() '(2 1)))
+ (pass-if (valid-append-reverse '(1 2) '(3) '(2 1 3)))
+ (pass-if (valid-append-reverse '(1 2) '(3 4) '(2 1 3 4)))
+
+ (pass-if (valid-append-reverse '(1 2 3) '() '(3 2 1)))
+ (pass-if (valid-append-reverse '(1 2 3) '(4) '(3 2 1 4)))
+ (pass-if (valid-append-reverse '(1 2 3) '(4 5) '(3 2 1 4 5))))
+
+;;
+;; append-reverse!
+;;
+
+(with-test-prefix "append-reverse!"
+
+ (pass-if-exception "too few args (0)" exception:wrong-num-args
+ (append-reverse!))
+
+ (pass-if-exception "too few args (1)" exception:wrong-num-args
+ (append-reverse! '(x)))
+
+ (pass-if-exception "too many args (3)" exception:wrong-num-args
+ (append-reverse! '() '() #f))
+
+ (pass-if (equal? '() (append-reverse! '() '())))
+ (pass-if (equal? '(1 2 3) (append-reverse! '() '(1 2 3))))
+
+ (pass-if (equal? '(1) (append-reverse! '(1) '())))
+ (pass-if (equal? '(1 2) (append-reverse! '(1) '(2))))
+ (pass-if (equal? '(1 2 3) (append-reverse! '(1) '(2 3))))
+
+ (pass-if (equal? '(2 1) (append-reverse! '(1 2) '())))
+ (pass-if (equal? '(2 1 3) (append-reverse! '(1 2) '(3))))
+ (pass-if (equal? '(2 1 3 4) (append-reverse! '(1 2) '(3 4))))
+
+ (pass-if (equal? '(3 2 1) (append-reverse! '(1 2 3) '())))
+ (pass-if (equal? '(3 2 1 4) (append-reverse! '(1 2 3) '(4))))
+ (pass-if (equal? '(3 2 1 4 5) (append-reverse! '(1 2 3) '(4 5)))))
+
+;;
+;; assoc
+;;
+
+(with-test-prefix "assoc"
+
+ (pass-if "not found"
+ (let ((alist '((a . 1)
+ (b . 2)
+ (c . 3))))
+ (eqv? #f (assoc 'z alist))))
+
+ (pass-if "found"
+ (let ((alist '((a . 1)
+ (b . 2)
+ (c . 3))))
+ (eqv? (second alist) (assoc 'b alist))))
+
+ ;; this was wrong in guile 1.8.0 (a gremlin newly introduced in the 1.8
+ ;; series, 1.6.x and earlier was ok)
+ (pass-if "= arg order"
+ (let ((alist '((b . 1)))
+ (good #f))
+ (assoc 'a alist (lambda (x y)
+ (set! good (and (eq? x 'a)
+ (eq? y 'b)))))
+ good))
+
+ ;; likewise this one bad in guile 1.8.0
+ (pass-if "srfi-1 example <"
+ (let ((alist '((1 . a)
+ (5 . b)
+ (6 . c))))
+ (eq? (third alist) (assoc 5 alist <)))))
+
;;
;; break
;;
(pass-if "nnn"
(test-break '(-1 -2 -3) '() '(-1 -2 -3))))
+;;
+;; break!
+;;
+
+(with-test-prefix "break!"
+
+ (define (test-break! lst want-v1 want-v2)
+ (call-with-values
+ (lambda ()
+ (break! negative? lst))
+ (lambda (got-v1 got-v2)
+ (and (equal? got-v1 want-v1)
+ (equal? got-v2 want-v2)))))
+
+ (pass-if "empty"
+ (test-break! '() '() '()))
+
+ (pass-if "y"
+ (test-break! (list 1) '(1) '()))
+
+ (pass-if "n"
+ (test-break! (list -1) '() '(-1)))
+
+ (pass-if "yy"
+ (test-break! (list 1 2) '(1 2) '()))
+
+ (pass-if "ny"
+ (test-break! (list -1 1) '() '(-1 1)))
+
+ (pass-if "yn"
+ (test-break! (list 1 -1) '(1) '(-1)))
+
+ (pass-if "nn"
+ (test-break! (list -1 -2) '() '(-1 -2)))
+
+ (pass-if "yyy"
+ (test-break! (list 1 2 3) '(1 2 3) '()))
+
+ (pass-if "nyy"
+ (test-break! (list -1 1 2) '() '(-1 1 2)))
+
+ (pass-if "yny"
+ (test-break! (list 1 -1 2) '(1) '(-1 2)))
+
+ (pass-if "nny"
+ (test-break! (list -1 -2 1) '() '(-1 -2 1)))
+
+ (pass-if "yyn"
+ (test-break! (list 1 2 -1) '(1 2) '(-1)))
+
+ (pass-if "nyn"
+ (test-break! (list -1 1 -2) '() '(-1 1 -2)))
+
+ (pass-if "ynn"
+ (test-break! (list 1 -1 -2) '(1) '(-1 -2)))
+
+ (pass-if "nnn"
+ (test-break! (list -1 -2 -3) '() '(-1 -2 -3))))
+
+;;
+;; car+cdr
+;;
+
+(with-test-prefix "car+cdr"
+
+ (pass-if "(1 . 2)"
+ (call-with-values
+ (lambda ()
+ (car+cdr '(1 . 2)))
+ (lambda (x y)
+ (and (eqv? x 1)
+ (eqv? y 2))))))
+
;;
;; concatenate and concatenate!
;;
(pass-if-exception "too many args" exception:wrong-num-args
(concatenate-proc '() '()))
+
+ (pass-if-exception "number" exception:wrong-type-arg
+ (concatenate-proc 123))
+
+ (pass-if-exception "vector" exception:wrong-type-arg
+ (concatenate-proc #(1 2 3)))
(pass-if "no lists"
(try '() '()))
(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-type-arg
(count (lambda () x) '(1 2 3)))
(pass-if-exception "pred arg count 2" exception:wrong-type-arg
(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-type-arg
(count (lambda () #t) '(1 2 3) '(1 2 3)))
(pass-if-exception "pred arg count 1" exception:wrong-type-arg
(count (lambda (x) x) '(1 2 3) '(1 2 3)))
(pass-if-exception "pred arg count 3" exception:wrong-type-arg
(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 (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)))))))
+ (pass-if (= 1 (count or3 '(#t #t #t) '(#t #t) '(#t)))))
+
+ (pass-if "apply list unchanged"
+ (let ((lst (list (list 1 2) (list 3 4) (list 5 6))))
+ (and (equal? 2 (apply count or3 lst))
+ ;; lst unmodified
+ (equal? '((1 2) (3 4) (5 6)) lst))))))
;;
;; delete and delete!
(delete-proc 0 '() equal? 99))
(pass-if "empty"
- (eq? '() (delete-proc 0 '())))
+ (eq? '() (delete-proc 0 '() equal?)))
- (pass-if "equal? (the default)"
+ (pass-if "equal?"
(equal? '((1) (3))
- (delete-proc '(2) '((1) (2) (3)))))
+ (delete-proc '(2) '((1) (2) (3)) equal?)))
(pass-if "eq?"
(equal? '((1) (2) (3))
(let ((lst-copy (list-copy lst)))
(with-test-prefix lst-copy
(pass-if "result"
- (equal? (delete #f lst)
- (ref-delete #f lst)))
+ (equal? (delete #f lst equal?)
+ (ref-delete #f lst equal?)))
(pass-if "non-destructive"
(equal? lst-copy lst)))))))
(pass-if-exception "(4 5 6) 4" exception:wrong-type-arg
(drop-right '(4 5 6) 4)))
+;;
+;; drop-right!
+;;
+
+(with-test-prefix "drop-right!"
+
+ (pass-if-exception "() -1" exception:out-of-range
+ (drop-right! '() -1))
+ (pass-if (equal? '() (drop-right! '() 0)))
+ (pass-if-exception "() 1" exception:wrong-type-arg
+ (drop-right! '() 1))
+
+ (pass-if-exception "(1) -1" exception:out-of-range
+ (drop-right! (list 1) -1))
+ (pass-if (equal? '(1) (drop-right! (list 1) 0)))
+ (pass-if (equal? '() (drop-right! (list 1) 1)))
+ (pass-if-exception "(1) 2" exception:wrong-type-arg
+ (drop-right! (list 1) 2))
+
+ (pass-if-exception "(4 5) -1" exception:out-of-range
+ (drop-right! (list 4 5) -1))
+ (pass-if (equal? '(4 5) (drop-right! (list 4 5) 0)))
+ (pass-if (equal? '(4) (drop-right! (list 4 5) 1)))
+ (pass-if (equal? '() (drop-right! (list 4 5) 2)))
+ (pass-if-exception "(4 5) 3" exception:wrong-type-arg
+ (drop-right! (list 4 5) 3))
+
+ (pass-if-exception "(4 5 6) -1" exception:out-of-range
+ (drop-right! (list 4 5 6) -1))
+ (pass-if (equal? '(4 5 6) (drop-right! (list 4 5 6) 0)))
+ (pass-if (equal? '(4 5) (drop-right! (list 4 5 6) 1)))
+ (pass-if (equal? '(4) (drop-right! (list 4 5 6) 2)))
+ (pass-if (equal? '() (drop-right! (list 4 5 6) 3)))
+ (pass-if-exception "(4 5 6) 4" exception:wrong-type-arg
+ (drop-right! (list 4 5 6) 4)))
+
+;;
+;; drop-while
+;;
+
+(with-test-prefix "drop-while"
+
+ (pass-if (equal? '() (drop-while odd? '())))
+ (pass-if (equal? '() (drop-while odd? '(1))))
+ (pass-if (equal? '() (drop-while odd? '(1 3))))
+ (pass-if (equal? '() (drop-while odd? '(1 3 5))))
+
+ (pass-if (equal? '(2) (drop-while odd? '(2))))
+ (pass-if (equal? '(2) (drop-while odd? '(1 2))))
+ (pass-if (equal? '(4) (drop-while odd? '(1 3 4))))
+
+ (pass-if (equal? '(2 1) (drop-while odd? '(2 1))))
+ (pass-if (equal? '(4 3) (drop-while odd? '(1 4 3))))
+ (pass-if (equal? '(4 1 3) (drop-while odd? '(4 1 3)))))
+
+;;
+;; eighth
+;;
+
+(with-test-prefix "eighth"
+ (pass-if-exception "() -1" exception:out-of-range
+ (eighth '(a b c d e f g)))
+ (pass-if (eq? 'h (eighth '(a b c d e f g h))))
+ (pass-if (eq? 'h (eighth '(a b c d e f g h i)))))
+
+;;
+;; fifth
+;;
+
+(with-test-prefix "fifth"
+ (pass-if-exception "() -1" exception:out-of-range
+ (fifth '(a b c d)))
+ (pass-if (eq? 'e (fifth '(a b c d e))))
+ (pass-if (eq? 'e (fifth '(a b c d e f)))))
+
;;
;; filter-map
;;
(with-test-prefix "filter-map"
(with-test-prefix "one list"
+ (pass-if-exception "'x" exception:wrong-type-arg
+ (filter-map noop 'x))
+
+ (pass-if-exception "'(1 . x)" exception:wrong-type-arg
+ (filter-map noop '(1 . x)))
+
(pass-if "(1)"
(equal? '(1) (filter-map noop '(1))))
(equal? '(1 2) (filter-map noop '(1 2 #f)))))
(with-test-prefix "two lists"
+ (pass-if-exception "'x '(1 2 3)" exception:wrong-type-arg
+ (filter-map noop 'x '(1 2 3)))
+
+ (pass-if-exception "'(1 2 3) 'x" exception:wrong-type-arg
+ (filter-map noop '(1 2 3) 'x))
+
+ (pass-if-exception "'(1 . x) '(1 2 3)" exception:wrong-type-arg
+ (filter-map noop '(1 . x) '(1 2 3)))
+
+ (pass-if-exception "'(1 2 3) '(1 . x)" exception:wrong-type-arg
+ (filter-map noop '(1 2 3) '(1 . x)))
+
(pass-if "(1 2 3) (4 5 6)"
- (equal? '(1 2 3) (filter-map noop '(1 2 3) '(4 5 6))))
+ (equal? '(5 7 9) (filter-map + '(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))))))
+ (equal? '(4) (filter-map noop '(4 #f) '(1 2 3))))
+
+ (pass-if "() (1 2 3)"
+ (equal? '() (filter-map noop '() '(1 2 3))))
+
+ (pass-if "(1 2 3) ()"
+ (equal? '() (filter-map noop '(1 2 3) '()))))
+
+ (with-test-prefix "three lists"
+ (pass-if-exception "'x '(1 2 3) '(1 2 3)" exception:wrong-type-arg
+ (filter-map noop 'x '(1 2 3) '(1 2 3)))
+
+ (pass-if-exception "'(1 2 3) 'x '(1 2 3)" exception:wrong-type-arg
+ (filter-map noop '(1 2 3) 'x '(1 2 3)))
+
+ (pass-if-exception "'(1 2 3) '(1 2 3) 'x" exception:wrong-type-arg
+ (filter-map noop '(1 2 3) '(1 2 3) 'x))
+
+ (pass-if-exception "'(1 . x) '(1 2 3) '(1 2 3)" exception:wrong-type-arg
+ (filter-map noop '(1 . x) '(1 2 3) '(1 2 3)))
+
+ (pass-if-exception "'(1 2 3) '(1 . x) '(1 2 3)" exception:wrong-type-arg
+ (filter-map noop '(1 2 3) '(1 . x) '(1 2 3)))
+
+ (pass-if-exception "'(1 2 3) '(1 2 3) '(1 . x)" exception:wrong-type-arg
+ (filter-map noop '(1 2 3) '(1 2 3) '(1 . x)))
+
+ (pass-if "(1 2 3) (4 5 6) (7 8 9)"
+ (equal? '(12 15 18) (filter-map + '(1 2 3) '(4 5 6) '(7 8 9))))
+
+ (pass-if "(#f 2 3) (4 5) (7 8 9)"
+ (equal? '(2) (filter-map noop '(#f 2 3) '(4 5) '(7 8 9))))
+
+ (pass-if "(#f 2 3) (7 8 9) (4 5)"
+ (equal? '(2) (filter-map noop '(#f 2 3) '(7 8 9) '(4 5))))
+
+ (pass-if "(4 #f) (1 2 3) (7 8 9)"
+ (equal? '(4) (filter-map noop '(4 #f) '(1 2 3) '(7 8 9))))
+
+ (pass-if "apply list unchanged"
+ (let ((lst (list (list 1 #f 2) (list 3 4 5) (list 6 7 8))))
+ (and (equal? '(1 2) (apply filter-map noop lst))
+ ;; lst unmodified
+ (equal? lst '((1 #f 2) (3 4 5) (6 7 8))))))))
;;
;; find
(pass-if (let ((lst '(2 0 1)))
(eq? (cddr lst) (find-tail (lambda (x) (= 1 x)) lst)))))
+;;
+;; fold
+;;
+
+(with-test-prefix "fold"
+ (pass-if-exception "no args" exception:wrong-num-args
+ (fold))
+
+ (pass-if-exception "one arg" exception:wrong-num-args
+ (fold 123))
+
+ (pass-if-exception "two args" exception:wrong-num-args
+ (fold 123 noop))
+
+ (with-test-prefix "one list"
+
+ (pass-if "arg order"
+ (eq? #t (fold (lambda (x prev)
+ (and (= 1 x)
+ (= 2 prev)))
+ 2 '(1))))
+
+ (pass-if "empty list" (= 123 (fold + 123 '())))
+
+ (pass-if-exception "proc arg count 0" exception:wrong-type-arg
+ (fold (lambda () x) 123 '(1 2 3)))
+ (pass-if-exception "proc arg count 1" exception:wrong-type-arg
+ (fold (lambda (x) x) 123 '(1 2 3)))
+ (pass-if-exception "proc arg count 3" exception:wrong-type-arg
+ (fold (lambda (x y z) x) 123 '(1 2 3)))
+
+ (pass-if-exception "improper 1" exception:wrong-type-arg
+ (fold + 123 1))
+ (pass-if-exception "improper 2" exception:wrong-type-arg
+ (fold + 123 '(1 . 2)))
+ (pass-if-exception "improper 3" exception:wrong-type-arg
+ (fold + 123 '(1 2 . 3)))
+
+ (pass-if (= 3 (fold + 1 '(2))))
+ (pass-if (= 6 (fold + 1 '(2 3))))
+ (pass-if (= 10 (fold + 1 '(2 3 4)))))
+
+ (with-test-prefix "two lists"
+
+ (pass-if "arg order"
+ (eq? #t (fold (lambda (x y prev)
+ (and (= 1 x)
+ (= 2 y)
+ (= 3 prev)))
+ 3 '(1) '(2))))
+
+ (pass-if "empty lists" (= 1 (fold + 1 '() '())))
+
+ ;; currently bad proc argument gives wrong-num-args when 2 or more
+ ;; lists, as opposed to wrong-type-arg for 1 list
+ (pass-if-exception "proc arg count 2" exception:wrong-num-args
+ (fold (lambda (x prev) x) 1 '(1 2 3) '(1 2 3)))
+ (pass-if-exception "proc arg count 4" exception:wrong-num-args
+ (fold (lambda (x y z prev) x) 1 '(1 2 3) '(1 2 3)))
+
+ (pass-if-exception "improper first 1" exception:wrong-type-arg
+ (fold + 1 1 '(1 2 3)))
+ (pass-if-exception "improper first 2" exception:wrong-type-arg
+ (fold + 1 '(1 . 2) '(1 2 3)))
+ (pass-if-exception "improper first 3" exception:wrong-type-arg
+ (fold + 1 '(1 2 . 3) '(1 2 3)))
+
+ (pass-if-exception "improper second 1" exception:wrong-type-arg
+ (fold + 1 '(1 2 3) 1))
+ (pass-if-exception "improper second 2" exception:wrong-type-arg
+ (fold + 1 '(1 2 3) '(1 . 2)))
+ (pass-if-exception "improper second 3" exception:wrong-type-arg
+ (fold + 1 '(1 2 3) '(1 2 . 3)))
+
+ (pass-if (= 6 (fold + 1 '(2) '(3))))
+ (pass-if (= 15 (fold + 1 '(2 3) '(4 5))))
+ (pass-if (= 28 (fold + 1 '(2 3 4) '(5 6 7))))
+
+ (with-test-prefix "stop shortest"
+ (pass-if (= 13 (fold + 1 '(1 2 3) '(4 5))))
+ (pass-if (= 13 (fold + 1 '(4 5) '(1 2 3))))
+ (pass-if (= 11 (fold + 1 '(3 4) '(1 2 9 9))))
+ (pass-if (= 11 (fold + 1 '(1 2 9 9) '(3 4)))))
+
+ (pass-if "apply list unchanged"
+ (let ((lst (list (list 1 2) (list 3 4))))
+ (and (equal? 11 (apply fold + 1 lst))
+ ;; lst unmodified
+ (equal? '((1 2) (3 4)) lst)))))
+
+ (with-test-prefix "three lists"
+
+ (pass-if "arg order"
+ (eq? #t (fold (lambda (x y z prev)
+ (and (= 1 x)
+ (= 2 y)
+ (= 3 z)
+ (= 4 prev)))
+ 4 '(1) '(2) '(3))))
+
+ (pass-if "empty lists" (= 1 (fold + 1 '() '() '())))
+
+ (pass-if-exception "proc arg count 3" exception:wrong-num-args
+ (fold (lambda (x y prev) x) 1 '(1 2 3) '(1 2 3)'(1 2 3) ))
+ (pass-if-exception "proc arg count 5" exception:wrong-num-args
+ (fold (lambda (w x y z prev) x) 1 '(1 2 3) '(1 2 3) '(1 2 3)))
+
+ (pass-if-exception "improper first 1" exception:wrong-type-arg
+ (fold + 1 1 '(1 2 3) '(1 2 3)))
+ (pass-if-exception "improper first 2" exception:wrong-type-arg
+ (fold + 1 '(1 . 2) '(1 2 3) '(1 2 3)))
+ (pass-if-exception "improper first 3" exception:wrong-type-arg
+ (fold + 1 '(1 2 . 3) '(1 2 3) '(1 2 3)))
+
+ (pass-if-exception "improper second 1" exception:wrong-type-arg
+ (fold + 1 '(1 2 3) 1 '(1 2 3)))
+ (pass-if-exception "improper second 2" exception:wrong-type-arg
+ (fold + 1 '(1 2 3) '(1 . 2) '(1 2 3)))
+ (pass-if-exception "improper second 3" exception:wrong-type-arg
+ (fold + 1 '(1 2 3) '(1 2 . 3) '(1 2 3)))
+
+ (pass-if-exception "improper third 1" exception:wrong-type-arg
+ (fold + 1 '(1 2 3) '(1 2 3) 1))
+ (pass-if-exception "improper third 2" exception:wrong-type-arg
+ (fold + 1 '(1 2 3) '(1 2 3) '(1 . 2)))
+ (pass-if-exception "improper third 3" exception:wrong-type-arg
+ (fold + 1 '(1 2 3) '(1 2 3) '(1 2 . 3)))
+
+ (pass-if (= 10 (fold + 1 '(2) '(3) '(4))))
+ (pass-if (= 28 (fold + 1 '(2 5) '(3 6) '(4 7))))
+ (pass-if (= 55 (fold + 1 '(2 5 8) '(3 6 9) '(4 7 10))))
+
+ (with-test-prefix "stop shortest"
+ (pass-if (= 28 (fold + 1 '(2 5 9) '(3 6) '(4 7))))
+ (pass-if (= 28 (fold + 1 '(2 5) '(3 6 9) '(4 7))))
+ (pass-if (= 28 (fold + 1 '(2 5) '(3 6) '(4 7 9)))))
+
+ (pass-if "apply list unchanged"
+ (let ((lst (list (list 1 2) (list 3 4) (list 5 6))))
+ (and (equal? 22 (apply fold + 1 lst))
+ ;; lst unmodified
+ (equal? '((1 2) (3 4) (5 6)) lst))))))
+
;;
;; length+
;;
(pass-if (not (length+ (circular-list 1 2))))
(pass-if (not (length+ (circular-list 1 2 3)))))
+;;
+;; last
+;;
+
+(with-test-prefix "last"
+
+ (pass-if-exception "empty" exception:wrong-type-arg
+ (last '()))
+ (pass-if "one elem"
+ (eqv? 1 (last '(1))))
+ (pass-if "two elems"
+ (eqv? 2 (last '(1 2))))
+ (pass-if "three elems"
+ (eqv? 3 (last '(1 2 3))))
+ (pass-if "four elems"
+ (eqv? 4 (last '(1 2 3 4)))))
+
;;
;; list=
;;
(pass-if (equal? '(1 2 3 . 4) (list-copy '(1 2 3 . 4))))
(pass-if (equal? '(1 2 3 4 . 5) (list-copy '(1 2 3 4 . 5)))))
+;;
+;; list-index
+;;
+
+(with-test-prefix "list-index"
+ (pass-if-exception "no args" exception:wrong-num-args
+ (list-index))
+
+ (pass-if-exception "one arg" exception:wrong-num-args
+ (list-index noop))
+
+ (with-test-prefix "one list"
+
+ (pass-if "empty list" (eq? #f (list-index symbol? '())))
+
+ (pass-if-exception "pred arg count 0" exception:wrong-type-arg
+ (list-index (lambda () x) '(1 2 3)))
+ (pass-if-exception "pred arg count 2" exception:wrong-type-arg
+ (list-index (lambda (x y) x) '(1 2 3)))
+
+ (pass-if-exception "improper 1" exception:wrong-type-arg
+ (list-index symbol? 1))
+ (pass-if-exception "improper 2" exception:wrong-type-arg
+ (list-index symbol? '(1 . 2)))
+ (pass-if-exception "improper 3" exception:wrong-type-arg
+ (list-index symbol? '(1 2 . 3)))
+
+ (pass-if (eqv? #f (list-index symbol? '(1))))
+ (pass-if (eqv? 0 (list-index symbol? '(x))))
+
+ (pass-if (eqv? #f (list-index symbol? '(1 2))))
+ (pass-if (eqv? 0 (list-index symbol? '(x 1))))
+ (pass-if (eqv? 1 (list-index symbol? '(1 x))))
+
+ (pass-if (eqv? #f (list-index symbol? '(1 2 3))))
+ (pass-if (eqv? 0 (list-index symbol? '(x 1 2))))
+ (pass-if (eqv? 1 (list-index symbol? '(1 x 2))))
+ (pass-if (eqv? 2 (list-index symbol? '(1 2 x)))))
+
+ (with-test-prefix "two lists"
+ (define (sym1 x y)
+ (symbol? x))
+ (define (sym2 x y)
+ (symbol? y))
+
+ (pass-if "arg order"
+ (eqv? 0 (list-index (lambda (x y)
+ (and (= 1 x)
+ (= 2 y)))
+ '(1) '(2))))
+
+ (pass-if "empty lists" (eqv? #f (list-index sym2 '() '())))
+
+ (pass-if-exception "pred arg count 0" exception:wrong-type-arg
+ (list-index (lambda () #t) '(1 2 3) '(1 2 3)))
+ (pass-if-exception "pred arg count 1" exception:wrong-type-arg
+ (list-index (lambda (x) x) '(1 2 3) '(1 2 3)))
+ (pass-if-exception "pred arg count 3" exception:wrong-type-arg
+ (list-index (lambda (x y z) x) '(1 2 3) '(1 2 3)))
+
+ (pass-if-exception "improper first 1" exception:wrong-type-arg
+ (list-index sym2 1 '(1 2 3)))
+ (pass-if-exception "improper first 2" exception:wrong-type-arg
+ (list-index sym2 '(1 . 2) '(1 2 3)))
+ (pass-if-exception "improper first 3" exception:wrong-type-arg
+ (list-index sym2 '(1 2 . 3) '(1 2 3)))
+
+ (pass-if-exception "improper second 1" exception:wrong-type-arg
+ (list-index sym2 '(1 2 3) 1))
+ (pass-if-exception "improper second 2" exception:wrong-type-arg
+ (list-index sym2 '(1 2 3) '(1 . 2)))
+ (pass-if-exception "improper second 3" exception:wrong-type-arg
+ (list-index sym2 '(1 2 3) '(1 2 . 3)))
+
+ (pass-if (eqv? #f (list-index sym2 '(1) '(2))))
+ (pass-if (eqv? 0 (list-index sym2 '(1) '(x))))
+
+ (pass-if (eqv? #f (list-index sym2 '(1 2) '(3 4))))
+ (pass-if (eqv? 0 (list-index sym2 '(1 2) '(x 3))))
+ (pass-if (eqv? 1 (list-index sym2 '(1 2) '(3 x))))
+
+ (pass-if (eqv? #f (list-index sym2 '(1 2 3) '(3 4 5))))
+ (pass-if (eqv? 0 (list-index sym2 '(1 2 3) '(x 3 4))))
+ (pass-if (eqv? 1 (list-index sym2 '(1 2 3) '(3 x 4))))
+ (pass-if (eqv? 2 (list-index sym2 '(1 2 3) '(3 4 x))))
+
+ (with-test-prefix "stop shortest"
+ (pass-if (eqv? #f (list-index sym1 '(1 2 x) '(4 5))))
+ (pass-if (eqv? #f (list-index sym2 '(4 5) '(1 2 x))))
+ (pass-if (eqv? #f (list-index sym1 '(3 4) '(1 2 x y))))
+ (pass-if (eqv? #f (list-index sym2 '(1 2 x y) '(3 4))))))
+
+ (with-test-prefix "three lists"
+ (define (sym1 x y z)
+ (symbol? x))
+ (define (sym2 x y z)
+ (symbol? y))
+ (define (sym3 x y z)
+ (symbol? z))
+
+ (pass-if "arg order"
+ (eqv? 0 (list-index (lambda (x y z)
+ (and (= 1 x)
+ (= 2 y)
+ (= 3 z)))
+ '(1) '(2) '(3))))
+
+ (pass-if "empty lists" (eqv? #f (list-index sym3 '() '() '())))
+
+ ;; 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
+ (list-index (lambda () #t) '(1 2 3) '(1 2 3) '(1 2 3)))
+ (pass-if-exception "pred arg count 2" exception:wrong-num-args
+ (list-index (lambda (x y) x) '(1 2 3) '(1 2 3)'(1 2 3) ))
+ (pass-if-exception "pred arg count 4" exception:wrong-num-args
+ (list-index (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
+ (list-index sym3 1 '(1 2 3) '(1 2 3)))
+ (pass-if-exception "improper first 2" exception:wrong-type-arg
+ (list-index sym3 '(1 . 2) '(1 2 3) '(1 2 3)))
+ (pass-if-exception "improper first 3" exception:wrong-type-arg
+ (list-index sym3 '(1 2 . 3) '(1 2 3) '(1 2 3)))
+
+ (pass-if-exception "improper second 1" exception:wrong-type-arg
+ (list-index sym3 '(1 2 3) 1 '(1 2 3)))
+ (pass-if-exception "improper second 2" exception:wrong-type-arg
+ (list-index sym3 '(1 2 3) '(1 . 2) '(1 2 3)))
+ (pass-if-exception "improper second 3" exception:wrong-type-arg
+ (list-index sym3 '(1 2 3) '(1 2 . 3) '(1 2 3)))
+
+ (pass-if-exception "improper third 1" exception:wrong-type-arg
+ (list-index sym3 '(1 2 3) '(1 2 3) 1))
+ (pass-if-exception "improper third 2" exception:wrong-type-arg
+ (list-index sym3 '(1 2 3) '(1 2 3) '(1 . 2)))
+ (pass-if-exception "improper third 3" exception:wrong-type-arg
+ (list-index sym3 '(1 2 3) '(1 2 3) '(1 2 . 3)))
+
+ (pass-if (eqv? #f (list-index sym3 '(#f) '(#f) '(#f))))
+ (pass-if (eqv? 0 (list-index sym3 '(#f) '(#f) '(x))))
+
+ (pass-if (eqv? #f (list-index sym3 '(#f #f) '(#f #f) '(#f #f))))
+ (pass-if (eqv? 0 (list-index sym3 '(#f #f) '(#f #f) '(x #f))))
+ (pass-if (eqv? 1 (list-index sym3 '(#f #f) '(#f #f) '(#f x))))
+
+ (pass-if (eqv? #f (list-index sym3 '(#f #f #f) '(#f #f #f) '(#f #f #f))))
+ (pass-if (eqv? 0 (list-index sym3 '(#f #f #f) '(#f #f #f) '(x #f #f))))
+ (pass-if (eqv? 1 (list-index sym3 '(#f #f #f) '(#f #f #f) '(#f x #f))))
+ (pass-if (eqv? 2 (list-index sym3 '(#f #f #f) '(#f #f #f) '(#f #f x))))
+
+ (with-test-prefix "stop shortest"
+ (pass-if (eqv? #f (list-index sym2 '() '(x x x) '(x x))))
+ (pass-if (eqv? #f (list-index sym1 '(x x x) '() '(x x))))
+ (pass-if (eqv? #f (list-index sym2 '(x x x) '(x x) '())))
+
+ (pass-if (eqv? #f (list-index sym2 '(#t) '(#t x x) '(#t x))))
+ (pass-if (eqv? #f (list-index sym1 '(#t x x) '(#t) '(#t x))))
+ (pass-if (eqv? #f (list-index sym1 '(#t x x) '(#t x) '(#t)))))
+
+ (pass-if "apply list unchanged"
+ (let ((lst (list (list 1 2) (list 3 4) (list 5 6))))
+ (and (equal? #f (apply list-index sym3 lst))
+ ;; lst unmodified
+ (equal? '((1 2) (3 4) (5 6)) lst))))))
+
+;;
+;; list-tabulate
+;;
+
+(with-test-prefix "list-tabulate"
+
+ (pass-if-exception "-1" exception:out-of-range
+ (list-tabulate -1 identity))
+ (pass-if "0"
+ (equal? '() (list-tabulate 0 identity)))
+ (pass-if "1"
+ (equal? '(0) (list-tabulate 1 identity)))
+ (pass-if "2"
+ (equal? '(0 1) (list-tabulate 2 identity)))
+ (pass-if "3"
+ (equal? '(0 1 2) (list-tabulate 3 identity)))
+ (pass-if "4"
+ (equal? '(0 1 2 3) (list-tabulate 4 identity)))
+ (pass-if "string ref proc"
+ (equal? '(#\a #\b #\c #\d) (list-tabulate 4
+ (lambda (i)
+ (string-ref "abcd" i))))))
+
;;
;; lset=
;;
'(1) 2)
good))
+ (pass-if (equal? '() (lset-adjoin = '())))
+
+ (pass-if (equal? '(1) (lset-adjoin = '() 1)))
+
+ (pass-if (equal? '(1) (lset-adjoin = '() 1 1)))
+
+ (pass-if (equal? '(2 1) (lset-adjoin = '() 1 2)))
+
+ (pass-if (equal? '(3 1 2) (lset-adjoin = '(1 2) 1 2 3 2 1)))
+
+ (pass-if "apply list unchanged"
+ (let ((lst (list 1 2)))
+ (and (equal? '(2 1 3) (apply lset-adjoin = '(3) lst))
+ ;; lst unmodified
+ (equal? '(1 2) lst))))
+
(pass-if "(1 1) 1 1"
(equal? '(1 1) (lset-adjoin = '(1 1) 1 1)))
(pass-if "(2) 1 1"
(equal? '(1 2) (lset-adjoin = '(2) 1 1))))
+;;
+;; lset-difference
+;;
+
+(with-test-prefix "lset-difference"
+
+ (pass-if "called arg order"
+ (let ((good #f))
+ (lset-difference (lambda (x y)
+ (set! good (and (= x 1) (= y 2)))
+ (= x y))
+ '(1) '(2))
+ good)))
+
+;;
+;; lset-difference!
+;;
+
+(with-test-prefix "lset-difference!"
+
+ (pass-if-exception "proc - num" exception:wrong-type-arg
+ (lset-difference! 123 '(4)))
+ (pass-if-exception "proc - list" exception:wrong-type-arg
+ (lset-difference! (list 1 2 3) '(4)))
+
+ (pass-if "called arg order"
+ (let ((good #f))
+ (lset-difference! (lambda (x y)
+ (set! good (and (= x 1) (= y 2)))
+ (= x y))
+ (list 1) (list 2))
+ good))
+
+ (pass-if (equal? '() (lset-difference! = '())))
+ (pass-if (equal? '(1) (lset-difference! = (list 1))))
+ (pass-if (equal? '(1 2) (lset-difference! = (list 1 2))))
+
+ (pass-if (equal? '() (lset-difference! = (list ) '(3))))
+ (pass-if (equal? '() (lset-difference! = (list 3) '(3))))
+ (pass-if (equal? '(1) (lset-difference! = (list 1 3) '(3))))
+ (pass-if (equal? '(1) (lset-difference! = (list 3 1) '(3))))
+ (pass-if (equal? '(1) (lset-difference! = (list 1 3 3) '(3))))
+ (pass-if (equal? '(1) (lset-difference! = (list 3 1 3) '(3))))
+ (pass-if (equal? '(1) (lset-difference! = (list 3 3 1) '(3))))
+
+ (pass-if (equal? '(1) (lset-difference! = (list 1 2 3) '(2 3))))
+ (pass-if (equal? '(1) (lset-difference! = (list 1 2 3) '(3 2))))
+ (pass-if (equal? '(1) (lset-difference! = (list 1 2 3) '(3) '(2))))
+ (pass-if (equal? '(1) (lset-difference! = (list 1 2 3) '(2) '(3))))
+ (pass-if (equal? '(1) (lset-difference! = (list 1 2 3) '(2) '(2 3))))
+ (pass-if (equal? '(1) (lset-difference! = (list 1 2 3) '(2) '(3 2))))
+
+ (pass-if (equal? '(1 2) (lset-difference! = (list 1 2 3) '(3) '(3))))
+ (pass-if (equal? '(1 2) (lset-difference! = (list 1 3 2) '(3) '(3))))
+ (pass-if (equal? '(1 2) (lset-difference! = (list 3 1 2) '(3) '(3))))
+
+ (pass-if (equal? '(1 2 3) (lset-difference! = (list 1 2 3 4) '(4))))
+ (pass-if (equal? '(1 2 3) (lset-difference! = (list 1 2 4 3) '(4))))
+ (pass-if (equal? '(1 2 3) (lset-difference! = (list 1 4 2 3) '(4))))
+ (pass-if (equal? '(1 2 3) (lset-difference! = (list 4 1 2 3) '(4))))
+
+ (pass-if (equal? '(1 2) (lset-difference! = (list 1 2 3 4) '(4) '(3))))
+ (pass-if (equal? '(1 2) (lset-difference! = (list 1 3 2 4) '(4) '(3))))
+ (pass-if (equal? '(1 2) (lset-difference! = (list 3 1 2 4) '(4) '(3))))
+ (pass-if (equal? '(1 2) (lset-difference! = (list 1 3 4 2) '(4) '(3))))
+ (pass-if (equal? '(1 2) (lset-difference! = (list 3 1 4 2) '(4) '(3))))
+ (pass-if (equal? '(1 2) (lset-difference! = (list 3 4 1 2) '(4) '(3)))))
+
+;;
+;; lset-diff+intersection
+;;
+
+(with-test-prefix "lset-diff+intersection"
+
+ (pass-if "called arg order"
+ (let ((good #f))
+ (lset-diff+intersection (lambda (x y)
+ (set! good (and (= x 1) (= y 2)))
+ (= x y))
+ '(1) '(2))
+ good)))
+
+;;
+;; lset-diff+intersection!
+;;
+
+(with-test-prefix "lset-diff+intersection"
+
+ (pass-if "called arg order"
+ (let ((good #f))
+ (lset-diff+intersection (lambda (x y)
+ (set! good (and (= x 1) (= y 2)))
+ (= x y))
+ (list 1) (list 2))
+ good)))
+
+;;
+;; lset-intersection
+;;
+
+(with-test-prefix "lset-intersection"
+
+ (pass-if "called arg order"
+ (let ((good #f))
+ (lset-intersection (lambda (x y)
+ (set! good (and (= x 1) (= y 2)))
+ (= x y))
+ '(1) '(2))
+ good)))
+
+;;
+;; lset-intersection!
+;;
+
+(with-test-prefix "lset-intersection"
+
+ (pass-if "called arg order"
+ (let ((good #f))
+ (lset-intersection (lambda (x y)
+ (set! good (and (= x 1) (= y 2)))
+ (= x y))
+ (list 1) (list 2))
+ good)))
+
;;
;; lset-union
;;
(pass-if "one arg"
(equal? '(1 2 3) (lset-union eq? '(1 2 3))))
+ (pass-if "'() '()"
+ (equal? '() (lset-union eq? '() '())))
+
+ (pass-if "'() '(1 2 3)"
+ (equal? '(1 2 3) (lset-union eq? '() '(1 2 3))))
+
+ (pass-if "'(1 2 3) '()"
+ (equal? '(1 2 3) (lset-union eq? '(1 2 3) '())))
+
+ (pass-if "'(1 2 3) '(4 3 5)"
+ (equal? '(5 4 1 2 3) (lset-union eq? '(1 2 3) '(4 3 5))))
+
+ (pass-if "'(1 2 3) '(4) '(3 5))"
+ (equal? '(5 4 1 2 3) (lset-union eq? '(1 2 3) '(4) '(3 5))))
+
;; in guile 1.6.7 and earlier, `=' was called with the arguments the wrong
;; way around
(pass-if "called arg order"
(eqv? 2 y)))))
good)))
+;;
+;; ninth
+;;
+
+(with-test-prefix "ninth"
+ (pass-if-exception "() -1" exception:out-of-range
+ (ninth '(a b c d e f g h)))
+ (pass-if (eq? 'i (ninth '(a b c d e f g h i))))
+ (pass-if (eq? 'i (ninth '(a b c d e f g h i j)))))
+
+
+;;
+;; not-pair?
+;;
+
+(with-test-prefix "not-pair?"
+ (pass-if "inum"
+ (eq? #t (not-pair? 123)))
+ (pass-if "pair"
+ (eq? #f (not-pair? '(x . y))))
+ (pass-if "symbol"
+ (eq? #t (not-pair? 'x))))
+
;;
;; take
;;
(equal? '(a b)
(take '(a b . c) 2))))
+;;
+;; take-while
+;;
+
+(with-test-prefix "take-while"
+
+ (pass-if (equal? '() (take-while odd? '())))
+ (pass-if (equal? '(1) (take-while odd? '(1))))
+ (pass-if (equal? '(1 3) (take-while odd? '(1 3))))
+ (pass-if (equal? '(1 3 5) (take-while odd? '(1 3 5))))
+
+ (pass-if (equal? '() (take-while odd? '(2))))
+ (pass-if (equal? '(1) (take-while odd? '(1 2))))
+ (pass-if (equal? '(1 3) (take-while odd? '(1 3 4))))
+
+ (pass-if (equal? '() (take-while odd? '(2 1))))
+ (pass-if (equal? '(1) (take-while odd? '(1 4 3))))
+ (pass-if (equal? '() (take-while odd? '(4 1 3)))))
+
+;;
+;; take-while!
+;;
+
+(with-test-prefix "take-while!"
+
+ (pass-if (equal? '() (take-while! odd? '())))
+ (pass-if (equal? '(1) (take-while! odd? (list 1))))
+ (pass-if (equal? '(1 3) (take-while! odd? (list 1 3))))
+ (pass-if (equal? '(1 3 5) (take-while! odd? (list 1 3 5))))
+
+ (pass-if (equal? '() (take-while! odd? (list 2))))
+ (pass-if (equal? '(1) (take-while! odd? (list 1 2))))
+ (pass-if (equal? '(1 3) (take-while! odd? (list 1 3 4))))
+
+ (pass-if (equal? '() (take-while! odd? (list 2 1))))
+ (pass-if (equal? '(1) (take-while! odd? (list 1 4 3))))
+ (pass-if (equal? '() (take-while! odd? (list 4 1 3)))))
+
;;
;; partition
;;
(pass-if (equal? '(2 6) (remove! odd? (list 1 2 6))))
(pass-if (equal? '(2 4 6) (remove! odd? (list 2 4 6)))))
+;;
+;; seventh
+;;
+
+(with-test-prefix "seventh"
+ (pass-if-exception "() -1" exception:out-of-range
+ (seventh '(a b c d e f)))
+ (pass-if (eq? 'g (seventh '(a b c d e f g))))
+ (pass-if (eq? 'g (seventh '(a b c d e f g h)))))
+
+;;
+;; sixth
+;;
+
+(with-test-prefix "sixth"
+ (pass-if-exception "() -1" exception:out-of-range
+ (sixth '(a b c d e)))
+ (pass-if (eq? 'f (sixth '(a b c d e f))))
+ (pass-if (eq? 'f (sixth '(a b c d e f g)))))
+
;;
;; split-at
;;
(pass-if "nnn"
(test-span '(-1 -2 -3) '() '(-1 -2 -3))))
+;;
+;; span!
+;;
+
+(with-test-prefix "span!"
+
+ (define (test-span! lst want-v1 want-v2)
+ (call-with-values
+ (lambda ()
+ (span! positive? lst))
+ (lambda (got-v1 got-v2)
+ (and (equal? got-v1 want-v1)
+ (equal? got-v2 want-v2)))))
+
+ (pass-if "empty"
+ (test-span! '() '() '()))
+
+ (pass-if "y"
+ (test-span! (list 1) '(1) '()))
+
+ (pass-if "n"
+ (test-span! (list -1) '() '(-1)))
+
+ (pass-if "yy"
+ (test-span! (list 1 2) '(1 2) '()))
+
+ (pass-if "ny"
+ (test-span! (list -1 1) '() '(-1 1)))
+
+ (pass-if "yn"
+ (test-span! (list 1 -1) '(1) '(-1)))
+
+ (pass-if "nn"
+ (test-span! (list -1 -2) '() '(-1 -2)))
+
+ (pass-if "yyy"
+ (test-span! (list 1 2 3) '(1 2 3) '()))
+
+ (pass-if "nyy"
+ (test-span! (list -1 1 2) '() '(-1 1 2)))
+
+ (pass-if "yny"
+ (test-span! (list 1 -1 2) '(1) '(-1 2)))
+
+ (pass-if "nny"
+ (test-span! (list -1 -2 1) '() '(-1 -2 1)))
+
+ (pass-if "yyn"
+ (test-span! (list 1 2 -1) '(1 2) '(-1)))
+
+ (pass-if "nyn"
+ (test-span! (list -1 1 -2) '() '(-1 1 -2)))
+
+ (pass-if "ynn"
+ (test-span! (list 1 -1 -2) '(1) '(-1 -2)))
+
+ (pass-if "nnn"
+ (test-span! (list -1 -2 -3) '() '(-1 -2 -3))))
+
+;;
+;; take!
+;;
+
+(with-test-prefix "take!"
+
+ (pass-if-exception "() -1" exception:out-of-range
+ (take! '() -1))
+ (pass-if (equal? '() (take! '() 0)))
+ (pass-if-exception "() 1" exception:wrong-type-arg
+ (take! '() 1))
+
+ (pass-if-exception "(1) -1" exception:out-of-range
+ (take! '(1) -1))
+ (pass-if (equal? '() (take! '(1) 0)))
+ (pass-if (equal? '(1) (take! '(1) 1)))
+ (pass-if-exception "(1) 2" exception:wrong-type-arg
+ (take! '(1) 2))
+
+ (pass-if-exception "(4 5) -1" exception:out-of-range
+ (take! '(4 5) -1))
+ (pass-if (equal? '() (take! '(4 5) 0)))
+ (pass-if (equal? '(4) (take! '(4 5) 1)))
+ (pass-if (equal? '(4 5) (take! '(4 5) 2)))
+ (pass-if-exception "(4 5) 3" exception:wrong-type-arg
+ (take! '(4 5) 3))
+
+ (pass-if-exception "(4 5 6) -1" exception:out-of-range
+ (take! '(4 5 6) -1))
+ (pass-if (equal? '() (take! '(4 5 6) 0)))
+ (pass-if (equal? '(4) (take! '(4 5 6) 1)))
+ (pass-if (equal? '(4 5) (take! '(4 5 6) 2)))
+ (pass-if (equal? '(4 5 6) (take! '(4 5 6) 3)))
+ (pass-if-exception "(4 5 6) 4" exception:wrong-type-arg
+ (take! '(4 5 6) 4)))
+
+
;;
;; take-right
;;
(pass-if-exception "(4 5 6) 4" exception:wrong-type-arg
(take-right '(4 5 6) 4)))
+;;
+;; tenth
+;;
+
+(with-test-prefix "tenth"
+ (pass-if-exception "() -1" exception:out-of-range
+ (tenth '(a b c d e f g h i)))
+ (pass-if (eq? 'j (tenth '(a b c d e f g h i j))))
+ (pass-if (eq? 'j (tenth '(a b c d e f g h i j k)))))
+
+;;
+;; xcons
+;;
+(with-test-prefix "xcons"
+ (pass-if (equal? '(y . x) (xcons 'x 'y))))