Skip to content

Commit

Permalink
Accept capital strings in Level.UnmarshalText (#435)
Browse files Browse the repository at this point in the history
Since zap can be configured to emit all-caps levels, accept all-caps when unmarshaling too. At a slight performance penalty, also support mixed-case levels.
  • Loading branch information
jcorbin authored and akshayjshah committed May 25, 2017
1 parent fab4530 commit b33459c
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 12 deletions.
26 changes: 17 additions & 9 deletions zapcore/level.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
package zapcore

import (
"bytes"
"errors"
"fmt"
)
Expand Down Expand Up @@ -116,25 +117,32 @@ func (l *Level) UnmarshalText(text []byte) error {
if l == nil {
return errUnmarshalNilLevel
}
if !l.unmarshalText(text) && !l.unmarshalText(bytes.ToLower(text)) {
return fmt.Errorf("unrecognized level: %q", text)
}
return nil
}

func (l *Level) unmarshalText(text []byte) bool {
switch string(text) {
case "debug":
case "debug", "DEBUG":
*l = DebugLevel
case "info", "": // make the zero value useful
case "info", "INFO", "": // make the zero value useful
*l = InfoLevel
case "warn":
case "warn", "WARN":
*l = WarnLevel
case "error":
case "error", "ERROR":
*l = ErrorLevel
case "dpanic":
case "dpanic", "DPANIC":
*l = DPanicLevel
case "panic":
case "panic", "PANIC":
*l = PanicLevel
case "fatal":
case "fatal", "FATAL":
*l = FatalLevel
default:
return fmt.Errorf("unrecognized level: %v", string(text))
return false
}
return nil
return true
}

// Set sets the level for the flag.Value interface.
Expand Down
58 changes: 55 additions & 3 deletions zapcore/level_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,60 @@ func TestLevelText(t *testing.T) {

var unmarshaled Level
err := unmarshaled.UnmarshalText([]byte(tt.text))
assert.NoError(t, err, `Unexpected error unmarshaling text "%v" to level.`, tt.text)
assert.Equal(t, tt.level, unmarshaled, `Text "%v" unmarshaled to an unexpected level.`, tt.text)
assert.NoError(t, err, `Unexpected error unmarshaling text %q to level.`, tt.text)
assert.Equal(t, tt.level, unmarshaled, `Text %q unmarshaled to an unexpected level.`, tt.text)
}
}

func TestCapitalLevelsParse(t *testing.T) {
tests := []struct {
text string
level Level
}{
{"DEBUG", DebugLevel},
{"INFO", InfoLevel},
{"WARN", WarnLevel},
{"ERROR", ErrorLevel},
{"DPANIC", DPanicLevel},
{"PANIC", PanicLevel},
{"FATAL", FatalLevel},
}
for _, tt := range tests {
var unmarshaled Level
err := unmarshaled.UnmarshalText([]byte(tt.text))
assert.NoError(t, err, `Unexpected error unmarshaling text %q to level.`, tt.text)
assert.Equal(t, tt.level, unmarshaled, `Text %q unmarshaled to an unexpected level.`, tt.text)
}
}

func TestWeirdLevelsParse(t *testing.T) {
tests := []struct {
text string
level Level
}{
// I guess...
{"Debug", DebugLevel},
{"Info", InfoLevel},
{"Warn", WarnLevel},
{"Error", ErrorLevel},
{"Dpanic", DPanicLevel},
{"Panic", PanicLevel},
{"Fatal", FatalLevel},

// What even is...
{"DeBuG", DebugLevel},
{"InFo", InfoLevel},
{"WaRn", WarnLevel},
{"ErRor", ErrorLevel},
{"DpAnIc", DPanicLevel},
{"PaNiC", PanicLevel},
{"FaTaL", FatalLevel},
}
for _, tt := range tests {
var unmarshaled Level
err := unmarshaled.UnmarshalText([]byte(tt.text))
assert.NoError(t, err, `Unexpected error unmarshaling text %q to level.`, tt.text)
assert.Equal(t, tt.level, unmarshaled, `Text %q unmarshaled to an unexpected level.`, tt.text)
}
}

Expand Down Expand Up @@ -118,7 +170,7 @@ func TestLevelAsFlagValue(t *testing.T) {
assert.Error(t, fs.Parse([]string{"-level", "nope"}))
assert.Equal(
t,
`invalid value "nope" for flag -level: unrecognized level: nope`,
`invalid value "nope" for flag -level: unrecognized level: "nope"`,
strings.Split(buf.String(), "\n")[0], // second line is help message
"Unexpected error output from invalid flag input.",
)
Expand Down

0 comments on commit b33459c

Please sign in to comment.