Skip to content

Commit ebac1a4

Browse files
committed
Add support for Clojure CLR
1 parent 7c36bc6 commit ebac1a4

File tree

5 files changed

+111
-60
lines changed

5 files changed

+111
-60
lines changed

.github/workflows/test.yml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ jobs:
1313
distribution: 'zulu'
1414
java-version: '8'
1515

16+
- name: Prepare dotnet
17+
uses: xt0rted/setup-dotnet@v1.5.0
18+
19+
- name: Prepare Clojure CLR
20+
run: |
21+
dotnet tool install --global Clojure.Main --version 1.12.0-alpha10
22+
dotnet tool install --global Clojure.Cljr --version 0.1.0-alpha4
23+
1624
- name: Install clojure tools
1725
uses: DeLaGuardo/setup-clojure@10.1
1826
with:
@@ -25,5 +33,8 @@ jobs:
2533
key: cljdeps-${{ hashFiles('project.clj') }}
2634
restore-keys: cljdeps-
2735

28-
- name: Run tests
36+
- name: Run clj and cljs tests
2937
run: lein test-all
38+
39+
- name: Run cljr tests
40+
run: cljr -X:test

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ Or to your Leiningen project file:
1919

2020
[dev.weavejester/medley "1.8.1"]
2121

22+
Or to your deps-clr.edn file:
23+
24+
io.github.weavejester/medley {:git/tag "FIXME" :git/sha "FIXME"}
25+
2226
## Documentation
2327

2428
* [API Docs](http://weavejester.github.io/medley/medley.core.html)

deps-clr.edn

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{:paths ["src"]
2+
:aliases
3+
{:test {:extra-paths ["test"]
4+
:extra-deps {io.github.dmiller/test-runner {:git/tag "v0.5.1clr" :git/sha "814e06f"}}
5+
:exec-fn cognitect.test-runner.api/test
6+
:exec-args {:dirs ["test"]}}}}

src/medley/core.cljc

Lines changed: 55 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@
3838
(dissoc-in m ks))))
3939

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

4444
(defn- assoc-some-transient! [m k v]
4545
(if (nil? v) m (assoc! m k v)))
@@ -102,8 +102,8 @@
102102
(defn map-entry
103103
"Create a map entry for a key and value pair."
104104
[k v]
105-
#?(:clj (clojure.lang.MapEntry. k v)
106-
:cljs (cljs.core/MapEntry. k v nil)))
105+
#?(:cljs (cljs.core/MapEntry. k v nil)
106+
:default (clojure.lang.MapEntry. k v)))
107107

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

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

191191
(defn queue?
192192
"Returns true if x implements clojure.lang.PersistentQueue."
193193
[x]
194-
(instance? #?(:clj clojure.lang.PersistentQueue
195-
:cljs cljs.core/PersistentQueue) x))
194+
(instance? #?(:cljs cljs.core/PersistentQueue
195+
:default clojure.lang.PersistentQueue) x))
196196

197197
(defn boolean?
198198
"Returns true if x is a boolean."
199199
[x]
200-
#?(:clj (instance? Boolean x)
201-
:cljs (or (true? x) (false? x))))
200+
#?(:cljs (or (true? x) (false? x))
201+
:default (instance? Boolean x)))
202202

203203
(defn least
204204
"Return the least argument (as defined by the compare function) in O(n) time."
@@ -322,12 +322,14 @@
322322
(persistent!
323323
(reduce (fn [m v]
324324
(let [k (keyf v)]
325-
(assoc! m k #?(:clj (if-let [kv (find m k)]
326-
(collatef (val kv) v)
327-
(initf v))
328-
:cljs (if (contains? m k)
329-
(collatef (get m k) v)
330-
(initf v))))))
325+
(assoc! m k #?(:cljs
326+
(if (contains? m k)
327+
(collatef (get m k) v)
328+
(initf v))
329+
:default
330+
(if-let [kv (find m k)]
331+
(collatef (val kv) v)
332+
(initf v))))))
331333
(transient {})
332334
coll))))
333335

