lib/ubik/inversion-list/tests.ss
(library (ubik inversion-lists tests)
  (export)
  (import (rnrs base)
          (srfi n78)
          (ubik inversion-lists))

  ;; Derived from Scheme 48 source, which is:
  ;; Copyright (c) 1993-2008 by Richard Kelsey and Jonathan Rees.

  ;; Rewritten to use SRFI 78 testing framework.

  ;; Moved to definition context.
  (define (i-list-sum i-list)
    (let loop ((cursor (inversion-list-cursor i-list))
	       (sum 0))
      (if (inversion-list-cursor-at-end? cursor)
	  sum
	  (loop (inversion-list-cursor-next i-list cursor)
		(+ (inversion-list-cursor-ref cursor)
		   sum)))))  

  ;; creation/membership
  (check (inversion-list-member? 5 (make-empty-inversion-list 0 1000))         => #f)
  (check (inversion-list-member? 5 (number->inversion-list 0 1000 5))          => #t)
  (check (inversion-list-member? 4 (number->inversion-list 0 1000 5))          => #f)
  (check (inversion-list-member? 6 (number->inversion-list 0 1000 5))          => #f)
  (check (inversion-list-member? 6 (range->inversion-list 0 1000 500 1000))    => #f)
  (check (inversion-list-member? 499 (range->inversion-list 0 1000 500 1000))  => #f)
  (check (inversion-list-member? 500 (range->inversion-list 0 1000 500 1000))  => #t)
  (check (inversion-list-member? 1000 (range->inversion-list 0 1000 500 1000)) => #t)

  ;; complement/1
  (check
   (inversion-list-complement
    (inversion-list-complement
     (range->inversion-list 0 1000 5 10)))   
   (=> inversion-list=?)
   (range->inversion-list 0 1000 5 10))

  ;; complement/2
  (check
   (inversion-list-complement
    (inversion-list-complement
     (range->inversion-list 0 1000 0 1000)))
   (=> inversion-list=?)
   (range->inversion-list 0 1000 0 1000))

  ;; union/1
  (check
   (inversion-list-union (range->inversion-list 0 1000 5 10)
			 (range->inversion-list 0 1000 20 30))
   (=> inversion-list=?)
   (ranges->inversion-list 0 1000 '(5 . 10) '(20 . 30)))

  ;; union/2
  (check
   (inversion-list-union (range->inversion-list 0 1000 5 10)
			 (range->inversion-list 0 1000 7 8))
   (=> inversion-list=?)
   (range->inversion-list 0 1000 5 10))
  
  ;; union/3
  (check
   (inversion-list-union (range->inversion-list 0 1000 5 10)
			 (range->inversion-list 0 1000 7 15))
   (=> inversion-list=?)
   (range->inversion-list 0 1000 5 15))

  ;; union/4
  (check
   (inversion-list-union (range->inversion-list 0 1000 500 1000)
			 (range->inversion-list 0 1000 0 500))
   (=> inversion-list=?)
   (range->inversion-list 0 1000 0 1000))

  ;; intersection/1
  (check
   (inversion-list-intersection (range->inversion-list 0 1000 5 10)
				(range->inversion-list 0 1000 20 30))
   (=> inversion-list=?)
   (make-empty-inversion-list 0 1000))
  
  ;; intersection/2
  (check
   (inversion-list-intersection (range->inversion-list 0 1000 5 10)
				(range->inversion-list 0 1000 7 8))
   (=> inversion-list=?)
   (range->inversion-list 0 1000 7 8))

  ;; intersection/3
  (check
   (inversion-list-intersection (range->inversion-list 0 1000 5 10)
				(range->inversion-list 0 1000 7 15))
   (=> inversion-list=?)
   (range->inversion-list 0 1000 7 10))

  ;; intersection/4
  (check
   (inversion-list-intersection (range->inversion-list 0 1000 500 1000)
				(range->inversion-list 0 1000 0 501))
   (=> inversion-list=?)
   (range->inversion-list 0 1000 500 501))

  ;; intersection/5
  (check
   (inversion-list-intersection (range->inversion-list 0 1000 500 1000)
				(range->inversion-list 0 1000 501 505))
   (=> inversion-list=?)
   (range->inversion-list 0 1000 501 505))

  ;; adjoin
  (check
   (inversion-list-adjoin (range->inversion-list 0 1000 0 999) 999)
   (=> inversion-list=?)
   (range->inversion-list 0 1000 0 1000))

  ;; remove
  (check
   (inversion-list-remove (range->inversion-list 0 1000 0 1000) 999)
   (=> inversion-list=?)
   (range->inversion-list 0 1000 0 999))

  ;; size
  (check
   (inversion-list-size
    (ranges->inversion-list 0 1000 '(5 . 10) '(15 . 20) '(500 . 1000)))
   => 510)

  ;; copy
  (check
   (inversion-list-copy
    (ranges->inversion-list 0 1000 '(5 . 10) '(15 . 20) '(500 . 1000)))
   (=> inversion-list=?)
   (ranges->inversion-list 0 1000 '(5 . 10) '(15 . 20) '(500 . 1000)))

  ;; fold/done?
  (check
   (inversion-list-fold/done?
    (lambda (n sum)
      (+ n sum))
    0
    (lambda (sum)
      (> sum 250000))
    (ranges->inversion-list 0 1000 '(5 . 10) '(15 . 20) '(500 . 1000)))
   =>
   250781)

  ;; i-list-sum moved to definition position.

  ;; cursor
  (check
   (i-list-sum (ranges->inversion-list 0 1000 '(5 . 10) '(15 . 20) '(500 . 1000)))
   => 374870)

  ;; hash
  (check
   (inversion-list-hash (ranges->inversion-list 0 1000 '(5 . 10) '(15 . 20) '(500 . 1000)) 1031)
   (=> (lambda (x y) (not (= x y))))
   (inversion-list-hash (ranges->inversion-list 0 1000 '(5 . 10) '(500 . 1000)) 1031))

  (check-report)
) ; end library