Skip to content

Commit

Permalink
[#558] Support :rename in :refer-clojure
Browse files Browse the repository at this point in the history
  • Loading branch information
borkdude committed Apr 9, 2021
1 parent 9fe09b6 commit 672a46d
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 69 deletions.
17 changes: 16 additions & 1 deletion src/sci/impl/load.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,22 @@
other-vars (select-keys other-ns v)]
;; TODO: this is wrong, don't merge these vars into the current namespace
(update-in env [:namespaces cnn]
merge other-vars)))))
merge other-vars))))
:rename
(swap! (:env ctx)
(fn [env]
(let [cnn (vars/current-ns-name)
namespaces (:namespaces env)
the-current-ns (get namespaces cnn)
other-ns (get-in env [:namespaces ns-sym])
the-current-ns
(reduce (fn [acc [original-name new-name]]
(-> acc
(assoc-in [:refers new-name] (get other-ns original-name))
(update-in [:refer ns-sym :exclude] (fnil conj #{}) original-name)))
the-current-ns
v)]
(assoc-in env [:namespaces cnn] the-current-ns)))))
(recur (nnext exprs)))))))

(defn eval-refer* [env ns-sym filters]
Expand Down
68 changes: 0 additions & 68 deletions test/sci/core_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -537,74 +537,6 @@
(println i) (println j))"
{:bindings {'println println}}))))))

(deftest require-test
(is (= "1-2-3" (eval* "(str/join \"-\" [1 2 3])")))
(is (= "1-2-3" (eval* "(require '[clojure.string :as string]) (string/join \"-\" [1 2 3])")))
(is (= "1-2-3" (eval* "(require '[clojure.string :refer [join]]) (join \"-\" [1 2 3])")))
(is (= "1-2-3" (eval* "(require '[clojure.string :refer :all]) (join \"-\" [1 2 3])")))
(is (thrown-with-msg? #?(:clj Exception :cljs js/Error)
#"must be a sequential"
(eval* "(require '[clojure.string :refer 1]) (join \"-\" [1 2 3])")))
(is (= #{1 4 6 3 2 5} (eval* "(set/union #{1 2 3} #{4 5 6})")))
(is (= #{1 4 6 3 2 5} (eval* "(require '[clojure.set :as s]) (s/union #{1 2 3} #{4 5 6})")))
(is (thrown-with-msg? #?(:clj Exception :cljs js/Error)
#"clojure.foo"
(eval* "(require '[clojure.foo :as s])")))
(is (thrown-with-msg? #?(:clj Exception :cljs js/Error)
#"quux does not exist"
(eval* "(require '[clojure.set :refer [quux]])")))
(is (= [1 2 3] (eval* "(ns foo) (def x 1) (ns bar) (def x 2) (in-ns 'baz) (def x 3) (require 'foo 'bar) [foo/x bar/x x]")))
(testing
"Require evaluates arguments"
(is (= [1 2 3] (eval* "
(ns foo)
(def x 1)
(ns bar)
(def x 2)
(in-ns 'baz)
(def x 3)
(require (symbol \"foo\") (symbol \"bar\"))
[foo/x bar/x x]"))))
(testing "require as function"
(is (= 1 (eval* "(ns foo) (defn foo [] 1) (ns bar) (apply require ['[foo :as f]]) (f/foo)"))))
(testing "rename"
(is (= #{1 2} (eval* "(require '[clojure.set :refer [union] :rename {union union2}]) (union2 #{1} #{2})"))))
(when-not tu/native?
(testing "load-fn + requiring-resolve"
(is (= :success
(tu/eval* "(deref (requiring-resolve 'foo.bar/x))"
{:load-fn (fn [{:keys [:namespace]}]
(when (= 'foo.bar namespace)
{:source "(ns foo.bar) (def x :success)"
:file "foo/bar.clj"}))})))))
(is (thrown-with-msg?
#?(:clj Exception :cljs js/Error)
#"already refers to"
(eval* "
(ns foo (:require [clojure.string :refer [split]]))
(declare split)"))))

(deftest use-test
(is (= #{1 2} (eval* "(ns foo (:use clojure.set)) (union #{1} #{2})")))
(is (= #{1 2} (eval* "(use 'clojure.set) (union #{1} #{2})")))
(is (= #{1 2} (eval* "(use '[clojure.set :only [union]]) (union #{1} #{2})")))
(is (thrown-with-msg?
#?(:clj Exception :cljs js/Error)
#"not.*resolve.*union"
(eval* "(use '[clojure.set :exclude [union]]) (union #{1} #{2})")))
(is (thrown-with-msg?
#?(:clj Exception :cljs js/Error)
#"not.*resolve.*union"
(eval* "(use '[clojure.set :only [difference]]) (union #{1} #{2})")))
(is (thrown-with-msg?
#?(:clj Exception :cljs js/Error)
#"already refers to"
(eval* "
(ns foo (:use clojure.string))
(declare split)"))))

(deftest cond-test
(is (= 2 (eval* "(let [x 2]
(cond (string? x) 1 (int? x) 2))")))
Expand Down
73 changes: 73 additions & 0 deletions test/sci/namespaces_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,79 @@
([binding form]
(tu/eval* form {:bindings {'*in* binding}})))

(deftest require-test
(is (= "1-2-3" (eval* "(str/join \"-\" [1 2 3])")))
(is (= "1-2-3" (eval* "(require '[clojure.string :as string]) (string/join \"-\" [1 2 3])")))
(is (= "1-2-3" (eval* "(require '[clojure.string :refer [join]]) (join \"-\" [1 2 3])")))
(is (= "1-2-3" (eval* "(require '[clojure.string :refer :all]) (join \"-\" [1 2 3])")))
(is (thrown-with-msg? #?(:clj Exception :cljs js/Error)
#"must be a sequential"
(eval* "(require '[clojure.string :refer 1]) (join \"-\" [1 2 3])")))
(is (= #{1 4 6 3 2 5} (eval* "(set/union #{1 2 3} #{4 5 6})")))
(is (= #{1 4 6 3 2 5} (eval* "(require '[clojure.set :as s]) (s/union #{1 2 3} #{4 5 6})")))
(is (thrown-with-msg? #?(:clj Exception :cljs js/Error)
#"clojure.foo"
(eval* "(require '[clojure.foo :as s])")))
(is (thrown-with-msg? #?(:clj Exception :cljs js/Error)
#"quux does not exist"
(eval* "(require '[clojure.set :refer [quux]])")))
(is (= [1 2 3] (eval* "(ns foo) (def x 1) (ns bar) (def x 2) (in-ns 'baz) (def x 3) (require 'foo 'bar) [foo/x bar/x x]")))
(testing
"Require evaluates arguments"
(is (= [1 2 3] (eval* "
(ns foo)
(def x 1)
(ns bar)
(def x 2)
(in-ns 'baz)
(def x 3)
(require (symbol \"foo\") (symbol \"bar\"))
[foo/x bar/x x]"))))
(testing "require as function"
(is (= 1 (eval* "(ns foo) (defn foo [] 1) (ns bar) (apply require ['[foo :as f]]) (f/foo)"))))
(testing "rename"
(is (= #{1 2} (eval* "(require '[clojure.set :refer [union] :rename {union union2}]) (union2 #{1} #{2})")))
(is (= 16 (eval* "(ns foo (:refer-clojure :rename {bit-shift-left <<})) (<< 8 1)")))
(is (thrown-with-msg?
#?(:clj Exception :cljs js/Error)
#"not.*resolve.*bit-shift-left"
(eval* "(ns foo (:refer-clojure :rename {bit-shift-left <<})) (bit-shift-left 8 1)"))))
(when-not tu/native?
(testing "load-fn + requiring-resolve"
(is (= :success
(tu/eval* "(deref (requiring-resolve 'foo.bar/x))"
{:load-fn (fn [{:keys [:namespace]}]
(when (= 'foo.bar namespace)
{:source "(ns foo.bar) (def x :success)"
:file "foo/bar.clj"}))})))))
(is (thrown-with-msg?
#?(:clj Exception :cljs js/Error)
#"already refers to"
(eval* "
(ns foo (:require [clojure.string :refer [split]]))
(declare split)"))))

(deftest use-test
(is (= #{1 2} (eval* "(ns foo (:use clojure.set)) (union #{1} #{2})")))
(is (= #{1 2} (eval* "(use 'clojure.set) (union #{1} #{2})")))
(is (= #{1 2} (eval* "(use '[clojure.set :only [union]]) (union #{1} #{2})")))
(is (thrown-with-msg?
#?(:clj Exception :cljs js/Error)
#"not.*resolve.*union"
(eval* "(use '[clojure.set :exclude [union]]) (union #{1} #{2})")))
(is (thrown-with-msg?
#?(:clj Exception :cljs js/Error)
#"not.*resolve.*union"
(eval* "(use '[clojure.set :only [difference]]) (union #{1} #{2})")))
(is (thrown-with-msg?
#?(:clj Exception :cljs js/Error)
#"already refers to"
(eval* "
(ns foo (:use clojure.string))
(declare split)"))))

(deftest misc-namespace-test
(is (= 1 (eval* "(alias (symbol \"c\") (symbol \"clojure.core\")) (c/and true 1)")))
(is (= #{1 3 2} (eval* "(mapv alias ['set1 'set2] ['clojure.set 'clojure.set]) (set2/difference
Expand Down

0 comments on commit 672a46d

Please sign in to comment.