annotate src/clojure/contrib/test_is.clj @ 10:ef7dbbd6452c

added clojure source goodness
author Robert McIntyre <rlm@mit.edu>
date Sat, 21 Aug 2010 06:25:44 -0400
parents
children
rev   line source
rlm@10 1 ;;; test_is.clj: Compatibility layer for old clojure.contrib.test-is
rlm@10 2
rlm@10 3 ;; by Stuart Sierra, http://stuartsierra.com/
rlm@10 4 ;; August 28, 2009
rlm@10 5
rlm@10 6 ;; Copyright (c) Stuart Sierra, 2009. All rights reserved. The use
rlm@10 7 ;; and distribution terms for this software are covered by the Eclipse
rlm@10 8 ;; Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
rlm@10 9 ;; which can be found in the file epl-v10.html at the root of this
rlm@10 10 ;; distribution. By using this software in any fashion, you are
rlm@10 11 ;; agreeing to be bound by the terms of this license. You must not
rlm@10 12 ;; remove this notice, or any other, from this software.
rlm@10 13
rlm@10 14 ;; DEPRECATED in 1.2: Moved to clojure.test
rlm@10 15
rlm@10 16 (ns ^{:deprecated "1.2"
rlm@10 17 :doc "Backwards-compatibility for clojure.contrib.test-is
rlm@10 18
rlm@10 19 The clojure.contrib.test-is library moved from Contrib into the
rlm@10 20 Clojure distribution as clojure.test.
rlm@10 21
rlm@10 22 This happened on or around clojure-contrib Git commit
rlm@10 23 82cf0409d0fcb71be477ebfc4da18ee2128a2ad1 on June 25, 2009.
rlm@10 24
rlm@10 25 This file makes the clojure.test interface available under the old
rlm@10 26 namespace clojure.contrib.test-is.
rlm@10 27
rlm@10 28 This includes support for the old syntax of the 'are' macro.
rlm@10 29
rlm@10 30 This was suggested by Howard Lewis Ship in ticket #26,
rlm@10 31 http://www.assembla.com/spaces/clojure-contrib/tickets/26"
rlm@10 32 :author "Stuart Sierra"}
rlm@10 33 clojure.contrib.test-is
rlm@10 34 (:require clojure.test
rlm@10 35 [clojure.walk :as walk]))
rlm@10 36
rlm@10 37
rlm@10 38 ;;; COPY INTERNED VARS (EXCEPT are) FROM clojure.test
rlm@10 39
rlm@10 40 (doseq [v (disj (set (vals (ns-interns 'clojure.test)))
rlm@10 41 #'clojure.test/are)]
rlm@10 42 (intern *ns* (with-meta (:name (meta v)) (meta v)) (var-get v)))
rlm@10 43
rlm@10 44
rlm@10 45 ;;; REDEFINE OLD clojure.contrib.template
rlm@10 46
rlm@10 47 (defn find-symbols
rlm@10 48 "Recursively finds all symbols in form."
rlm@10 49 [form]
rlm@10 50 (distinct (filter symbol? (tree-seq coll? seq form))))
rlm@10 51
rlm@10 52 (defn find-holes
rlm@10 53 "Recursively finds all symbols starting with _ in form."
rlm@10 54 [form]
rlm@10 55 (sort (distinct (filter #(.startsWith (name %) "_")
rlm@10 56 (find-symbols form)))))
rlm@10 57
rlm@10 58 (defn find-pure-exprs
rlm@10 59 "Recursively finds all sub-expressions in form that do not contain
rlm@10 60 any symbols starting with _"
rlm@10 61 [form]
rlm@10 62 (filter #(and (list? %)
rlm@10 63 (empty? (find-holes %)))
rlm@10 64 (tree-seq seq? seq form)))
rlm@10 65
rlm@10 66 (defn flatten-map
rlm@10 67 "Transforms a map into a vector like [key value key value]."
rlm@10 68 [m]
rlm@10 69 (reduce (fn [coll [k v]] (conj coll k v))
rlm@10 70 [] m))
rlm@10 71
rlm@10 72 (defn template?
rlm@10 73 "Returns true if form is a valid template expression."
rlm@10 74 [form]
rlm@10 75 (if (seq (find-holes form)) true false))
rlm@10 76
rlm@10 77 (defn apply-template
rlm@10 78 "Replaces _1, _2, _3, etc. in expr with corresponding elements of
rlm@10 79 values. Returns the modified expression. For use in macros."
rlm@10 80 [expr values]
rlm@10 81 (when-not (template? expr)
rlm@10 82 (throw (IllegalArgumentException. (str (pr-str expr) " is not a valid template."))))
rlm@10 83 (let [expr (walk/postwalk-replace {'_ '_1} expr)
rlm@10 84 holes (find-holes expr)
rlm@10 85 smap (zipmap holes values)]
rlm@10 86 (walk/prewalk-replace smap expr)))
rlm@10 87
rlm@10 88 (defmacro do-template
rlm@10 89 "Repeatedly evaluates template expr (in a do block) using values in
rlm@10 90 args. args are grouped by the number of holes in the template.
rlm@10 91 Example: (do-template (check _1 _2) :a :b :c :d)
rlm@10 92 expands to (do (check :a :b) (check :c :d))"
rlm@10 93 [expr & args]
rlm@10 94 (when-not (template? expr)
rlm@10 95 (throw (IllegalArgumentException. (str (pr-str expr) " is not a valid template."))))
rlm@10 96 (let [expr (walk/postwalk-replace {'_ '_1} expr)
rlm@10 97 argcount (count (find-holes expr))]
rlm@10 98 `(do ~@(map (fn [a] (apply-template expr a))
rlm@10 99 (partition argcount args)))))
rlm@10 100
rlm@10 101
rlm@10 102
rlm@10 103 ;;; REDEFINE are MACRO TO MATCH OLD TEMPLATE BEHAVIOR
rlm@10 104
rlm@10 105 (defmacro are
rlm@10 106 "Checks multiple assertions with a template expression.
rlm@10 107 See clojure.contrib.template/do-template for an explanation of
rlm@10 108 templates.
rlm@10 109
rlm@10 110 Example: (are (= _1 _2)
rlm@10 111 2 (+ 1 1)
rlm@10 112 4 (* 2 2))
rlm@10 113 Expands to:
rlm@10 114 (do (is (= 2 (+ 1 1)))
rlm@10 115 (is (= 4 (* 2 2))))
rlm@10 116
rlm@10 117 Note: This breaks some reporting features, such as line numbers."
rlm@10 118 [expr & args]
rlm@10 119 `(do-template (is ~expr) ~@args))