Since there is now a movement afoot to write a comprehensive test  
suite, I want to re-post the spike I did earlier on ClojureCheck.

It would be cool to use check-style tests for at least part of the  
Clojure suite. If there is interest in this, I hope to have time to  
work on this in late November, or would be delighted if someone else  
picks up the idea and runs with it.

Original message follows:

---------------

At the JVM summit Clojure breakout someone suggested a Haskell  
QuickCheck/ScalaCheck library for Clojure. I am attaching a small  
spike in that direction below. A few questions:

(1) Is anybody interested?

(2) If the answer to (1) is yes, do you like the direction I am going  
in the public API, e.g.
        
        (for-all [x Integer y Integer] (some stuff that must be true))

(3) Any suggestions about implementation detail? (E.g. I like using a  
multimethod for arbitrary--is there a prettier syntax for ignoring the  
argument after using it for dispatch?)

Cheers,
Stuart

;;; clojure_check.clj: quick check framework for Clojure

;; Copyright (c) 2008 Stuart Halloway. All rights reserved.

;; Inspired by Scalacheck et al (http://code.google.com/p/scalacheck/)
;; Licensed under the same CPL as Clojure (http://clojure.org)

;; Uses clojure.contrib.test-is for assertions
;;
;; Example (passing)
;; (for-all [x Integer y Integer] (= (+ x y) (+ y x)))
;;
;; Example (failing)
;; (for-all [x Integer y Integer] (= (+ x y) (- y x)))

(ns clojure-check
  (:import (java.util Random))
  (:use clojure.contrib.test-is))

(defmulti arbitrary identity)

(def random (Random.))

(defn collection-size []
  (.nextInt random 100))
(def *check-count* 50)

(defn choose [rng]
  (nth rng (.nextInt random (count rng))))

(defmethod arbitrary Integer [_] (.nextInt random))
(defmethod arbitrary Character [_] (char (.nextInt random)))
(defmethod arbitrary :ascii-character [_] (char (choose (range 32  
128))))

(defmethod arbitrary String [_]
  (apply str (take (collection-size) (iterate (fn[_] (arbitrary  
Character)) nil))))
(defmethod arbitrary :ascii-string [_]
  (apply str (take (collection-size) (iterate (fn[_] (arbitrary :ascii- 
character)) nil))))

(defmacro binding-values [& vars]
  `(vector ~@(map (fn [v] `['~v ~v]) vars)))

(defmacro for-all [args & forms]
  (let [vars (take-nth 2 args)
        value-generators (map (fn [x] `(arbitrary ~x))(take-nth 2 (rest  
args)))]
    `(do
       ~@(map (fn [f]
                `(dotimes i# *check-count*
                   (let ~(apply vector (interleave vars value-generators))
                     (is (true? ~f) (pr-str (binding-values [EMAIL 
PROTECTED]))))))
              forms))))

        

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to