generated from strojure/library-template
-
Notifications
You must be signed in to change notification settings - Fork 0
/
walkthrough.clj
155 lines (128 loc) · 7.2 KB
/
walkthrough.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
(ns usage.walkthrough
(:require [strojure.ring-control.handler :as handler]))
;; ## Define builder configuration
;; - Define standard ring handlers
(defn- wrap1 [handler]
(fn [request]
(println :enter 'wrap1 {:request request})
(doto (-> (update request :trace/enter conj 'wrap1)
(handler)
(update :trace/leave conj 'wrap1))
(as-> response (println :leave 'wrap1 {:response response})))))
(defn- wrap2 [handler]
(fn [request]
(println :enter 'wrap2 {:request request})
(doto (-> (update request :trace/enter conj 'wrap2)
(handler)
(update :trace/leave conj 'wrap2))
(as-> response (println :leave 'wrap2 {:response response})))))
(defn- wrap3 [handler]
(fn [request]
(println :enter 'wrap3 {:request request})
(doto (-> (update request :trace/enter conj 'wrap3)
(handler)
(update :trace/leave conj 'wrap3))
(as-> response (println :leave 'wrap3 {:response response})))))
(defn- wrap4 [handler]
(fn [request]
(println :enter 'wrap4 {:request request})
(doto (-> (update request :trace/enter conj 'wrap4)
(handler)
(update :trace/leave conj 'wrap4))
(as-> response (println :leave 'wrap4 {:response response})))))
;; - Define ring request wrappers
(defn- request1 [request]
(println :enter 'request1 {:request request})
(update request :trace/enter conj 'request1))
(defn- request2 [request]
(println :enter 'request2 {:request request})
(update request :trace/enter conj 'request2))
;; - Define ring response wrappers
(defn- response1 [response request]
(println :leave 'response1 {:response response :request request})
(update response :trace/leave conj 'response1))
(defn- response2 [response request]
(println :leave 'response2 {:response response :request request})
(update response :trace/leave conj 'response2))
;; ## Define handler function to be wrapped
(defn- handler*
[request]
(println :handler {:request request})
(assoc request :trace/leave []))
;; ## Test middleware composition
;; - :enter before :leave
(let [handler (handler/build handler* [{:wrap wrap1}
{:wrap wrap2}
{:enter request1}
{:enter request2}
{:leave response1}
{:leave response2}
{:wrap wrap3}
{:wrap wrap4}])]
(handler {:trace/enter []}))
;:enter wrap1 {:request #:trace{:enter []}}
;:enter wrap2 {:request #:trace{:enter [wrap1]}}
;:enter request1 {:request #:trace{:enter [wrap1 wrap2]}}
;:enter request2 {:request #:trace{:enter [wrap1 wrap2 request1]}}
;:enter wrap3 {:request #:trace{:enter [wrap1 wrap2 request1 request2]}}
;:enter wrap4 {:request #:trace{:enter [wrap1 wrap2 request1 request2 wrap3]}}
;:handler {:request #:trace{:enter [wrap1 wrap2 request1 request2 wrap3 wrap4]}}
;:leave wrap4 {:response #:trace{:enter [wrap1 wrap2 request1 request2 wrap3 wrap4], :leave [wrap4]}}
;:leave wrap3 {:response #:trace{:enter [wrap1 wrap2 request1 request2 wrap3 wrap4], :leave [wrap4 wrap3]}}
;:leave response2 {:response #:trace{:enter [wrap1 wrap2 request1 request2 wrap3 wrap4], :leave [wrap4 wrap3]}, :request #:trace{:enter [wrap1 wrap2 request1 request2]}}
;:leave response1 {:response #:trace{:enter [wrap1 wrap2 request1 request2 wrap3 wrap4], :leave [wrap4 wrap3 response2]}, :request #:trace{:enter [wrap1 wrap2 request1 request2]}}
;:leave wrap2 {:response #:trace{:enter [wrap1 wrap2 request1 request2 wrap3 wrap4], :leave [wrap4 wrap3 response2 response1 wrap2]}}
;:leave wrap1 {:response #:trace{:enter [wrap1 wrap2 request1 request2 wrap3 wrap4], :leave [wrap4 wrap3 response2 response1 wrap2 wrap1]}}
#_#:trace{:enter [wrap1 wrap2 request1 request2 wrap3 wrap4],
:leave [wrap4 wrap3 response2 response1 wrap2 wrap1]}
;; - :leave before :enter
(let [handler (handler/build handler* [{:wrap wrap1}
{:wrap wrap2}
{:leave response1}
{:leave response2}
{:enter request1}
{:enter request2}
{:wrap wrap3}
{:wrap wrap4}])]
(handler {:trace/enter []}))
;:enter wrap1 {:request #:trace{:enter []}}
;:enter wrap2 {:request #:trace{:enter [wrap1]}}
;:enter request1 {:request #:trace{:enter [wrap1 wrap2]}}
;:enter request2 {:request #:trace{:enter [wrap1 wrap2 request1]}}
;:enter wrap3 {:request #:trace{:enter [wrap1 wrap2 request1 request2]}}
;:enter wrap4 {:request #:trace{:enter [wrap1 wrap2 request1 request2 wrap3]}}
;:handler {:request #:trace{:enter [wrap1 wrap2 request1 request2 wrap3 wrap4]}}
;:leave wrap4 {:response #:trace{:enter [wrap1 wrap2 request1 request2 wrap3 wrap4], :leave [wrap4]}}
;:leave wrap3 {:response #:trace{:enter [wrap1 wrap2 request1 request2 wrap3 wrap4], :leave [wrap4 wrap3]}}
;:leave response2 {:response #:trace{:enter [wrap1 wrap2 request1 request2 wrap3 wrap4], :leave [wrap4 wrap3]}, :request #:trace{:enter [wrap1 wrap2]}}
;:leave response1 {:response #:trace{:enter [wrap1 wrap2 request1 request2 wrap3 wrap4], :leave [wrap4 wrap3 response2]}, :request #:trace{:enter [wrap1 wrap2]}}
;:leave wrap2 {:response #:trace{:enter [wrap1 wrap2 request1 request2 wrap3 wrap4], :leave [wrap4 wrap3 response2 response1 wrap2]}}
;:leave wrap1 {:response #:trace{:enter [wrap1 wrap2 request1 request2 wrap3 wrap4], :leave [wrap4 wrap3 response2 response1 wrap2 wrap1]}}
#_#:trace{:enter [wrap1 wrap2 request1 request2 wrap3 wrap4],
:leave [wrap4 wrap3 response2 response1 wrap2 wrap1]}
;; ## Test middleware dependencies
(comment
;; - Require middleware before
(let [handler (handler/build handler* [{:leave response1 :name `response1 :deps {`request1 :before}}
{:enter request1 :name `request1}])]
(handler {:trace/enter []}))
;clojure.lang.ExceptionInfo:
; Require middleware usage.walkthrough/request1 before usage.walkthrough/response1
; {:names (usage.walkthrough/response1 usage.walkthrough/request1)}
;; - Require middleware after
(let [handler (handler/build handler* [{:enter request1 :name `request1}
{:leave response1 :name `response1 :deps {`wrap3 :after}}])]
(handler {:trace/enter []}))
;clojure.lang.ExceptionInfo:
; Require middleware usage.walkthrough/wrap3 after usage.walkthrough/response1
; {:names (usage.walkthrough/request1 usage.walkthrough/response1)}
;; - Ignore dependency error
(let [handler (handler/build handler* [{:leave response1 :name `response1 :deps {`request1 :before}}
{:enter request1 :name `request1}]
{:ignored-deps #{`request1}})]
(handler {:trace/enter []}))
;:enter request1 {:request #:trace{:enter []}}
;:handler {:request #:trace{:enter [request1]}}
;:leave response1 {:response #:trace{:enter [request1], :leave []}, :request #:trace{:enter []}}
;=> #:trace{:enter [request1], :leave [response1]}
)