user> (= #{1 4} #{2 3})
true
it's not, is it?
Kind regards,
achim
I hope not!
Patch attached.
--Chouser
Hi,
user> (= #{1 4} #{2 3})
true
it's not, is it?
I've been thinking the same thing for awhile now and I'd love to help
contribute to an effort like this. Thanks for getting the idea out
there.
- J.
> I've been thinking the same thing for awhile now and I'd love to help
> contribute to an effort like this. Thanks for getting the idea out
> there.
You're welcome. It seems like clojure.contrib could be a more
convenient place to keep this than the wiki.
Direct or indirect contributions to clojure.contrib require that the
contributed code be written by the contributor and that the
contributor have a contributor agreement on file with Rich. Would that
be acceptable to people interested in participating? I appreciate the
care Rich showed and long view he took in coming up with the
Contributor Agreement process. I think it would be a good idea to
leverage that process for this effort as well.
Discussion of alternative proposals for a good way to do this and
place to keep it are welcome.
I made a start on this today. I started with the Reader page at
clojure.org and started making tests. I'm thinking of a structure like
this:
Run tests with:
(require 'clojure.contrib.test-clojure)
The definition of clojure.contrib.test-clojure requires subordinate
test namespaces like
'clojure.contrib.test-clojure.Reader
'clojure.contrib.test-clojure.Evaluation
'clojure.contrib.test-clojure.Special-Forms
...
with names that correspond to pages on the Clojure web site. After
requiring the individual test namespaces, test-clojure runs
"clojure.contrib.test-is/run-tests" on each one.
Here's a sample from clojure.contrib.test-clojure.
(ns clojure.contrib.test-clojure.Reader
(:use clojure.contrib.test-is))
(deftest t-Symbols
(is (= 'abc (symbol "abc")))
(is (= '*+!-_? (symbol "*+!-_?")))
(is (= 'abc:def:ghi (symbol "abc:def:ghi")))
(is (= 'abc/def (symbol "abc" "def")))
(is (= 'abc.def/ghi (symbol "abc.def" "ghi")))
(is (= 'abc/def.ghi (symbol "abc" "def.ghi")))
(is (= 'abc:def/ghi:jkl.mno (symbol "abc:def" "ghi:jkl.mno")))
(is (instance? clojure.lang.Symbol 'alphabet))
)
; additional tests to flesh out
(deftest t-Numbers)
(deftest t-Characters)
(deftest t-nil)
(deftest t-Booleans)
(deftest t-Keywords)
(deftest t-Lists)
(deftest t-Vectors)
(deftest t-Maps)
(deftest t-Sets)
(deftest t-Quote)
(deftest t-Character)
(deftest t-Comment)
(deftest t-Meta)
(deftest t-Deref)
(deftest t-Regex)
(deftest t-Metadata)
(deftest t-read)
and a run:
user=> (require 'clojure.contrib.test-clojure)
Testing #<Namespace: clojure.contrib.test-clojure.Reader>
Ran 18 tests with 10 assertions.
0 failures, 0 exceptions.
nil
user=>
(Currently the number of tests exceeds the number of assertions by so
much because of the placeholders.)
Tesing Clojure is a big project and will take a lot of work over time.
There many pieces and many interactions among them to test. The hope
is that having it available will allow Rich to make changes with an
even higher degree of confidence that they didn't have unintended
consequences and to support efforts like Chouser's ClojureScript to
bring Clojure to new platforms
Discussion and suggestions are welcome.
--Steve
Just put mine in the mail :)
Unless I hear that someone else has started, I guess I'll take a shot
at the Evaluation page next time I get a chance.
- J.
Sounds good.
> Was the example I posted enough to get you started?
I think so, it made sense to me. If I'm stumped (I'm thinking of
load-file here) I'll be sure to ask questions here or on IRC.
Thanks,
- J.
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 ~@vars))))))
forms))))
I don't see clojure.contrib.test-clojure. Are you going to be committing that?
Thanks,
- J.
(deftest t-Symbols
(is (= 'abc (symbol "abc")))
(is (= '*+!-_? (symbol "*+!-_?")))
(is (= 'abc:def:ghi (symbol "abc:def:ghi")))
(is (= 'abc/def (symbol "abc" "def")))
(is (= 'abc.def/ghi (symbol "abc.def" "ghi")))
(is (= 'abc/def.ghi (symbol "abc" "def.ghi")))
(is (= 'abc:def/ghi:jkl.mno (symbol "abc:def" "ghi:jkl.mno")))
(is (instance? clojure.lang.Symbol 'alphabet))
)
becomes:
(deftest t-Symbols
(check
(:equal
'abc (symbol "abc")
'*+!-_? (symbol "*+!-_?")
'abc:def:ghi (symbol "abc:def:ghi")
'abc/def (symbol "abc" "def")
'abc.def/ghi (symbol "abc.def" "ghi")
'abc/def.ghi (symbol "abc" "def.ghi")
'abc:def/ghi:jkl.mno (symbol "abc:def" "ghi:jkl.mno")
)
(instance? clojure.lang.Symbol 'alphabet)))
which is in my opinion much more readable. Any comments to this syntactic
enhancement?
Thank you, Frantisek
My first impression when I read that is that it's expecting each arg to be equal to each other, not the reality of being a list of (expected to be) equal pairs.
That's probably just me, I'm sure, but I find the original more readable and precise--something I think is key in tests, as tests are also documentation.
Dave
Yes, I am just trying to save on typing... ;-)
:equal could be also :equal-pairs. It introduces new (and maybe strange)
syntax...
Anyway, accepting multiple expressions would be nice.
Frantisek