test-random.ss
(module test-random mzscheme

  (require "random.ss"
           "schemeunit.ss"
           (lib "etc.ss")
           (only (lib "1.ss" "srfi") fold)
           (only  (lib "43.ss" "srfi") vector-map vector-fold)
           (planet "test.ss" ("schematics" "schemeunit.plt" 2 8))
           (planet "graphical-ui.ss" ("schematics" "schemeunit.plt" 2 8)))


  (define-syntax (test-case/repeat stx)
    (syntax-case stx ()
      [(form count message body)
       (and (integer? (syntax-e (syntax count)))
            (string? (syntax-e (syntax message))))
       (syntax/loc stx
         (apply test-suite message
                (build-list count
                            (lambda (index)
                              (test-case (number->string (+ index 1))
                                body)))))]))
  
  
  
  (test/graphical-ui
   (test-suite "Random.ss testing"
#|(test-case/repeat numberofruns
                      name
                      exp)|#
    
    (test-case/repeat 100
                      "Random-Boolean"
                      (check-pred boolean? (generate random-boolean)))
    (test-case/repeat 3
                      "Random NonRandom"
                      (check = 4 (generate(nonrandom 4))))
    
    (test-case/repeat  4
                       "random-apply"
                      (check-equal? (cons 1 2)  (generate (random-apply cons (nonrandom 1) (nonrandom 2)))))
    (test-case/repeat 100
                      "random choice"
                      (check-pred boolean? (generate (random-choice (nonrandom #t) (nonrandom #f)))))
    
    (test-case/repeat 100
                      "random int between"
                      (check = 5 (generate (random-int-between 5 5))))
    
    (test-case/repeat 100 
                      "random listof"
                      (check-true (fold (lambda (a b) (and a b))
                                        #t 
                                        (map integer? (generate (random-list-of (random-int-between 1 100)))))))
;    (test-case/repeat 100
;                      "random list of fixed size"
;                      (check-true (fold (lambda (a b) (and a b))
;                                        #t
;                                        (map integer? (generate (random-list-of-fixed-size
;                                                                 (random-int-between 1 100) 3))))))
    (test-case/repeat 100
                      "random vector of"
                      (check-true (vector-fold (lambda ( i a b) (and a b))
                                               #t
                                               (vector-map (lambda (i x) (integer? x))
                                                           (generate 
                                                            (random-vector-of 
                                                             (random-int-between 1 100)))))))
    (test-case/repeat 100
                      "random list"
                      (check-pred (lambda (x)
                                    (and (boolean? (car x))
                                         (string? (cadr x))))
                                 (generate (random-list random-boolean (random-string)))))
    
    (test-case/repeat 100
                      "random vector"
                      (check-pred (lambda (x)
                                    (and (boolean? (vector-ref x 0))
                                         (string? (vector-ref x 1))))
                                  (generate (random-vector random-boolean (random-string)))))
    
    (test-case/repeat 100
                      "random weighted"
                      (check-pred boolean? (generate(random-weighted  1/2 (nonrandom #t)
                                                                      1/2 (nonrandom #f)))))
    (test-case/repeat 100
                      "random recursive custom list"
                      (let ((val (generate
                                  (random-recursive
                                   my-list
                                   (3/5 (nonrandom '()))
                                   (2/5 (random-apply 
                                         cons 
                                         (random-int-between 0 100)
                                        my-list))))))
                                 (check-true (fold (lambda (a b) (and a b))
                                                   #t 
                                                   (map integer? val)))))
    (test-case/repeat 100 
                      "random function"
                      (let* ((fun-gen (random-function (lambda (n)
                                                        random-nat)))
                            (f (generate fun-gen))
                            (g (generate fun-gen))
                            (lst (generate (random-list-of random-nat))))
                        
                        (check-equal?
                         (map f (map g lst))
                         (map (lambda (a) (f ( g a))) lst)))) 
    (test-randomly "array-access" 56 
                                   ((size (random-int-between 20 456))
                                    (array (random-vector-of random-boolean (nonrandom size)))
                                    (index (random-int-between 0 (- size 1))))
                                   (check-pred boolean? (vector-ref array index)))
                  
    (test-randomly "append preserves length" 34
                     ((little-lst (random-list (random-string) (random-symbol)))
                      (num (random-int-between 30 70))
                      (big-lst (random-list-of (random-char) (nonrandom num))))
                     (check-equal? (+ num 2) (length (append little-lst big-lst))))
    (test-randomly
                  "map is nice" 69
                   ((f (random-function (lambda (n)  random-nat)))
                    (g (random-function (lambda (n)  random-nat)))
                    (lst (random-list-of random-nat)))
                   
                   (check-equal?
                    (map f (map g lst))
                    (map (lambda (a) (f ( g a))) lst)))
    (test-randomly "my-list" 20
                      ((lst (random-recursive 
                             mylst
                             (1/2 (nonrandom '()))
                             (1/2 (random-apply cons (random-char)  mylst)))))
                      (check-pred list? lst))
     (test-randomly
      "mystream" 34
      ((strm (random-recursive 
              stream
              (0 (nonrandom '()))
              (1 (random-apply cons 
                               (random-int-between 0 40 )
                               (nonrandom(lambda () (generate stream))))))))
      (check-pred number? (car ((cdr strm)))))

    
    
    )))