|
1 | 1 | (ns sci.core-test |
2 | 2 | (:require |
| 3 | + #?(:clj [sci.ctx-store :as store]) |
3 | 4 | [clojure.edn :as edn] |
4 | 5 | [clojure.string :as str] |
5 | 6 | [clojure.test :as test :refer [deftest is testing]] |
6 | | - #?(:clj [sci.ctx-store :as store]) |
7 | 7 | [sci.copy-ns-test-ns] |
8 | | - [sci.core :as sci :refer [eval-string]] |
| 8 | + [sci.core :as sci] |
9 | 9 | [sci.impl.unrestrict :as unrestrict] |
10 | 10 | [sci.test-utils :as tu])) |
11 | 11 |
|
|
755 | 755 | (def state (atom [])) |
756 | 756 | (doseq [i [1 2 3]] (swap! state conj i)) |
757 | 757 | @state" |
758 | | - {})))) |
| 758 | + {})))) |
759 | 759 |
|
760 | 760 | (deftest for-test |
761 | 761 | (is (= '([1 4] [1 6]) |
|
902 | 902 | (is (thrown? js/Error |
903 | 903 | (sci/eval-string "(try (throw \"blah\") (catch js/Error e (str e e)))"))) |
904 | 904 | (is (= "blahblah" (sci/eval-string "(try (throw \"blah\") (catch :default e (str e e)))"))))) |
905 | | - (is (= [1](sci/eval-string "(defn catch [] 1) (try [(catch)])")))) |
| 905 | + (is (= [1] (sci/eval-string "(defn catch [] 1) (try [(catch)])")))) |
906 | 906 |
|
907 | 907 | (deftest syntax-quote-test |
908 | 908 | (is (= '(clojure.core/list 10 10) |
|
967 | 967 | (when-not tu/native? |
968 | 968 | (is (= ":dude\n:dude\n" |
969 | 969 | (let [out (sci/with-out-str |
970 | | - (eval-string "(defmacro foo [x] (list 'do x x)) (foo (prn :dude))"))] |
| 970 | + (sci/eval-string "(defmacro foo [x] (list 'do x x)) (foo (prn :dude))"))] |
971 | 971 | out)))))) |
972 | 972 |
|
973 | 973 | (deftest declare-test |
|
1107 | 1107 | (is (= '(clojure.core/defrecord Foo []) (eval* "(macroexpand '(defrecord Foo []))"))) |
1108 | 1108 | (is (= '(. nil log) (eval* "(macroexpand-1 '(.log))"))) |
1109 | 1109 | (is (= '(. js/console log) (eval* "(macroexpand-1 '(.log js/console))"))) |
1110 | | - (is (= '(. js/console log 1 2 3) (eval* "(macroexpand-1 '(.log js/console 1 2 3))"))) |
1111 | | - ) |
| 1110 | + (is (= '(. js/console log 1 2 3) (eval* "(macroexpand-1 '(.log js/console 1 2 3))")))) |
1112 | 1111 |
|
1113 | 1112 | (deftest macroexpand-call-test |
1114 | 1113 | (is (= [1 1] (eval* "(defmacro foo [x] `(bar ~x)) (defmacro bar [x] [x x]) (macroexpand '(foo 1))"))) |
|
1157 | 1156 | {:load-fn (fn [{:keys [:namespace]}] |
1158 | 1157 | (case namespace |
1159 | 1158 | foo {:file "foo.clj" |
1160 | | - :source "(ns foo) (println \"hello\")"}))}))))))) |
| 1159 | + :source "(ns foo) (println \"hello\")"}))}))))))) |
1161 | 1160 |
|
1162 | 1161 | (deftest reload-all-test |
1163 | 1162 | (when-not tu/native? |
|
1454 | 1453 | (is (= 2 (sci/eval-form @C 'n/foo))))) |
1455 | 1454 |
|
1456 | 1455 | (deftest merge-opts-preserves-features-test |
1457 | | - (let [ctx(sci/init {:features #{:cljs}})] |
| 1456 | + (let [ctx (sci/init {:features #{:cljs}})] |
1458 | 1457 | (is (= 2 (sci/eval-string* ctx "#?(:clj 1 :cljs 2)"))) |
1459 | 1458 | (is (= 2 (sci/eval-string* (sci/merge-opts ctx {}) "#?(:clj 1 :cljs 2)"))))) |
1460 | 1459 |
|
|
1654 | 1653 | 'format-stacktrace sci/format-stacktrace}}})] |
1655 | 1654 | (is (str/includes? (str st) "1:31")))) |
1656 | 1655 |
|
| 1656 | +(deftest sci-error-multiple-catches-test |
| 1657 | + (testing "^:sci/error works with multiple catch clauses - specific catch first" |
| 1658 | + (let [result (sci/eval-string |
| 1659 | + (-> "(defn foo [] (/ 1 0)) |
| 1660 | + (defn bar [] |
| 1661 | + (try (foo) |
| 1662 | + (catch ArithmeticException e |
| 1663 | + {:caught :arithmetic :msg (ex-message e)}) |
| 1664 | + (catch ^:sci/error Exception e |
| 1665 | + {:caught :exception}))) |
| 1666 | + (bar)" |
| 1667 | + #?(:cljs (str/replace "ArithmeticException" "js/RangeError")) |
| 1668 | + #?(:cljs (str/replace "Exception" "js/Error")) |
| 1669 | + #?(:cljs (str/replace "(/ 1 0)" "(js/Array. -1)"))) |
| 1670 | + {:classes #?(:clj {'ArithmeticException ArithmeticException} |
| 1671 | + :cljs {:allow :all 'js js/global})})] |
| 1672 | + (is (= :arithmetic (:caught result))) |
| 1673 | + (is (str/includes? (:msg result) #?(:clj "Divide by zero" |
| 1674 | + :cljs "length"))))) |
| 1675 | + (testing "^:sci/error Exception catch still gets location info with multiple catches" |
| 1676 | + (let [result (sci/eval-string |
| 1677 | + (-> "(require '[sci.core :as sci]) |
| 1678 | + (defn foo [] (assoc :foo :bar)) |
| 1679 | + (defn bar [] |
| 1680 | + (try (foo) |
| 1681 | + (catch ArithmeticException e |
| 1682 | + {:caught :not-found}) |
| 1683 | + (catch ^:sci/error Exception e |
| 1684 | + {:caught :exception :st (sci/format-stacktrace (sci/stacktrace e))}))) |
| 1685 | + (bar)" |
| 1686 | + #?(:cljs (str/replace "ArithmeticException" "js/RangeError")) |
| 1687 | + #?(:cljs (str/replace "Exception" "js/Error"))) |
| 1688 | + {:classes #?(:clj {'ArithmeticException ArithmeticException} |
| 1689 | + :cljs {:allow :all 'js js/global}) |
| 1690 | + :namespaces {'sci.core {'stacktrace sci/stacktrace |
| 1691 | + 'format-stacktrace sci/format-stacktrace}}})] |
| 1692 | + (is (= :exception (:caught result))) |
| 1693 | + ;; Check that we have location info (user/foo on line 2) |
| 1694 | + (is (str/includes? (str (:st result)) "user/foo")) |
| 1695 | + (is (str/includes? (str (:st result)) ":2:"))))) |
| 1696 | + |
1657 | 1697 | (deftest var->sym-test |
1658 | 1698 | (is (= 'clojure.core/inc (sci/var->symbol (sci/eval-string "#'inc"))))) |
1659 | 1699 |
|
|
1726 | 1766 | (is (true? (sci/eval-string "(exists? js/console.log)" {:classes {'js js/globalThis |
1727 | 1767 | :allow :all}}))) |
1728 | 1768 | (is (false? (sci/eval-string "(exists? js/foo.bar)" {:classes {'js js/globalThis |
1729 | | - :allow :all}}))) |
| 1769 | + :allow :all}}))) |
1730 | 1770 | (is (false? (sci/eval-string "(exists? js/console.log.foobar)" {:classes {'js js/globalThis |
1731 | 1771 | :allow :all}}))) |
1732 | 1772 | (is (false? (sci/eval-string "(exists? console.log)" {:classes {'js js/globalThis |
|
0 commit comments