diff options
Diffstat (limited to 'src/clojure/contrib/test_clojure/evaluation.clj')
-rw-r--r-- | src/clojure/contrib/test_clojure/evaluation.clj | 230 |
1 files changed, 0 insertions, 230 deletions
diff --git a/src/clojure/contrib/test_clojure/evaluation.clj b/src/clojure/contrib/test_clojure/evaluation.clj deleted file mode 100644 index fdd84bba..00000000 --- a/src/clojure/contrib/test_clojure/evaluation.clj +++ /dev/null @@ -1,230 +0,0 @@ -;; Copyright (c) J. McConnell. All rights reserved. The use and -;; distribution terms for this software are covered by the Common Public -;; License 1.0 (http://opensource.org/licenses/cpl.php) which can be found -;; in the file CPL.TXT 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. -;; -;; clojure.contrib.test-clojure.evaluation.clj -;; -;; Tests for the Clojure functions documented at the URL: -;; -;; http://clojure.org/Evaluation -;; -;; by J. McConnell, http://ubermenschconsulting.com -;; Created 22 October 2008 - -(ns clojure.contrib.test-clojure.evaluation - (:use clojure.contrib.test-is)) - -(import '(java.lang Boolean) - '(clojure.lang Compiler Compiler$CompilerException)) - -(defmacro test-that - "Provides a useful way for specifying the purpose of tests. If the first-level - forms are lists that make a call to a test-is function, it supplies the - purpose as the msg argument to those functions. Otherwise, the purpose just - acts like a comment and the forms are run unchanged." - [purpose & test-forms] - (let [tests (map - #(if (= (:ns (meta (resolve (first %)))) - (the-ns 'clojure.contrib.test-is)) - (concat % (list purpose)) - %) - test-forms)] - `(do ~@tests))) - -(deftest Eval - (is (= (eval '(+ 1 2 3)) (Compiler/eval '(+ 1 2 3)))) - (is (= (eval '(list 1 2 3)) '(1 2 3))) - (is (= (eval '(list + 1 2 3)) (list clojure.core/+ 1 2 3))) - (test-that "Non-closure fns are supported as code" - (is (= (eval (eval '(list + 1 2 3))) 6))) - (is (= (eval (list '+ 1 2 3)) 6))) - -; not using Clojure's RT/classForName since a bug in it could hide a bug in -; eval's resolution -(defn class-for-name [name] - (java.lang.Class/forName name)) - -(defmacro in-test-ns [& body] - `(binding [*ns* *ns*] - (in-ns 'clojure.contrib.test-clojure.evaluation) - ~@body)) - -;;; Literals tests ;;; - -(defmacro #^{:private true} evaluates-to-itself? [expr] - `(let [v# ~expr - q# (quote ~expr)] - (is (= (eval q#) q#) (str q# " does not evaluate to itself")))) - -(deftest Literals - ; Strings, numbers, characters, nil and keywords should evaluate to themselves - (evaluates-to-itself? "test") - (evaluates-to-itself? "test - multi-line - string") - (evaluates-to-itself? 1) - (evaluates-to-itself? 1.0) - (evaluates-to-itself? 1.123456789) - (evaluates-to-itself? 1/2) - (evaluates-to-itself? 1M) - (evaluates-to-itself? 999999999999999999) - (evaluates-to-itself? \a) - (evaluates-to-itself? \newline) - (evaluates-to-itself? nil) - (evaluates-to-itself? :test) - ; Boolean literals should evaluate to Boolean.{TRUE|FALSE} - (is (identical? (eval true) Boolean/TRUE)) - (is (identical? (eval false) Boolean/FALSE))) - -;;; Symbol resolution tests ;;; - -(def foo "abc") -(in-ns 'resolution-test) -(def bar 123) -(def #^{:private true} baz 456) -(in-ns 'clojure.contrib.test-clojure.evaluation) - -(defn a-match? [re s] (not (nil? (re-matches re s)))) - -(defmacro throws-with-msg - ([re form] `(throws-with-msg ~re ~form Exception)) - ([re form x] `(throws-with-msg - ~re - ~form - ~(if (instance? Exception x) x Exception) - ~(if (instance? String x) x nil))) - ([re form class msg] - `(let [ex# (try - ~form - (catch ~class e# e#) - (catch Exception e# - (let [cause# (.getCause e#)] - (if (= ~class (class cause#)) cause# (throw e#)))))] - (is (a-match? ~re (.toString ex#)) - (or ~msg - (str "Expected exception that matched " (pr-str ~re) - ", but got exception with message: \"" ex#)))))) - -(deftest SymbolResolution - (test-that - "If a symbol is namespace-qualified, the evaluated value is the value - of the binding of the global var named by the symbol" - (is (= (eval 'resolution-test/bar) 123))) - - (test-that - "It is an error if there is no global var named by the symbol" - (throws-with-msg - #".*Unable to resolve symbol: bar.*" (eval 'bar))) - - (test-that - "It is an error if the symbol reference is to a non-public var in a - different namespace" - (throws-with-msg - #".*resolution-test/baz is not public.*" - (eval 'resolution-test/baz) - Compiler$CompilerException)) - - (test-that - "If a symbol is package-qualified, its value is the Java class named by the - symbol" - (is (= (eval 'java.lang.Math) (class-for-name "java.lang.Math")))) - - (test-that - "If a symbol is package-qualified, it is an error if there is no Class named - by the symbol" - (is (thrown? Compiler$CompilerException (eval 'java.lang.FooBar)))) - - (test-that - "If a symbol is not qualified, the following applies, in this order: - - 1. If it names a special form it is considered a special form, and must - be utilized accordingly. - - 2. A lookup is done in the current namespace to see if there is a mapping - from the symbol to a class. If so, the symbol is considered to name a - Java class object. - - 3. If in a local scope (i.e. in a function definition), a lookup is done - to see if it names a local binding (e.g. a function argument or - let-bound name). If so, the value is the value of the local binding. - - 4. A lookup is done in the current namespace to see if there is a mapping - from the symbol to a var. If so, the value is the value of the binding - of the var referred-to by the symbol. - - 5. It is an error." - - ; First - (doall (for [form '(def if do let quote var fn loop recur throw try - monitor-enter monitor-exit)] - (is (thrown? Compiler$CompilerException (eval form))))) - (let [if "foo"] - (is (thrown? Compiler$CompilerException (eval 'if))) - - ; Second - (is (= (eval 'Boolean) (class-for-name "java.lang.Boolean")))) - (let [Boolean "foo"] - (is (= (eval 'Boolean) (class-for-name "java.lang.Boolean")))) - - ; Third - (is (= (eval '(let [foo "bar"] foo)) "bar")) - - ; Fourth - (in-test-ns (is (= (eval 'foo) "abc"))) - (is (thrown? Compiler$CompilerException (eval 'bar))) ; not in this namespace - - ; Fifth - (is (thrown? Compiler$CompilerException (eval 'foobar))))) - -;;; Metadata tests ;;; - -(defstruct struct-with-symbols (with-meta 'k {:a "A"})) - -(deftest Metadata - (test-that - "If a Symbol has metadata, it will not be part of the resulting value" - (is (not (nil? (meta (with-meta (symbol "test") {:doc "doc"}))))) - (is (nil? (meta (eval (with-meta (symbol "test") {:doc "doc"})))))) - - (test-that - "find returns key symbols and their metadata" - (let [s (struct struct-with-symbols 1)] - (is (= {:a "A"} (meta (first (find s 'k)))))))) - -;;; Collections tests ;;; -(def x 1) -(def y 2) - -(deftest Collections - (in-test-ns - (test-that - "Vectors and Maps yield vectors and (hash) maps whose contents are the - evaluated values of the objects they contain." - (is (= (eval '[x y 3]) [1 2 3])) - (is (= (eval '{:x x :y y :z 3}) {:x 1 :y 2 :z 3})) - (is (instance? clojure.lang.IPersistentMap (eval '{:x x :y y}))))) - - (in-test-ns - (test-that - "Metadata maps yield maps whose contents are the evaluated values of - the objects they contain. If a vector or map has metadata, the evaluated - metadata map will become the metadata of the resulting value." - (is (= (eval #^{:x x} '[x y]) #^{:x 1} [1 2])))) - - (test-that - "An empty list () evaluates to an empty list." - (is (= (eval '()) ())) - (is (empty? (eval ()))) - (is (= (eval (list)) ()))) - - (test-that - "Non-empty lists are considered calls" - (is (thrown? Compiler$CompilerException (eval '(1 2 3)))))) - -(deftest Macros) - -(deftest Loading) |