Skip to content

Commit

Permalink
qa: more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dcilke committed Apr 27, 2023
1 parent 4f9a32e commit 72ee711
Show file tree
Hide file tree
Showing 43 changed files with 367 additions and 44 deletions.
2 changes: 1 addition & 1 deletion integration/setup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,5 @@ func hz(args ...string) ([]byte, error) {
}

func fn(file string) string {
return filepath.Join("data", file)
return filepath.Join("testdata", "samples", file)
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
14 changes: 6 additions & 8 deletions pkg/formatter/caller.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,18 @@ const (
var _ Formatter = (*Caller)(nil)

type Caller struct {
noColor bool
formatKey Stringer
keys []string
noColor bool
keys []string
}

func NewCaller(noColor bool, formatKey Stringer) Formatter {
func NewCaller(noColor bool) Formatter {
return &Caller{
noColor: noColor,
formatKey: formatKey,
keys: []string{KeyCaller},
noColor: noColor,
keys: []string{KeyCaller},
}
}

func (f *Caller) Format(m map[string]any, _ string) string {
func (f *Caller) Format(m map[string]any) string {
if i, ok := m[KeyCaller]; ok {
var c string
if cc, ok := i.(string); ok {
Expand Down
34 changes: 34 additions & 0 deletions pkg/formatter/caller_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package formatter_test

import (
"testing"

"github.com/dcilke/hz/pkg/formatter"
"github.com/stretchr/testify/require"
)

func TestCaller(t *testing.T) {
testcases := map[string]struct {
noColor bool
expect string
}{
"no-color": {true, "caller >"},
"color": {false, "\x1b[1mcaller\x1b[0m\x1b[36m >\x1b[0m"},
}
for name, tc := range testcases {
t.Run(name, func(t *testing.T) {
f := formatter.NewCaller(tc.noColor)
str := f.Format(map[string]any{
formatter.KeyCaller: "caller",
"extra": "should be ignored",
})

require.Equal(t, tc.expect, str)
})
}
}

func TestCaller_ExcludeKeys(t *testing.T) {
f := formatter.NewCaller(false)
require.Equal(t, []string{formatter.KeyCaller}, f.ExcludeKeys())
}
2 changes: 1 addition & 1 deletion pkg/formatter/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func NewError(noColor bool, formatKey Stringer) Formatter {
}
}

func (f *Error) Format(m map[string]any, _ string) string {
func (f *Error) Format(m map[string]any) string {
var ferr string
var ferror string
if i, ok := m[KeyError]; ok {
Expand Down
35 changes: 35 additions & 0 deletions pkg/formatter/error_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package formatter_test

import (
"testing"

"github.com/dcilke/hz/pkg/formatter"
"github.com/stretchr/testify/require"
)

func TestError(t *testing.T) {
testcases := map[string]struct {
noColor bool
msg map[string]any
expect string
}{
"error-no-color": {true, map[string]any{"error": "err"}, "error=err"},
"err-no-color": {true, map[string]any{"err": "err"}, "error=err"},
"error-color": {false, map[string]any{"error": "err"}, "error=\x1b[31merr\x1b[0m"},
"err-color": {false, map[string]any{"err": "err"}, "error=\x1b[31merr\x1b[0m"},
"diff": {true, map[string]any{"error": "error", "err": "err"}, "error=error err=err"},
}
for name, tc := range testcases {
t.Run(name, func(t *testing.T) {
f := formatter.NewError(tc.noColor, formatKey)
str := f.Format(tc.msg)

require.Equal(t, tc.expect, str)
})
}
}

func TestError_ExcludeKeys(t *testing.T) {
f := formatter.NewError(false, nil)
require.Equal(t, []string{formatter.KeyError, formatter.KeyErr}, f.ExcludeKeys())
}
15 changes: 9 additions & 6 deletions pkg/formatter/formatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import (
"encoding/json"
"fmt"
"strconv"
"strings"
)

// Formatter defines a formatter for a specific pin key
type Formatter interface {
Format(map[string]any, string) string
Format(map[string]any) string
ExcludeKeys() []string
}

Expand All @@ -20,11 +21,11 @@ type Stringer func(any) string

func Key(noColor bool) Stringer {
return func(i any) string {
return Colorize(fmt.Sprintf("%s=", i), ColorCyan, noColor)
return Colorize(fmt.Sprintf("%v=", i), ColorCyan, noColor)
}
}

func Map(noColor bool, fn Stringer) Extractor {
func Map(fn Stringer) Extractor {
return func(m map[string]any, k string) string {
ret := fn(k)
switch fValue := m[k].(type) {
Expand All @@ -38,10 +39,12 @@ func Map(noColor bool, fn Stringer) Extractor {
ret += fValue.String()
default:
b, err := json.Marshal(fValue)
if err != nil {
ret += fmt.Sprintf(Colorize("[error: %v]", ColorRed, noColor), err)
} else {
if err == nil {
ret += string(b)
} else if strings.HasPrefix(err.Error(), "json: unsupported value: encountered a cycle") {
ret += "<cycle>"
} else {
ret += fmt.Sprintf("%v", fValue)
}
}
return ret
Expand Down
80 changes: 80 additions & 0 deletions pkg/formatter/formatter_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package formatter_test

import (
"fmt"
"math"
"testing"

"github.com/dcilke/hz/pkg/formatter"
"github.com/stretchr/testify/require"
)

func formatKey(key any) string {
return fmt.Sprintf("%s=", key)
}

func TestKey(t *testing.T) {
testcases := map[string]struct {
noColor bool
key any
expect string
}{
"no-color": {true, "key", "key="},
"color": {false, "key", "\x1b[36mkey=\x1b[0m"},
"number": {true, 42, "42="},
"byte": {true, byte(195), "195="},
"rune": {true, rune(195), "195="},
"object": {true, map[string]any{"foo": "bar"}, "map[foo:bar]="},
"array": {true, []string{"foo", "bar"}, "[foo bar]="},
}
for name, tc := range testcases {
t.Run(name, func(t *testing.T) {
f := formatter.Key(tc.noColor)
require.Equal(t, tc.expect, f(tc.key))
})
}
}

func TestMap(t *testing.T) {
var (
mapCycle = make(map[string]any)
sliceCycle = []any{nil}
)
mapCycle["x"] = mapCycle
sliceCycle[0] = sliceCycle

data := map[string]any{
"key": "value",
"map": map[string]any{
"foo": "bar",
},
"quotes": `this is a string`,
"num": 42,
"nan": math.NaN(),
"pinf": math.Inf(1),
"ninf": math.Inf(-1),
"map-cycle": mapCycle,
"slice-cycle": sliceCycle,
}

testcases := map[string]struct {
key string
expect string
}{
"key": {"key", "key=value"},
"map": {"map", "map={\"foo\":\"bar\"}"},
"quotes": {"quotes", "quotes=\"this is a string\""},
"num": {"num", "num=42"},
"nan": {"nan", "nan=NaN"},
"pinf": {"pinf", "pinf=+Inf"},
"ninf": {"ninf", "ninf=-Inf"},
"map-cycle": {"map-cycle", "map-cycle=<cycle>"},
"slice-cycle": {"slice-cycle", "slice-cycle=<cycle>"},
}
for name, tc := range testcases {
t.Run(name, func(t *testing.T) {
f := formatter.Map(formatKey)
require.Equal(t, tc.expect, f(data, tc.key))
})
}
}
47 changes: 27 additions & 20 deletions pkg/formatter/level.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package formatter
import (
"encoding/json"
"fmt"
"strings"

"github.com/dcilke/hz/pkg/g"
)
Expand Down Expand Up @@ -53,7 +54,7 @@ func NewLevel(noColor bool, formatKey Stringer) Formatter {
}
}

func (f *Level) Format(m map[string]any, _ string) string {
func (f *Level) Format(m map[string]any) string {
levels := GetLevels(m)

if ok, value := g.SameOrEmpty(levels[KeyLevel], levels[KeyLog]); ok {
Expand Down Expand Up @@ -90,7 +91,11 @@ func (f *Level) format(l string) string {
case LevelTraceStr:
return Colorize(DefaultLevelTraceValue, ColorMagenta, f.noColor)
default:
return Colorize(DefaultLevelValue, ColorBold, f.noColor)
ll := strings.ToUpper(l)
if len(ll) > 3 {
ll = ll[0:3]
}
return Colorize(ll, ColorBold, f.noColor)
}
}

Expand All @@ -114,24 +119,7 @@ func getLevel(i any) string {
return ""
}

if l, ok := i.(string); ok {
switch l {
case LevelPanicStr:
return LevelPanicStr
case LevelFatalStr:
return LevelFatalStr
case LevelErrorStr:
return LevelErrorStr
case LevelWarnStr:
return LevelWarnStr
case LevelInfoStr:
return LevelInfoStr
case LevelDebugStr:
return LevelDebugStr
case LevelTraceStr:
return LevelTraceStr
}
} else if n, ok := i.(json.Number); ok {
if n, ok := i.(json.Number); ok {
if l, err := n.Int64(); err == nil {
if l >= LevelPanicNum {
return LevelPanicStr
Expand All @@ -155,6 +143,25 @@ func getLevel(i any) string {
return LevelTraceStr
}
}
} else {
if l, ok := i.(string); ok {
switch l {
case LevelPanicStr:
return LevelPanicStr
case LevelFatalStr:
return LevelFatalStr
case LevelErrorStr:
return LevelErrorStr
case LevelWarnStr:
return LevelWarnStr
case LevelInfoStr:
return LevelInfoStr
case LevelDebugStr:
return LevelDebugStr
case LevelTraceStr:
return LevelTraceStr
}
}
}
return fmt.Sprintf("%s", i)
}
75 changes: 75 additions & 0 deletions pkg/formatter/level_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package formatter_test

import (
"testing"

"github.com/dcilke/hz/pkg/formatter"
"github.com/stretchr/testify/require"
)

func TestLevel(t *testing.T) {

testcases := map[string]struct {
noColor bool
msg map[string]any
expect string
}{
"trace-no-color": {true, ml("trace"), "TRC"},
"debug-no-color": {true, ml("debug"), "DBG"},
"info-no-color": {true, ml("info"), "INF"},
"warn-no-color": {true, ml("warn"), "WRN"},
"error-no-color": {true, ml("error"), "ERR"},
"fatal-no-color": {true, ml("fatal"), "FTL"},
"panic-no-color": {true, ml("panic"), "PNC"},
"unknown-no-color": {true, ml("unknown"), "UNK"},
"10-no-color": {true, ml(10), "TRC"},
"20-no-color": {true, ml(20), "DBG"},
"30-no-color": {true, ml(30), "INF"},
"40-no-color": {true, ml(40), "WRN"},
"50-no-color": {true, ml(50), "ERR"},
"60-no-color": {true, ml(60), "FTL"},
"100-no-color": {true, ml(100), "PNC"},
"2-no-color": {true, ml(2), "2"},
"trace-color": {false, ml("trace"), "\x1b[35mTRC\x1b[0m"},
"debug-color": {false, ml("debug"), "\x1b[33mDBG\x1b[0m"},
"info-color": {false, ml("info"), "\x1b[32mINF\x1b[0m"},
"warn-color": {false, ml("warn"), "\x1b[31mWRN\x1b[0m"},
"error-color": {false, ml("error"), "\x1b[1m\x1b[31mERR\x1b[0m\x1b[0m"},
"fatal-color": {false, ml("fatal"), "\x1b[1m\x1b[31mFTL\x1b[0m\x1b[0m"},
"panic-color": {false, ml("panic"), "\x1b[1m\x1b[31mPNC\x1b[0m\x1b[0m"},
"unknown-color": {false, ml("unknown"), "\x1b[1mUNK\x1b[0m"},
"10-color": {false, ml(10), "\x1b[35mTRC\x1b[0m"},
"20-color": {false, ml(20), "\x1b[33mDBG\x1b[0m"},
"30-color": {false, ml(30), "\x1b[32mINF\x1b[0m"},
"40-color": {false, ml(40), "\x1b[31mWRN\x1b[0m"},
"50-color": {false, ml(50), "\x1b[1m\x1b[31mERR\x1b[0m\x1b[0m"},
"60-color": {false, ml(60), "\x1b[1m\x1b[31mFTL\x1b[0m\x1b[0m"},
"100-color": {false, ml(100), "\x1b[1m\x1b[31mPNC\x1b[0m\x1b[0m"},
"2-color": {false, ml(2), "\x1b[1m2\x1b[0m"},
"diff": {true, map[string]any{"level": "info", "log": map[string]any{"level": "debug"}}, "level=INF log.level=DBG"},
}
for name, tc := range testcases {
t.Run(name, func(t *testing.T) {
f := formatter.NewLevel(tc.noColor, formatKey)
str := f.Format(tc.msg)
require.Equal(t, tc.expect, str)
})
}
}

func TestLevel_ExcludeKeys(t *testing.T) {
f := formatter.NewLevel(false, nil)
require.Equal(t, []string{formatter.KeyLevel, formatter.KeyLog}, f.ExcludeKeys())
}

func ml(level any) map[string]any {
if l, ok := level.(int); ok {
level = jn(l)
}
return map[string]any{
formatter.KeyLevel: level,
formatter.KeyLog: map[string]any{
formatter.KeyLevel: level,
},
}
}
Loading

0 comments on commit 72ee711

Please sign in to comment.