@@ -453,27 +455,31 @@
453455
{:added "1.7.0"}
454456
([pred]
455457
(fn [rf]
456-
(let [part #?(:clj (java.util.ArrayList.) :cljs (array-list))
458+
(let [part #?(:clj (java.util.ArrayList.)
459+
:cljr (System.Collections.ArrayList.)
460+
:cljs (array-list))
457461
prev (volatile! ::none)]
458462
(fn
459463
([] (rf))
460464
([result]
461-
(rf (if (.isEmpty part)
465+
(rf (if #?(:cljr (zero? (.-Count part))
466+
:default (.isEmpty part))
462467
result
463-
(let [v (vec (.toArray part))]
464-
(.clear part)
468+
(let [v (vec (#?(:cljr .ToArray :default .toArray) part))]
469+
(#?(:cljr .Clear :default .clear) part)
465470
(unreduced (rf result v))))))
466471
([result input]
467472
(let [p @prev]
468473
(vreset! prev input)
469-
(if (or (#?(:clj identical? :cljs keyword-identical?) p ::none)
474+
(if (or (#?(:cljs keyword-identical? :default identical?) p ::none)
470475
(not (pred p input)))
471-
(do (.add part input) result)
472-
(let [v (vec (.toArray part))]
473-
(.clear part)
476+
(do (#?(:cljr .Add :default .add) part input)
477+
result)
478+
(let [v (vec (#?(:cljr .ToArray :default .toArray) part))]
479+
(#?(:cljr .Clear :default .clear) part)
474480
(let [ret (rf result v)]
475481
(when-not (reduced? ret)
476-
(.add part input))
482+
(#?(:cljr .Add :default .add) part input))
477483
ret)))))))))
478484
([pred coll]
479485
(lazy-seq
@@ -601,14 +607,16 @@
601607
This function therefore acts like an atomic `deref` then `swap!`."
602608
{:arglists '([atom f & args])}
603609
([atom f]
604-
#?(:clj (loop []
605-
(let [value @atom]
606-
(if (compare-and-set! atom value (f value))
607-
value
608-
(recur))))
609-
:cljs (let [value @atom]
610-
(reset! atom (f value))
611-
value)))
610+
#?(:cljs
611+
(let [value @atom]
612+
(reset! atom (f value))
613+
value)
614+
:default
615+
(loop []
616+
(let [value @atom]
617+
(if (compare-and-set! atom value (f value))
618+
value
619+
(recur))))))
612620
([atom f & args]
613621
(deref-swap! atom #(apply f % args))))
614622

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

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

637647
(defn uuid?
638648
"Returns true if the value is a UUID."
639649
[x]
640-
(instance? #?(:clj java.util.UUID :cljs cljs.core/UUID) x))
650+
(instance? #?(:clj java.util.UUID
651+
:cljr System.Guid
652+
:cljs cljs.core/UUID) x))
641653

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

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

656670
(defn regexp?
657671
"Returns true if the value is a regular expression."
658672
{:added "1.4.0"}
659673
[x]
660-
(instance? #?(:clj java.util.regex.Pattern :cljs js/RegExp) x))
674+
(instance? #?(:clj java.util.regex.Pattern
675+
:cljr System.Text.RegularExpressions.Regex
676+
:cljs js/RegExp) x))
661677

662678
(defn index-of
663679
"Returns the index of the first occurrence of the item in the sequential
664680
collection coll, or nil if not found."
665681
{:added "1.9.0"}
666-
[^java.util.List coll item]
682+
#?(:clj [^java.util.List coll item]
683+
:cljr [^System.Collections.IEnumerable coll item]
684+
:default [coll item])
667685
(when (some? coll)
668-
(let [index (.indexOf coll item)]
686+
(let [index (#?(:cljr .IndexOf :default .indexOf) coll item)]
669687
(when-not (neg? index) index))))
670688

671689
(defn find-in

test/medley/core_test.cljc

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
(ns medley.core-test
2-
#?(:clj (:import [clojure.lang ArityException]))
3-
(:require #?(:clj [clojure.test :refer :all]
4-
:cljs [cljs.test :refer-macros [deftest is testing]])
2+
#?@(:cljs []
3+
:default [(:import [clojure.lang ArityException])])
4+
(:require #?(:cljs [cljs.test :refer-macros [deftest is testing]]
5+
:default [clojure.test :refer :all])
56
[medley.core :as m]))
67

78
(deftest test-find-first
@@ -162,17 +163,17 @@
162163

163164
(deftest test-queue
164165
(testing "empty"
165-
#?(:clj (is (instance? clojure.lang.PersistentQueue (m/queue)))
166-
:cljs (is (instance? cljs.core.PersistentQueue (m/queue))))
166+
#?(:cljs (is (instance? cljs.core.PersistentQueue (m/queue)))
167+
:default (is (instance? clojure.lang.PersistentQueue (m/queue))))
167168
(is (empty? (m/queue))))
168169
(testing "not empty"
169-
#?(:clj (is (instance? clojure.lang.PersistentQueue (m/queue [1 2 3])))
170-
:cljs (is (instance? cljs.core.PersistentQueue (m/queue [1 2 3]))))
170+
#?(:cljs (is (instance? cljs.core.PersistentQueue (m/queue [1 2 3])))
171+
:default (is (instance? clojure.lang.PersistentQueue (m/queue [1 2 3]))))
171172
(is (= (first (m/queue [1 2 3])) 1))))
172173

173174
(deftest test-queue?
174-
#?(:clj (is (m/queue? clojure.lang.PersistentQueue/EMPTY))
175-
:cljs (is (m/queue? cljs.core.PersistentQueue.EMPTY)))
175+
#?(:cljs (is (m/queue? cljs.core.PersistentQueue.EMPTY))
176+
:default (is (m/queue? clojure.lang.PersistentQueue/EMPTY)))
176177
(is (not (m/queue? []))))
177178

178179
(deftest test-boolean?
@@ -241,9 +242,11 @@
241242
(is (= (m/mapply foo 0 {:baz 1}) [0 1]))
242243
(is (= (m/mapply foo 0 {:spam 1}) [0 nil]))
243244
(is (= (m/mapply foo 0 nil) [0 nil]))
244-
#?@(:clj [(is (thrown? ArityException (m/mapply foo {})))
245-
(is (thrown? IllegalArgumentException (m/mapply foo 0)))]
246-
:cljs [(is (thrown? js/Error (m/mapply foo 0)))])))
245+
(is (thrown? #?(:clj IllegalArgumentException
246+
:cljr ArgumentException
247+
:cljs js/Error) (m/mapply foo 0)))
248+
#?(:cljs (is (= (m/mapply foo {}) [nil nil]))
249+
:default (is (thrown? ArityException (m/mapply foo {}))))))
247250

248251
(deftest test-collate-by
249252
(is (= (m/collate-by identity conj vector [1 2 2 3 3])
@@ -451,10 +454,11 @@
451454
(is (= (m/abs 2) 2))
452455
(is (= (m/abs -2.1) 2.1))
453456
(is (= (m/abs 1.8) 1.8))
454-
#?@(:clj [(is (= (m/abs -1/3) 1/3))
455-
(is (= (m/abs 1/2) 1/2))
456-
(is (= (m/abs 3N) 3N))
457-
(is (= (m/abs -4N) 4N))]))
457+
#?@(:cljs []
458+
:default [(is (= (m/abs -1/3) 1/3))
459+
(is (= (m/abs 1/2) 1/2))
460+
(is (= (m/abs 3N) 3N))
461+
(is (= (m/abs -4N) 4N))]))
458462

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

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

477482
(deftest test-ex-cause
478-
(let [cause (new #?(:clj Exception :cljs js/Error) "foo")]
483+
(let [cause (new #?(:cljs js/Error :default Exception) "foo")]
479484
(is (= (m/ex-cause (ex-info "foo" {} cause)) cause))
480-
#?(:clj (is (= (m/ex-cause (Exception. "foo" cause)) cause)))))
485+
#?@(:cljs []
486+
:default [(is (= (m/ex-cause (Exception. "foo" cause)) cause))])))
481487

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

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

494502
(deftest test-random-uuid
495503
(let [x (m/random-uuid)
496504
y (m/random-uuid)]
497-
(is (instance? #?(:clj java.util.UUID :cljs cljs.core.UUID) x))
498-
(is (instance? #?(:clj java.util.UUID :cljs cljs.core.UUID) y))
505+
(is (instance? #?(:clj java.util.UUID
506+
:cljr System.Guid
507+
:cljs cljs.core.UUID) x))
508+
(is (instance? #?(:clj java.util.UUID
509+
:cljr System.Guid
510+
:cljs cljs.core.UUID) y))
499511
(is (not= x y))))
500512

501513
(deftest test-regexp?

0 commit comments

Comments
 (0)