@@ -24,30 +24,36 @@ func removeKeys(keys ...string) func([]string, slog.Attr) slog.Attr {
2424 }
2525}
2626
27+ func replaceKey (key string , newAttr slog.Attr ) func ([]string , slog.Attr ) slog.Attr {
28+ return func (_ []string , a slog.Attr ) slog.Attr {
29+ if a .Key == key {
30+ return newAttr
31+ }
32+
33+ return a
34+ }
35+ }
36+
2737func TestHandlers (t * testing.T ) {
28- tests := []struct {
29- name string
30- wantJSON string
31- wantText string
32- level slog.Level
33- handlerFn func (t * testing.T , buf * bytes.Buffer , opts * slog.HandlerOptions ) slog.Handler
34- }{
38+ tests := []handlerTest {
3539 {
3640 name : "nil" ,
3741 handlerFn : func (_ * testing.T , _ * bytes.Buffer , _ * slog.HandlerOptions ) slog.Handler {
3842 return NewController (nil ).Handler ("h1" )
3943 },
4044 },
4145 {
42- name : "factory constructor" ,
43- wantJSON : `{"level": "INFO", "logger": "h1", "msg":"hi"}` ,
46+ name : "factory constructor" ,
47+ want : `{"level": "INFO", "logger": "h1", "msg":"hi"}` ,
48+ json : true ,
4449 handlerFn : func (_ * testing.T , buf * bytes.Buffer , opts * slog.HandlerOptions ) slog.Handler {
4550 return NewController (slog .NewJSONHandler (buf , opts )).Handler ("h1" )
4651 },
4752 },
4853 {
49- name : "change default sink before handler" ,
50- wantJSON : `{"level": "INFO", "logger": "h1", "msg":"hi"}` ,
54+ name : "change default sink before handler" ,
55+ want : `{"level": "INFO", "logger": "h1", "msg":"hi"}` ,
56+ json : true ,
5157 handlerFn : func (_ * testing.T , buf * bytes.Buffer , opts * slog.HandlerOptions ) slog.Handler {
5258 f := NewController (nil )
5359 f .SetDefaultSink (slog .NewJSONHandler (buf , opts ))
@@ -56,8 +62,8 @@ func TestHandlers(t *testing.T) {
5662 },
5763 },
5864 {
59- name : "change default sink after handler" ,
60- wantText : "level=INFO msg=hi logger=h1\n " ,
65+ name : "change default sink after handler" ,
66+ want : "level=INFO msg=hi logger=h1\n " ,
6167 handlerFn : func (_ * testing.T , buf * bytes.Buffer , opts * slog.HandlerOptions ) slog.Handler {
6268 f := NewController (slog .NewJSONHandler (buf , opts ))
6369 h := f .Handler ("h1" )
@@ -67,8 +73,9 @@ func TestHandlers(t *testing.T) {
6773 },
6874 },
6975 {
70- name : "change other sink before handler" ,
71- wantJSON : `{"level": "INFO", "logger": "h1", "msg":"hi"}` ,
76+ name : "change other sink before handler" ,
77+ want : `{"level": "INFO", "logger": "h1", "msg":"hi"}` ,
78+ json : true ,
7279 handlerFn : func (_ * testing.T , buf * bytes.Buffer , opts * slog.HandlerOptions ) slog.Handler {
7380 f := NewController (slog .NewJSONHandler (buf , opts ))
7481 f .SetSink ("h2" , slog .NewTextHandler (buf , opts ))
@@ -77,8 +84,8 @@ func TestHandlers(t *testing.T) {
7784 },
7885 },
7986 {
80- name : "change sink before handler" ,
81- wantText : "level=INFO msg=hi logger=h1\n " ,
87+ name : "change sink before handler" ,
88+ want : "level=INFO msg=hi logger=h1\n " ,
8289 handlerFn : func (_ * testing.T , buf * bytes.Buffer , opts * slog.HandlerOptions ) slog.Handler {
8390 f := NewController (slog .NewJSONHandler (buf , opts ))
8491 f .SetSink ("h1" , slog .NewTextHandler (buf , opts ))
@@ -87,8 +94,8 @@ func TestHandlers(t *testing.T) {
8794 },
8895 },
8996 {
90- name : "change sink after handler" ,
91- wantText : "level=INFO msg=hi logger=h1\n " ,
97+ name : "change sink after handler" ,
98+ want : "level=INFO msg=hi logger=h1\n " ,
9299 handlerFn : func (_ * testing.T , buf * bytes.Buffer , opts * slog.HandlerOptions ) slog.Handler {
93100 f := NewController (slog .NewJSONHandler (buf , opts ))
94101 h := f .Handler ("h1" )
@@ -98,8 +105,8 @@ func TestHandlers(t *testing.T) {
98105 },
99106 },
100107 {
101- name : "WithXXX" ,
102- wantText : "level=INFO msg=hi logger=h1 props.color=red\n " ,
108+ name : "WithXXX" ,
109+ want : "level=INFO msg=hi logger=h1 props.color=red\n " ,
103110 handlerFn : func (_ * testing.T , buf * bytes.Buffer , opts * slog.HandlerOptions ) slog.Handler {
104111 f := NewController (slog .NewTextHandler (buf , opts ))
105112 h := f .Handler ("h1" )
@@ -109,8 +116,8 @@ func TestHandlers(t *testing.T) {
109116 },
110117 },
111118 {
112- name : "change sink after WithXXX" ,
113- wantText : "level=INFO msg=hi logger=h1 size=big props.color=red props.address.street=mockingbird\n " ,
119+ name : "change sink after WithXXX" ,
120+ want : "level=INFO msg=hi logger=h1 size=big props.color=red props.address.street=mockingbird\n " ,
114121 handlerFn : func (_ * testing.T , buf * bytes.Buffer , opts * slog.HandlerOptions ) slog.Handler {
115122 f := NewController (slog .NewJSONHandler (buf , opts ))
116123 h := f .Handler ("h1" )
@@ -122,8 +129,8 @@ func TestHandlers(t *testing.T) {
122129 },
123130 },
124131 {
125- name : "change sink before WithXXX" ,
126- wantText : "level=INFO msg=hi logger=h1 size=big props.color=red props.address.street=mockingbird\n " ,
132+ name : "change sink before WithXXX" ,
133+ want : "level=INFO msg=hi logger=h1 size=big props.color=red props.address.street=mockingbird\n " ,
127134 handlerFn : func (_ * testing.T , buf * bytes.Buffer , opts * slog.HandlerOptions ) slog.Handler {
128135 f := NewController (slog .NewJSONHandler (buf , opts ))
129136 f .SetSink ("h1" , slog .NewTextHandler (buf , opts ))
@@ -155,8 +162,9 @@ func TestHandlers(t *testing.T) {
155162 },
156163 },
157164 {
158- name : "set other logger to nil" ,
159- wantJSON : `{"level": "INFO", "logger": "h1", "msg":"hi"}` ,
165+ name : "set other logger to nil" ,
166+ want : `{"level": "INFO", "logger": "h1", "msg":"hi"}` ,
167+ json : true ,
160168 handlerFn : func (_ * testing.T , buf * bytes.Buffer , opts * slog.HandlerOptions ) slog.Handler {
161169 f := NewController (slog .NewJSONHandler (buf , opts ))
162170 h := f .Handler ("h1" )
@@ -166,24 +174,25 @@ func TestHandlers(t *testing.T) {
166174 },
167175 },
168176 {
169- name : "default" ,
170- wantJSON : `{"level": "INFO", "logger": "def1", "msg":"hi"}` ,
177+ name : "default" ,
178+ want : `{"level": "INFO", "logger": "def1", "msg":"hi"}` ,
179+ json : true ,
171180 handlerFn : func (_ * testing.T , buf * bytes.Buffer , opts * slog.HandlerOptions ) slog.Handler {
172181 Default ().SetDefaultSink (slog .NewJSONHandler (buf , opts ))
173182 return Handler ("def1" )
174183 },
175184 },
176185 {
177- name : "default with text" ,
178- wantText : "level=INFO msg=hi logger=def1\n " ,
186+ name : "default with text" ,
187+ want : "level=INFO msg=hi logger=def1\n " ,
179188 handlerFn : func (_ * testing.T , buf * bytes.Buffer , opts * slog.HandlerOptions ) slog.Handler {
180189 Default ().SetDefaultSink (slog .NewTextHandler (buf , opts ))
181190 return Handler ("def1" )
182191 },
183192 },
184193 {
185- name : "default with specific logger" ,
186- wantText : "level=INFO msg=hi logger=def2\n " ,
194+ name : "default with specific logger" ,
195+ want : "level=INFO msg=hi logger=def2\n " ,
187196 handlerFn : func (_ * testing.T , buf * bytes.Buffer , opts * slog.HandlerOptions ) slog.Handler {
188197 Default ().SetDefaultSink (slog .NewJSONHandler (buf , opts ))
189198 Default ().SetSink ("def2" , slog .NewTextHandler (buf , opts ))
@@ -201,9 +210,9 @@ func TestHandlers(t *testing.T) {
201210 },
202211 },
203212 {
204- name : "set default log level" ,
205- level : slog .LevelDebug ,
206- wantText : "level=DEBUG msg=hi logger=def1\n " ,
213+ name : "set default log level" ,
214+ level : slog .LevelDebug ,
215+ want : "level=DEBUG msg=hi logger=def1\n " ,
207216 handlerFn : func (_ * testing.T , buf * bytes.Buffer , opts * slog.HandlerOptions ) slog.Handler {
208217 Default ().SetDefaultSink (slog .NewTextHandler (buf , opts ))
209218 Default ().SetDefaultLevel (slog .LevelDebug )
@@ -212,9 +221,9 @@ func TestHandlers(t *testing.T) {
212221 },
213222 },
214223 {
215- name : "set specific log level" ,
216- level : slog .LevelDebug ,
217- wantText : "level=DEBUG msg=hi logger=TestHandlers/set_specific_log_level\n " ,
224+ name : "set specific log level" ,
225+ level : slog .LevelDebug ,
226+ want : "level=DEBUG msg=hi logger=TestHandlers/set_specific_log_level\n " ,
218227 handlerFn : func (t * testing.T , buf * bytes.Buffer , opts * slog.HandlerOptions ) slog.Handler {
219228 Default ().SetDefaultSink (slog .NewTextHandler (buf , opts ))
220229 Default ().SetDefaultLevel (slog .LevelInfo )
@@ -224,8 +233,8 @@ func TestHandlers(t *testing.T) {
224233 },
225234 },
226235 {
227- name : "ensure cloned slices" ,
228- wantText : "level=INFO msg=hi logger=h1 props.flavor=lemon props.color=red\n " ,
236+ name : "ensure cloned slices" ,
237+ want : "level=INFO msg=hi logger=h1 props.flavor=lemon props.color=red\n " ,
229238 handlerFn : func (_ * testing.T , buf * bytes.Buffer , opts * slog.HandlerOptions ) slog.Handler {
230239 ctl := NewController (slog .NewTextHandler (buf , opts ))
231240 h1 := ctl .Handler ("h1" ).WithGroup ("props" ).WithAttrs ([]slog.Attr {slog .String ("flavor" , "lemon" )})
@@ -241,20 +250,46 @@ func TestHandlers(t *testing.T) {
241250 }
242251
243252 for _ , test := range tests {
244- t .Run (test .name , func (t * testing.T ) {
245- buf := bytes .NewBuffer (nil )
246- h := test .handlerFn (t , buf , & slog.HandlerOptions {ReplaceAttr : removeKeys (slog .TimeKey )})
247- l := slog .New (h )
248- l .Log (context .Background (), test .level , "hi" )
249- switch {
250- case test .wantJSON != "" :
251- assert .JSONEq (t , test .wantJSON , buf .String ())
252- case test .wantText != "" :
253- assert .Equal (t , test .wantText , buf .String ())
254- default :
255- assert .Empty (t , buf .String ())
256- }
257- })
253+ t .Run (test .name , test .Run )
254+ }
255+ }
256+
257+ const emptyMsg = "<<<EMPTY>>>"
258+
259+ type handlerTest struct {
260+ name string
261+ json bool
262+ want string
263+ // defaults to "hi". set to emptyMsg to use an empty message.
264+ msg string
265+ level slog.Level
266+ args []any
267+
268+ handlerFn func (t * testing.T , buf * bytes.Buffer , opts * slog.HandlerOptions ) slog.Handler
269+ }
270+
271+ func (ht handlerTest ) Run (t * testing.T ) {
272+ t .Helper ()
273+ buf := bytes .NewBuffer (nil )
274+ h := ht .handlerFn (t , buf , & slog.HandlerOptions {ReplaceAttr : removeKeys (slog .TimeKey )})
275+ l := slog .New (h )
276+
277+ msg := ht .msg
278+ switch msg {
279+ case "" :
280+ msg = "hi"
281+ case emptyMsg :
282+ msg = ""
283+ }
284+
285+ l .Log (context .Background (), ht .level , msg , ht .args ... )
286+ switch {
287+ case ht .want == "" :
288+ assert .Empty (t , buf .String ())
289+ case ht .json :
290+ assert .JSONEq (t , ht .want , buf .String ())
291+ default :
292+ assert .Equal (t , ht .want , buf .String ())
258293 }
259294}
260295
0 commit comments