1 package clog
2
3 import (
4 "encoding/json"
5 "testing"
6 )
7
8
9 type Tmarshaler struct{ val string }
10
11 func (t Tmarshaler) MarshalLog() any {
12 return struct{ Inner string }{"I am a logr.Marshaler"}
13 }
14
15 func (t Tmarshaler) String() string {
16 return "String(): you should not see this"
17 }
18
19 func (t Tmarshaler) Error() string {
20 return "Error(): you should not see this"
21 }
22
23
24 type Tmarshalerpanic struct{ val string }
25
26 func (t Tmarshalerpanic) MarshalLog() any {
27 panic("Tmarshalerpanic")
28 }
29
30
31 type Tstringer struct{ val string }
32
33 func (t Tstringer) String() string {
34 return "I am a fmt.Stringer"
35 }
36
37 func (t Tstringer) Error() string {
38 return "Error(): you should not see this"
39 }
40
41
42 type Tstringerpanic struct{ val string }
43
44 func (t Tstringerpanic) String() string {
45 panic("Tstringerpanic")
46 }
47
48
49 type Terror struct{ val string }
50
51 func (t Terror) Error() string {
52 return "I am an error"
53 }
54
55
56 type Terrorpanic struct{ val string }
57
58 func (t Terrorpanic) Error() string {
59 panic("Terrorpanic")
60 }
61
62 func TestPretty(t *testing.T) {
63 cases := []struct {
64 val any
65 exp string
66 }{
67 {
68 val: "strval",
69 exp: "strval",
70 }, {
71 val: "strval\nwith\t\"escapes\"",
72 }, {
73 val: true,
74 }, {
75 val: false,
76 }, {
77 val: int(93),
78 }, {
79 val: int8(93),
80 }, {
81 val: int16(93),
82 }, {
83 val: int32(93),
84 }, {
85 val: int64(93),
86 }, {
87 val: int(-93),
88 }, {
89 val: int8(-93),
90 }, {
91 val: int16(-93),
92 }, {
93 val: int32(-93),
94 }, {
95 val: int64(-93),
96 }, {
97 val: uint(93),
98 }, {
99 val: uint8(93),
100 }, {
101 val: uint16(93),
102 }, {
103 val: uint32(93),
104 }, {
105 val: uint64(93),
106 }, {
107 val: uintptr(93),
108 }, {
109 val: float32(93.76),
110 }, {
111 val: float64(93.76),
112 }, {
113 val: complex64(93i),
114 exp: `"(0+93i)"`,
115 }, {
116 val: complex128(93i),
117 exp: `"(0+93i)"`,
118 }, {
119 val: Tmarshaler{"foobar"},
120 exp: "{Inner:I am a logr.Marshaler}",
121 }, {
122 val: &Tmarshaler{"foobar"},
123 exp: "{Inner:I am a logr.Marshaler}",
124 }, {
125 val: (*Tmarshaler)(nil),
126 exp: "<panic: value method edge-infra.dev/pkg/lib/cli/clog.Tmarshaler.MarshalLog called using nil *Tmarshaler pointer>",
127 }, {
128 val: Tmarshalerpanic{"foobar"},
129 exp: "<panic: Tmarshalerpanic>",
130 }, {
131 val: Tstringer{"foobar"},
132 exp: "I am a fmt.Stringer",
133 }, {
134 val: &Tstringer{"foobar"},
135 exp: "I am a fmt.Stringer",
136 }, {
137 val: (*Tstringer)(nil),
138 exp: "<panic: value method edge-infra.dev/pkg/lib/cli/clog.Tstringer.String called using nil *Tstringer pointer>",
139 }, {
140 val: Tstringerpanic{"foobar"},
141 exp: "<panic: Tstringerpanic>",
142 }, {
143 val: Terror{"foobar"},
144 exp: "I am an error",
145 }, {
146 val: &Terror{"foobar"},
147 exp: "I am an error",
148 }, {
149 val: (*Terror)(nil),
150 exp: "<panic: value method edge-infra.dev/pkg/lib/cli/clog.Terror.Error called using nil *Terror pointer>",
151 }, {
152 val: Terrorpanic{"foobar"},
153 exp: "<panic: Terrorpanic>",
154 }, {
155 val: []string{"foo", "bar"},
156 exp: "\n foo\n bar",
157 }, {
158 val: map[string]string{
159 "foo": "bar",
160 "yes": "no",
161 },
162 exp: "\n foo bar\n yes no",
163 }, {
164 val: map[string]string{
165 "yes": "",
166 "foo": "bar",
167 },
168 exp: "\n foo bar",
169 }, {
170 val: map[string]string{
171 "foo": "bar",
172 "yes": "",
173 },
174 exp: "\n foo bar",
175 }, {
176 val: map[string]string{
177 "no": "",
178 "foo": "bar",
179 "yes": "",
180 "op": "delete",
181 },
182 exp: "\n foo bar\n op delete",
183 },
184
185 }
186
187 for i, tc := range cases {
188 l := &clog{tabWidth: 2}
189 ours := l.pretty(tc.val)
190 want := ""
191 if tc.exp != "" {
192 want = tc.exp
193 } else {
194 jb, err := json.Marshal(tc.val)
195 if err != nil {
196 t.Fatalf("[%d]: unexpected error: %v\ngot: %q", i, err, ours)
197 }
198 want = string(jb)
199 }
200 if ours != want {
201 t.Errorf("[%d]:\n\texpected %q\n\tgot %q", i, want, ours)
202 }
203 }
204 }
205
View as plain text