aboutsummaryrefslogtreecommitdiff
path: root/src/clojure/contrib/test_clojure/evaluation.clj
diff options
context:
space:
mode:
Diffstat (limited to 'src/clojure/contrib/test_clojure/evaluation.clj')
-rw-r--r--src/clojure/contrib/test_clojure/evaluation.clj230
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)