Skip to content

Instantly share code, notes, and snippets.

@ikitommi
Last active May 3, 2018 07:26
Show Gist options
  • Save ikitommi/d119ae3e1c6397245f8a3378d6dbc2e1 to your computer and use it in GitHub Desktop.
Save ikitommi/d119ae3e1c6397245f8a3378d6dbc2e1 to your computer and use it in GitHub Desktop.
Spec encoding & decoding (X -> y -> x -> y)
(require '[clojure.spec.alpha :as s])
(require '[spec-tools.core :as st])
(require '[clojure.test :refer [deftest testing is are]])
(s/def ::my-spec
(st/spec
{:spec #(and (simple-keyword? %) (-> % name str/lower-case keyword (= %)))
:description "a lowercase simple keyword, encoded in uppercase in string-mode"
:decode/string #(-> %2 name str/lower-case keyword)
:encode/string #(-> %2 name str/upper-case)}))
(s/def ::my-spec-map (s/keys :req [::my-spec]))
(deftest encode-decode-test
(testing "spec-driven encode & decode"
(let [invalid {::my-spec "kikka"}
encoded {::my-spec "KIKKA"}
decoded {::my-spec :kikka}]
(testing "without conforming"
(testing "decode works just like s/conform"
(is (= ::s/invalid (st/decode ::my-spec-map encoded)))
(is (= decoded (st/decode ::my-spec-map decoded))))
(testing "encode fails if no encoder is founds"
(is (= ::s/invalid (st/encode ::my-spec-map invalid)))))
(testing "with conforming"
(testing "decoding is applied before validation if found"
(is (= ::s/invalid (st/decode ::my-spec-map encoded st/json-conforming)))
(is (= decoded (st/decode ::my-spec-map decoded st/string-conforming)))
(is (= decoded (st/decode ::my-spec-map encoded st/string-conforming))))
(testing "encoding is applied without validation if found"
(is (= ::s/invalid (st/encode ::my-spec-map decoded st/json-conforming)))
(is (= encoded (st/encode ::my-spec-map encoded st/string-conforming)))
(is (= encoded (st/encode ::my-spec-map decoded st/string-conforming))))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment