summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStuart Halloway <stu@thinkrelevance.com>2010-05-27 23:00:45 -0400
committerStuart Halloway <stu@thinkrelevance.com>2010-05-28 07:53:42 -0400
commitd694d6d45fb46195ae4de01aab9a2b9f9c06355f (patch)
tree3932020284d3862ac27bc2f6f2a2ff4b41a13cca
parentb2f9b4413ed0a7a299a286663e07c26445db013b (diff)
place to hang defn error messages
Signed-off-by: Stuart Halloway <stu@thinkrelevance.com>
-rw-r--r--src/clj/clojure/core.clj10
-rw-r--r--test/clojure/test_clojure/def.clj16
-rw-r--r--test/clojure/test_clojure/helpers.clj24
-rw-r--r--test/clojure/test_clojure/protocols.clj27
4 files changed, 52 insertions, 25 deletions
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj
index 65b3bc2d..b3f364c6 100644
--- a/src/clj/clojure/core.clj
+++ b/src/clj/clojure/core.clj
@@ -191,10 +191,14 @@
with-meta (fn with-meta [^clojure.lang.IObj x m]
(. x (withMeta m))))
+(def ^{:private true :dynamic true}
+ assert-valid-fdecl (fn [fdecl]))
+
(def
^{:private true}
sigs
(fn [fdecl]
+ (assert-valid-fdecl fdecl)
(let [asig
(fn [fdecl]
(let [arglist (first fdecl)
@@ -5652,3 +5656,9 @@
(keepi (inc idx) (rest s))
(cons x (keepi (inc idx) (rest s)))))))))]
(keepi 0 coll))))
+
+(defn- ^{:dynamic true} assert-valid-fdecl
+ "A good fdecl looks like (([a] ...) ([a b] ...)) near the end of defn."
+ [fdecl]
+ (if-let [bad-args (seq (remove #(vector? %) (map first fdecl)))]
+ (throw (IllegalArgumentException. (str "Parameter declaration " (first bad-args) " should be a vector")))))
diff --git a/test/clojure/test_clojure/def.clj b/test/clojure/test_clojure/def.clj
new file mode 100644
index 00000000..950f2a68
--- /dev/null
+++ b/test/clojure/test_clojure/def.clj
@@ -0,0 +1,16 @@
+; Copyright (c) Rich Hickey. All rights reserved.
+; The use and distribution terms for this software are covered by the
+; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+; which can be found in the file epl-v10.html at the root of this distribution.
+; By using this software in any fashion, you are agreeing to be bound by
+; the terms of this license.
+; You must not remove this notice, or any other, from this software.
+
+(ns clojure.test-clojure.def
+ (:use clojure.test clojure.test-clojure.helpers
+ clojure.test-clojure.protocols))
+
+(deftest defn-error-messages
+ (testing "bad arglist forms"
+ (is (fails-with-cause? IllegalArgumentException '#"Parameter declaration arg1 should be a vector"
+ (eval-in-temp-ns (defn foo (arg1 arg2)))))))
diff --git a/test/clojure/test_clojure/helpers.clj b/test/clojure/test_clojure/helpers.clj
index 42e88047..777b5f64 100644
--- a/test/clojure/test_clojure/helpers.clj
+++ b/test/clojure/test_clojure/helpers.clj
@@ -25,3 +25,27 @@
(eval
'(do ~@forms))))
+(defn causes
+ [^Throwable throwable]
+ (loop [causes []
+ t throwable]
+ (if t (recur (conj causes t) (.getCause t)) causes)))
+
+;; this is how I wish clojure.test/thrown? worked...
+;; Does body throw expected exception, anywhere in the .getCause chain?
+(defmethod assert-expr 'fails-with-cause?
+ [msg [_ exception-class msg-re & body :as form]]
+ `(try
+ ~@body
+ (report {:type :fail, :message ~msg, :expected '~form, :actual nil})
+ (catch Throwable t#
+ (if (some (fn [cause#]
+ (and
+ (= ~exception-class (class cause#))
+ (re-find ~msg-re (.getMessage cause#))))
+ (causes t#))
+ (report {:type :pass, :message ~msg,
+ :expected '~form, :actual t#})
+ (report {:type :fail, :message ~msg,
+ :expected '~form, :actual t#})))))
+
diff --git a/test/clojure/test_clojure/protocols.clj b/test/clojure/test_clojure/protocols.clj
index 52aa346f..b0f48453 100644
--- a/test/clojure/test_clojure/protocols.clj
+++ b/test/clojure/test_clojure/protocols.clj
@@ -10,33 +10,10 @@
(ns clojure.test-clojure.protocols
(:use clojure.test clojure.test-clojure.protocols.examples)
- (:require [clojure.test-clojure.protocols.more-examples :as other])
+ (:require [clojure.test-clojure.protocols.more-examples :as other]
+ clojure.test-clojure.helpers)
(:import [clojure.test_clojure.protocols.examples ExampleInterface]))
-(defn causes
- [^Throwable throwable]
- (loop [causes []
- t throwable]
- (if t (recur (conj causes t) (.getCause t)) causes)))
-
-;; this is how I wish clojure.test/thrown? worked...
-;; Does body throw expected exception, anywhere in the .getCause chain?
-(defmethod assert-expr 'fails-with-cause?
- [msg [_ exception-class msg-re & body :as form]]
- `(try
- ~@body
- (report {:type :fail, :message ~msg, :expected '~form, :actual nil})
- (catch Throwable t#
- (if (some (fn [cause#]
- (and
- (= ~exception-class (class cause#))
- (re-find ~msg-re (.getMessage cause#))))
- (causes t#))
- (report {:type :pass, :message ~msg,
- :expected '~form, :actual t#})
- (report {:type :fail, :message ~msg,
- :expected '~form, :actual t#})))))
-
;; temporary hack until I decide how to cleanly reload protocol
(defn reload-example-protocols
[]