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))
|