#lang scheme
(require (planet cce/scheme:4:1/planet)
(planet schematics/schemeunit)
(planet schematics/schemeunit/text-ui)
(this-package-in main)
(this-package-in private/scons)
(this-package-in private/tree))
(define (make-list-test name
empty cons
empty? cons?
first rest
foldl foldr map)
(test-suite
name
(check-true (empty? empty))
(check-false (empty? (cons 9 empty)))
(check-false (empty? 'your-mom))
(check-true (cons? (cons 9 empty)))
(check-false (cons? empty))
(check-false (cons? 'your-mom))
(check-equal? (first (cons 9 empty)) 9)
(check-equal? (rest (cons 9 empty)) empty)
(check-equal? (map add1 empty) empty)
(check-equal? (map add1 (cons 0 (cons 1 (cons 2 empty))))
(cons 1 (cons 2 (cons 3 empty))))
(check-equal? (foldl + 0 empty) 0)
(check-equal? (foldl + 0 (cons 1 (cons 2 (cons 3 empty)))) 6)
(check-equal? (foldl cons empty empty) empty)
(check-equal? (foldl cons empty (cons 0 (cons 1 (cons 2 (cons 3 empty)))))
(cons 3 (cons 2 (cons 1 (cons 0 empty)))))
(check-equal? (foldr + 0 empty) 0)
(check-equal? (foldr + 0 (cons 1 (cons 2 (cons 3 empty)))) 6)
(check-equal? (foldr cons empty empty) empty)
(check-equal? (foldr cons empty (cons 0 (cons 1 (cons 2 (cons 3 empty)))))
(cons 0 (cons 1 (cons 2 (cons 3 empty)))))
(check-equal? (for/fold ([sum 0]) ([i empty]) (+ sum i)) 0)
(check-equal? (for/fold ([sum 0]) ([i (cons 1 (cons 2 (cons 3 empty)))])
(+ sum i)) 6)
(check-equal? (for/fold ([str ""]) ([c (cons "a" (cons "b" (cons "c" empty)))])
(string-append str c))
"abc")
(check-exn exn? (λ () (first empty)))
(check-exn exn? (λ () (rest empty)))))
(run-tests
(test-suite
"All tests"
tree-tests
(make-list-test "Sequential basic list tests"
s:empty s:cons
s:empty? s:cons?
s:first s:rest
s:foldl s:foldr s:map)
(make-list-test "Random-access basic list tests"
empty cons
empty? cons?
first rest
foldl foldr map)
(test-suite
"Random-access advanced list tests"
(check-true (list? empty))
(check-true (list? (cons 9 empty)))
(check-false (list? 'your-mom))
(check-exn exn? (λ () (cons 9 9)))
(check-equal? (list-ref (cons 9 empty) 0) 9)
(check-equal? (list-set (cons 9 empty) 0 4)
(cons 4 empty))
(check-equal? (list-ref (list 'a 'b 'c 'd 'e) 2) 'c)
(check-equal? (list-set (list 'a 'b 'c 'd 'e) 2 'f)
(list 'a 'b 'f 'd 'e))
(let ((ls (build-list 100 (lambda (i) i))))
(for/list ([i (in-range 100)])
(check-equal? (list-ref ls i) i)))
(let-values ([(v l) (list-ref/set (list 'a 'b 'c 'd 'e) 2 'f)])
(check-equal? v 'c)
(check-equal? l (list 'a 'b 'f 'd 'e)))
(let-values ([(v l) (list-ref/update (list 5 6 7 8 9) 2 add1)])
(check-equal? v 7)
(check-equal? l (list 5 6 8 8 9)))
(check-equal? (list) empty)
(check-equal? (list 1 2 3) (cons 1 (cons 2 (cons 3 empty))))
(check-equal? (list* empty) empty)
(check-equal? (list* 1 2 3 empty) (list 1 2 3))
(check-equal? (list* 1 2 3 (list 4 5)) (list 1 2 3 4 5))
(check-exn exn? (λ () (list* 5)))
(check-equal? (build-list 0 (lambda (i) i)) empty)
(check-equal? (build-list 5 (lambda (i) i))
(list 0 1 2 3 4))
(check-equal? (build-list 5 add1)
(list 1 2 3 4 5))
(check-equal? (length empty) 0)
(check-equal? (length (cons 9 empty)) 1)
(check-equal? (length (build-list 10 (lambda (i) i))) 10)
(check-equal? (list-tail empty 0) empty)
(check-equal? (list-tail (cons 9 empty) 1) empty)
(check-equal? (list-tail (list 0 1 2 3 4) 2)
(list 2 3 4))
(check-equal? (append empty empty) empty)
(check-equal? (append empty (list 1 2 3)) (list 1 2 3))
(check-equal? (append (list 1 2 3) empty) (list 1 2 3))
(check-equal? (append (list 1 2 3) (list 4 5 6))
(list 1 2 3 4 5 6))
(check-equal? (reverse empty) empty)
(check-equal? (reverse (cons 9 empty)) (cons 9 empty))
(check-equal? (reverse (list 0 1 2 3 4))
(list 4 3 2 1 0))
(check-equal? (for/last ([i (in-list (list))]) i) false)
(check-equal? (for/last ([i (in-list (list 1 2))]) i) 2)
(check-equal? (for/last ([i (in-list (list 1 2 3 4))]) i) 4)
(check-exn exn? (λ () (list-ref empty 0)))
(check-exn exn? (λ () (list-ref (cons 9 empty) 1)))
(check-exn exn? (λ () (list-set empty 0)))
(check-exn exn? (λ () (list-set (cons 9 empty) 1))))))