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 "take"
306 (null? (take '() 0)))
309 (null? (take '(a) 0)))
312 (null? (take '() 0)))
314 (pass-if "'(a b c) 0"
315 (null? (take '() 0)))
320 (and (equal? '(a) got)
321 (not (eq? lst got)))))
327 (pass-if "'(a b c) 1"
334 (and (equal? '(a b) got)
335 (not (eq? lst got)))))
337 (pass-if "'(a b c) 2"
341 (pass-if "circular '(a) 0"
343 (take (circular-list 'a) 0)))
345 (pass-if "circular '(a) 1"
347 (take (circular-list 'a) 1)))
349 (pass-if "circular '(a) 2"
351 (take (circular-list 'a) 2)))
353 (pass-if "circular '(a b) 5"
355 (take (circular-list 'a 'b) 5)))
357 (pass-if "'(a . b) 1"
361 (pass-if "'(a b . c) 1"
363 (take '(a b . c) 1)))
365 (pass-if "'(a b . c) 2"
367 (take '(a b . c) 2))))
373 (define (test-partition pred list kept-good dropped-good)
374 (call-with-values (lambda ()
375 (partition pred list))
376 (lambda (kept dropped)
377 (and (equal? kept kept-good)
378 (equal? dropped dropped-good)))))
380 (with-test-prefix "partition"
382 (pass-if "with dropped tail"
383 (test-partition even? '(1 2 3 4 5 6 7)
384 '(2 4 6) '(1 3 5 7)))
386 (pass-if "with kept tail"
387 (test-partition even? '(1 2 3 4 5 6)
390 (pass-if "with everything dropped"
391 (test-partition even? '(1 3 5 7)
394 (pass-if "with everything kept"
395 (test-partition even? '(2 4 6)
398 (pass-if "with empty list"
399 (test-partition even? '()
402 (pass-if "with reasonably long list"
403 ;; the old implementation from SRFI-1 reference implementation
404 ;; would signal a stack-overflow for a list of only 500 elements!
405 (call-with-values (lambda ()
407 (make-list 10000 1)))
409 (and (= (length odd) 10000)
410 (= (length even) 0))))))