add from-clj to convert rhino to clojure objects
This commit is contained in:
parent
91cfb163e9
commit
eb42749079
|
@ -1,14 +1,22 @@
|
|||
(ns clj-rhino
|
||||
(:refer-clojure :exclude (eval get get-in set!))
|
||||
(:import [org.mozilla.javascript Context UniqueTag]))
|
||||
(:import [org.mozilla.javascript Context UniqueTag NativeArray NativeObject]))
|
||||
|
||||
(defprotocol RhinoConvertible
|
||||
(-to-rhino [object scope ctx] "convert a value to a rhino compatible type"))
|
||||
|
||||
(defprotocol ClojureConvertible
|
||||
(-from-rhino [object]
|
||||
"convert a value from rhino to a more clojure friendly representation"))
|
||||
|
||||
(defn to-js [obj scope ctx]
|
||||
"convert obj to a rhino compatible object"
|
||||
(-to-rhino obj scope ctx))
|
||||
|
||||
(defn from-js [obj]
|
||||
"convert obj from rhino into a clojure friendly representation"
|
||||
(-from-rhino obj))
|
||||
|
||||
(defn- return-self [obj scope ctx] obj)
|
||||
|
||||
(defn to-js-array [arr scope ctx]
|
||||
|
@ -52,6 +60,31 @@
|
|||
;; Maybe a Java array, otherwise fail
|
||||
(extend java.lang.Object RhinoConvertible {:-to-rhino to-js-generic})
|
||||
|
||||
(defn- entryset-to-pair [entry]
|
||||
(let [str-key (.getKey entry)
|
||||
key (keyword str-key)
|
||||
js-value (.getValue entry)
|
||||
val (from-js js-value)]
|
||||
|
||||
[key val]))
|
||||
|
||||
(defn- from-js-object [obj]
|
||||
(apply hash-map (mapcat entryset-to-pair (.entrySet obj))))
|
||||
|
||||
(extend nil ClojureConvertible {:-from-rhino identity})
|
||||
(extend java.lang.Boolean ClojureConvertible {:-from-rhino identity})
|
||||
(extend java.lang.Number ClojureConvertible {:-from-rhino identity})
|
||||
(extend java.math.BigInteger ClojureConvertible {:-from-rhino identity})
|
||||
(extend java.math.BigDecimal ClojureConvertible {:-from-rhino identity})
|
||||
(extend java.lang.CharSequence ClojureConvertible {:-from-rhino identity})
|
||||
(extend java.lang.Object ClojureConvertible {:-from-rhino identity})
|
||||
; NOTE: undefined and null will return nil, there are other tags which should not
|
||||
; be produced from a js program
|
||||
; https://github.com/mozilla/rhino/blob/master/src/org/mozilla/javascript/UniqueTag.java
|
||||
(extend UniqueTag ClojureConvertible {:-from-rhino (fn [obj] nil)})
|
||||
(extend NativeObject ClojureConvertible {:-from-rhino from-js-object})
|
||||
(extend NativeArray ClojureConvertible {:-from-rhino (comp vec (partial map from-js))})
|
||||
|
||||
(def insecure-vars ["isXMLName" "uneval" "InternalError" "JavaException"
|
||||
"With" "Call" "Script" "Iterator" "StopIteration",
|
||||
"Packages" "java" "javax" "org" "com" "edu" "net"
|
||||
|
|
|
@ -16,6 +16,12 @@
|
|||
(is (= (js/to-js item scope ctx) js-item)))
|
||||
(map vector arr js-arr)))))
|
||||
|
||||
(defn- is-identity [value]
|
||||
(is (= (js/from-js value) value)))
|
||||
|
||||
(defn- assert-simetric-convertion [obj1 scope ctx obj2]
|
||||
(is (= (js/from-js (js/to-js obj1 scope ctx)) obj2)))
|
||||
|
||||
(deftest js-test
|
||||
(testing "undefined? works"
|
||||
(is (not (js/undefined? 1)))
|
||||
|
@ -114,4 +120,39 @@
|
|||
(js/with-context (fn [ctx]
|
||||
(let [scope (js/new-safe-scope)]
|
||||
(is (thrown? Exception (js/to-js (atom {}) scope ctx)))))))
|
||||
|
||||
(testing "from-js works"
|
||||
(is-identity nil)
|
||||
(is-identity 1)
|
||||
(is-identity 1.2)
|
||||
(is-identity "asd")
|
||||
(is-identity true)
|
||||
|
||||
(js/with-context
|
||||
(fn [ctx]
|
||||
(let [scope (js/new-safe-scope)]
|
||||
(is (= (js/from-js UniqueTag/NOT_FOUND) nil))
|
||||
(assert-simetric-convertion [] scope ctx [])
|
||||
(assert-simetric-convertion [1] scope ctx [1])
|
||||
(assert-simetric-convertion [1 nil] scope ctx [1 nil])
|
||||
(assert-simetric-convertion [1 nil 1.2] scope ctx [1 nil 1.2])
|
||||
(assert-simetric-convertion [1 nil 1.2 "asd"] scope ctx
|
||||
[1 nil 1.2 "asd"])
|
||||
(assert-simetric-convertion [1 nil 1.2 "asd" true] scope ctx
|
||||
[1 nil 1.2 "asd" true])
|
||||
|
||||
(assert-simetric-convertion {} scope ctx {})
|
||||
(assert-simetric-convertion {:b 1} scope ctx {:b 1})
|
||||
(assert-simetric-convertion {:b 1 "c" true} scope ctx
|
||||
{:b 1 :c true})
|
||||
(assert-simetric-convertion {:b 1 "c" true :foo nil} scope ctx
|
||||
{:b 1 :c true :foo nil})
|
||||
(assert-simetric-convertion {:b {:c {:d 4}}} scope ctx
|
||||
{:b {:c {:d 4}}})
|
||||
(assert-simetric-convertion {:b {"c" {:d 4}}} scope ctx
|
||||
{:b {:c {:d 4}}})
|
||||
(assert-simetric-convertion {:b {"c" {:d [{"e" 4}]}}} scope ctx
|
||||
{:b {:c {:d [{:e 4}]}}})
|
||||
))))
|
||||
)
|
||||
|
||||
|
|
Reference in a new issue