1 ;;;; srfi-1.test --- Test suite for Guile's SRFI-1 functions. -*- scheme -*-
3 ;;;; Copyright 2003 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))))))
47 ;; concatenate and concatenate!
51 (define (common-tests concatenate-proc unmodified?)
52 (define (try lstlst want)
53 (let ((lstlst-copy (copy-tree lstlst))
54 (got (concatenate-proc lstlst)))
56 (if (not (equal? lstlst lstlst-copy))
57 (error "input lists modified")))
60 (pass-if-exception "too few args" exception:wrong-num-args
63 (pass-if-exception "too many args" exception:wrong-num-args
64 (concatenate-proc '() '()))
69 (pass-if (try '((1)) '(1)))
70 (pass-if (try '((1 2)) '(1 2)))
71 (pass-if (try '(() (1)) '(1)))
72 (pass-if (try '(() () (1)) '(1)))
74 (pass-if (try '((1) (2)) '(1 2)))
75 (pass-if (try '(() (1 2)) '(1 2)))
77 (pass-if (try '((1) 2) '(1 . 2)))
78 (pass-if (try '((1) (2) 3) '(1 2 . 3)))
79 (pass-if (try '((1) (2) (3 . 4)) '(1 2 3 . 4)))
82 (with-test-prefix "concatenate"
83 (common-tests concatenate #t))
85 (with-test-prefix "concatenate!"
86 (common-tests concatenate! #f)))
94 ;; Call (PROC lst) for all lists of length up to 6, with all combinations
95 ;; of elements to be retained or deleted. Elements to retain are numbers,
96 ;; 0 upwards. Elements to be deleted are #f.
97 (define (test-lists proc)
100 (do ((limit (ash 1 n))
104 (do ((bit 0 (1+ bit)))
106 (set! lst (cons (if (logbit? bit i) bit #f) lst)))
109 (define (common-tests delete-proc)
110 (pass-if-exception "too few args" exception:wrong-num-args
113 (pass-if-exception "too many args" exception:wrong-num-args
114 (delete-proc 0 '() equal? 99))
117 (eq? '() (delete-proc 0 '())))
119 (pass-if "equal? (the default)"
121 (delete-proc '(2) '((1) (2) (3)))))
124 (equal? '((1) (2) (3))
125 (delete-proc '(2) '((1) (2) (3)) eq?)))
127 (pass-if "called arg order"
129 (delete-proc 3 '(1 2 3 4 5) <))))
131 (with-test-prefix "delete"
132 (common-tests delete)
136 (let ((lst-copy (list-copy lst)))
137 (with-test-prefix lst-copy
139 (equal? (delete #f lst)
140 (ref-delete #f lst)))
141 (pass-if "non-destructive"
142 (equal? lst-copy lst)))))))
144 (with-test-prefix "delete!"
145 (common-tests delete!)
150 (equal? (delete! #f lst)
151 (ref-delete #f lst)))))))
154 ;; delete-duplicates and delete-duplicates!
158 ;; Call (PROC lst) for all lists of length 1 <= n <= 4, with all
159 ;; combinations of numbers 1 to n in the elements
160 (define (test-lists proc)
163 (do ((limit (integer-expt n n))
168 (rem i (quotient rem n)))
170 (set! lst (cons (remainder rem n) lst)))
173 (define (common-tests delete-duplicates-proc)
174 (pass-if-exception "too few args" exception:wrong-num-args
175 (delete-duplicates-proc))
177 (pass-if-exception "too many args" exception:wrong-num-args
178 (delete-duplicates-proc '() equal? 99))
181 (eq? '() (delete-duplicates-proc '())))
183 (pass-if "equal? (the default)"
185 (delete-duplicates-proc '((2) (2) (2)))))
188 (equal? '((2) (2) (2))
189 (delete-duplicates-proc '((2) (2) (2)) eq?)))
191 (pass-if "called arg order"
193 (delete-duplicates-proc '(1 2 3 4 5)
200 (with-test-prefix "delete-duplicates"
201 (common-tests delete-duplicates)
205 (let ((lst-copy (list-copy lst)))
206 (with-test-prefix lst-copy
208 (equal? (delete-duplicates lst)
209 (ref-delete-duplicates lst)))
210 (pass-if "non-destructive"
211 (equal? lst-copy lst)))))))
213 (with-test-prefix "delete-duplicates!"
214 (common-tests delete-duplicates!)
219 (equal? (delete-duplicates! lst)
220 (ref-delete-duplicates lst)))))))
226 (with-test-prefix "drop"
229 (null? (drop '() 0)))
256 (pass-if "'(a b c) 1"
257 (let ((lst '(a b c)))
261 (pass-if "circular '(a) 0"
262 (let ((lst (circular-list 'a)))
266 (pass-if "circular '(a) 1"
267 (let ((lst (circular-list 'a)))
271 (pass-if "circular '(a) 2"
272 (let ((lst (circular-list 'a)))
276 (pass-if "circular '(a b) 1"
277 (let ((lst (circular-list 'a)))
281 (pass-if "circular '(a b) 2"
282 (let ((lst (circular-list 'a)))
286 (pass-if "circular '(a b) 5"
287 (let ((lst (circular-list 'a)))
291 (pass-if "'(a . b) 1"
295 (pass-if "'(a b . c) 1"
297 (drop '(a b . c) 2))))
303 (with-test-prefix "length+"
304 (pass-if-exception "too few args" exception:wrong-num-args
306 (pass-if-exception "too many args" exception:wrong-num-args
308 (pass-if (= 0 (length+ '())))
309 (pass-if (= 1 (length+ '(x))))
310 (pass-if (= 2 (length+ '(x y))))
311 (pass-if (= 3 (length+ '(x y z))))
312 (pass-if (not (length+ (circular-list 1))))
313 (pass-if (not (length+ (circular-list 1 2))))
314 (pass-if (not (length+ (circular-list 1 2 3)))))
320 (with-test-prefix "take"
323 (null? (take '() 0)))
326 (null? (take '(a) 0)))
329 (null? (take '() 0)))
331 (pass-if "'(a b c) 0"
332 (null? (take '() 0)))
337 (and (equal? '(a) got)
338 (not (eq? lst got)))))
344 (pass-if "'(a b c) 1"
351 (and (equal? '(a b) got)
352 (not (eq? lst got)))))
354 (pass-if "'(a b c) 2"
358 (pass-if "circular '(a) 0"
360 (take (circular-list 'a) 0)))
362 (pass-if "circular '(a) 1"
364 (take (circular-list 'a) 1)))
366 (pass-if "circular '(a) 2"
368 (take (circular-list 'a) 2)))
370 (pass-if "circular '(a b) 5"
372 (take (circular-list 'a 'b) 5)))
374 (pass-if "'(a . b) 1"
378 (pass-if "'(a b . c) 1"
380 (take '(a b . c) 1)))
382 (pass-if "'(a b . c) 2"
384 (take '(a b . c) 2))))
390 (define (test-partition pred list kept-good dropped-good)
391 (call-with-values (lambda ()
392 (partition pred list))
393 (lambda (kept dropped)
394 (and (equal? kept kept-good)
395 (equal? dropped dropped-good)))))
397 (with-test-prefix "partition"
399 (pass-if "with dropped tail"
400 (test-partition even? '(1 2 3 4 5 6 7)
401 '(2 4 6) '(1 3 5 7)))
403 (pass-if "with kept tail"
404 (test-partition even? '(1 2 3 4 5 6)
407 (pass-if "with everything dropped"
408 (test-partition even? '(1 3 5 7)
411 (pass-if "with everything kept"
412 (test-partition even? '(2 4 6)
415 (pass-if "with empty list"
416 (test-partition even? '()
419 (pass-if "with reasonably long list"
420 ;; the old implementation from SRFI-1 reference implementation
421 ;; would signal a stack-overflow for a list of only 500 elements!
422 (call-with-values (lambda ()
424 (make-list 10000 1)))
426 (and (= (length odd) 10000)
427 (= (length even) 0))))))