1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package zapcore
22
23 import (
24 "bytes"
25 "flag"
26 "strings"
27 "testing"
28
29 "github.com/stretchr/testify/assert"
30 )
31
32 func TestLevelString(t *testing.T) {
33 tests := map[Level]string{
34 DebugLevel: "debug",
35 InfoLevel: "info",
36 WarnLevel: "warn",
37 ErrorLevel: "error",
38 DPanicLevel: "dpanic",
39 PanicLevel: "panic",
40 FatalLevel: "fatal",
41 Level(-42): "Level(-42)",
42 InvalidLevel: "Level(6)",
43 }
44
45 for lvl, stringLevel := range tests {
46 assert.Equal(t, stringLevel, lvl.String(), "Unexpected lowercase level string.")
47 assert.Equal(t, strings.ToUpper(stringLevel), lvl.CapitalString(), "Unexpected all-caps level string.")
48 }
49 }
50
51 func TestLevelText(t *testing.T) {
52 tests := []struct {
53 text string
54 level Level
55 }{
56 {"debug", DebugLevel},
57 {"info", InfoLevel},
58 {"", InfoLevel},
59 {"warn", WarnLevel},
60 {"error", ErrorLevel},
61 {"dpanic", DPanicLevel},
62 {"panic", PanicLevel},
63 {"fatal", FatalLevel},
64 }
65 for _, tt := range tests {
66 if tt.text != "" {
67 lvl := tt.level
68 marshaled, err := lvl.MarshalText()
69 assert.NoError(t, err, "Unexpected error marshaling level %v to text.", &lvl)
70 assert.Equal(t, tt.text, string(marshaled), "Marshaling level %v to text yielded unexpected result.", &lvl)
71 }
72
73 var unmarshaled Level
74 err := unmarshaled.UnmarshalText([]byte(tt.text))
75 assert.NoError(t, err, `Unexpected error unmarshaling text %q to level.`, tt.text)
76 assert.Equal(t, tt.level, unmarshaled, `Text %q unmarshaled to an unexpected level.`, tt.text)
77 }
78 }
79
80 func TestParseLevel(t *testing.T) {
81 tests := []struct {
82 text string
83 level Level
84 err string
85 }{
86 {"info", InfoLevel, ""},
87 {"DEBUG", DebugLevel, ""},
88 {"FOO", 0, `unrecognized level: "FOO"`},
89 }
90 for _, tt := range tests {
91 parsedLevel, err := ParseLevel(tt.text)
92 if len(tt.err) == 0 {
93 assert.NoError(t, err)
94 assert.Equal(t, tt.level, parsedLevel)
95 } else {
96 assert.ErrorContains(t, err, tt.err)
97 }
98 }
99 }
100
101 func TestCapitalLevelsParse(t *testing.T) {
102 tests := []struct {
103 text string
104 level Level
105 }{
106 {"DEBUG", DebugLevel},
107 {"INFO", InfoLevel},
108 {"WARN", WarnLevel},
109 {"ERROR", ErrorLevel},
110 {"DPANIC", DPanicLevel},
111 {"PANIC", PanicLevel},
112 {"FATAL", FatalLevel},
113 }
114 for _, tt := range tests {
115 var unmarshaled Level
116 err := unmarshaled.UnmarshalText([]byte(tt.text))
117 assert.NoError(t, err, `Unexpected error unmarshaling text %q to level.`, tt.text)
118 assert.Equal(t, tt.level, unmarshaled, `Text %q unmarshaled to an unexpected level.`, tt.text)
119 }
120 }
121
122 func TestWeirdLevelsParse(t *testing.T) {
123 tests := []struct {
124 text string
125 level Level
126 }{
127
128 {"Debug", DebugLevel},
129 {"Info", InfoLevel},
130 {"Warn", WarnLevel},
131 {"Error", ErrorLevel},
132 {"Dpanic", DPanicLevel},
133 {"Panic", PanicLevel},
134 {"Fatal", FatalLevel},
135
136
137 {"DeBuG", DebugLevel},
138 {"InFo", InfoLevel},
139 {"WaRn", WarnLevel},
140 {"ErRor", ErrorLevel},
141 {"DpAnIc", DPanicLevel},
142 {"PaNiC", PanicLevel},
143 {"FaTaL", FatalLevel},
144 }
145 for _, tt := range tests {
146 var unmarshaled Level
147 err := unmarshaled.UnmarshalText([]byte(tt.text))
148 assert.NoError(t, err, `Unexpected error unmarshaling text %q to level.`, tt.text)
149 assert.Equal(t, tt.level, unmarshaled, `Text %q unmarshaled to an unexpected level.`, tt.text)
150 }
151 }
152
153 func TestLevelNils(t *testing.T) {
154 var l *Level
155
156
157 assert.Panics(t, func() {
158 assert.Equal(t, "Level(nil)", l.String(), "Unexpected result stringifying nil *Level.")
159 }, "Level(nil).String() should panic")
160
161 assert.Panics(t, func() {
162 _, _ = l.MarshalText()
163 }, "Expected to panic when marshalling a nil level.")
164
165 err := l.UnmarshalText([]byte("debug"))
166 assert.Equal(t, errUnmarshalNilLevel, err, "Expected to error unmarshalling into a nil Level.")
167 }
168
169 func TestLevelUnmarshalUnknownText(t *testing.T) {
170 var l Level
171 err := l.UnmarshalText([]byte("foo"))
172 assert.ErrorContains(t, err, "unrecognized level", "Expected unmarshaling arbitrary text to fail.")
173 }
174
175 func TestLevelAsFlagValue(t *testing.T) {
176 var (
177 buf bytes.Buffer
178 lvl Level
179 )
180 fs := flag.NewFlagSet("levelTest", flag.ContinueOnError)
181 fs.SetOutput(&buf)
182 fs.Var(&lvl, "level", "log level")
183
184 for _, expected := range []Level{DebugLevel, InfoLevel, WarnLevel, ErrorLevel, DPanicLevel, PanicLevel, FatalLevel} {
185 assert.NoError(t, fs.Parse([]string{"-level", expected.String()}))
186 assert.Equal(t, expected, lvl, "Unexpected level after parsing flag.")
187 assert.Equal(t, expected, lvl.Get(), "Unexpected output using flag.Getter API.")
188 assert.Empty(t, buf.String(), "Unexpected error output parsing level flag.")
189 buf.Reset()
190 }
191
192 assert.Error(t, fs.Parse([]string{"-level", "nope"}))
193 assert.Equal(
194 t,
195 `invalid value "nope" for flag -level: unrecognized level: "nope"`,
196 strings.Split(buf.String(), "\n")[0],
197 "Unexpected error output from invalid flag input.",
198 )
199 }
200
201
202
203 type enablerWithCustomLevel struct{ lvl Level }
204
205 var _ leveledEnabler = (*enablerWithCustomLevel)(nil)
206
207 func (l *enablerWithCustomLevel) Enabled(lvl Level) bool {
208 return l.lvl.Enabled(lvl)
209 }
210
211 func (l *enablerWithCustomLevel) Level() Level {
212 return l.lvl
213 }
214
215 func TestLevelOf(t *testing.T) {
216 tests := []struct {
217 desc string
218 give LevelEnabler
219 want Level
220 }{
221 {desc: "debug", give: DebugLevel, want: DebugLevel},
222 {desc: "info", give: InfoLevel, want: InfoLevel},
223 {desc: "warn", give: WarnLevel, want: WarnLevel},
224 {desc: "error", give: ErrorLevel, want: ErrorLevel},
225 {desc: "dpanic", give: DPanicLevel, want: DPanicLevel},
226 {desc: "panic", give: PanicLevel, want: PanicLevel},
227 {desc: "fatal", give: FatalLevel, want: FatalLevel},
228 {
229 desc: "leveledEnabler",
230 give: &enablerWithCustomLevel{lvl: InfoLevel},
231 want: InfoLevel,
232 },
233 {
234 desc: "noop",
235 give: NewNopCore(),
236 want: InvalidLevel,
237 },
238 }
239
240 for _, tt := range tests {
241 tt := tt
242 t.Run(tt.desc, func(t *testing.T) {
243 t.Parallel()
244
245 assert.Equal(t, tt.want, LevelOf(tt.give), "Reported level did not match.")
246 })
247 }
248 }
249
View as plain text