Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/sci/impl/namespaces.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,17 @@
g
(last steps)))))

(defn- assert-single-binding-vector [expr macro-name bindings]
(when-not (vector? bindings)
(utils/throw-error-with-location (str macro-name " requires a vector for its binding") expr))
(when-not (= 2 (count bindings))
(utils/throw-error-with-location (str macro-name " requires exactly 2 forms in binding vector") expr)))

(defn if-let*
([&form &env bindings then]
(if-let* &form &env bindings then nil))
([&form _&env bindings then else & _oldform]
(assert-single-binding-vector &form "if-let" bindings)
(let [form (bindings 0) tst (bindings 1)
tmp (gensym "temp")]
`(let [~tmp ~tst]
Expand All @@ -191,6 +198,7 @@
([&form &env bindings then]
(if-some* &form &env bindings then nil))
([&form _&env bindings then else & _oldform]
(assert-single-binding-vector &form "if-some" bindings)
(let [form (bindings 0) tst (bindings 1)
tmp (gensym "temp")]
`(let [~tmp ~tst]
Expand All @@ -203,6 +211,7 @@

(defn when-let*
[&form _&env bindings & body]
(assert-single-binding-vector &form "when-let" bindings)
(let [form (bindings 0) tst (bindings 1)
tmp (gensym "temp")]
`(let [~tmp ~tst]
Expand All @@ -219,6 +228,7 @@
~@body))))

(defn when-some* [&form _ bindings & body]
(assert-single-binding-vector &form "when-some" bindings)
(let [form (bindings 0) tst (bindings 1)
tmp (gensym "temp")]
`(let [~tmp ~tst]
Expand Down
20 changes: 18 additions & 2 deletions test/sci/core_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -1318,13 +1318,29 @@
(is (= 2 (eval* "(if-let [foo nil] 1 2)")))
(is (= 2 (eval* "(if-let [foo false] 1 2)")))
(is (= 2 (eval* "(if-some [foo nil] 1 2)")))
(is (= 1 (eval* "(if-some [foo false] 1 2)"))))
(is (= 1 (eval* "(if-some [foo false] 1 2)")))
(is (thrown-with-msg?
#?(:clj Exception :cljs js/Error)
#"if-let requires exactly 2 forms in binding vector"
(eval* "(if-let [x (range 5) y (range 5)] x :else)")))
(is (thrown-with-msg?
#?(:clj Exception :cljs js/Error)
#"if-some requires exactly 2 forms in binding vector"
(eval* "(if-some [x (range 5) y (range 5)] x :else)"))))

(deftest whens-test
(is (= nil (eval* "(when-let [foo nil] 1)")))
(is (= nil (eval* "(when-let [foo false] 1)")))
(is (= nil (eval* "(when-some [foo nil] 1)")))
(is (= 1 (eval* "(when-some [foo false] 1)"))))
(is (= 1 (eval* "(when-some [foo false] 1)")))
(is (thrown-with-msg?
#?(:clj Exception :cljs js/Error)
#"when-let requires exactly 2 forms in binding vector"
(eval* "(when-let [x (range 5) y (range 5)] x)")))
(is (thrown-with-msg?
#?(:clj Exception :cljs js/Error)
#"when-some requires exactly 2 forms in binding vector"
(eval* "(when-some [x (range 5) y (range 5)] x)"))))

(deftest read-string-eval-test
(is (= 3 (eval* "(load-string \"1 2 3\")")))
Expand Down
15 changes: 15 additions & 0 deletions test/sci/error_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,21 @@
(catch Exception e
(is (= [line col] ((juxt :line :column) (ex-data e))) snippet)))))

(deftest let-like-binding-arity-test
(doseq [[snippet expected-message]
[["(str (if-let [x 0 y 1] x))" "if-let requires exactly 2 forms in binding vector"]
["(str (when-let [x 0 y 1] x))" "when-let requires exactly 2 forms in binding vector"]
["(str (if-some [x 0 y 1] x))" "if-some requires exactly 2 forms in binding vector"]
["(str (when-some [x 0 y 1] x))" "when-some requires exactly 2 forms in binding vector"]]]
(try
(sci.core/eval-string snippet)
(is false snippet)
(catch Exception e
(is (= expected-message #?(:clj (.getMessage e)
:cljs (.-message e)))
snippet)
(is (= [1 6] ((juxt :line :column) (ex-data e))) snippet)))))

#?(:cljs
(deftest js-interop-test
(is (str/includes?
Expand Down
Loading