response endoding, WIP: tests

This commit is contained in:
Tommi Reiman 2019-12-04 08:10:21 +02:00
parent 5a533c25a7
commit a7cd1cf398
2 changed files with 44 additions and 27 deletions

View file

@ -92,7 +92,7 @@
(defn response-coercer [coercion body {:keys [extract-response-format]
:or {extract-response-format extract-response-format-default}}]
(if coercion
(let [coercer (-response-coercer coercion body)]
(if-let [coercer (-response-coercer coercion body)]
(fn [request response]
(let [format (extract-response-format request response)
value (:body response)
@ -130,6 +130,7 @@
(defn response-coercers [coercion responses opts]
(->> (for [[status {:keys [body]}] responses :when body]
[status (response-coercer coercion body opts)])
(filter second)
(into {})))
;;

View file

@ -5,6 +5,10 @@
[malli.core :as m]
[clojure.set :as set]))
;;
;; coercion
;;
(defrecord Coercer [decoder encoder validator explainer])
(def string-transformer
@ -19,6 +23,37 @@
(defmulti coerce-response? identity :default ::default)
(defmethod coerce-response? ::default [_] true)
(defn- -coercer [schema type transformers f]
(if schema
(let [->coercer (fn [t] (if t (->Coercer (m/decoder schema t)
(m/encoder schema t)
(m/validator schema)
(m/explainer schema))))
{:keys [formats default]} (transformers type)
default-coercer (->coercer default)
format-coercers (->> (for [[f t] formats] [f (->coercer t)]) (into {}))
get-coercer (if (seq format-coercers)
(fn [format] (or (get format-coercers format) default-coercer))
(constantly default-coercer))]
(if default-coercer
(fn [value format]
(if-let [coercer (get-coercer format)]
(let [transform (f coercer)
validator (:validator coercer)
transformed (transform value)]
(if (validator transformed)
transformed
(let [explainer (:explainer coercer)
errors (explainer transformed)]
(coercion/map->CoercionError
{:schema schema
:errors errors}))))
value))))))
;;
;; swagger
;;
(defmulti extract-parameter (fn [in _] in))
(defmethod extract-parameter :body [_ schema]
@ -42,6 +77,10 @@
schema))
properties)))
;;
;; public api
;;
(def default-options
{:coerce-response? coerce-response?
:transformers {:body {:default default-transformer
@ -82,32 +121,9 @@
(-open-model [_ schema] schema)
(-encode-error [_ error] error)
(-request-coercer [_ type schema]
(if schema
(let [->coercer (fn [t] (->Coercer (m/decoder schema t)
(m/encoder schema t)
(m/validator schema)
(m/explainer schema)))
{:keys [formats default]} (transformers type)
default-coercer (->coercer default)
format-coercers (->> (for [[f t] formats] [f (->coercer t)]) (into {}))
get-coercer (if (seq format-coercers)
(fn [format] (or (get format-coercers format) default-coercer))
(constantly default-coercer))]
(fn [value format]
(if-let [coercer (get-coercer format)]
(let [decoder (:decoder coercer)
validator (:validator coercer)
decoded (decoder value)]
(if (validator decoded)
decoded
(let [explainer (:explainer coercer)
errors (explainer decoded)]
(coercion/map->CoercionError
{:schema schema
:errors errors}))))
value)))))
(-response-coercer [this schema]
(-coercer schema type transformers :decoder))
(-response-coercer [_ schema]
(if (coerce-response? schema)
(coercion/-request-coercer this :response schema)))))
(-coercer schema :response transformers :encoder)))))
(def coercion (create default-options))