234 lines
5.6 KiB
Go
Raw Normal View History

package logfmt
import (
"bytes"
"errors"
"fmt"
"reflect"
"testing"
)
func TestSafeString(t *testing.T) {
_, ok := safeString((*stringStringer)(nil))
if got, want := ok, false; got != want {
t.Errorf(" got %v, want %v", got, want)
}
}
func TestSafeMarshal(t *testing.T) {
kb, err := safeMarshal((*stringMarshaler)(nil))
if got := kb; got != nil {
t.Errorf(" got %v, want nil", got)
}
if got, want := err, error(nil); got != want {
t.Errorf(" got %v, want %v", got, want)
}
}
func TestWriteKeyStrings(t *testing.T) {
keygen := []func(string) interface{}{
func(s string) interface{} { return s },
func(s string) interface{} { return stringData(s) },
func(s string) interface{} { return stringStringer(s) },
func(s string) interface{} { return stringMarshaler(s) },
}
data := []struct {
key string
want string
err error
}{
{key: "k", want: "k"},
{key: `\`, want: `\`},
{key: "\n", err: ErrInvalidKey},
{key: "\x00", err: ErrInvalidKey},
{key: "\x10", err: ErrInvalidKey},
{key: "\x1F", err: ErrInvalidKey},
{key: "", err: ErrInvalidKey},
{key: " ", err: ErrInvalidKey},
{key: "=", err: ErrInvalidKey},
{key: `"`, err: ErrInvalidKey},
}
for _, g := range keygen {
for _, d := range data {
w := &bytes.Buffer{}
key := g(d.key)
err := writeKey(w, key)
if err != d.err {
t.Errorf("%#v (%[1]T): got error: %v, want error: %v", key, err, d.err)
}
if err != nil {
continue
}
if got, want := w.String(), d.want; got != want {
t.Errorf("%#v (%[1]T): got '%s', want '%s'", key, got, want)
}
}
}
}
func TestWriteKey(t *testing.T) {
var (
nilPtr *int
one = 1
ptr = &one
)
data := []struct {
key interface{}
want string
err error
}{
{key: nil, err: ErrNilKey},
{key: nilPtr, err: ErrNilKey},
{key: (*stringStringer)(nil), err: ErrNilKey},
{key: (*stringMarshaler)(nil), err: ErrNilKey},
{key: (*stringerMarshaler)(nil), err: ErrNilKey},
{key: ptr, want: "1"},
{key: errorMarshaler{}, err: &MarshalerError{Type: reflect.TypeOf(errorMarshaler{}), Err: errMarshaling}},
{key: make(chan int), err: ErrUnsupportedKeyType},
{key: []int{}, err: ErrUnsupportedKeyType},
{key: map[int]int{}, err: ErrUnsupportedKeyType},
{key: [2]int{}, err: ErrUnsupportedKeyType},
{key: struct{}{}, err: ErrUnsupportedKeyType},
{key: fmt.Sprint, err: ErrUnsupportedKeyType},
}
for _, d := range data {
w := &bytes.Buffer{}
err := writeKey(w, d.key)
if !reflect.DeepEqual(err, d.err) {
t.Errorf("%#v: got error: %v, want error: %v", d.key, err, d.err)
}
if err != nil {
continue
}
if got, want := w.String(), d.want; got != want {
t.Errorf("%#v: got '%s', want '%s'", d.key, got, want)
}
}
}
func TestWriteValueStrings(t *testing.T) {
keygen := []func(string) interface{}{
func(s string) interface{} { return s },
func(s string) interface{} { return errors.New(s) },
func(s string) interface{} { return stringData(s) },
func(s string) interface{} { return stringStringer(s) },
func(s string) interface{} { return stringMarshaler(s) },
}
data := []struct {
value string
want string
err error
}{
{value: "", want: ""},
{value: "v", want: "v"},
{value: " ", want: `" "`},
{value: "=", want: `"="`},
{value: `\`, want: `\`},
{value: `"`, want: `"\""`},
{value: `\"`, want: `"\\\""`},
{value: "\n", want: `"\n"`},
{value: "\x00", want: `"\u0000"`},
{value: "\x10", want: `"\u0010"`},
{value: "\x1F", want: `"\u001f"`},
{value: "µ", want: `µ`},
}
for _, g := range keygen {
for _, d := range data {
w := &bytes.Buffer{}
value := g(d.value)
err := writeValue(w, value)
if err != d.err {
t.Errorf("%#v (%[1]T): got error: %v, want error: %v", value, err, d.err)
}
if err != nil {
continue
}
if got, want := w.String(), d.want; got != want {
t.Errorf("%#v (%[1]T): got '%s', want '%s'", value, got, want)
}
}
}
}
func TestWriteValue(t *testing.T) {
var (
nilPtr *int
one = 1
ptr = &one
)
data := []struct {
value interface{}
want string
err error
}{
{value: nil, want: "null"},
{value: nilPtr, want: "null"},
{value: (*stringStringer)(nil), want: "null"},
{value: (*stringMarshaler)(nil), want: "null"},
{value: (*stringerMarshaler)(nil), want: "null"},
{value: ptr, want: "1"},
{value: errorMarshaler{}, err: &MarshalerError{Type: reflect.TypeOf(errorMarshaler{}), Err: errMarshaling}},
{value: make(chan int), err: ErrUnsupportedValueType},
{value: []int{}, err: ErrUnsupportedValueType},
{value: map[int]int{}, err: ErrUnsupportedValueType},
{value: [2]int{}, err: ErrUnsupportedValueType},
{value: struct{}{}, err: ErrUnsupportedValueType},
{value: fmt.Sprint, err: ErrUnsupportedValueType},
}
for _, d := range data {
w := &bytes.Buffer{}
err := writeValue(w, d.value)
if !reflect.DeepEqual(err, d.err) {
t.Errorf("%#v: got error: %v, want error: %v", d.value, err, d.err)
}
if err != nil {
continue
}
if got, want := w.String(), d.want; got != want {
t.Errorf("%#v: got '%s', want '%s'", d.value, got, want)
}
}
}
type stringData string
type stringStringer string
func (s stringStringer) String() string {
return string(s)
}
type stringMarshaler string
func (s stringMarshaler) MarshalText() ([]byte, error) {
return []byte(s), nil
}
type stringerMarshaler string
func (s stringerMarshaler) String() string {
return "String() called"
}
func (s stringerMarshaler) MarshalText() ([]byte, error) {
return []byte(s), nil
}
var errMarshaling = errors.New("marshal error")
type errorMarshaler struct{}
func (errorMarshaler) MarshalText() ([]byte, error) {
return nil, errMarshaling
}