(include "#.scm")

(define bool #f)

;; proper lists
(define lst0 (list))
(define lst1 (list 11))
(define lst2 (list 22 33))

;; dotted list
(define lst3 (cons 44 55))
(define lst4 (cons 66 (cons 77 88)))

(check-eq? (concatenate! lst0) '())
(check-eq? (concatenate! (list bool)) bool)
(check-eq? (concatenate! (list lst0 bool)) bool)
(check-eq? (concatenate! (list lst0 lst0)) lst0)
(check-eq? (concatenate! (list lst0 lst1)) lst1)
(check-eq? (concatenate! (list lst0 lst2)) lst2)
(check-eq? (concatenate! (list lst0 lst3)) lst3)
(check-eq? (concatenate! (list lst0 lst4)) lst4)
(check-eq? (concatenate! (list lst0 lst0 bool)) bool)
(check-eq? (concatenate! (list lst0 lst0 lst0)) lst0)
(check-eq? (concatenate! (list lst0 lst0 lst1)) lst1)
(check-eq? (concatenate! (list lst0 lst0 lst2)) lst2)
(check-eq? (concatenate! (list lst0 lst0 lst3)) lst3)
(check-eq? (concatenate! (list lst0 lst0 lst4)) lst4)

(define a (concatenate! (list lst1 bool)))

(check-equal? a '(11 . #f))
(check-eq? a lst1)

(define b (concatenate! (list lst0 lst0 lst2 lst0 lst1)))

(check-equal? b '(22 33 11 . #f))
(check-eq? b lst2)
(check-eq? (cddr b) lst1)

(check-tail-exn type-exception? (lambda () (concatenate! bool)))
(check-tail-exn type-exception? (lambda () (concatenate! (cons lst0 bool))))
(check-tail-exn type-exception? (lambda () (concatenate! (cons lst0 (cons lst0 bool)))))
(check-tail-exn type-exception? (lambda () (concatenate! (cons lst1 (cons lst0 bool)))))
(check-tail-exn type-exception? (lambda () (concatenate! (cons lst0 (cons lst1 bool)))))
(check-tail-exn type-exception? (lambda () (concatenate! (list bool lst0))))
(check-tail-exn type-exception? (lambda () (concatenate! (list bool lst1))))
(check-tail-exn type-exception? (lambda () (concatenate! (list bool lst2))))
(check-tail-exn type-exception? (lambda () (concatenate! (list bool lst3))))
(check-tail-exn type-exception? (lambda () (concatenate! (list lst3 bool))))
(check-tail-exn type-exception? (lambda () (concatenate! (list lst3 lst0))))
(check-tail-exn type-exception? (lambda () (concatenate! (list lst3 lst1))))
(check-tail-exn type-exception? (lambda () (concatenate! (list lst3 lst2))))
(check-tail-exn type-exception? (lambda () (concatenate! (list lst3 lst3))))
(check-tail-exn type-exception? (lambda () (concatenate! (list lst4 bool))))
(check-tail-exn type-exception? (lambda () (concatenate! (list lst4 lst0))))
(check-tail-exn type-exception? (lambda () (concatenate! (list lst4 lst1))))
(check-tail-exn type-exception? (lambda () (concatenate! (list lst4 lst2))))
(check-tail-exn type-exception? (lambda () (concatenate! (list lst4 lst3))))
(check-tail-exn type-exception? (lambda () (concatenate! (list lst0 bool lst0))))
(check-tail-exn type-exception? (lambda () (concatenate! (list lst0 bool lst1))))
(check-tail-exn type-exception? (lambda () (concatenate! (list lst0 bool lst2))))
(check-tail-exn type-exception? (lambda () (concatenate! (list lst0 bool lst3))))
(check-tail-exn type-exception? (lambda () (concatenate! (list lst0 lst3 bool))))
(check-tail-exn type-exception? (lambda () (concatenate! (list lst0 lst3 lst0))))
(check-tail-exn type-exception? (lambda () (concatenate! (list lst0 lst3 lst1))))
(check-tail-exn type-exception? (lambda () (concatenate! (list lst0 lst3 lst2))))
(check-tail-exn type-exception? (lambda () (concatenate! (list lst0 lst3 lst3))))
(check-tail-exn type-exception? (lambda () (concatenate! (list lst0 lst4 bool))))
(check-tail-exn type-exception? (lambda () (concatenate! (list lst0 lst4 lst0))))
(check-tail-exn type-exception? (lambda () (concatenate! (list lst0 lst4 lst1))))
(check-tail-exn type-exception? (lambda () (concatenate! (list lst0 lst4 lst2))))
(check-tail-exn type-exception? (lambda () (concatenate! (list lst0 lst4 lst3))))

(check-tail-exn wrong-number-of-arguments-exception? (lambda () (concatenate!)))
(check-tail-exn wrong-number-of-arguments-exception? (lambda () (concatenate! lst0 lst1)))
