Skip to content

Commit c55d585

Browse files
authored
Add tests for eval (#868)
* Add tests for `eval` * Use single reader conditional to avoid testing eval in cljs * Add tests for eval-ing functions * Add more function tests * Add var test * Test eval'ing an eval form * Fix comment * Test infinite sequence * Add one more level of recursive evaluation * Bypass function tests for Basilisp
1 parent ee60cc6 commit c55d585

1 file changed

Lines changed: 78 additions & 0 deletions

File tree

test/clojure/core_test/eval.cljc

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
(ns clojure.core-test.eval
2+
(:require [clojure.test :as t :refer [are deftest is testing]]
3+
[clojure.core-test.portability #?(:cljs :refer-macros :default :refer) [when-var-exists] :as p]
4+
#?(:cljs [cljs.js]))) ; need this for eval support in CLJS
5+
6+
(when-var-exists eval
7+
(def x 42)
8+
9+
(deftest test-eval
10+
#?(:cljs nil
11+
:default
12+
(do (testing "Strings, numbers, characters, true, false, nil and keywords evaluate to themselves."
13+
(are [expected form] (= expected (eval form))
14+
;; lots of Clojure objects just evaluate to themselves
15+
1 1
16+
0 0
17+
-1 -1
18+
1.0 1.0
19+
1N 1N
20+
1.0M 1.0M
21+
1/2 1/2
22+
"a string" "a string"
23+
"(+ 1 2)" "(+ 1 2)" ; strings are just evaluated as strings
24+
\x \x
25+
true true
26+
false false
27+
nil nil
28+
:a-keyword :a-keyword))
29+
30+
(testing "Functions"
31+
#?(:lpy nil
32+
:default (is (fn? (eval (fn [x] x)))))
33+
(is (fn? (eval '(fn [x] x))))
34+
#?(:lpy nil
35+
:default (is (fn? (eval +))))
36+
(is (fn? (eval '+))))
37+
38+
(testing "Vars"
39+
;; eval'ing a var just returns the var
40+
(is (var? (eval '(var +)))))
41+
42+
(testing "Symbol resolution"
43+
;; namespace qualified
44+
(is (= 42 (eval 'clojure.core-test.eval/x))))
45+
46+
(testing "Vectors, Maps, Sets"
47+
;; basic literal collections
48+
(is (= [:a :b] (eval [:a :b])))
49+
(is (= {:a :b} (eval {:a :b})))
50+
(is (= #{:a :b} (eval #{:a :b})))
51+
;; collections with embedded symbols
52+
(is (= [:a :b 42] (eval [:a :b 'clojure.core-test.eval/x]))))
53+
54+
(testing "Lists, function application, and macros"
55+
;; empty list evaluates to itself
56+
(is (= '() (eval '())))
57+
;; function calls
58+
(is (= 5 (eval '(+ 2 3))))
59+
(is (= 6 (eval '(* 2 3))))
60+
;; macros
61+
(is (= 42 (eval '(or false clojure.core-test.eval/x))))
62+
(is (= 42 (eval '(and (+ 2 3) clojure.core-test.eval/x))))
63+
;; special forms
64+
(is (= 43 (eval '(let [y 43] (or false y)))))
65+
(is (= 43 (eval '(loop [y 0] (if (= y 43) y (recur (inc y))))))))
66+
67+
(testing "Infinite sequence"
68+
;; The `(range)` form is a lazy infinite sequence. If it
69+
;; remains unrealized by the `eval`, as it should, then
70+
;; we should get back an implementation-specific value of
71+
;; some sort. If the sequence is fully realized, then
72+
;; we'd expect to get an out-of-memory Exception which
73+
;; will throw and fail the test.
74+
(is (eval '(range))))
75+
76+
(testing "Recursive eval"
77+
(is (= 1 (eval '(eval 1))))
78+
(is (= 1 (eval '(eval (eval 1))))))))))

0 commit comments

Comments
 (0)