Commit 13b93b66 authored by Anthony Fok's avatar Anthony Fok

New upstream version 0.0~git20181024.d37bc2a

parent 76173af4
...@@ -61,6 +61,7 @@ func NoIndent() Option { return Indent("") } ...@@ -61,6 +61,7 @@ func NoIndent() Option { return Indent("") }
// OmitEmpty sets whether empty field members should be omitted from output. // OmitEmpty sets whether empty field members should be omitted from output.
func OmitEmpty(omitEmpty bool) Option { return func(o *Printer) { o.omitEmpty = omitEmpty } } func OmitEmpty(omitEmpty bool) Option { return func(o *Printer) { o.omitEmpty = omitEmpty } }
// IgnoreGoStringer disables use of the .GoString() method.
func IgnoreGoStringer() Option { return func(o *Printer) { o.ignoreGoStringer = true } } func IgnoreGoStringer() Option { return func(o *Printer) { o.ignoreGoStringer = true } }
// Hide excludes the given types from representation, instead just printing the name of the type. // Hide excludes the given types from representation, instead just printing the name of the type.
...@@ -73,13 +74,17 @@ func Hide(ts ...interface{}) Option { ...@@ -73,13 +74,17 @@ func Hide(ts ...interface{}) Option {
} }
} }
// AlwaysIncludeType always includes explicit type information for each item.
func AlwaysIncludeType() Option { return func(o *Printer) { o.alwaysIncludeType = true } }
// Printer represents structs in a printable manner. // Printer represents structs in a printable manner.
type Printer struct { type Printer struct {
indent string indent string
omitEmpty bool omitEmpty bool
ignoreGoStringer bool ignoreGoStringer bool
exclude map[reflect.Type]bool alwaysIncludeType bool
w io.Writer exclude map[reflect.Type]bool
w io.Writer
} }
// New creates a new Printer on w with the given Options. // New creates a new Printer on w with the given Options.
...@@ -139,7 +144,7 @@ func (p *Printer) reprValue(seen map[reflect.Value]bool, v reflect.Value, indent ...@@ -139,7 +144,7 @@ func (p *Printer) reprValue(seen map[reflect.Value]bool, v reflect.Value, indent
seen[v] = true seen[v] = true
defer delete(seen, v) defer delete(seen, v)
if (v.Kind() == reflect.Ptr || v.Kind() == reflect.Map || v.Kind() == reflect.Chan || v.Kind() == reflect.Slice || v.Kind() == reflect.Func || v.Kind() == reflect.Interface) && v.IsNil() { if v.Kind() == reflect.Invalid || (v.Kind() == reflect.Ptr || v.Kind() == reflect.Map || v.Kind() == reflect.Chan || v.Kind() == reflect.Slice || v.Kind() == reflect.Func || v.Kind() == reflect.Interface) && v.IsNil() {
fmt.Fprint(p.w, "nil") fmt.Fprint(p.w, "nil")
return return
} }
...@@ -247,7 +252,7 @@ func (p *Printer) reprValue(seen map[reflect.Value]bool, v reflect.Value, indent ...@@ -247,7 +252,7 @@ func (p *Printer) reprValue(seen map[reflect.Value]bool, v reflect.Value, indent
p.reprValue(seen, v.Elem(), indent) p.reprValue(seen, v.Elem(), indent)
case reflect.String: case reflect.String:
if t.Name() != "string" { if t.Name() != "string" || p.alwaysIncludeType {
fmt.Fprintf(p.w, "%s(%q)", t, v.String()) fmt.Fprintf(p.w, "%s(%q)", t, v.String())
} else { } else {
fmt.Fprintf(p.w, "%q", v.String()) fmt.Fprintf(p.w, "%q", v.String())
...@@ -261,7 +266,7 @@ func (p *Printer) reprValue(seen map[reflect.Value]bool, v reflect.Value, indent ...@@ -261,7 +266,7 @@ func (p *Printer) reprValue(seen map[reflect.Value]bool, v reflect.Value, indent
} }
default: default:
if t.Name() != realKindName[t.Kind()] { if t.Name() != realKindName[t.Kind()] || p.alwaysIncludeType {
fmt.Fprintf(p.w, "%s(%v)", t, v) fmt.Fprintf(p.w, "%s(%v)", t, v)
} else { } else {
fmt.Fprintf(p.w, "%v", v) fmt.Fprintf(p.w, "%v", v)
......
package repr package repr
import ( import (
"strings"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
...@@ -74,7 +75,7 @@ func TestReprStructWithIndent(t *testing.T) { ...@@ -74,7 +75,7 @@ func TestReprStructWithIndent(t *testing.T) {
func TestReprByteArray(t *testing.T) { func TestReprByteArray(t *testing.T) {
b := []byte{1, 2, 3} b := []byte{1, 2, 3}
assert.Equal(t, `[]uint8{1, 2, 3}`, String(b)) assert.Equal(t, "[]byte(\"\\x01\\x02\\x03\")", String(b))
} }
type privateTestStruct struct { type privateTestStruct struct {
...@@ -86,6 +87,18 @@ func TestReprPrivateField(t *testing.T) { ...@@ -86,6 +87,18 @@ func TestReprPrivateField(t *testing.T) {
assert.Equal(t, `repr.privateTestStruct{a: "hello"}`, String(s)) assert.Equal(t, `repr.privateTestStruct{a: "hello"}`, String(s))
} }
func TestReprNilAlone(t *testing.T) {
var err error
s := String(err)
assert.Equal(t, "nil", s)
}
func TestReprNilInsideArray(t *testing.T) {
arr := []*privateTestStruct{{"hello"}, nil}
s := String(arr)
assert.Equal(t, "[]*repr.privateTestStruct{&repr.privateTestStruct{a: \"hello\"}, nil}", s)
}
type Enum int type Enum int
func (e Enum) String() string { func (e Enum) String() string {
...@@ -97,3 +110,16 @@ func TestEnum(t *testing.T) { ...@@ -97,3 +110,16 @@ func TestEnum(t *testing.T) {
s := String(v) s := String(v)
assert.Equal(t, "repr.Enum(Value)", s) assert.Equal(t, "repr.Enum(Value)", s)
} }
func TestShowType(t *testing.T) {
a := map[string]privateTestStruct{"foo": {"bar"}}
s := String(a, AlwaysIncludeType(), Indent(" "))
t.Log(s)
assert.Equal(t, strings.TrimSpace(`
map[string]repr.privateTestStruct{
string("foo"): repr.privateTestStruct{
a: string("bar"),
},
}
`), s)
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment