Skip to content

Commit

Permalink
fnk
Browse files Browse the repository at this point in the history
  • Loading branch information
frenchy64 committed Apr 24, 2024
1 parent efd5a71 commit 79b8d39
Show file tree
Hide file tree
Showing 2 changed files with 152 additions and 3 deletions.
8 changes: 5 additions & 3 deletions src/compojure/api/meta.clj
Original file line number Diff line number Diff line change
Expand Up @@ -415,10 +415,12 @@
" (ok {:total (+ x y)}))")))

(defmethod restructure-param :body-params [_ body-params acc]
(let [schema (strict (fnk-schema body-params))]
(let [schema (strict (fnk-schema body-params))
g (gensym 'body-params-schema)]
(-> acc
(update-in [:letks] into [body-params (src-coerce! schema :body-params :body)])
(assoc-in [:info :public :parameters :body] schema))))
(update :outer-lets into [g schema])
(update-in [:letks] into [body-params (src-coerce! g :body-params :body)])
(assoc-in [:info :public :parameters :body] g))))

;;
;; form-params
Expand Down
147 changes: 147 additions & 0 deletions test/compojure/api/meta_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -999,3 +999,150 @@
(is (= 1 @times))
(dorun (repeatedly 10 exercise))
(is (= 1 @times)))))

(deftest body-params-double-eval-test
(testing "no :body-params double expansion"
(is-expands (GET "/ping" []
:body-params [field :- EXPENSIVE, field2, {default :- s/Int 42} & foo :- {s/Keyword s/Keyword} :as all]
(ok "kikka"))
`(let [?body-schema {:field ~'EXPENSIVE
:field2 s/Any
(with-meta
(s/optional-key :default)
{:default '42})
~'s/Int
~'s/Keyword ~'s/Keyword}]
(map->Route
{:path "/ping",
:method :get,
:info (merge-parameters
{:public {:parameters {:body ?body-schema}}})
:handler
(make-route
:get
{:__record__ "clout.core.CompiledRoute",
:source "/ping",
:re #"/ping",
:keys [],
:absolute? false}
(fn [?request]
(let-request [[:as +compojure-api-request+] ?request]
(plumbing.core/letk
[~'[field :- EXPENSIVE, field2, {default :- s/Int 42}
& foo :- {s/Keyword s/Keyword} :as all]
(compojure.api.coercion/coerce-request!
?body-schema
:body-params
:body
true
false
+compojure-api-request+)]
(do ~'(ok "kikka"))))))}))))
(testing "no context"
(let [times (atom 0)
route (GET "/ping" []
:body [body (do (swap! times inc) s/Any)]
(ok "kikka"))
exercise #(is (= "kikka" (:body (route {:request-method :get :uri "/ping"}))))]
(exercise)
(is (= 1 @times))
(dorun (repeatedly 10 exercise))
(is (= 1 @times))))
(testing "inferred static context"
(let [times (atom 0)
route (context
"" []
(GET "/ping" []
:body [body (do (swap! times inc) s/Any)]
(ok "kikka")))
exercise #(is (= "kikka" (:body (route {:request-method :get :uri "/ping"}))))]
(exercise)
(is (= 1 @times))
(dorun (repeatedly 10 exercise))
(is (= 1 @times))))
(testing "dynamic context that doesn't bind variables"
(let [times (atom 0)
route (context
"" []
:dynamic true
(GET "/ping" []
:body [body (do (swap! times inc) s/Any)]
(ok "kikka")))
exercise #(is (= "kikka" (:body (route {:request-method :get :uri "/ping"}))))]
(exercise)
(is (= 1 @times))
(dorun (repeatedly 10 exercise))
(is (= 11 @times))))
(testing "dynamic context where schema is bound outside context"
(let [times (atom 0)
route (let [s s/Any]
(context
"" []
:dynamic true
(GET "/ping" []
;;TODO could lift this since the locals occur outside the context
:body [body (do (swap! times inc) s)]
(ok "kikka"))))
exercise #(is (= "kikka" (:body (route {:request-method :get :uri "/ping"}))))]
(exercise)
(is (= 1 @times))
(dorun (repeatedly 10 exercise))
(is (= 11 @times))))
(testing "dynamic context that binds req and uses it in schema"
(let [times (atom 0)
route (context
"" req
(GET "/ping" req
:body [body (do (swap! times inc)
;; should never lift this since it refers to request
(second [req s/Any]))]
(ok "kikka")))
exercise #(is (= "kikka" (:body (route {:request-method :get :uri "/ping"}))))]
(exercise)
(is (= 1 @times))
(dorun (repeatedly 10 exercise))
(is (= 11 @times))))
(testing "bind :body in static context"
(is-thrown-with-msg?
AssertionError
#"cannot be :static"
(eval `(context
"" []
:static true
:body [body (do (swap! times update :outer inc)
s/Any)]
(GET "/ping" req
:body [body (do (swap! times update :inner inc)
s/Any)]
(ok "kikka"))))))
(testing "bind :body in dynamic context"
(let [times (atom {:outer 0 :inner 0})
route (context
"" []
:dynamic true
:body [body (do (swap! times update :outer inc)
s/Any)]
(GET "/ping" req
:body [body (do (swap! times update :inner inc)
s/Any)]
(ok "kikka")))
exercise #(is (= "kikka" (:body (route {:request-method :get :uri "/ping"}))))]
(exercise)
(is (= {:outer 1 :inner 1} @times))
(dorun (repeatedly 10 exercise))
(is (= {:outer 1 :inner 11} @times))))
(testing "idea for lifting impl"
(let [times (atom 0)
route (let [rs (GET "/ping" req
:body [body (do (swap! times inc)
s/Any)]
(ok "kikka"))]
(context
"" []
:dynamic true
rs))
exercise #(is (= "kikka" (:body (route {:request-method :get :uri "/ping"}))))]
(exercise)
(is (= 1 @times))
(dorun (repeatedly 10 exercise))
(is (= 1 @times)))))

0 comments on commit 79b8d39

Please sign in to comment.