Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Clojure CLR #96

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
13 changes: 12 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ jobs:
distribution: 'zulu'
java-version: '8'

- name: Prepare dotnet
uses: xt0rted/[email protected]

- name: Prepare Clojure CLR
run: |
dotnet tool install --global Clojure.Main --version 1.12.0-alpha10
dotnet tool install --global Clojure.Cljr --version 0.1.0-alpha4

- name: Install clojure tools
uses: DeLaGuardo/[email protected]
with:
Expand All @@ -25,5 +33,8 @@ jobs:
key: cljdeps-${{ hashFiles('project.clj') }}
restore-keys: cljdeps-

- name: Run tests
- name: Run clj and cljs tests
run: lein test-all

- name: Run cljr tests
run: cljr -X:test
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ Or to your Leiningen project file:

[dev.weavejester/medley "1.8.1"]

Or to your deps-clr.edn file:

io.github.weavejester/medley {:git/tag "FIXME" :git/sha "FIXME"}

## Documentation

* [API Docs](http://weavejester.github.io/medley/medley.core.html)
Expand Down
6 changes: 6 additions & 0 deletions deps-clr.edn
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{:paths ["src"]
:aliases
{:test {:extra-paths ["test"]
:extra-deps {io.github.dmiller/test-runner {:git/tag "v0.5.1clr" :git/sha "814e06f"}}
:exec-fn cognitect.test-runner.api/test
:exec-args {:dirs ["test"]}}}}
92 changes: 55 additions & 37 deletions src/medley/core.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@
(dissoc-in m ks))))

(defn- editable? [coll]
#?(:clj (instance? clojure.lang.IEditableCollection coll)
:cljs (satisfies? cljs.core/IEditableCollection coll)))
#?(:cljs (satisfies? cljs.core/IEditableCollection coll)
:default (instance? clojure.lang.IEditableCollection coll)))

(defn- assoc-some-transient! [m k v]
(if (nil? v) m (assoc! m k v)))
Expand Down Expand Up @@ -102,8 +102,8 @@
(defn map-entry
"Create a map entry for a key and value pair."
[k v]
#?(:clj (clojure.lang.MapEntry. k v)
:cljs (cljs.core/MapEntry. k v nil)))
#?(:cljs (cljs.core/MapEntry. k v nil)
:default (clojure.lang.MapEntry. k v)))

(defn map-kv
"Maps a function over the key/value pairs of an associative collection. Expects
Expand Down Expand Up @@ -184,21 +184,21 @@

(defn queue
"Creates an empty persistent queue, or one populated with a collection."
([] #?(:clj clojure.lang.PersistentQueue/EMPTY
:cljs cljs.core/PersistentQueue.EMPTY))
([] #?(:cljs cljs.core/PersistentQueue.EMPTY
:default clojure.lang.PersistentQueue/EMPTY))
([coll] (into (queue) coll)))

(defn queue?
"Returns true if x implements clojure.lang.PersistentQueue."
[x]
(instance? #?(:clj clojure.lang.PersistentQueue
:cljs cljs.core/PersistentQueue) x))
(instance? #?(:cljs cljs.core/PersistentQueue
:default clojure.lang.PersistentQueue) x))

(defn boolean?
"Returns true if x is a boolean."
[x]
#?(:clj (instance? Boolean x)
:cljs (or (true? x) (false? x))))
#?(:cljs (or (true? x) (false? x))
:default (instance? Boolean x)))

(defn least
"Return the least argument (as defined by the compare function) in O(n) time."
Expand Down Expand Up @@ -322,12 +322,14 @@
(persistent!
(reduce (fn [m v]
(let [k (keyf v)]
(assoc! m k #?(:clj (if-let [kv (find m k)]
(collatef (val kv) v)
(initf v))
:cljs (if (contains? m k)
(collatef (get m k) v)
(initf v))))))
(assoc! m k #?(:cljs
(if (contains? m k)
(collatef (get m k) v)
(initf v))
:default
(if-let [kv (find m k)]
(collatef (val kv) v)
(initf v))))))
(transient {})
coll))))

