Source file
src/log/slog/slogtest_test.go
1
2
3
4
5 package slog_test
6
7 import (
8 "bytes"
9 "encoding/json"
10 "fmt"
11 "io"
12 "log/slog"
13 "strings"
14 "testing"
15 "testing/slogtest"
16 )
17
18 func TestSlogtest(t *testing.T) {
19 for _, test := range []struct {
20 name string
21 new func(io.Writer) slog.Handler
22 parse func([]byte) (map[string]any, error)
23 }{
24 {"JSON", func(w io.Writer) slog.Handler { return slog.NewJSONHandler(w, nil) }, parseJSON},
25 {"Text", func(w io.Writer) slog.Handler { return slog.NewTextHandler(w, nil) }, parseText},
26 } {
27 t.Run(test.name, func(t *testing.T) {
28 var buf bytes.Buffer
29 h := test.new(&buf)
30 results := func() []map[string]any {
31 ms, err := parseLines(buf.Bytes(), test.parse)
32 if err != nil {
33 t.Fatal(err)
34 }
35 return ms
36 }
37 if err := slogtest.TestHandler(h, results); err != nil {
38 t.Fatal(err)
39 }
40 })
41 }
42 }
43
44 func parseLines(src []byte, parse func([]byte) (map[string]any, error)) ([]map[string]any, error) {
45 var records []map[string]any
46 for _, line := range bytes.Split(src, []byte{'\n'}) {
47 if len(line) == 0 {
48 continue
49 }
50 m, err := parse(line)
51 if err != nil {
52 return nil, fmt.Errorf("%s: %w", string(line), err)
53 }
54 records = append(records, m)
55 }
56 return records, nil
57 }
58
59 func parseJSON(bs []byte) (map[string]any, error) {
60 var m map[string]any
61 if err := json.Unmarshal(bs, &m); err != nil {
62 return nil, err
63 }
64 return m, nil
65 }
66
67
68
69
70
71
72
73 func parseText(bs []byte) (map[string]any, error) {
74 top := map[string]any{}
75 s := string(bytes.TrimSpace(bs))
76 for len(s) > 0 {
77 kv, rest, _ := strings.Cut(s, " ")
78 k, value, found := strings.Cut(kv, "=")
79 if !found {
80 return nil, fmt.Errorf("no '=' in %q", kv)
81 }
82 keys := strings.Split(k, ".")
83
84 m := top
85 for _, key := range keys[:len(keys)-1] {
86 x, ok := m[key]
87 var m2 map[string]any
88 if !ok {
89 m2 = map[string]any{}
90 m[key] = m2
91 } else {
92 m2, ok = x.(map[string]any)
93 if !ok {
94 return nil, fmt.Errorf("value for %q in composite key %q is not map[string]any", key, k)
95
96 }
97 }
98 m = m2
99 }
100 m[keys[len(keys)-1]] = value
101 s = rest
102 }
103 return top, nil
104 }
105
View as plain text