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 "list-copy"
321 (pass-if (equal? '() (list-copy '())))
322 (pass-if (equal? '(1 2) (list-copy '(1 2))))
323 (pass-if (equal? '(1 2 3) (list-copy '(1 2 3))))
324 (pass-if (equal? '(1 2 3 4) (list-copy '(1 2 3 4))))
325 (pass-if (equal? '(1 2 3 4 5) (list-copy '(1 2 3 4 5))))
327 ;; improper lists can be copied
328 (pass-if (equal? 1 (list-copy 1)))
329 (pass-if (equal? '(1 . 2) (list-copy '(1 . 2))))
330 (pass-if (equal? '(1 2 . 3) (list-copy '(1 2 . 3))))
331 (pass-if (equal? '(1 2 3 . 4) (list-copy '(1 2 3 . 4))))
332 (pass-if (equal? '(1 2 3 4 . 5) (list-copy '(1 2 3 4 . 5)))))
338 (with-test-prefix "take"
341 (null? (take '() 0)))
344 (null? (take '(a) 0)))
347 (null? (take '() 0)))
349 (pass-if "'(a b c) 0"
350 (null? (take '() 0)))
355 (and (equal? '(a) got)
356 (not (eq? lst got)))))
362 (pass-if "'(a b c) 1"
369 (and (equal? '(a b) got)
370 (not (eq? lst got)))))
372 (pass-if "'(a b c) 2"
376 (pass-if "circular '(a) 0"
378 (take (circular-list 'a) 0)))
380 (pass-if "circular '(a) 1"
382 (take (circular-list 'a) 1)))
384 (pass-if "circular '(a) 2"
386 (take (circular-list 'a) 2)))
388 (pass-if "circular '(a b) 5"
390 (take (circular-list 'a 'b) 5)))
392 (pass-if "'(a . b) 1"
396 (pass-if "'(a b . c) 1"
398 (take '(a b . c) 1)))
400 (pass-if "'(a b . c) 2"
402 (take '(a b . c) 2))))
408 (define (test-partition pred list kept-good dropped-good)
409 (call-with-values (lambda ()
410 (partition pred list))
411 (lambda (kept dropped)
412 (and (equal? kept kept-good)
413 (equal? dropped dropped-good)))))
415 (with-test-prefix "partition"
417 (pass-if "with dropped tail"
418 (test-partition even? '(1 2 3 4 5 6 7)
419 '(2 4 6) '(1 3 5 7)))
421 (pass-if "with kept tail"
422 (test-partition even? '(1 2 3 4 5 6)
425 (pass-if "with everything dropped"
426 (test-partition even? '(1 3 5 7)
429 (pass-if "with everything kept"
430 (test-partition even? '(2 4 6)
433 (pass-if "with empty list"
434 (test-partition even? '()
437 (pass-if "with reasonably long list"
438 ;; the old implementation from SRFI-1 reference implementation
439 ;; would signal a stack-overflow for a list of only 500 elements!
440 (call-with-values (lambda ()
442 (make-list 10000 1)))
444 (and (= (length odd) 10000)
445 (= (length even) 0))))))