Skip to content

Commit

Permalink
draft - full cljs compat
Browse files Browse the repository at this point in the history
there's an xxx, and a clj-only test

see nedap/speced.def#80
  • Loading branch information
vemv committed Dec 28, 2019
1 parent dff68f7 commit 1993e10
Show file tree
Hide file tree
Showing 10 changed files with 77 additions and 59 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ This has multiple advantages:

* One can code with plain defns, making things more homogeneous
* And decoupled, reusable
* Said defns can be [utils.spec](https://github.com/nedap/utils.spec/) ones
* Said defns can be [speced.def](https://github.com/nedap/speced.def) ones
* Importantly, one should understand that `defmethod` is a side-effect, and as such should be avoided.
* Better to `add-method` in a [Component](https://github.com/stuartsierra/component) `start` definition

Expand Down
7 changes: 3 additions & 4 deletions project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@
;; NOTE: deps marked with #_"transitive" are there to satisfy the `:pedantic?` option.
:profiles {:dev {:dependencies [[cider/cider-nrepl "0.16.0" #_"formatting-stack needs it"]
[com.clojure-goes-fast/clj-java-decompiler "0.2.1"]
[com.nedap.staffing-solutions/utils.modular "2.0.0"]
[com.nedap.staffing-solutions/utils.spec.predicates "1.1.0"]
[com.stuartsierra/component "0.4.0"]
[com.taoensso/timbre "4.10.0"]
Expand All @@ -76,9 +75,9 @@
[com.google.errorprone/error_prone_annotations "2.1.3" #_"transitive"]
[com.google.code.findbugs/jsr305 "3.0.2" #_"transitive"]]}

:check {:global-vars {*unchecked-math* :warn-on-boxed
;; avoid warnings that cannot affect production:
*assert* false}}
:check {:global-vars {*unchecked-math* :warn-on-boxed
;; avoid warnings that cannot affect production:
*assert* false}}

:test {:dependencies [[com.nedap.staffing-solutions/utils.test "1.6.1"]]
:jvm-opts ["-Dclojure.core.async.go-checking=true"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
(ns nedap.utils.modular.api
(:require
#?(:clj [nedap.utils.modular.impl.defmethod :refer [defmethod-source]])
#?(:clj [nedap.utils.modular.impl.implement :as implement])
[clojure.repl]
[clojure.spec.alpha :as spec]
[nedap.utils.modular.impl.defmethod :refer [defmethod-source]]
[nedap.utils.modular.impl.dependent :as dependent]
[nedap.utils.modular.impl.implement :as implement]
[nedap.utils.spec.api :refer [check!]]))

(spec/def ::method-pair (spec/cat :protocol-method symbol?
Expand All @@ -14,33 +14,38 @@
(or (-> clojure-version :minor long (> 9))
(-> clojure-version :major long (> 1))))

(defmacro implement
"Returns a copy of `object` that implements `methods` via metadata (Clojure 1.10 feature).
#?(:clj
(defmacro implement
"Returns a copy of `object` that implements `methods` via metadata (Clojure 1.10 feature).
In order to foster clear code, it is enforced that `methods` are expressed as symbols (and not as inline functions).
It is verified at runtime that the symbols do resove to protocol functions and implementation functions (respectively).
This run-time checking yields a superior solution to plain metadata-based protocol extension, where symbols may contain typos."
{:style/indent 1}
[object & methods]
{:pre [(check! (spec/coll-of ::method-pair :min-count 1) (partition 2 methods)
metadata-extension-supported? *clojure-version*)]}
(let [clj? (-> &env :ns nil?)
caller-ns (if clj?
*ns*
(-> &env :ns))]
(implement/implement clj?
object
caller-ns
methods
&env)))

(defmacro add-method
"Installs a new method of multimethod associated with dispatch-value."
{:pre [(-> 'defmethod clojure.repl/source-fn #{defmethod-source})]}
[multifn dispatch-val f]
`(. ~(with-meta multifn {:tag 'clojure.lang.MultiFn}) addMethod ~dispatch-val ~f))
{:style/indent 1}
[object & methods]
{:pre [(check! (spec/coll-of ::method-pair :min-count 1) (partition 2 methods)
metadata-extension-supported? *clojure-version*)]}
(let [clj? (-> &env :ns nil?)
caller-ns (if clj?
*ns*
(-> &env :ns))]
(implement/implement clj?
object
caller-ns
methods
&env))))

#?(:clj
(defmacro add-method
"Installs a new method of multimethod associated with dispatch-value."
;; XXX check cljs src too https://github.com/clojure/clojurescript/blob/23cedecbf4f704f9fee672e395bbfa1e3fe3ee1a/src/main/clojure/cljs/core.cljc#L2776
{:pre [(-> 'defmethod clojure.repl/source-fn #{defmethod-source})]}
[multifn dispatch-val f]
(if-let [clj? (-> &env :ns nil?)]
`(. ~(with-meta multifn {:tag 'clojure.lang.MultiFn}) addMethod ~dispatch-val ~f)
`(cljs.core/-add-method ~(with-meta multifn {:tag 'cljs.core/MultiFn}) ~dispatch-val ~f))))

(defn dependent
"A replacement for `#'com.stuartsierra.component/using`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
[com.stuartsierra.component :as component]
[nedap.speced.def :as speced]))

(spec/def ::component #(speced/satisfies? component/Lifecycle %))
(spec/def ::component #(#?(:clj speced/satisfies?
:cljs satisfies?) component/Lifecycle %))
(spec/def ::dependency-map (spec/map-of keyword? keyword?))
(spec/def ::dependency-vec (spec/coll-of keyword? :kind vector?))

Expand Down
11 changes: 8 additions & 3 deletions test/nedap/utils/modular/test_runner.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@
(:require
[cljs.nodejs :as nodejs]
[nedap.utils.test.api :refer-macros [run-tests]]
[unit.nedap.utils.modular.api.implement]))
[unit.nedap.utils.modular.api.add-method]
[unit.nedap.utils.modular.api.dependent]
[unit.nedap.utils.modular.api.implement]
[unit.nedap.utils.modular.api.omit-this]))

(nodejs/enable-util-print!)

(defn -main []
(run-tests
'unit.nedap.utils.modular.api.implement))
(run-tests 'unit.nedap.utils.modular.api.add-method
'unit.nedap.utils.modular.api.dependent
'unit.nedap.utils.modular.api.implement
'unit.nedap.utils.modular.api.omit-this))

(set! *main-cli-fn* -main)
23 changes: 0 additions & 23 deletions test/unit/nedap/utils/modular/api/add_method.clj

This file was deleted.

31 changes: 31 additions & 0 deletions test/unit/nedap/utils/modular/api/add_method.cljc
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
(ns unit.nedap.utils.modular.api.add-method
(:require
#?(:clj [nedap.utils.modular.api :as sut])
#?(:clj [clojure.test :refer [deftest testing are is use-fixtures]] :cljs [cljs.test :refer-macros [deftest testing is are] :refer [use-fixtures]])
[nedap.speced.def :as speced])
#?(:cljs (:require-macros [nedap.utils.modular.api :as sut])))

(defn handle-integer [i]
(+ i i))

(speced/defn handle-string [^string? s]
(str s s))

#?(:clj (defmulti handle class)
:cljs (defmulti handle (fn [x]
(cond
(number? x) ::number
(string? x) ::string
true (assert false)))))

#?(:clj (sut/add-method handle Long handle-integer)
:cljs (sut/add-method handle ::number handle-integer))

#?(:clj (sut/add-method handle String handle-string)
:cljs (sut/add-method handle ::string handle-string))

(deftest works
(are [input e] (= e
(handle input))
2 4
"2" "22"))
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
(ns unit.nedap.utils.modular.api.dependent
(:require
[clojure.test :refer :all]
#?(:clj [clojure.test :refer [deftest testing are is use-fixtures]] :cljs [cljs.test :refer-macros [deftest testing is are] :refer [use-fixtures]])
[com.stuartsierra.component :as component]
[nedap.utils.modular.api :as sut]
[nedap.utils.modular.impl.dependent :as impl.dependent]))
Expand Down Expand Up @@ -38,5 +38,5 @@
{:c :d}
{:a :b :c :d})

(testing "Wrong keys in options"
(is (spec-assertion-thrown? ::impl.dependent/options (sut/dependent {} :on {} :reneames {})))))
#?(:clj (testing "Wrong keys in options"
(is (spec-assertion-thrown? ::impl.dependent/options (sut/dependent {} :on {} :reneames {}))))))
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
(ns unit.nedap.utils.modular.api.omit-this
(:require
[clojure.test :refer :all]
#?(:clj [clojure.test :refer [deftest testing are is use-fixtures]] :cljs [cljs.test :refer-macros [deftest testing is are] :refer [use-fixtures]])
[nedap.utils.modular.api :as sut]
[unit.nedap.utils.modular.api.omit-this.example-protocol :as example-protocol]))

Expand Down

0 comments on commit 1993e10

Please sign in to comment.