Expand Down Expand Up @@ -453,27 +455,31 @@
{:added "1.7.0"}
([pred]
(fn [rf]
(let [part #?(:clj (java.util.ArrayList.) :cljs (array-list))
(let [part #?(:clj (java.util.ArrayList.)
:cljr (System.Collections.ArrayList.)
:cljs (array-list))
prev (volatile! ::none)]
(fn
([] (rf))
([result]
(rf (if (.isEmpty part)
(rf (if #?(:cljr (zero? (.-Count part))
:default (.isEmpty part))
result
(let [v (vec (.toArray part))]
(.clear part)
(let [v (vec (#?(:cljr .ToArray :default .toArray) part))]
(#?(:cljr .Clear :default .clear) part)
(unreduced (rf result v))))))
([result input]
(let [p @prev]
(vreset! prev input)
(if (or (#?(:clj identical? :cljs keyword-identical?) p ::none)
(if (or (#?(:cljs keyword-identical? :default identical?) p ::none)
(not (pred p input)))
(do (.add part input) result)
(let [v (vec (.toArray part))]
(.clear part)
(do (#?(:cljr .Add :default .add) part input)
result)
(let [v (vec (#?(:cljr .ToArray :default .toArray) part))]
(#?(:cljr .Clear :default .clear) part)
(let [ret (rf result v)]
(when-not (reduced? ret)
(.add part input))
(#?(:cljr .Add :default .add) part input))
ret)))))))))
([pred coll]
(lazy-seq
Expand Down Expand Up @@ -601,14 +607,16 @@
This function therefore acts like an atomic `deref` then `swap!`."
{:arglists '([atom f & args])}
([atom f]
#?(:clj (loop []
(let [value @atom]
(if (compare-and-set! atom value (f value))
value
(recur))))
:cljs (let [value @atom]
(reset! atom (f value))
value)))
#?(:cljs
(let [value @atom]
(reset! atom (f value))
value)
:default
(loop []
(let [value @atom]
(if (compare-and-set! atom value (f value))
value
(recur))))))
([atom f & args]
(deref-swap! atom #(apply f % args))))

Expand All @@ -624,6 +632,7 @@
Clojure as well as ClojureScript."
[ex]
#?(:clj (when (instance? Throwable ex) (.getMessage ^Throwable ex))
:cljr (when (instance? Exception ex) (.-Message ^Exception ex))
:cljs (cljs.core/ex-message ex)))

(defn ex-cause
Expand All @@ -632,40 +641,49 @@
Clojure as well as ClojureScript."
[ex]
#?(:clj (when (instance? Throwable ex) (.getCause ^Throwable ex))
:cljr (when (instance? Exception ex) (.-InnerException ^Exception ex))
:cljs (cljs.core/ex-cause ex)))

(defn uuid?
"Returns true if the value is a UUID."
[x]
(instance? #?(:clj java.util.UUID :cljs cljs.core/UUID) x))
(instance? #?(:clj java.util.UUID
:cljr System.Guid
:cljs cljs.core/UUID) x))

(defn uuid
"Returns a UUID generated from the supplied string. Same as `cljs.core/uuid`
in ClojureScript, while in Clojure it returns a `java.util.UUID` object."
[s]
#?(:clj (java.util.UUID/fromString s)
:cljr (System.Guid. s)
:cljs (cljs.core/uuid s)))

(defn random-uuid
"Generates a new random UUID. Same as `cljs.core/random-uuid` except it works
for Clojure as well as ClojureScript."
[]
#?(:clj (java.util.UUID/randomUUID)
:cljr (System.Guid/NewGuid)
:cljs (cljs.core/random-uuid)))

(defn regexp?
"Returns true if the value is a regular expression."
{:added "1.4.0"}
[x]
(instance? #?(:clj java.util.regex.Pattern :cljs js/RegExp) x))
(instance? #?(:clj java.util.regex.Pattern
:cljr System.Text.RegularExpressions.Regex
:cljs js/RegExp) x))

(defn index-of
"Returns the index of the first occurrence of the item in the sequential
collection coll, or nil if not found."
{:added "1.9.0"}
[^java.util.List coll item]
#?(:clj [^java.util.List coll item]
:cljr [^System.Collections.IEnumerable coll item]
:default [coll item])
(when (some? coll)
(let [index (.indexOf coll item)]
(let [index (#?(:cljr .IndexOf :default .indexOf) coll item)]
(when-not (neg? index) index))))

(defn find-in
Expand Down
56 changes: 34 additions & 22 deletions test/medley/core_test.cljc
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
(ns medley.core-test
#?(:clj (:import [clojure.lang ArityException]))
(:require #?(:clj [clojure.test :refer :all]
:cljs [cljs.test :refer-macros [deftest is testing]])
#?@(:cljs []
:default [(:import [clojure.lang ArityException])])
(:require #?(:cljs [cljs.test :refer-macros [deftest is testing]]
:default [clojure.test :refer :all])
[medley.core :as m]))

(deftest test-find-first
Expand Down Expand Up @@ -162,17 +163,17 @@

(deftest test-queue
(testing "empty"
#?(:clj (is (instance? clojure.lang.PersistentQueue (m/queue)))
:cljs (is (instance? cljs.core.PersistentQueue (m/queue))))
#?(:cljs (is (instance? cljs.core.PersistentQueue (m/queue)))
:default (is (instance? clojure.lang.PersistentQueue (m/queue))))
(is (empty? (m/queue))))
(testing "not empty"
#?(:clj (is (instance? clojure.lang.PersistentQueue (m/queue [1 2 3])))
:cljs (is (instance? cljs.core.PersistentQueue (m/queue [1 2 3]))))
#?(:cljs (is (instance? cljs.core.PersistentQueue (m/queue [1 2 3])))
:default (is (instance? clojure.lang.PersistentQueue (m/queue [1 2 3]))))
(is (= (first (m/queue [1 2 3])) 1))))

(deftest test-queue?
#?(:clj (is (m/queue? clojure.lang.PersistentQueue/EMPTY))
:cljs (is (m/queue? cljs.core.PersistentQueue.EMPTY)))
#?(:cljs (is (m/queue? cljs.core.PersistentQueue.EMPTY))
:default (is (m/queue? clojure.lang.PersistentQueue/EMPTY)))
(is (not (m/queue? []))))

(deftest test-boolean?
Expand Down Expand Up @@ -241,9 +242,11 @@
(is (= (m/mapply foo 0 {:baz 1}) [0 1]))
(is (= (m/mapply foo 0 {:spam 1}) [0 nil]))
(is (= (m/mapply foo 0 nil) [0 nil]))
#?@(:clj [(is (thrown? ArityException (m/mapply foo {})))
(is (thrown? IllegalArgumentException (m/mapply foo 0)))]
:cljs [(is (thrown? js/Error (m/mapply foo 0)))])))
(is (thrown? #?(:clj IllegalArgumentException
:cljr ArgumentException
:cljs js/Error) (m/mapply foo 0)))
#?(:cljs (is (= (m/mapply foo {}) [nil nil]))
:default (is (thrown? ArityException (m/mapply foo {}))))))

(deftest test-collate-by
(is (= (m/collate-by identity conj vector [1 2 2 3 3])
Expand Down Expand Up @@ -451,10 +454,11 @@
(is (= (m/abs 2) 2))
(is (= (m/abs -2.1) 2.1))
(is (= (m/abs 1.8) 1.8))
#?@(:clj [(is (= (m/abs -1/3) 1/3))
(is (= (m/abs 1/2) 1/2))
(is (= (m/abs 3N) 3N))
(is (= (m/abs -4N) 4N))]))
#?@(:cljs []
:default [(is (= (m/abs -1/3) 1/3))
(is (= (m/abs 1/2) 1/2))
(is (= (m/abs 3N) 3N))
(is (= (m/abs -4N) 4N))]))

(deftest test-deref-swap!
(let [a (atom 0)]
Expand All @@ -472,12 +476,14 @@

(deftest test-ex-message
(is (= (m/ex-message (ex-info "foo" {})) "foo"))
(is (= (m/ex-message (new #?(:clj Exception :cljs js/Error) "bar")) "bar")))
(let [ex (new #?(:cljs js/Error :default Exception) "bar")]
(is (= (m/ex-message ex) "bar"))))

(deftest test-ex-cause
(let [cause (new #?(:clj Exception :cljs js/Error) "foo")]
(let [cause (new #?(:cljs js/Error :default Exception) "foo")]
(is (= (m/ex-cause (ex-info "foo" {} cause)) cause))
#?(:clj (is (= (m/ex-cause (Exception. "foo" cause)) cause)))))
#?@(:cljs []
:default [(is (= (m/ex-cause (Exception. "foo" cause)) cause))])))

(deftest test-uuid?
(let [x #uuid "d1a4adfa-d9cf-4aa5-9f05-a15365d1bfa6"]
Expand All @@ -488,14 +494,20 @@

(deftest test-uuid
(let [x (m/uuid "d1a4adfa-d9cf-4aa5-9f05-a15365d1bfa6")]
(is (instance? #?(:clj java.util.UUID :cljs cljs.core.UUID) x))
(is (instance? #?(:clj java.util.UUID
:cljr System.Guid
:cljs cljs.core.UUID) x))
(is (= x #uuid "d1a4adfa-d9cf-4aa5-9f05-a15365d1bfa6"))))

(deftest test-random-uuid
(let [x (m/random-uuid)
y (m/random-uuid)]
(is (instance? #?(:clj java.util.UUID :cljs cljs.core.UUID) x))
(is (instance? #?(:clj java.util.UUID :cljs cljs.core.UUID) y))
(is (instance? #?(:clj java.util.UUID
:cljr System.Guid
:cljs cljs.core.UUID) x))
(is (instance? #?(:clj java.util.UUID
:cljr System.Guid
:cljs cljs.core.UUID) y))
(is (not= x y))))

(deftest test-regexp?
Expand Down
Loading