diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj index 65b3bc2da3..b3f364c60c 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 0000000000..950f2a6876 --- /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 42e8804735..777b5f64a7 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 52aa346ffd..b0f48453f9 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 []