Codebase list comidi-clojure / eba551a
Merge pull request #23 from mruzicka/TK-297_wrap_routes_fix (TK-297) Fix wrap-routes Scott Walker 8 years ago
2 changed file(s) with 43 addition(s) and 18 deletion(s). Raw diff Collapse all Expand all
275275 [method pattern bindings body]
276276 `[~pattern {~method (handler-fn* ~bindings ~body)}])
277277
278 (defn route-tree-zip
279 "Returns a zipper for a bidi route tree i.e. for an arbitrarily nested structure of
280 `bidi.schema/RoutePair`s"
281 [root]
282 (zip/zipper
283 (fn [[_ matched]]
284 (or (vector? matched) (map? matched)))
285
286 (fn [[_ matched]]
287 (seq matched))
288
289 (fn [[pattern matched :as node] children]
290 (with-meta
291 [pattern (into (if (vector? matched) [] {}) children)]
292 (meta node)))
293
294 root))
295
278296 (defn wrap-routes*
279297 "Help function, used by compojure-like wrap-routes function to wrap leaf handlers
280298 in the bidi route with the middleware"
281299 [loc middleware]
282 (let [node (zip/node loc)
283 loc (cond
284 (fn? node) (zip/replace loc (middleware node))
285 (map? node) (zip/replace
286 loc
287 (reduce-kv (fn [m k v] (assoc m k (middleware v))) {} node))
288 :else loc)]
289 (if (zip/end? loc)
290 loc
291 (wrap-routes* (zip/next loc) middleware))))
300 (if (zip/end? loc)
301 loc
302 (let [loc (if (zip/branch? loc) ; we only want modify the leaf nodes
303 loc
304 (let [[pattern matched] (zip/node loc)]
305 (if (fn? matched)
306 (zip/replace loc [pattern (middleware matched)])
307 loc)))]
308 (recur (zip/next loc) middleware))))
292309
293310 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
294311 ;;;; Public - core functions
327344 [routes :- bidi-schema/RoutePair
328345 middleware :- (schema/pred fn?)]
329346 (-> routes
330 zip/vector-zip
347 route-tree-zip
331348 (wrap-routes* middleware)
332349 zip/root))
333350
22 [puppetlabs.comidi :as comidi :refer :all]
33 [schema.test :as schema-test]
44 [schema.core :as schema]
5 [clojure.zip :as zip]))
5 [clojure.zip :as zip]
6 [bidi.bidi :as bidi]))
67
78 (use-fixtures :once schema-test/validate-schemas)
89
358359 dd-route (DELETE "/dd" request "dd!")
359360 ee-route (GET "/ee" request "ee!")
360361 ff-route (ANY "/ff" request "ff!")
362 gh-route (ANY (bidi/alts "/gg" "/hh") request "gg-or-hh!")
361363 left-routes (context "/left" aa-route bb-route)
362364 middle-routes (context "/middle" cc-route dd-route)
363365 right-routes (context "/right" ee-route ff-route)
364 handler (-> (routes left-routes middle-routes right-routes) routes->handler)]
366 alternate-routes ["/alts" [gh-route]]
367 handler (-> (routes left-routes middle-routes right-routes alternate-routes) routes->handler)]
365368 (testing "Routes without middleware applied"
366369 (is (= (:body (handler {:uri "/left/aa" :request-method :get})) "aa!"))
367370 (is (= (:body (handler {:uri "/left/bb" :request-method :post})) "bb!"))
368371 (is (= (:body (handler {:uri "/middle/cc" :request-method :get})) "cc!"))
369372 (is (= (:body (handler {:uri "/middle/dd" :request-method :delete})) "dd!"))
370373 (is (= (:body (handler {:uri "/right/ee" :request-method :get})) "ee!"))
371 (is (= (:body (handler {:uri "/right/ff" :request-method :delete})) "ff!")))
374 (is (= (:body (handler {:uri "/right/ff" :request-method :delete})) "ff!"))
375 (is (= (:body (handler {:uri "/alts/gg" :request-method :put})) "gg-or-hh!"))
376 (is (= (:body (handler {:uri "/alts/hh" :request-method :post})) "gg-or-hh!"))
377 (is (= (:body (handler {:uri "/alts/ii" :request-method :post})) nil)))
372378 (testing "Routes but now with middleware applied"
373379 (let [wrapped-bb-route (-> bb-route (wrap-routes bb-wrapper-middleware))
374380 left-routes (-> (context "/left" aa-route wrapped-bb-route)
375381 (wrap-routes inner-middleware)
376382 (wrap-routes outer-middleware))
377 middle-routes (context "/middle" cc-route dd-route)
378 right-routes (-> (context "/right" ee-route ff-route) (wrap-routes outer-middleware))
379 handler (-> (routes left-routes middle-routes right-routes) routes->handler)]
383 right-routes (-> right-routes (wrap-routes outer-middleware))
384 alternate-routes (-> alternate-routes (wrap-routes inner-middleware) (wrap-routes outer-middleware))
385 handler (-> (routes left-routes middle-routes right-routes alternate-routes) routes->handler)]
380386 (is (= (:body (handler {:uri "/left/aa" :request-method :get})) "outer-inner-aa!"))
381387 (is (= (:body (handler {:uri "/left/bb" :request-method :post})) "outer-inner-bb-wrapper-bb!"))
382388 (is (= (:body (handler {:uri "/middle/cc" :request-method :get})) "cc!"))
383389 (is (= (:body (handler {:uri "/middle/dd" :request-method :delete})) "dd!"))
384390 (is (= (:body (handler {:uri "/right/ee" :request-method :get})) "outer-ee!"))
385 (is (= (:body (handler {:uri "/right/ff" :request-method :delete})) "outer-ff!"))))))
391 (is (= (:body (handler {:uri "/right/ff" :request-method :delete})) "outer-ff!"))
392 (is (= (:body (handler {:uri "/alts/gg" :request-method :delete})) "outer-inner-gg-or-hh!"))
393 (is (= (:body (handler {:uri "/alts/hh" :request-method :delete})) "outer-inner-gg-or-hh!"))))))
386394
387395 (deftest destructuring-test
388396 (testing "Compojure-style destructuring works as expected"