diff --git a/.github/workflows/assign.yaml b/.github/workflows/assign.yaml new file mode 100644 index 0000000..6b3d20e --- /dev/null +++ b/.github/workflows/assign.yaml @@ -0,0 +1,21 @@ +name: Assign + +on: + issues: + types: [opened, reopened] + pull_request_target: + types: [opened, reopened] + +jobs: + assign: + runs-on: ubuntu-latest + steps: + - uses: actions/github-script@v6 + with: + script: | + github.rest.issues.addAssignees({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + assignees: ['thockin'] + }) diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml new file mode 100644 index 0000000..c46cb8b --- /dev/null +++ b/.github/workflows/lint.yaml @@ -0,0 +1,21 @@ +name: Run lint + +on: [ push, pull_request ] + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + - name: Lint + uses: golangci/golangci-lint-action@v2 + with: + # version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version + version: latest + + # Optional: show only new issues if it's a pull request. The default value is `false`. + # only-new-issues: true + + # Read args from .golangci.yaml + # args: diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml new file mode 100644 index 0000000..2b7f2b5 --- /dev/null +++ b/.github/workflows/tests.yaml @@ -0,0 +1,22 @@ +name: Run tests + +on: [ push, pull_request ] + +jobs: + test: + strategy: + matrix: + version: [ '1.15', '1.16', '1.17', '1.18' ] + platform: [ ubuntu-latest, macos-latest, windows-latest ] + runs-on: ${{ matrix.platform }} + steps: + - name: Install Go + uses: actions/setup-go@v2 + with: + go-version: ${{ matrix.version }} + - name: Checkout code + uses: actions/checkout@v2 + - name: Build + run: go build -v ./... + - name: Test + run: go test -v -race ./... diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 0026861..0000000 --- a/.gitignore +++ /dev/null @@ -1,22 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe diff --git a/.golangci.yaml b/.golangci.yaml new file mode 100644 index 0000000..515e5b8 --- /dev/null +++ b/.golangci.yaml @@ -0,0 +1,28 @@ +run: + timeout: 1m + tests: true + +linters: + disable-all: true + enable: + - asciicheck + - deadcode + - forcetypeassert + - gocritic + - gofmt + - goimports + - gosimple + - govet + - ineffassign + - misspell + - revive + - staticcheck + - structcheck + - typecheck + - unused + - varcheck + +issues: + exclude-use-default: false + max-issues-per-linter: 0 + max-same-issues: 10 diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..7de8190 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/thockin/go-spew + +go 1.18 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..e69de29 diff --git a/spew/TODO b/spew/TODO new file mode 100644 index 0000000..87b828e --- /dev/null +++ b/spew/TODO @@ -0,0 +1,9 @@ +benchmark +optimize + - avoid reflect first +use `string` where possible in tests +comprehend tests +remove linewraps in tests +update docs +OmitNilValues + - if I have a `[]*Foo{&Foo{}, &Foo{}, nil}` - should still print nil diff --git a/spew/bypass.go b/spew/bypass.go index 7929947..7f172e3 100644 --- a/spew/bypass.go +++ b/spew/bypass.go @@ -18,6 +18,7 @@ // tag is deprecated and thus should not be used. // Go versions prior to 1.4 are disabled because they use a different layout // for interfaces which make the implementation of unsafeReflectValue more complex. +//go:build !js && !appengine && !safe && !disableunsafe && go1.4 // +build !js,!appengine,!safe,!disableunsafe,go1.4 package spew @@ -31,9 +32,6 @@ const ( // UnsafeDisabled is a build-time constant which specifies whether or // not access to the unsafe package is available. UnsafeDisabled = false - - // ptrSize is the size of a pointer on the current arch. - ptrSize = unsafe.Sizeof((*byte)(nil)) ) type flag uintptr diff --git a/spew/common.go b/spew/common.go index 1be8ce9..4f53561 100644 --- a/spew/common.go +++ b/spew/common.go @@ -34,11 +34,16 @@ var ( trueBytes = []byte("true") falseBytes = []byte("false") interfaceBytes = []byte("(interface {})") + commaBytes = []byte(",") commaNewlineBytes = []byte(",\n") newlineBytes = []byte("\n") openBraceBytes = []byte("{") openBraceNewlineBytes = []byte("{\n") closeBraceBytes = []byte("}") + emptyBracesBytes = []byte("{}") + openListNewlineBytes = []byte("[\n") + closeListBytes = []byte("]") + emptyListBytes = []byte("[]") asteriskBytes = []byte("*") colonBytes = []byte(":") colonSpaceBytes = []byte(": ") @@ -100,7 +105,7 @@ func handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handled bool) // Choose whether or not to do error and Stringer interface lookups against // the base type or a pointer to the base type depending on settings. // Technically calling one of these methods with a pointer receiver can - // mutate the value, however, types which choose to satisify an error or + // mutate the value, however, types which choose to satisfy an error or // Stringer interface with a pointer receiver should not be mutating their // state inside these interface methods. if !cs.DisablePointerMethods && !UnsafeDisabled && !v.CanAddr() { @@ -114,27 +119,35 @@ func handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handled bool) switch iface := v.Interface().(type) { case error: defer catchPanic(w, v) + s := iface.Error() + if cs.QuoteStrings { + s = strconv.Quote(s) + } if cs.ContinueOnMethod { w.Write(openParenBytes) - w.Write([]byte(iface.Error())) + w.Write([]byte(s)) w.Write(closeParenBytes) w.Write(spaceBytes) return false } - w.Write([]byte(iface.Error())) + w.Write([]byte(s)) return true case fmt.Stringer: defer catchPanic(w, v) + s := iface.String() + if cs.QuoteStrings { + s = strconv.Quote(s) + } if cs.ContinueOnMethod { w.Write(openParenBytes) - w.Write([]byte(iface.String())) + w.Write([]byte(s)) w.Write(closeParenBytes) w.Write(spaceBytes) return false } - w.Write([]byte(iface.String())) + w.Write([]byte(s)) return true } return false @@ -254,7 +267,7 @@ func newValuesSorter(values []reflect.Value, cs *ConfigState) sort.Interface { // directly, or whether it should be considered for sorting by surrogate keys // (if the ConfigState allows it). func canSortSimply(kind reflect.Kind) bool { - // This switch parallels valueSortLess, except for the default case. + // This switch parallels valueLessEqual, except for the default case. switch kind { case reflect.Bool: return true @@ -289,43 +302,55 @@ func (s *valuesSorter) Swap(i, j int) { } } -// valueSortLess returns whether the first value should sort before the second +// valueLessEqual returns whether the first value should sort before the second // value. It is used by valueSorter.Less as part of the sort.Interface // implementation. -func valueSortLess(a, b reflect.Value) bool { +func valueLessEqual(a, b reflect.Value) (less, equal bool) { switch a.Kind() { case reflect.Bool: - return !a.Bool() && b.Bool() + av, bv := a.Bool(), b.Bool() + return !av && bv, av == bv case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: - return a.Int() < b.Int() + av, bv := a.Int(), b.Int() + return av < bv, av == bv case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: - return a.Uint() < b.Uint() + av, bv := a.Uint(), b.Uint() + return av < bv, av == bv case reflect.Float32, reflect.Float64: - return a.Float() < b.Float() + av, bv := a.Float(), b.Float() + return av < bv, av == bv case reflect.String: - return a.String() < b.String() + av, bv := a.String(), b.String() + return av < bv, av == bv case reflect.Uintptr: - return a.Uint() < b.Uint() + av, bv := a.Uint(), b.Uint() + return av < bv, av == bv case reflect.Array: // Compare the contents of both arrays. l := a.Len() for i := 0; i < l; i++ { av := a.Index(i) bv := b.Index(i) - if av.Interface() == bv.Interface() { + + less, equal := valueLessEqual(av, bv) + if equal { continue } - return valueSortLess(av, bv) + + return less, false } } - return a.String() < b.String() + + av, bv := a.String(), b.String() + return av < bv, av == bv } // Less returns whether the value at index i should sort before the // value at index j. It is part of the sort.Interface implementation. func (s *valuesSorter) Less(i, j int) bool { if s.strings == nil { - return valueSortLess(s.values[i], s.values[j]) + less, _ := valueLessEqual(s.values[i], s.values[j]) + return less } return s.strings[i] < s.strings[j] } diff --git a/spew/common_test.go b/spew/common_test.go index 0f5ce47..cac0e5c 100644 --- a/spew/common_test.go +++ b/spew/common_test.go @@ -19,9 +19,11 @@ package spew_test import ( "fmt" "reflect" + "runtime" + "strings" "testing" - "github.com/davecgh/go-spew/spew" + "github.com/thockin/go-spew/spew" ) // custom type to test Stinger interface on non-pointer receiver. @@ -91,14 +93,14 @@ func (e customError) Error() string { // stringizeWants converts a slice of wanted test output into a format suitable // for a test error message. -func stringizeWants(wants []string) string { +func stringizeWants(wants []string, secondaryFmt string) string { s := "" for i, want := range wants { - if i > 0 { - s += fmt.Sprintf("want%d: %s", i+1, want) - } else { - s += "want: " + want + if i == 0 { + s += want + continue } + s += fmt.Sprintf(secondaryFmt, want) } return s } @@ -114,6 +116,92 @@ func testFailed(result string, wants []string) bool { return true } +// line returns the line number of the caller, if possible. This is useful in +// tests with a large number of cases - when something goes wrong you can find +// which case more easily. +func line() string { + _, _, line, ok := runtime.Caller(1) + var s string + if ok { + s = fmt.Sprintf("%d", line) + } else { + s = "" + } + return s +} + +func typeNameOf(in interface{}) (v interface{}, typ string) { + var b strings.Builder + + // Using reflect package it seems impossible to + // get a reflect.ValueOf of type "interface {}", + // so use ifaceVal as a sentinel value to signal + // in is an interface{} and use as special case + // to handle this situation. + if ifv, ok := in.(ifaceVal); ok { + v = ifv.v + rv := reflect.ValueOf(v) + + // count and dereference any pointers + indir := 0 + for rv.Kind() == reflect.Pointer { + rv = rv.Elem() + indir++ + } + + b.WriteString("interface {}(") + if rv.IsValid() { + for i := 0; i < indir; i++ { + b.WriteByte('*') + } + + // get type boxed in the interface + if rv.Kind() == reflect.Interface { + rv = rv.Elem() + } + + if rv.IsValid() { + b.WriteString(rv.Type().String()) + } else { + b.WriteString("interface {}(nil)") + } + } else { + b.WriteString("nil") + } + b.WriteByte(')') + + } else { + v = in + rv := reflect.ValueOf(v) + + if !rv.IsValid() { + b.WriteString("nil") + } else { + // record type of v before derefencing + ptyp := rv.Type().String() + for rv.Kind() == reflect.Pointer { + rv = rv.Elem() + } + + // handle typed nil separately + if rv.Kind() == reflect.Invalid { + b.WriteString("nil(") + b.WriteString(ptyp) + b.WriteByte(')') + } else { + b.WriteString(ptyp) + } + } + } + + typ = b.String() + return v, typ +} + +type ifaceVal struct { + v interface{} +} + type sortableStruct struct { x int } diff --git a/spew/config.go b/spew/config.go index 2e3d22f..eb000fb 100644 --- a/spew/config.go +++ b/spew/config.go @@ -59,7 +59,7 @@ type ConfigState struct { // // NOTE: This might be an unsafe action since calling one of these methods // with a pointer receiver could technically mutate the value, however, - // in practice, types which choose to satisify an error or Stringer + // in practice, types which choose to satisfy an error or Stringer // interface with a pointer receiver should not be mutating their state // inside these interface methods. As a result, this option relies on // access to the unsafe package, so it will not have any effect when @@ -76,6 +76,42 @@ type ConfigState struct { // data structures in tests. DisableCapacities bool + // DisableTypes specifies whether to disable the printing of types. + DisableTypes bool + + // DisableLengths specifies whether to disable the printing of lengths. + // This also disables the printing of capacities. + DisableLengths bool + + // Commas specifies whether to use commas or spaces between elements of + // lists, maps, and structs. + Commas bool + + // TrailingCommas specifies whether to always include a trailing comma, + // Go-style. This is useful to avoid false positives when diffing data + // structures in tests. + TrailingCommas bool + + // DisableUnexported specifies whether to disable the unexported fields of + // struct. This is useful for debugging APIs. + DisableUnexported bool + + // DumpListSquareBraces specifies whether to render lists with square + // braces (JSON-style) or curly braces (Go-style) in dumps. + DumpListSquareBraces bool + + // QuoteStrings specifies whether to render strings with quotes + // (JSON-style) or not (Go-style) in Printf() family calls. + QuoteStrings bool + + // AbbreviateEmpty specifies whether to render empty lists, maps, and + // structs in a shortened, one-line form ([] and {}). + AbbreviateEmpty bool + + // FuncSymbols specifies whether to render func values as a symbol name + // plus file:line or just as pointers. + FuncSymbols bool + // ContinueOnMethod specifies whether or not recursion should continue once // a custom error or Stringer interface is invoked. The default, false, // means it will print the results of invoking the custom error or Stringer @@ -104,6 +140,24 @@ type ConfigState struct { // The configuration can be changed by modifying the contents of spew.Config. var Config = ConfigState{Indent: " "} +// CleanConfig is a pre-build ConfigState which offers the "best" configuration +// for clean, simple output. In other words, most of the decorations are +// disabled. +var CleanConfig = ConfigState{ + Indent: " ", + DisableMethods: true, + DisablePointerAddresses: true, + DisableCapacities: true, + DisablePointerMethods: true, + DisableTypes: true, + DisableLengths: true, + DumpListSquareBraces: true, + Commas: true, + QuoteStrings: true, + AbbreviateEmpty: true, + FuncSymbols: true, +} + // Errorf is a wrapper for fmt.Errorf that treats each argument as if it were // passed with a Formatter interface returned by c.NewFormatter. It returns // the formatted string as a value that satisfies error. See NewFormatter diff --git a/spew/doc.go b/spew/doc.go index aacaac6..b079c26 100644 --- a/spew/doc.go +++ b/spew/doc.go @@ -100,6 +100,42 @@ The following configuration options are available: capacities for arrays, slices, maps and channels. This is useful when diffing data structures in tests. + * DisableTypes + DisableTypes specifies whether to disable the printing of types. + + * DisableLengths + DisableLengths specifies whether to disable the printing of lengths. + This also disables the printing of capacities. + + * Commas + Commas specifies whether to use commas or spaces between elements of + lists, maps, and structs. + + * TrailingCommas + TrailingCommas specifies whether to always include a + trailing comma, Go-style. This is useful to avoid false positives when + diffing data structures in tests. + + * DisableUnexported + DisableUnexported specifies whether to disable the unexported fields of + struct. This is useful for debugging APIs. + + * DumpListSquareBraces + DumpListSquareBraces specifies whether to render lists with square + braces (JSON-style) or curly braces (Go-style) in dumps. + + * QuoteStrings + QuoteStrings specifies whether to render strings with quotes + (JSON-style) or not (Go-style) in Printf() family calls. + + * AbbreviateEmpty + AbbreviateEmpty specifies whether to render empty lists, maps, and + structs in a shortened, one-line form ([] and {}). + + * FuncSymbols + FuncSymbols specifies whether to render func values as a symbol name + plus file:line or just as pointers. + * ContinueOnMethod Enables recursion into types after invoking error and Stringer interface methods. Recursion after method invocation is disabled by default. diff --git a/spew/dump.go b/spew/dump.go index f78d89f..e2ab883 100644 --- a/spew/dump.go +++ b/spew/dump.go @@ -22,8 +22,10 @@ import ( "fmt" "io" "os" + "path/filepath" "reflect" "regexp" + "runtime" "strconv" "strings" ) @@ -227,7 +229,7 @@ func (d *dumpState) dumpSlice(v reflect.Value) { if doHexDump { indent := strings.Repeat(d.cs.Indent, d.depth) str := indent + hex.Dump(buf) - str = strings.Replace(str, "\n", "\n"+indent, -1) + str = strings.ReplaceAll(str, "\n", "\n"+indent) str = strings.TrimRight(str, d.cs.Indent) d.w.Write([]byte(str)) return @@ -236,11 +238,7 @@ func (d *dumpState) dumpSlice(v reflect.Value) { // Recursively call dump for each item. for i := 0; i < numEntries; i++ { d.dump(d.unpackValue(v.Index(i))) - if i < (numEntries - 1) { - d.w.Write(commaNewlineBytes) - } else { - d.w.Write(newlineBytes) - } + d.writeComma(i < (numEntries - 1)) } } @@ -266,37 +264,41 @@ func (d *dumpState) dump(v reflect.Value) { // Print type information unless already handled elsewhere. if !d.ignoreNextType { d.indent() - d.w.Write(openParenBytes) - d.w.Write([]byte(v.Type().String())) - d.w.Write(closeParenBytes) - d.w.Write(spaceBytes) + if !d.cs.DisableTypes { + d.w.Write(openParenBytes) + d.w.Write([]byte(v.Type().String())) + d.w.Write(closeParenBytes) + d.w.Write(spaceBytes) + } } d.ignoreNextType = false // Display length and capacity if the built-in len and cap functions // work with the value's kind and the len/cap itself is non-zero. - valueLen, valueCap := 0, 0 - switch v.Kind() { - case reflect.Array, reflect.Slice, reflect.Chan: - valueLen, valueCap = v.Len(), v.Cap() - case reflect.Map, reflect.String: - valueLen = v.Len() - } - if valueLen != 0 || !d.cs.DisableCapacities && valueCap != 0 { - d.w.Write(openParenBytes) - if valueLen != 0 { - d.w.Write(lenEqualsBytes) - printInt(d.w, int64(valueLen), 10) + if !d.cs.DisableLengths { + valueLen, valueCap := 0, 0 + switch v.Kind() { + case reflect.Array, reflect.Slice, reflect.Chan: + valueLen, valueCap = v.Len(), v.Cap() + case reflect.Map, reflect.String: + valueLen = v.Len() } - if !d.cs.DisableCapacities && valueCap != 0 { + if valueLen != 0 || !d.cs.DisableCapacities && valueCap != 0 { + d.w.Write(openParenBytes) if valueLen != 0 { - d.w.Write(spaceBytes) + d.w.Write(lenEqualsBytes) + printInt(d.w, int64(valueLen), 10) } - d.w.Write(capEqualsBytes) - printInt(d.w, int64(valueCap), 10) + if !d.cs.DisableCapacities && valueCap != 0 { + if valueLen != 0 { + d.w.Write(spaceBytes) + } + d.w.Write(capEqualsBytes) + printInt(d.w, int64(valueCap), 10) + } + d.w.Write(closeParenBytes) + d.w.Write(spaceBytes) } - d.w.Write(closeParenBytes) - d.w.Write(spaceBytes) } // Call Stringer/error interfaces if they exist and the handle methods flag @@ -340,10 +342,20 @@ func (d *dumpState) dump(v reflect.Value) { d.w.Write(nilAngleBytes) break } + if v.Len() == 0 && d.cs.AbbreviateEmpty { + d.w.Write(emptyListBytes) + break + } + fallthrough case reflect.Array: - d.w.Write(openBraceNewlineBytes) + if d.cs.DumpListSquareBraces { + d.w.Write(openListNewlineBytes) + } else { + d.w.Write(openBraceNewlineBytes) + } + d.depth++ if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { d.indent() @@ -353,7 +365,11 @@ func (d *dumpState) dump(v reflect.Value) { } d.depth-- d.indent() - d.w.Write(closeBraceBytes) + if d.cs.DumpListSquareBraces { + d.w.Write(closeListBytes) + } else { + d.w.Write(closeBraceBytes) + } case reflect.String: d.w.Write([]byte(strconv.Quote(v.String()))) @@ -375,6 +391,10 @@ func (d *dumpState) dump(v reflect.Value) { d.w.Write(nilAngleBytes) break } + if v.Len() == 0 && d.cs.AbbreviateEmpty { + d.w.Write(emptyBracesBytes) + break + } d.w.Write(openBraceNewlineBytes) d.depth++ @@ -392,11 +412,7 @@ func (d *dumpState) dump(v reflect.Value) { d.w.Write(colonSpaceBytes) d.ignoreNextIndent = true d.dump(d.unpackValue(v.MapIndex(key))) - if i < (numEntries - 1) { - d.w.Write(commaNewlineBytes) - } else { - d.w.Write(newlineBytes) - } + d.writeComma(i < (numEntries - 1)) } } d.depth-- @@ -404,6 +420,10 @@ func (d *dumpState) dump(v reflect.Value) { d.w.Write(closeBraceBytes) case reflect.Struct: + if v.NumField() == 0 && d.cs.AbbreviateEmpty { + d.w.Write(emptyBracesBytes) + break + } d.w.Write(openBraceNewlineBytes) d.depth++ if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { @@ -413,17 +433,17 @@ func (d *dumpState) dump(v reflect.Value) { vt := v.Type() numFields := v.NumField() for i := 0; i < numFields; i++ { - d.indent() vtf := vt.Field(i) + // StructField has an IsExported() method, but only in 1.17+. + if d.cs.DisableUnexported && vtf.PkgPath != "" { + continue + } + d.indent() d.w.Write([]byte(vtf.Name)) d.w.Write(colonSpaceBytes) d.ignoreNextIndent = true d.dump(d.unpackValue(v.Field(i))) - if i < (numFields - 1) { - d.w.Write(commaNewlineBytes) - } else { - d.w.Write(newlineBytes) - } + d.writeComma(i < (numFields - 1)) } } d.depth-- @@ -433,9 +453,26 @@ func (d *dumpState) dump(v reflect.Value) { case reflect.Uintptr: printHexPtr(d.w, uintptr(v.Uint())) - case reflect.UnsafePointer, reflect.Chan, reflect.Func: + case reflect.UnsafePointer, reflect.Chan: printHexPtr(d.w, v.Pointer()) + case reflect.Func: + if d.cs.FuncSymbols { + fn := runtime.FuncForPC(v.Pointer()) + if fn != nil { + name := fn.Name() + file, line := fn.FileLine(v.Pointer()) + d.w.Write([]byte(filepath.Base(name))) + d.w.Write([]byte("[")) + d.w.Write([]byte(filepath.Base(file))) + d.w.Write([]byte(":")) + printInt(d.w, int64(line), 10) + d.w.Write([]byte("]")) + } + } else { + printHexPtr(d.w, v.Pointer()) + } + // There were not any other types at the time this code was written, but // fall back to letting the default fmt package handle it in case any new // types are added. @@ -448,6 +485,16 @@ func (d *dumpState) dump(v reflect.Value) { } } +// writeComma emits a comma if hasMoreElements is true, or if trailing commas +// are always enabled. +func (d *dumpState) writeComma(hasMoreElements bool) { + if hasMoreElements || d.cs.TrailingCommas { + d.w.Write(commaNewlineBytes) + } else { + d.w.Write(newlineBytes) + } +} + // fdump is a helper function to consolidate the logic from the various public // methods which take varying writers and config states. func fdump(cs *ConfigState, w io.Writer, a ...interface{}) { diff --git a/spew/dump_test.go b/spew/dump_test.go index 4a31a2e..492f08f 100644 --- a/spew/dump_test.go +++ b/spew/dump_test.go @@ -44,6 +44,7 @@ base test element are also tested to ensure proper indirection across all types. - Struct that contains custom type with Stringer pointer interface via both exported and unexported fields - Struct that contains embedded struct and field to same struct +- Struct that contains unexported field and exported field - Uintptr to 0 (null pointer) - Uintptr address of real variable - Unsafe.Pointer to 0 (null pointer) @@ -64,25 +65,50 @@ package spew_test import ( "bytes" "fmt" + "io" "testing" "unsafe" - "github.com/davecgh/go-spew/spew" + "github.com/thockin/go-spew/spew" ) // dumpTest is used to describe a test to be performed against the Dump method. type dumpTest struct { + typ string in interface{} wants []string } // dumpTests houses all of the tests to be performed against the Dump method. -var dumpTests = make([]dumpTest, 0) +var dumpTests []dumpTest + +func init() { + addIntDumpTests() + addUintDumpTests() + addBoolDumpTests() + addFloatDumpTests() + addComplexDumpTests() + addArrayDumpTests() + addSliceDumpTests() + addStringDumpTests() + addInterfaceDumpTests() + addMapDumpTests() + addStructDumpTests() + addUintptrDumpTests() + addUnsafePointerDumpTests() + addChanDumpTests() + addFuncDumpTests() + addCircularDumpTests() + addPanicDumpTests() + addErrorDumpTests() + addCgoDumpTests() +} // addDumpTest is a helper method to append the passed input and desired result // to dumpTests func addDumpTest(in interface{}, wants ...string) { - test := dumpTest{in, wants} + in, typ := typeNameOf(in) + test := dumpTest{typ, in, wants} dumpTests = append(dumpTests, test) } @@ -530,10 +556,10 @@ func addInterfaceDumpTests() { pvAddr := fmt.Sprintf("%p", &pv) vt := "interface {}" vs := "" - addDumpTest(v, "("+vt+") "+vs+"\n") - addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n") - addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n") - addDumpTest(nv, "(*"+vt+")()\n") + addDumpTest(ifaceVal{v}, "("+vt+") "+vs+"\n") + addDumpTest(ifaceVal{pv}, "(*"+vt+")("+vAddr+")("+vs+")\n") + addDumpTest(ifaceVal{&pv}, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n") + addDumpTest(ifaceVal{nv}, "(*"+vt+")()\n") // Sub-interface. v2 := interface{}(uint16(65535)) @@ -542,9 +568,9 @@ func addInterfaceDumpTests() { pv2Addr := fmt.Sprintf("%p", &pv2) v2t := "uint16" v2s := "65535" - addDumpTest(v2, "("+v2t+") "+v2s+"\n") - addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n") - addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n") + addDumpTest(ifaceVal{v2}, "("+v2t+") "+v2s+"\n") + addDumpTest(ifaceVal{pv2}, "(*"+v2t+")("+v2Addr+")("+v2s+")\n") + addDumpTest(ifaceVal{&pv2}, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n") } func addMapDumpTests() { @@ -958,36 +984,29 @@ func addErrorDumpTests() { // TestDump executes all of the tests described by dumpTests. func TestDump(t *testing.T) { - // Setup tests. - addIntDumpTests() - addUintDumpTests() - addBoolDumpTests() - addFloatDumpTests() - addComplexDumpTests() - addArrayDumpTests() - addSliceDumpTests() - addStringDumpTests() - addInterfaceDumpTests() - addMapDumpTests() - addStructDumpTests() - addUintptrDumpTests() - addUnsafePointerDumpTests() - addChanDumpTests() - addFuncDumpTests() - addCircularDumpTests() - addPanicDumpTests() - addErrorDumpTests() - addCgoDumpTests() - t.Logf("Running %d tests", len(dumpTests)) + buf := new(bytes.Buffer) for i, test := range dumpTests { - buf := new(bytes.Buffer) - spew.Fdump(buf, test.in) - s := buf.String() - if testFailed(s, test.wants) { - t.Errorf("Dump #%d\n got: %s %s", i, s, stringizeWants(test.wants)) - continue - } + t.Run(test.typ, func(t *testing.T) { + t.Cleanup(buf.Reset) + spew.Fdump(buf, test.in) + s := buf.String() + if testFailed(s, test.wants) { + t.Errorf("Dump #%d\n got: %s\nwant: %s", i, s, stringizeWants(test.wants, "\n or: %s")) + } + }) + } +} + +func BenchmarkDump(b *testing.B) { + for _, test := range dumpTests { + b.Run(test.typ, func(b *testing.B) { + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + spew.Fdump(io.Discard, test.in) + } + }) } } @@ -1039,4 +1058,95 @@ func TestDumpSortedKeys(t *testing.T) { t.Errorf("Sorted keys mismatch:\n %v %v", s, expected) } + type structWithUnexportedMapWithArrayKey struct { + f map[[3]byte]int + } + s = cfg.Sdump(structWithUnexportedMapWithArrayKey{ + map[[3]byte]int{ + {0x1, 0x2, 0x3}: 2, + {0x1, 0x3, 0x2}: 3, + {0x1, 0x2, 0x2}: 1, + }, + }) + expected = + `(spew_test.structWithUnexportedMapWithArrayKey) { +f: (map[[3]uint8]int) (len=3) { +([3]uint8) (len=3 cap=3) { +00000000 01 02 02 |...| +}: (int) 1, +([3]uint8) (len=3 cap=3) { +00000000 01 02 03 |...| +}: (int) 2, +([3]uint8) (len=3 cap=3) { +00000000 01 03 02 |...| +}: (int) 3 +} +} +` + + if s != expected { + t.Errorf("Sorted keys mismatch:\n %v %v", s, expected) + } + +} + +func TestDumpUnexportedFields(t *testing.T) { + dumpTests = make([]dumpTest, 0) + + // Struct with both exported and unexported field. + type s struct { + ExportedVarA int8 + ExportedVarB int8 + unExportedVarC int8 + unExportedVarD int8 + } + v := s{10, 20, 30, 40} + nv := (*s)(nil) + pv := &v + vAddr := fmt.Sprintf("%p", pv) + pvAddr := fmt.Sprintf("%p", &pv) + vt := "spew_test.s" + vt2 := "int8" + vs := "{\n ExportedVarA: (" + vt2 + ") 10,\n ExportedVarB: (" + vt2 + ") 20,\n}" + + addDumpTest(v, "("+vt+") "+vs+"\n") + addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n") + addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n") + addDumpTest(nv, "(*"+vt+")()\n") + + type s2 struct { + unExportedVarA int8 + unExportedVarB int8 + ExportedVarC int8 + ExportedVarD int8 + } + v2 := s2{10, 20, 30, 40} + nv2 := (*s2)(nil) + pv2 := &v2 + v2Addr := fmt.Sprintf("%p", pv2) + pv2Addr := fmt.Sprintf("%p", &pv2) + v2t := "spew_test.s2" + v2t2 := "int8" + v2s := "{\n ExportedVarC: (" + v2t2 + ") 30,\n ExportedVarD: (" + v2t2 + ") 40\n}" + + addDumpTest(v2, "("+v2t+") "+v2s+"\n") + addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n") + addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n") + addDumpTest(nv2, "(*"+v2t+")()\n") + + cs := spew.ConfigState{ + Indent: " ", + DisableUnexported: true, + } + + t.Logf("Running %d tests", len(dumpTests)) + for i, test := range dumpTests { + buf := new(bytes.Buffer) + cs.Fdump(buf, test.in) + s := buf.String() + if testFailed(s, test.wants) { + t.Errorf("Dump #%d\n got: %s\nwant: %s", i, s, stringizeWants(test.wants, "\n or: %s")) + continue + } + } } diff --git a/spew/dumpcgo_test.go b/spew/dumpcgo_test.go index 108baa5..b42e555 100644 --- a/spew/dumpcgo_test.go +++ b/spew/dumpcgo_test.go @@ -19,6 +19,7 @@ // does not require cgo to run even though it does handle certain cgo types // specially. Rather than forcing all clients to require cgo and an external // C compiler just to run the tests, this scheme makes them optional. +//go:build cgo && testcgo // +build cgo,testcgo package spew_test @@ -26,7 +27,7 @@ package spew_test import ( "fmt" - "github.com/davecgh/go-spew/spew/testdata" + "github.com/thockin/go-spew/spew/testdata" ) func addCgoDumpTests() { diff --git a/spew/dumpnocgo_test.go b/spew/dumpnocgo_test.go index 52a0971..9498d98 100644 --- a/spew/dumpnocgo_test.go +++ b/spew/dumpnocgo_test.go @@ -16,6 +16,7 @@ // when either cgo is not supported or "-tags testcgo" is not added to the go // test command line. This file intentionally does not setup any cgo tests in // this scenario. +//go:build !cgo || !testcgo // +build !cgo !testcgo package spew_test diff --git a/spew/example_test.go b/spew/example_test.go index c6ec8c6..e955ecb 100644 --- a/spew/example_test.go +++ b/spew/example_test.go @@ -19,7 +19,7 @@ package spew_test import ( "fmt" - "github.com/davecgh/go-spew/spew" + "github.com/thockin/go-spew/spew" ) type Flag int diff --git a/spew/format.go b/spew/format.go index b04edb7..934c94d 100644 --- a/spew/format.go +++ b/spew/format.go @@ -19,7 +19,9 @@ package spew import ( "bytes" "fmt" + "path/filepath" "reflect" + "runtime" "strconv" "strings" ) @@ -272,7 +274,11 @@ func (f *formatState) format(v reflect.Value) { numEntries := v.Len() for i := 0; i < numEntries; i++ { if i > 0 { - f.fs.Write(spaceBytes) + if f.cs.Commas { + f.fs.Write(commaBytes) + } else { + f.fs.Write(spaceBytes) + } } f.ignoreNextType = true f.format(f.unpackValue(v.Index(i))) @@ -282,7 +288,11 @@ func (f *formatState) format(v reflect.Value) { f.fs.Write(closeBracketBytes) case reflect.String: - f.fs.Write([]byte(v.String())) + s := v.String() + if f.cs.QuoteStrings { + s = strconv.Quote(s) + } + f.fs.Write([]byte(s)) case reflect.Interface: // The only time we should get here is for nil interfaces due to @@ -313,7 +323,11 @@ func (f *formatState) format(v reflect.Value) { } for i, key := range keys { if i > 0 { - f.fs.Write(spaceBytes) + if f.cs.Commas { + f.fs.Write(commaBytes) + } else { + f.fs.Write(spaceBytes) + } } f.ignoreNextType = true f.format(f.unpackValue(key)) @@ -334,10 +348,18 @@ func (f *formatState) format(v reflect.Value) { } else { vt := v.Type() for i := 0; i < numFields; i++ { + vtf := vt.Field(i) + // StructField has an IsExported() method, but only in 1.17+. + if f.cs.DisableUnexported && vtf.PkgPath != "" { + continue + } if i > 0 { - f.fs.Write(spaceBytes) + if f.cs.Commas { + f.fs.Write(commaBytes) + } else { + f.fs.Write(spaceBytes) + } } - vtf := vt.Field(i) if f.fs.Flag('+') || f.fs.Flag('#') { f.fs.Write([]byte(vtf.Name)) f.fs.Write(colonBytes) @@ -351,9 +373,26 @@ func (f *formatState) format(v reflect.Value) { case reflect.Uintptr: printHexPtr(f.fs, uintptr(v.Uint())) - case reflect.UnsafePointer, reflect.Chan, reflect.Func: + case reflect.UnsafePointer, reflect.Chan: printHexPtr(f.fs, v.Pointer()) + case reflect.Func: + if f.cs.FuncSymbols { + fn := runtime.FuncForPC(v.Pointer()) + if fn != nil { + name := fn.Name() + file, line := fn.FileLine(v.Pointer()) + f.fs.Write([]byte(filepath.Base(name))) + f.fs.Write([]byte("[")) + f.fs.Write([]byte(filepath.Base(file))) + f.fs.Write([]byte(":")) + printInt(f.fs, int64(line), 10) + f.fs.Write([]byte("]")) + } + } else { + printHexPtr(f.fs, v.Pointer()) + } + // There were not any other types at the time this code was written, but // fall back to letting the default fmt package handle it if any get added. default: diff --git a/spew/format_test.go b/spew/format_test.go index 87ee965..6b25633 100644 --- a/spew/format_test.go +++ b/spew/format_test.go @@ -72,11 +72,12 @@ import ( "testing" "unsafe" - "github.com/davecgh/go-spew/spew" + "github.com/thockin/go-spew/spew" ) // formatterTest is used to describe a test to be performed against NewFormatter. type formatterTest struct { + line string // use line() to fill this format string in interface{} wants []string @@ -87,8 +88,8 @@ var formatterTests = make([]formatterTest, 0) // addFormatterTest is a helper method to append the passed input and desired // result to formatterTests. -func addFormatterTest(format string, in interface{}, wants ...string) { - test := formatterTest{format, in, wants} +func addFormatterTest(line string, format string, in interface{}, wants ...string) { + test := formatterTest{line, format, in, wants} formatterTests = append(formatterTests, test) } @@ -101,22 +102,22 @@ func addIntFormatterTests() { pvAddr := fmt.Sprintf("%p", &pv) vt := "int8" vs := "127" - addFormatterTest("%v", v, vs) - addFormatterTest("%v", pv, "<*>"+vs) - addFormatterTest("%v", &pv, "<**>"+vs) - addFormatterTest("%v", nv, "") - addFormatterTest("%+v", v, vs) - addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs) - addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs) - addFormatterTest("%+v", nv, "") - addFormatterTest("%#v", v, "("+vt+")"+vs) - addFormatterTest("%#v", pv, "(*"+vt+")"+vs) - addFormatterTest("%#v", &pv, "(**"+vt+")"+vs) - addFormatterTest("%#v", nv, "(*"+vt+")"+"") - addFormatterTest("%#+v", v, "("+vt+")"+vs) - addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs) - addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs) - addFormatterTest("%#+v", nv, "(*"+vt+")"+"") + addFormatterTest(line(), "%v", v, vs) + addFormatterTest(line(), "%v", pv, "<*>"+vs) + addFormatterTest(line(), "%v", &pv, "<**>"+vs) + addFormatterTest(line(), "%v", nv, "") + addFormatterTest(line(), "%+v", v, vs) + addFormatterTest(line(), "%+v", pv, "<*>("+vAddr+")"+vs) + addFormatterTest(line(), "%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs) + addFormatterTest(line(), "%+v", nv, "") + addFormatterTest(line(), "%#v", v, "("+vt+")"+vs) + addFormatterTest(line(), "%#v", pv, "(*"+vt+")"+vs) + addFormatterTest(line(), "%#v", &pv, "(**"+vt+")"+vs) + addFormatterTest(line(), "%#v", nv, "(*"+vt+")"+"") + addFormatterTest(line(), "%#+v", v, "("+vt+")"+vs) + addFormatterTest(line(), "%#+v", pv, "(*"+vt+")("+vAddr+")"+vs) + addFormatterTest(line(), "%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs) + addFormatterTest(line(), "%#+v", nv, "(*"+vt+")"+"") // Max int16. v2 := int16(32767) @@ -126,22 +127,22 @@ func addIntFormatterTests() { pv2Addr := fmt.Sprintf("%p", &pv2) v2t := "int16" v2s := "32767" - addFormatterTest("%v", v2, v2s) - addFormatterTest("%v", pv2, "<*>"+v2s) - addFormatterTest("%v", &pv2, "<**>"+v2s) - addFormatterTest("%v", nv2, "") - addFormatterTest("%+v", v2, v2s) - addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s) - addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s) - addFormatterTest("%+v", nv2, "") - addFormatterTest("%#v", v2, "("+v2t+")"+v2s) - addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s) - addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s) - addFormatterTest("%#v", nv2, "(*"+v2t+")"+"") - addFormatterTest("%#+v", v2, "("+v2t+")"+v2s) - addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s) - addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s) - addFormatterTest("%#+v", nv2, "(*"+v2t+")"+"") + addFormatterTest(line(), "%v", v2, v2s) + addFormatterTest(line(), "%v", pv2, "<*>"+v2s) + addFormatterTest(line(), "%v", &pv2, "<**>"+v2s) + addFormatterTest(line(), "%v", nv2, "") + addFormatterTest(line(), "%+v", v2, v2s) + addFormatterTest(line(), "%+v", pv2, "<*>("+v2Addr+")"+v2s) + addFormatterTest(line(), "%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s) + addFormatterTest(line(), "%+v", nv2, "") + addFormatterTest(line(), "%#v", v2, "("+v2t+")"+v2s) + addFormatterTest(line(), "%#v", pv2, "(*"+v2t+")"+v2s) + addFormatterTest(line(), "%#v", &pv2, "(**"+v2t+")"+v2s) + addFormatterTest(line(), "%#v", nv2, "(*"+v2t+")"+"") + addFormatterTest(line(), "%#+v", v2, "("+v2t+")"+v2s) + addFormatterTest(line(), "%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s) + addFormatterTest(line(), "%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s) + addFormatterTest(line(), "%#+v", nv2, "(*"+v2t+")"+"") // Max int32. v3 := int32(2147483647) @@ -151,22 +152,22 @@ func addIntFormatterTests() { pv3Addr := fmt.Sprintf("%p", &pv3) v3t := "int32" v3s := "2147483647" - addFormatterTest("%v", v3, v3s) - addFormatterTest("%v", pv3, "<*>"+v3s) - addFormatterTest("%v", &pv3, "<**>"+v3s) - addFormatterTest("%v", nv3, "") - addFormatterTest("%+v", v3, v3s) - addFormatterTest("%+v", pv3, "<*>("+v3Addr+")"+v3s) - addFormatterTest("%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s) - addFormatterTest("%+v", nv3, "") - addFormatterTest("%#v", v3, "("+v3t+")"+v3s) - addFormatterTest("%#v", pv3, "(*"+v3t+")"+v3s) - addFormatterTest("%#v", &pv3, "(**"+v3t+")"+v3s) - addFormatterTest("%#v", nv3, "(*"+v3t+")"+"") - addFormatterTest("%#+v", v3, "("+v3t+")"+v3s) - addFormatterTest("%#+v", pv3, "(*"+v3t+")("+v3Addr+")"+v3s) - addFormatterTest("%#+v", &pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")"+v3s) - addFormatterTest("%#v", nv3, "(*"+v3t+")"+"") + addFormatterTest(line(), "%v", v3, v3s) + addFormatterTest(line(), "%v", pv3, "<*>"+v3s) + addFormatterTest(line(), "%v", &pv3, "<**>"+v3s) + addFormatterTest(line(), "%v", nv3, "") + addFormatterTest(line(), "%+v", v3, v3s) + addFormatterTest(line(), "%+v", pv3, "<*>("+v3Addr+")"+v3s) + addFormatterTest(line(), "%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s) + addFormatterTest(line(), "%+v", nv3, "") + addFormatterTest(line(), "%#v", v3, "("+v3t+")"+v3s) + addFormatterTest(line(), "%#v", pv3, "(*"+v3t+")"+v3s) + addFormatterTest(line(), "%#v", &pv3, "(**"+v3t+")"+v3s) + addFormatterTest(line(), "%#v", nv3, "(*"+v3t+")"+"") + addFormatterTest(line(), "%#+v", v3, "("+v3t+")"+v3s) + addFormatterTest(line(), "%#+v", pv3, "(*"+v3t+")("+v3Addr+")"+v3s) + addFormatterTest(line(), "%#+v", &pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")"+v3s) + addFormatterTest(line(), "%#v", nv3, "(*"+v3t+")"+"") // Max int64. v4 := int64(9223372036854775807) @@ -176,22 +177,22 @@ func addIntFormatterTests() { pv4Addr := fmt.Sprintf("%p", &pv4) v4t := "int64" v4s := "9223372036854775807" - addFormatterTest("%v", v4, v4s) - addFormatterTest("%v", pv4, "<*>"+v4s) - addFormatterTest("%v", &pv4, "<**>"+v4s) - addFormatterTest("%v", nv4, "") - addFormatterTest("%+v", v4, v4s) - addFormatterTest("%+v", pv4, "<*>("+v4Addr+")"+v4s) - addFormatterTest("%+v", &pv4, "<**>("+pv4Addr+"->"+v4Addr+")"+v4s) - addFormatterTest("%+v", nv4, "") - addFormatterTest("%#v", v4, "("+v4t+")"+v4s) - addFormatterTest("%#v", pv4, "(*"+v4t+")"+v4s) - addFormatterTest("%#v", &pv4, "(**"+v4t+")"+v4s) - addFormatterTest("%#v", nv4, "(*"+v4t+")"+"") - addFormatterTest("%#+v", v4, "("+v4t+")"+v4s) - addFormatterTest("%#+v", pv4, "(*"+v4t+")("+v4Addr+")"+v4s) - addFormatterTest("%#+v", &pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")"+v4s) - addFormatterTest("%#+v", nv4, "(*"+v4t+")"+"") + addFormatterTest(line(), "%v", v4, v4s) + addFormatterTest(line(), "%v", pv4, "<*>"+v4s) + addFormatterTest(line(), "%v", &pv4, "<**>"+v4s) + addFormatterTest(line(), "%v", nv4, "") + addFormatterTest(line(), "%+v", v4, v4s) + addFormatterTest(line(), "%+v", pv4, "<*>("+v4Addr+")"+v4s) + addFormatterTest(line(), "%+v", &pv4, "<**>("+pv4Addr+"->"+v4Addr+")"+v4s) + addFormatterTest(line(), "%+v", nv4, "") + addFormatterTest(line(), "%#v", v4, "("+v4t+")"+v4s) + addFormatterTest(line(), "%#v", pv4, "(*"+v4t+")"+v4s) + addFormatterTest(line(), "%#v", &pv4, "(**"+v4t+")"+v4s) + addFormatterTest(line(), "%#v", nv4, "(*"+v4t+")"+"") + addFormatterTest(line(), "%#+v", v4, "("+v4t+")"+v4s) + addFormatterTest(line(), "%#+v", pv4, "(*"+v4t+")("+v4Addr+")"+v4s) + addFormatterTest(line(), "%#+v", &pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")"+v4s) + addFormatterTest(line(), "%#+v", nv4, "(*"+v4t+")"+"") // Max int. v5 := int(2147483647) @@ -201,22 +202,22 @@ func addIntFormatterTests() { pv5Addr := fmt.Sprintf("%p", &pv5) v5t := "int" v5s := "2147483647" - addFormatterTest("%v", v5, v5s) - addFormatterTest("%v", pv5, "<*>"+v5s) - addFormatterTest("%v", &pv5, "<**>"+v5s) - addFormatterTest("%v", nv5, "") - addFormatterTest("%+v", v5, v5s) - addFormatterTest("%+v", pv5, "<*>("+v5Addr+")"+v5s) - addFormatterTest("%+v", &pv5, "<**>("+pv5Addr+"->"+v5Addr+")"+v5s) - addFormatterTest("%+v", nv5, "") - addFormatterTest("%#v", v5, "("+v5t+")"+v5s) - addFormatterTest("%#v", pv5, "(*"+v5t+")"+v5s) - addFormatterTest("%#v", &pv5, "(**"+v5t+")"+v5s) - addFormatterTest("%#v", nv5, "(*"+v5t+")"+"") - addFormatterTest("%#+v", v5, "("+v5t+")"+v5s) - addFormatterTest("%#+v", pv5, "(*"+v5t+")("+v5Addr+")"+v5s) - addFormatterTest("%#+v", &pv5, "(**"+v5t+")("+pv5Addr+"->"+v5Addr+")"+v5s) - addFormatterTest("%#+v", nv5, "(*"+v5t+")"+"") + addFormatterTest(line(), "%v", v5, v5s) + addFormatterTest(line(), "%v", pv5, "<*>"+v5s) + addFormatterTest(line(), "%v", &pv5, "<**>"+v5s) + addFormatterTest(line(), "%v", nv5, "") + addFormatterTest(line(), "%+v", v5, v5s) + addFormatterTest(line(), "%+v", pv5, "<*>("+v5Addr+")"+v5s) + addFormatterTest(line(), "%+v", &pv5, "<**>("+pv5Addr+"->"+v5Addr+")"+v5s) + addFormatterTest(line(), "%+v", nv5, "") + addFormatterTest(line(), "%#v", v5, "("+v5t+")"+v5s) + addFormatterTest(line(), "%#v", pv5, "(*"+v5t+")"+v5s) + addFormatterTest(line(), "%#v", &pv5, "(**"+v5t+")"+v5s) + addFormatterTest(line(), "%#v", nv5, "(*"+v5t+")"+"") + addFormatterTest(line(), "%#+v", v5, "("+v5t+")"+v5s) + addFormatterTest(line(), "%#+v", pv5, "(*"+v5t+")("+v5Addr+")"+v5s) + addFormatterTest(line(), "%#+v", &pv5, "(**"+v5t+")("+pv5Addr+"->"+v5Addr+")"+v5s) + addFormatterTest(line(), "%#+v", nv5, "(*"+v5t+")"+"") } func addUintFormatterTests() { @@ -228,22 +229,22 @@ func addUintFormatterTests() { pvAddr := fmt.Sprintf("%p", &pv) vt := "uint8" vs := "255" - addFormatterTest("%v", v, vs) - addFormatterTest("%v", pv, "<*>"+vs) - addFormatterTest("%v", &pv, "<**>"+vs) - addFormatterTest("%v", nv, "") - addFormatterTest("%+v", v, vs) - addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs) - addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs) - addFormatterTest("%+v", nv, "") - addFormatterTest("%#v", v, "("+vt+")"+vs) - addFormatterTest("%#v", pv, "(*"+vt+")"+vs) - addFormatterTest("%#v", &pv, "(**"+vt+")"+vs) - addFormatterTest("%#v", nv, "(*"+vt+")"+"") - addFormatterTest("%#+v", v, "("+vt+")"+vs) - addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs) - addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs) - addFormatterTest("%#+v", nv, "(*"+vt+")"+"") + addFormatterTest(line(), "%v", v, vs) + addFormatterTest(line(), "%v", pv, "<*>"+vs) + addFormatterTest(line(), "%v", &pv, "<**>"+vs) + addFormatterTest(line(), "%v", nv, "") + addFormatterTest(line(), "%+v", v, vs) + addFormatterTest(line(), "%+v", pv, "<*>("+vAddr+")"+vs) + addFormatterTest(line(), "%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs) + addFormatterTest(line(), "%+v", nv, "") + addFormatterTest(line(), "%#v", v, "("+vt+")"+vs) + addFormatterTest(line(), "%#v", pv, "(*"+vt+")"+vs) + addFormatterTest(line(), "%#v", &pv, "(**"+vt+")"+vs) + addFormatterTest(line(), "%#v", nv, "(*"+vt+")"+"") + addFormatterTest(line(), "%#+v", v, "("+vt+")"+vs) + addFormatterTest(line(), "%#+v", pv, "(*"+vt+")("+vAddr+")"+vs) + addFormatterTest(line(), "%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs) + addFormatterTest(line(), "%#+v", nv, "(*"+vt+")"+"") // Max uint16. v2 := uint16(65535) @@ -253,22 +254,22 @@ func addUintFormatterTests() { pv2Addr := fmt.Sprintf("%p", &pv2) v2t := "uint16" v2s := "65535" - addFormatterTest("%v", v2, v2s) - addFormatterTest("%v", pv2, "<*>"+v2s) - addFormatterTest("%v", &pv2, "<**>"+v2s) - addFormatterTest("%v", nv2, "") - addFormatterTest("%+v", v2, v2s) - addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s) - addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s) - addFormatterTest("%+v", nv2, "") - addFormatterTest("%#v", v2, "("+v2t+")"+v2s) - addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s) - addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s) - addFormatterTest("%#v", nv2, "(*"+v2t+")"+"") - addFormatterTest("%#+v", v2, "("+v2t+")"+v2s) - addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s) - addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s) - addFormatterTest("%#+v", nv2, "(*"+v2t+")"+"") + addFormatterTest(line(), "%v", v2, v2s) + addFormatterTest(line(), "%v", pv2, "<*>"+v2s) + addFormatterTest(line(), "%v", &pv2, "<**>"+v2s) + addFormatterTest(line(), "%v", nv2, "") + addFormatterTest(line(), "%+v", v2, v2s) + addFormatterTest(line(), "%+v", pv2, "<*>("+v2Addr+")"+v2s) + addFormatterTest(line(), "%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s) + addFormatterTest(line(), "%+v", nv2, "") + addFormatterTest(line(), "%#v", v2, "("+v2t+")"+v2s) + addFormatterTest(line(), "%#v", pv2, "(*"+v2t+")"+v2s) + addFormatterTest(line(), "%#v", &pv2, "(**"+v2t+")"+v2s) + addFormatterTest(line(), "%#v", nv2, "(*"+v2t+")"+"") + addFormatterTest(line(), "%#+v", v2, "("+v2t+")"+v2s) + addFormatterTest(line(), "%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s) + addFormatterTest(line(), "%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s) + addFormatterTest(line(), "%#+v", nv2, "(*"+v2t+")"+"") // Max uint32. v3 := uint32(4294967295) @@ -278,22 +279,22 @@ func addUintFormatterTests() { pv3Addr := fmt.Sprintf("%p", &pv3) v3t := "uint32" v3s := "4294967295" - addFormatterTest("%v", v3, v3s) - addFormatterTest("%v", pv3, "<*>"+v3s) - addFormatterTest("%v", &pv3, "<**>"+v3s) - addFormatterTest("%v", nv3, "") - addFormatterTest("%+v", v3, v3s) - addFormatterTest("%+v", pv3, "<*>("+v3Addr+")"+v3s) - addFormatterTest("%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s) - addFormatterTest("%+v", nv3, "") - addFormatterTest("%#v", v3, "("+v3t+")"+v3s) - addFormatterTest("%#v", pv3, "(*"+v3t+")"+v3s) - addFormatterTest("%#v", &pv3, "(**"+v3t+")"+v3s) - addFormatterTest("%#v", nv3, "(*"+v3t+")"+"") - addFormatterTest("%#+v", v3, "("+v3t+")"+v3s) - addFormatterTest("%#+v", pv3, "(*"+v3t+")("+v3Addr+")"+v3s) - addFormatterTest("%#+v", &pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")"+v3s) - addFormatterTest("%#v", nv3, "(*"+v3t+")"+"") + addFormatterTest(line(), "%v", v3, v3s) + addFormatterTest(line(), "%v", pv3, "<*>"+v3s) + addFormatterTest(line(), "%v", &pv3, "<**>"+v3s) + addFormatterTest(line(), "%v", nv3, "") + addFormatterTest(line(), "%+v", v3, v3s) + addFormatterTest(line(), "%+v", pv3, "<*>("+v3Addr+")"+v3s) + addFormatterTest(line(), "%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s) + addFormatterTest(line(), "%+v", nv3, "") + addFormatterTest(line(), "%#v", v3, "("+v3t+")"+v3s) + addFormatterTest(line(), "%#v", pv3, "(*"+v3t+")"+v3s) + addFormatterTest(line(), "%#v", &pv3, "(**"+v3t+")"+v3s) + addFormatterTest(line(), "%#v", nv3, "(*"+v3t+")"+"") + addFormatterTest(line(), "%#+v", v3, "("+v3t+")"+v3s) + addFormatterTest(line(), "%#+v", pv3, "(*"+v3t+")("+v3Addr+")"+v3s) + addFormatterTest(line(), "%#+v", &pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")"+v3s) + addFormatterTest(line(), "%#v", nv3, "(*"+v3t+")"+"") // Max uint64. v4 := uint64(18446744073709551615) @@ -303,22 +304,22 @@ func addUintFormatterTests() { pv4Addr := fmt.Sprintf("%p", &pv4) v4t := "uint64" v4s := "18446744073709551615" - addFormatterTest("%v", v4, v4s) - addFormatterTest("%v", pv4, "<*>"+v4s) - addFormatterTest("%v", &pv4, "<**>"+v4s) - addFormatterTest("%v", nv4, "") - addFormatterTest("%+v", v4, v4s) - addFormatterTest("%+v", pv4, "<*>("+v4Addr+")"+v4s) - addFormatterTest("%+v", &pv4, "<**>("+pv4Addr+"->"+v4Addr+")"+v4s) - addFormatterTest("%+v", nv4, "") - addFormatterTest("%#v", v4, "("+v4t+")"+v4s) - addFormatterTest("%#v", pv4, "(*"+v4t+")"+v4s) - addFormatterTest("%#v", &pv4, "(**"+v4t+")"+v4s) - addFormatterTest("%#v", nv4, "(*"+v4t+")"+"") - addFormatterTest("%#+v", v4, "("+v4t+")"+v4s) - addFormatterTest("%#+v", pv4, "(*"+v4t+")("+v4Addr+")"+v4s) - addFormatterTest("%#+v", &pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")"+v4s) - addFormatterTest("%#+v", nv4, "(*"+v4t+")"+"") + addFormatterTest(line(), "%v", v4, v4s) + addFormatterTest(line(), "%v", pv4, "<*>"+v4s) + addFormatterTest(line(), "%v", &pv4, "<**>"+v4s) + addFormatterTest(line(), "%v", nv4, "") + addFormatterTest(line(), "%+v", v4, v4s) + addFormatterTest(line(), "%+v", pv4, "<*>("+v4Addr+")"+v4s) + addFormatterTest(line(), "%+v", &pv4, "<**>("+pv4Addr+"->"+v4Addr+")"+v4s) + addFormatterTest(line(), "%+v", nv4, "") + addFormatterTest(line(), "%#v", v4, "("+v4t+")"+v4s) + addFormatterTest(line(), "%#v", pv4, "(*"+v4t+")"+v4s) + addFormatterTest(line(), "%#v", &pv4, "(**"+v4t+")"+v4s) + addFormatterTest(line(), "%#v", nv4, "(*"+v4t+")"+"") + addFormatterTest(line(), "%#+v", v4, "("+v4t+")"+v4s) + addFormatterTest(line(), "%#+v", pv4, "(*"+v4t+")("+v4Addr+")"+v4s) + addFormatterTest(line(), "%#+v", &pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")"+v4s) + addFormatterTest(line(), "%#+v", nv4, "(*"+v4t+")"+"") // Max uint. v5 := uint(4294967295) @@ -328,22 +329,22 @@ func addUintFormatterTests() { pv5Addr := fmt.Sprintf("%p", &pv5) v5t := "uint" v5s := "4294967295" - addFormatterTest("%v", v5, v5s) - addFormatterTest("%v", pv5, "<*>"+v5s) - addFormatterTest("%v", &pv5, "<**>"+v5s) - addFormatterTest("%v", nv5, "") - addFormatterTest("%+v", v5, v5s) - addFormatterTest("%+v", pv5, "<*>("+v5Addr+")"+v5s) - addFormatterTest("%+v", &pv5, "<**>("+pv5Addr+"->"+v5Addr+")"+v5s) - addFormatterTest("%+v", nv5, "") - addFormatterTest("%#v", v5, "("+v5t+")"+v5s) - addFormatterTest("%#v", pv5, "(*"+v5t+")"+v5s) - addFormatterTest("%#v", &pv5, "(**"+v5t+")"+v5s) - addFormatterTest("%#v", nv5, "(*"+v5t+")"+"") - addFormatterTest("%#+v", v5, "("+v5t+")"+v5s) - addFormatterTest("%#+v", pv5, "(*"+v5t+")("+v5Addr+")"+v5s) - addFormatterTest("%#+v", &pv5, "(**"+v5t+")("+pv5Addr+"->"+v5Addr+")"+v5s) - addFormatterTest("%#v", nv5, "(*"+v5t+")"+"") + addFormatterTest(line(), "%v", v5, v5s) + addFormatterTest(line(), "%v", pv5, "<*>"+v5s) + addFormatterTest(line(), "%v", &pv5, "<**>"+v5s) + addFormatterTest(line(), "%v", nv5, "") + addFormatterTest(line(), "%+v", v5, v5s) + addFormatterTest(line(), "%+v", pv5, "<*>("+v5Addr+")"+v5s) + addFormatterTest(line(), "%+v", &pv5, "<**>("+pv5Addr+"->"+v5Addr+")"+v5s) + addFormatterTest(line(), "%+v", nv5, "") + addFormatterTest(line(), "%#v", v5, "("+v5t+")"+v5s) + addFormatterTest(line(), "%#v", pv5, "(*"+v5t+")"+v5s) + addFormatterTest(line(), "%#v", &pv5, "(**"+v5t+")"+v5s) + addFormatterTest(line(), "%#v", nv5, "(*"+v5t+")"+"") + addFormatterTest(line(), "%#+v", v5, "("+v5t+")"+v5s) + addFormatterTest(line(), "%#+v", pv5, "(*"+v5t+")("+v5Addr+")"+v5s) + addFormatterTest(line(), "%#+v", &pv5, "(**"+v5t+")("+pv5Addr+"->"+v5Addr+")"+v5s) + addFormatterTest(line(), "%#v", nv5, "(*"+v5t+")"+"") } func addBoolFormatterTests() { @@ -355,22 +356,22 @@ func addBoolFormatterTests() { pvAddr := fmt.Sprintf("%p", &pv) vt := "bool" vs := "true" - addFormatterTest("%v", v, vs) - addFormatterTest("%v", pv, "<*>"+vs) - addFormatterTest("%v", &pv, "<**>"+vs) - addFormatterTest("%v", nv, "") - addFormatterTest("%+v", v, vs) - addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs) - addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs) - addFormatterTest("%+v", nv, "") - addFormatterTest("%#v", v, "("+vt+")"+vs) - addFormatterTest("%#v", pv, "(*"+vt+")"+vs) - addFormatterTest("%#v", &pv, "(**"+vt+")"+vs) - addFormatterTest("%#v", nv, "(*"+vt+")"+"") - addFormatterTest("%#+v", v, "("+vt+")"+vs) - addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs) - addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs) - addFormatterTest("%#+v", nv, "(*"+vt+")"+"") + addFormatterTest(line(), "%v", v, vs) + addFormatterTest(line(), "%v", pv, "<*>"+vs) + addFormatterTest(line(), "%v", &pv, "<**>"+vs) + addFormatterTest(line(), "%v", nv, "") + addFormatterTest(line(), "%+v", v, vs) + addFormatterTest(line(), "%+v", pv, "<*>("+vAddr+")"+vs) + addFormatterTest(line(), "%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs) + addFormatterTest(line(), "%+v", nv, "") + addFormatterTest(line(), "%#v", v, "("+vt+")"+vs) + addFormatterTest(line(), "%#v", pv, "(*"+vt+")"+vs) + addFormatterTest(line(), "%#v", &pv, "(**"+vt+")"+vs) + addFormatterTest(line(), "%#v", nv, "(*"+vt+")"+"") + addFormatterTest(line(), "%#+v", v, "("+vt+")"+vs) + addFormatterTest(line(), "%#+v", pv, "(*"+vt+")("+vAddr+")"+vs) + addFormatterTest(line(), "%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs) + addFormatterTest(line(), "%#+v", nv, "(*"+vt+")"+"") // Boolean false. v2 := bool(false) @@ -379,18 +380,18 @@ func addBoolFormatterTests() { pv2Addr := fmt.Sprintf("%p", &pv2) v2t := "bool" v2s := "false" - addFormatterTest("%v", v2, v2s) - addFormatterTest("%v", pv2, "<*>"+v2s) - addFormatterTest("%v", &pv2, "<**>"+v2s) - addFormatterTest("%+v", v2, v2s) - addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s) - addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s) - addFormatterTest("%#v", v2, "("+v2t+")"+v2s) - addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s) - addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s) - addFormatterTest("%#+v", v2, "("+v2t+")"+v2s) - addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s) - addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s) + addFormatterTest(line(), "%v", v2, v2s) + addFormatterTest(line(), "%v", pv2, "<*>"+v2s) + addFormatterTest(line(), "%v", &pv2, "<**>"+v2s) + addFormatterTest(line(), "%+v", v2, v2s) + addFormatterTest(line(), "%+v", pv2, "<*>("+v2Addr+")"+v2s) + addFormatterTest(line(), "%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s) + addFormatterTest(line(), "%#v", v2, "("+v2t+")"+v2s) + addFormatterTest(line(), "%#v", pv2, "(*"+v2t+")"+v2s) + addFormatterTest(line(), "%#v", &pv2, "(**"+v2t+")"+v2s) + addFormatterTest(line(), "%#+v", v2, "("+v2t+")"+v2s) + addFormatterTest(line(), "%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s) + addFormatterTest(line(), "%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s) } func addFloatFormatterTests() { @@ -402,22 +403,22 @@ func addFloatFormatterTests() { pvAddr := fmt.Sprintf("%p", &pv) vt := "float32" vs := "3.1415" - addFormatterTest("%v", v, vs) - addFormatterTest("%v", pv, "<*>"+vs) - addFormatterTest("%v", &pv, "<**>"+vs) - addFormatterTest("%v", nv, "") - addFormatterTest("%+v", v, vs) - addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs) - addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs) - addFormatterTest("%+v", nv, "") - addFormatterTest("%#v", v, "("+vt+")"+vs) - addFormatterTest("%#v", pv, "(*"+vt+")"+vs) - addFormatterTest("%#v", &pv, "(**"+vt+")"+vs) - addFormatterTest("%#v", nv, "(*"+vt+")"+"") - addFormatterTest("%#+v", v, "("+vt+")"+vs) - addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs) - addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs) - addFormatterTest("%#+v", nv, "(*"+vt+")"+"") + addFormatterTest(line(), "%v", v, vs) + addFormatterTest(line(), "%v", pv, "<*>"+vs) + addFormatterTest(line(), "%v", &pv, "<**>"+vs) + addFormatterTest(line(), "%v", nv, "") + addFormatterTest(line(), "%+v", v, vs) + addFormatterTest(line(), "%+v", pv, "<*>("+vAddr+")"+vs) + addFormatterTest(line(), "%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs) + addFormatterTest(line(), "%+v", nv, "") + addFormatterTest(line(), "%#v", v, "("+vt+")"+vs) + addFormatterTest(line(), "%#v", pv, "(*"+vt+")"+vs) + addFormatterTest(line(), "%#v", &pv, "(**"+vt+")"+vs) + addFormatterTest(line(), "%#v", nv, "(*"+vt+")"+"") + addFormatterTest(line(), "%#+v", v, "("+vt+")"+vs) + addFormatterTest(line(), "%#+v", pv, "(*"+vt+")("+vAddr+")"+vs) + addFormatterTest(line(), "%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs) + addFormatterTest(line(), "%#+v", nv, "(*"+vt+")"+"") // Standard float64. v2 := float64(3.1415926) @@ -427,22 +428,22 @@ func addFloatFormatterTests() { pv2Addr := fmt.Sprintf("%p", &pv2) v2t := "float64" v2s := "3.1415926" - addFormatterTest("%v", v2, v2s) - addFormatterTest("%v", pv2, "<*>"+v2s) - addFormatterTest("%v", &pv2, "<**>"+v2s) - addFormatterTest("%+v", nv2, "") - addFormatterTest("%+v", v2, v2s) - addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s) - addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s) - addFormatterTest("%+v", nv2, "") - addFormatterTest("%#v", v2, "("+v2t+")"+v2s) - addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s) - addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s) - addFormatterTest("%#v", nv2, "(*"+v2t+")"+"") - addFormatterTest("%#+v", v2, "("+v2t+")"+v2s) - addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s) - addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s) - addFormatterTest("%#+v", nv2, "(*"+v2t+")"+"") + addFormatterTest(line(), "%v", v2, v2s) + addFormatterTest(line(), "%v", pv2, "<*>"+v2s) + addFormatterTest(line(), "%v", &pv2, "<**>"+v2s) + addFormatterTest(line(), "%+v", nv2, "") + addFormatterTest(line(), "%+v", v2, v2s) + addFormatterTest(line(), "%+v", pv2, "<*>("+v2Addr+")"+v2s) + addFormatterTest(line(), "%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s) + addFormatterTest(line(), "%+v", nv2, "") + addFormatterTest(line(), "%#v", v2, "("+v2t+")"+v2s) + addFormatterTest(line(), "%#v", pv2, "(*"+v2t+")"+v2s) + addFormatterTest(line(), "%#v", &pv2, "(**"+v2t+")"+v2s) + addFormatterTest(line(), "%#v", nv2, "(*"+v2t+")"+"") + addFormatterTest(line(), "%#+v", v2, "("+v2t+")"+v2s) + addFormatterTest(line(), "%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s) + addFormatterTest(line(), "%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s) + addFormatterTest(line(), "%#+v", nv2, "(*"+v2t+")"+"") } func addComplexFormatterTests() { @@ -454,22 +455,22 @@ func addComplexFormatterTests() { pvAddr := fmt.Sprintf("%p", &pv) vt := "complex64" vs := "(6-2i)" - addFormatterTest("%v", v, vs) - addFormatterTest("%v", pv, "<*>"+vs) - addFormatterTest("%v", &pv, "<**>"+vs) - addFormatterTest("%+v", nv, "") - addFormatterTest("%+v", v, vs) - addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs) - addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs) - addFormatterTest("%+v", nv, "") - addFormatterTest("%#v", v, "("+vt+")"+vs) - addFormatterTest("%#v", pv, "(*"+vt+")"+vs) - addFormatterTest("%#v", &pv, "(**"+vt+")"+vs) - addFormatterTest("%#v", nv, "(*"+vt+")"+"") - addFormatterTest("%#+v", v, "("+vt+")"+vs) - addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs) - addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs) - addFormatterTest("%#+v", nv, "(*"+vt+")"+"") + addFormatterTest(line(), "%v", v, vs) + addFormatterTest(line(), "%v", pv, "<*>"+vs) + addFormatterTest(line(), "%v", &pv, "<**>"+vs) + addFormatterTest(line(), "%+v", nv, "") + addFormatterTest(line(), "%+v", v, vs) + addFormatterTest(line(), "%+v", pv, "<*>("+vAddr+")"+vs) + addFormatterTest(line(), "%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs) + addFormatterTest(line(), "%+v", nv, "") + addFormatterTest(line(), "%#v", v, "("+vt+")"+vs) + addFormatterTest(line(), "%#v", pv, "(*"+vt+")"+vs) + addFormatterTest(line(), "%#v", &pv, "(**"+vt+")"+vs) + addFormatterTest(line(), "%#v", nv, "(*"+vt+")"+"") + addFormatterTest(line(), "%#+v", v, "("+vt+")"+vs) + addFormatterTest(line(), "%#+v", pv, "(*"+vt+")("+vAddr+")"+vs) + addFormatterTest(line(), "%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs) + addFormatterTest(line(), "%#+v", nv, "(*"+vt+")"+"") // Standard complex128. v2 := complex(float64(-6), 2) @@ -479,22 +480,22 @@ func addComplexFormatterTests() { pv2Addr := fmt.Sprintf("%p", &pv2) v2t := "complex128" v2s := "(-6+2i)" - addFormatterTest("%v", v2, v2s) - addFormatterTest("%v", pv2, "<*>"+v2s) - addFormatterTest("%v", &pv2, "<**>"+v2s) - addFormatterTest("%+v", nv2, "") - addFormatterTest("%+v", v2, v2s) - addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s) - addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s) - addFormatterTest("%+v", nv2, "") - addFormatterTest("%#v", v2, "("+v2t+")"+v2s) - addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s) - addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s) - addFormatterTest("%#v", nv2, "(*"+v2t+")"+"") - addFormatterTest("%#+v", v2, "("+v2t+")"+v2s) - addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s) - addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s) - addFormatterTest("%#+v", nv2, "(*"+v2t+")"+"") + addFormatterTest(line(), "%v", v2, v2s) + addFormatterTest(line(), "%v", pv2, "<*>"+v2s) + addFormatterTest(line(), "%v", &pv2, "<**>"+v2s) + addFormatterTest(line(), "%+v", nv2, "") + addFormatterTest(line(), "%+v", v2, v2s) + addFormatterTest(line(), "%+v", pv2, "<*>("+v2Addr+")"+v2s) + addFormatterTest(line(), "%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s) + addFormatterTest(line(), "%+v", nv2, "") + addFormatterTest(line(), "%#v", v2, "("+v2t+")"+v2s) + addFormatterTest(line(), "%#v", pv2, "(*"+v2t+")"+v2s) + addFormatterTest(line(), "%#v", &pv2, "(**"+v2t+")"+v2s) + addFormatterTest(line(), "%#v", nv2, "(*"+v2t+")"+"") + addFormatterTest(line(), "%#+v", v2, "("+v2t+")"+v2s) + addFormatterTest(line(), "%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s) + addFormatterTest(line(), "%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s) + addFormatterTest(line(), "%#+v", nv2, "(*"+v2t+")"+"") } func addArrayFormatterTests() { @@ -506,22 +507,22 @@ func addArrayFormatterTests() { pvAddr := fmt.Sprintf("%p", &pv) vt := "[3]int" vs := "[1 2 3]" - addFormatterTest("%v", v, vs) - addFormatterTest("%v", pv, "<*>"+vs) - addFormatterTest("%v", &pv, "<**>"+vs) - addFormatterTest("%+v", nv, "") - addFormatterTest("%+v", v, vs) - addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs) - addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs) - addFormatterTest("%+v", nv, "") - addFormatterTest("%#v", v, "("+vt+")"+vs) - addFormatterTest("%#v", pv, "(*"+vt+")"+vs) - addFormatterTest("%#v", &pv, "(**"+vt+")"+vs) - addFormatterTest("%#v", nv, "(*"+vt+")"+"") - addFormatterTest("%#+v", v, "("+vt+")"+vs) - addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs) - addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs) - addFormatterTest("%#+v", nv, "(*"+vt+")"+"") + addFormatterTest(line(), "%v", v, vs) + addFormatterTest(line(), "%v", pv, "<*>"+vs) + addFormatterTest(line(), "%v", &pv, "<**>"+vs) + addFormatterTest(line(), "%+v", nv, "") + addFormatterTest(line(), "%+v", v, vs) + addFormatterTest(line(), "%+v", pv, "<*>("+vAddr+")"+vs) + addFormatterTest(line(), "%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs) + addFormatterTest(line(), "%+v", nv, "") + addFormatterTest(line(), "%#v", v, "("+vt+")"+vs) + addFormatterTest(line(), "%#v", pv, "(*"+vt+")"+vs) + addFormatterTest(line(), "%#v", &pv, "(**"+vt+")"+vs) + addFormatterTest(line(), "%#v", nv, "(*"+vt+")"+"") + addFormatterTest(line(), "%#+v", v, "("+vt+")"+vs) + addFormatterTest(line(), "%#+v", pv, "(*"+vt+")("+vAddr+")"+vs) + addFormatterTest(line(), "%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs) + addFormatterTest(line(), "%#+v", nv, "(*"+vt+")"+"") // Array containing type with custom formatter on pointer receiver only. v2 := [3]pstringer{"1", "2", "3"} @@ -535,22 +536,22 @@ func addArrayFormatterTests() { if spew.UnsafeDisabled { v2s = "[1 2 3]" } - addFormatterTest("%v", v2, v2s) - addFormatterTest("%v", pv2, "<*>"+v2sp) - addFormatterTest("%v", &pv2, "<**>"+v2sp) - addFormatterTest("%+v", nv2, "") - addFormatterTest("%+v", v2, v2s) - addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2sp) - addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2sp) - addFormatterTest("%+v", nv2, "") - addFormatterTest("%#v", v2, "("+v2t+")"+v2s) - addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2sp) - addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2sp) - addFormatterTest("%#v", nv2, "(*"+v2t+")"+"") - addFormatterTest("%#+v", v2, "("+v2t+")"+v2s) - addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2sp) - addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2sp) - addFormatterTest("%#+v", nv2, "(*"+v2t+")"+"") + addFormatterTest(line(), "%v", v2, v2s) + addFormatterTest(line(), "%v", pv2, "<*>"+v2sp) + addFormatterTest(line(), "%v", &pv2, "<**>"+v2sp) + addFormatterTest(line(), "%+v", nv2, "") + addFormatterTest(line(), "%+v", v2, v2s) + addFormatterTest(line(), "%+v", pv2, "<*>("+v2Addr+")"+v2sp) + addFormatterTest(line(), "%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2sp) + addFormatterTest(line(), "%+v", nv2, "") + addFormatterTest(line(), "%#v", v2, "("+v2t+")"+v2s) + addFormatterTest(line(), "%#v", pv2, "(*"+v2t+")"+v2sp) + addFormatterTest(line(), "%#v", &pv2, "(**"+v2t+")"+v2sp) + addFormatterTest(line(), "%#v", nv2, "(*"+v2t+")"+"") + addFormatterTest(line(), "%#+v", v2, "("+v2t+")"+v2s) + addFormatterTest(line(), "%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2sp) + addFormatterTest(line(), "%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2sp) + addFormatterTest(line(), "%#+v", nv2, "(*"+v2t+")"+"") // Array containing interfaces. v3 := [3]interface{}{"one", int(2), uint(3)} @@ -564,22 +565,22 @@ func addArrayFormatterTests() { v3t4 := "uint" v3s := "[one 2 3]" v3s2 := "[(" + v3t2 + ")one (" + v3t3 + ")2 (" + v3t4 + ")3]" - addFormatterTest("%v", v3, v3s) - addFormatterTest("%v", pv3, "<*>"+v3s) - addFormatterTest("%v", &pv3, "<**>"+v3s) - addFormatterTest("%+v", nv3, "") - addFormatterTest("%+v", v3, v3s) - addFormatterTest("%+v", pv3, "<*>("+v3Addr+")"+v3s) - addFormatterTest("%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s) - addFormatterTest("%+v", nv3, "") - addFormatterTest("%#v", v3, "("+v3t+")"+v3s2) - addFormatterTest("%#v", pv3, "(*"+v3t+")"+v3s2) - addFormatterTest("%#v", &pv3, "(**"+v3t+")"+v3s2) - addFormatterTest("%#v", nv3, "(*"+v3t+")"+"") - addFormatterTest("%#+v", v3, "("+v3t+")"+v3s2) - addFormatterTest("%#+v", pv3, "(*"+v3t+")("+v3Addr+")"+v3s2) - addFormatterTest("%#+v", &pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")"+v3s2) - addFormatterTest("%#+v", nv3, "(*"+v3t+")"+"") + addFormatterTest(line(), "%v", v3, v3s) + addFormatterTest(line(), "%v", pv3, "<*>"+v3s) + addFormatterTest(line(), "%v", &pv3, "<**>"+v3s) + addFormatterTest(line(), "%+v", nv3, "") + addFormatterTest(line(), "%+v", v3, v3s) + addFormatterTest(line(), "%+v", pv3, "<*>("+v3Addr+")"+v3s) + addFormatterTest(line(), "%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s) + addFormatterTest(line(), "%+v", nv3, "") + addFormatterTest(line(), "%#v", v3, "("+v3t+")"+v3s2) + addFormatterTest(line(), "%#v", pv3, "(*"+v3t+")"+v3s2) + addFormatterTest(line(), "%#v", &pv3, "(**"+v3t+")"+v3s2) + addFormatterTest(line(), "%#v", nv3, "(*"+v3t+")"+"") + addFormatterTest(line(), "%#+v", v3, "("+v3t+")"+v3s2) + addFormatterTest(line(), "%#+v", pv3, "(*"+v3t+")("+v3Addr+")"+v3s2) + addFormatterTest(line(), "%#+v", &pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")"+v3s2) + addFormatterTest(line(), "%#+v", nv3, "(*"+v3t+")"+"") } func addSliceFormatterTests() { @@ -591,22 +592,22 @@ func addSliceFormatterTests() { pvAddr := fmt.Sprintf("%p", &pv) vt := "[]float32" vs := "[3.14 6.28 12.56]" - addFormatterTest("%v", v, vs) - addFormatterTest("%v", pv, "<*>"+vs) - addFormatterTest("%v", &pv, "<**>"+vs) - addFormatterTest("%+v", nv, "") - addFormatterTest("%+v", v, vs) - addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs) - addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs) - addFormatterTest("%+v", nv, "") - addFormatterTest("%#v", v, "("+vt+")"+vs) - addFormatterTest("%#v", pv, "(*"+vt+")"+vs) - addFormatterTest("%#v", &pv, "(**"+vt+")"+vs) - addFormatterTest("%#v", nv, "(*"+vt+")"+"") - addFormatterTest("%#+v", v, "("+vt+")"+vs) - addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs) - addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs) - addFormatterTest("%#+v", nv, "(*"+vt+")"+"") + addFormatterTest(line(), "%v", v, vs) + addFormatterTest(line(), "%v", pv, "<*>"+vs) + addFormatterTest(line(), "%v", &pv, "<**>"+vs) + addFormatterTest(line(), "%+v", nv, "") + addFormatterTest(line(), "%+v", v, vs) + addFormatterTest(line(), "%+v", pv, "<*>("+vAddr+")"+vs) + addFormatterTest(line(), "%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs) + addFormatterTest(line(), "%+v", nv, "") + addFormatterTest(line(), "%#v", v, "("+vt+")"+vs) + addFormatterTest(line(), "%#v", pv, "(*"+vt+")"+vs) + addFormatterTest(line(), "%#v", &pv, "(**"+vt+")"+vs) + addFormatterTest(line(), "%#v", nv, "(*"+vt+")"+"") + addFormatterTest(line(), "%#+v", v, "("+vt+")"+vs) + addFormatterTest(line(), "%#+v", pv, "(*"+vt+")("+vAddr+")"+vs) + addFormatterTest(line(), "%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs) + addFormatterTest(line(), "%#+v", nv, "(*"+vt+")"+"") // Slice containing type with custom formatter on pointer receiver only. v2 := []pstringer{"1", "2", "3"} @@ -616,22 +617,22 @@ func addSliceFormatterTests() { pv2Addr := fmt.Sprintf("%p", &pv2) v2t := "[]spew_test.pstringer" v2s := "[stringer 1 stringer 2 stringer 3]" - addFormatterTest("%v", v2, v2s) - addFormatterTest("%v", pv2, "<*>"+v2s) - addFormatterTest("%v", &pv2, "<**>"+v2s) - addFormatterTest("%+v", nv2, "") - addFormatterTest("%+v", v2, v2s) - addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s) - addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s) - addFormatterTest("%+v", nv2, "") - addFormatterTest("%#v", v2, "("+v2t+")"+v2s) - addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s) - addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s) - addFormatterTest("%#v", nv2, "(*"+v2t+")"+"") - addFormatterTest("%#+v", v2, "("+v2t+")"+v2s) - addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s) - addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s) - addFormatterTest("%#+v", nv2, "(*"+v2t+")"+"") + addFormatterTest(line(), "%v", v2, v2s) + addFormatterTest(line(), "%v", pv2, "<*>"+v2s) + addFormatterTest(line(), "%v", &pv2, "<**>"+v2s) + addFormatterTest(line(), "%+v", nv2, "") + addFormatterTest(line(), "%+v", v2, v2s) + addFormatterTest(line(), "%+v", pv2, "<*>("+v2Addr+")"+v2s) + addFormatterTest(line(), "%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s) + addFormatterTest(line(), "%+v", nv2, "") + addFormatterTest(line(), "%#v", v2, "("+v2t+")"+v2s) + addFormatterTest(line(), "%#v", pv2, "(*"+v2t+")"+v2s) + addFormatterTest(line(), "%#v", &pv2, "(**"+v2t+")"+v2s) + addFormatterTest(line(), "%#v", nv2, "(*"+v2t+")"+"") + addFormatterTest(line(), "%#+v", v2, "("+v2t+")"+v2s) + addFormatterTest(line(), "%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s) + addFormatterTest(line(), "%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s) + addFormatterTest(line(), "%#+v", nv2, "(*"+v2t+")"+"") // Slice containing interfaces. v3 := []interface{}{"one", int(2), uint(3), nil} @@ -647,22 +648,22 @@ func addSliceFormatterTests() { v3s := "[one 2 3 ]" v3s2 := "[(" + v3t2 + ")one (" + v3t3 + ")2 (" + v3t4 + ")3 (" + v3t5 + ")]" - addFormatterTest("%v", v3, v3s) - addFormatterTest("%v", pv3, "<*>"+v3s) - addFormatterTest("%v", &pv3, "<**>"+v3s) - addFormatterTest("%+v", nv3, "") - addFormatterTest("%+v", v3, v3s) - addFormatterTest("%+v", pv3, "<*>("+v3Addr+")"+v3s) - addFormatterTest("%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s) - addFormatterTest("%+v", nv3, "") - addFormatterTest("%#v", v3, "("+v3t+")"+v3s2) - addFormatterTest("%#v", pv3, "(*"+v3t+")"+v3s2) - addFormatterTest("%#v", &pv3, "(**"+v3t+")"+v3s2) - addFormatterTest("%#v", nv3, "(*"+v3t+")"+"") - addFormatterTest("%#+v", v3, "("+v3t+")"+v3s2) - addFormatterTest("%#+v", pv3, "(*"+v3t+")("+v3Addr+")"+v3s2) - addFormatterTest("%#+v", &pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")"+v3s2) - addFormatterTest("%#+v", nv3, "(*"+v3t+")"+"") + addFormatterTest(line(), "%v", v3, v3s) + addFormatterTest(line(), "%v", pv3, "<*>"+v3s) + addFormatterTest(line(), "%v", &pv3, "<**>"+v3s) + addFormatterTest(line(), "%+v", nv3, "") + addFormatterTest(line(), "%+v", v3, v3s) + addFormatterTest(line(), "%+v", pv3, "<*>("+v3Addr+")"+v3s) + addFormatterTest(line(), "%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s) + addFormatterTest(line(), "%+v", nv3, "") + addFormatterTest(line(), "%#v", v3, "("+v3t+")"+v3s2) + addFormatterTest(line(), "%#v", pv3, "(*"+v3t+")"+v3s2) + addFormatterTest(line(), "%#v", &pv3, "(**"+v3t+")"+v3s2) + addFormatterTest(line(), "%#v", nv3, "(*"+v3t+")"+"") + addFormatterTest(line(), "%#+v", v3, "("+v3t+")"+v3s2) + addFormatterTest(line(), "%#+v", pv3, "(*"+v3t+")("+v3Addr+")"+v3s2) + addFormatterTest(line(), "%#+v", &pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")"+v3s2) + addFormatterTest(line(), "%#+v", nv3, "(*"+v3t+")"+"") // Nil slice. var v4 []int @@ -672,22 +673,22 @@ func addSliceFormatterTests() { pv4Addr := fmt.Sprintf("%p", &pv4) v4t := "[]int" v4s := "" - addFormatterTest("%v", v4, v4s) - addFormatterTest("%v", pv4, "<*>"+v4s) - addFormatterTest("%v", &pv4, "<**>"+v4s) - addFormatterTest("%+v", nv4, "") - addFormatterTest("%+v", v4, v4s) - addFormatterTest("%+v", pv4, "<*>("+v4Addr+")"+v4s) - addFormatterTest("%+v", &pv4, "<**>("+pv4Addr+"->"+v4Addr+")"+v4s) - addFormatterTest("%+v", nv4, "") - addFormatterTest("%#v", v4, "("+v4t+")"+v4s) - addFormatterTest("%#v", pv4, "(*"+v4t+")"+v4s) - addFormatterTest("%#v", &pv4, "(**"+v4t+")"+v4s) - addFormatterTest("%#v", nv4, "(*"+v4t+")"+"") - addFormatterTest("%#+v", v4, "("+v4t+")"+v4s) - addFormatterTest("%#+v", pv4, "(*"+v4t+")("+v4Addr+")"+v4s) - addFormatterTest("%#+v", &pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")"+v4s) - addFormatterTest("%#+v", nv4, "(*"+v4t+")"+"") + addFormatterTest(line(), "%v", v4, v4s) + addFormatterTest(line(), "%v", pv4, "<*>"+v4s) + addFormatterTest(line(), "%v", &pv4, "<**>"+v4s) + addFormatterTest(line(), "%+v", nv4, "") + addFormatterTest(line(), "%+v", v4, v4s) + addFormatterTest(line(), "%+v", pv4, "<*>("+v4Addr+")"+v4s) + addFormatterTest(line(), "%+v", &pv4, "<**>("+pv4Addr+"->"+v4Addr+")"+v4s) + addFormatterTest(line(), "%+v", nv4, "") + addFormatterTest(line(), "%#v", v4, "("+v4t+")"+v4s) + addFormatterTest(line(), "%#v", pv4, "(*"+v4t+")"+v4s) + addFormatterTest(line(), "%#v", &pv4, "(**"+v4t+")"+v4s) + addFormatterTest(line(), "%#v", nv4, "(*"+v4t+")"+"") + addFormatterTest(line(), "%#+v", v4, "("+v4t+")"+v4s) + addFormatterTest(line(), "%#+v", pv4, "(*"+v4t+")("+v4Addr+")"+v4s) + addFormatterTest(line(), "%#+v", &pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")"+v4s) + addFormatterTest(line(), "%#+v", nv4, "(*"+v4t+")"+"") } func addStringFormatterTests() { @@ -699,22 +700,22 @@ func addStringFormatterTests() { pvAddr := fmt.Sprintf("%p", &pv) vt := "string" vs := "test" - addFormatterTest("%v", v, vs) - addFormatterTest("%v", pv, "<*>"+vs) - addFormatterTest("%v", &pv, "<**>"+vs) - addFormatterTest("%+v", nv, "") - addFormatterTest("%+v", v, vs) - addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs) - addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs) - addFormatterTest("%+v", nv, "") - addFormatterTest("%#v", v, "("+vt+")"+vs) - addFormatterTest("%#v", pv, "(*"+vt+")"+vs) - addFormatterTest("%#v", &pv, "(**"+vt+")"+vs) - addFormatterTest("%#v", nv, "(*"+vt+")"+"") - addFormatterTest("%#+v", v, "("+vt+")"+vs) - addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs) - addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs) - addFormatterTest("%#+v", nv, "(*"+vt+")"+"") + addFormatterTest(line(), "%v", v, vs) + addFormatterTest(line(), "%v", pv, "<*>"+vs) + addFormatterTest(line(), "%v", &pv, "<**>"+vs) + addFormatterTest(line(), "%+v", nv, "") + addFormatterTest(line(), "%+v", v, vs) + addFormatterTest(line(), "%+v", pv, "<*>("+vAddr+")"+vs) + addFormatterTest(line(), "%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs) + addFormatterTest(line(), "%+v", nv, "") + addFormatterTest(line(), "%#v", v, "("+vt+")"+vs) + addFormatterTest(line(), "%#v", pv, "(*"+vt+")"+vs) + addFormatterTest(line(), "%#v", &pv, "(**"+vt+")"+vs) + addFormatterTest(line(), "%#v", nv, "(*"+vt+")"+"") + addFormatterTest(line(), "%#+v", v, "("+vt+")"+vs) + addFormatterTest(line(), "%#+v", pv, "(*"+vt+")("+vAddr+")"+vs) + addFormatterTest(line(), "%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs) + addFormatterTest(line(), "%#+v", nv, "(*"+vt+")"+"") } func addInterfaceFormatterTests() { @@ -726,22 +727,22 @@ func addInterfaceFormatterTests() { pvAddr := fmt.Sprintf("%p", &pv) vt := "interface {}" vs := "" - addFormatterTest("%v", v, vs) - addFormatterTest("%v", pv, "<*>"+vs) - addFormatterTest("%v", &pv, "<**>"+vs) - addFormatterTest("%+v", nv, "") - addFormatterTest("%+v", v, vs) - addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs) - addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs) - addFormatterTest("%+v", nv, "") - addFormatterTest("%#v", v, "("+vt+")"+vs) - addFormatterTest("%#v", pv, "(*"+vt+")"+vs) - addFormatterTest("%#v", &pv, "(**"+vt+")"+vs) - addFormatterTest("%#v", nv, "(*"+vt+")"+"") - addFormatterTest("%#+v", v, "("+vt+")"+vs) - addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs) - addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs) - addFormatterTest("%#+v", nv, "(*"+vt+")"+"") + addFormatterTest(line(), "%v", v, vs) + addFormatterTest(line(), "%v", pv, "<*>"+vs) + addFormatterTest(line(), "%v", &pv, "<**>"+vs) + addFormatterTest(line(), "%+v", nv, "") + addFormatterTest(line(), "%+v", v, vs) + addFormatterTest(line(), "%+v", pv, "<*>("+vAddr+")"+vs) + addFormatterTest(line(), "%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs) + addFormatterTest(line(), "%+v", nv, "") + addFormatterTest(line(), "%#v", v, "("+vt+")"+vs) + addFormatterTest(line(), "%#v", pv, "(*"+vt+")"+vs) + addFormatterTest(line(), "%#v", &pv, "(**"+vt+")"+vs) + addFormatterTest(line(), "%#v", nv, "(*"+vt+")"+"") + addFormatterTest(line(), "%#+v", v, "("+vt+")"+vs) + addFormatterTest(line(), "%#+v", pv, "(*"+vt+")("+vAddr+")"+vs) + addFormatterTest(line(), "%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs) + addFormatterTest(line(), "%#+v", nv, "(*"+vt+")"+"") // Sub-interface. v2 := interface{}(uint16(65535)) @@ -750,18 +751,18 @@ func addInterfaceFormatterTests() { pv2Addr := fmt.Sprintf("%p", &pv2) v2t := "uint16" v2s := "65535" - addFormatterTest("%v", v2, v2s) - addFormatterTest("%v", pv2, "<*>"+v2s) - addFormatterTest("%v", &pv2, "<**>"+v2s) - addFormatterTest("%+v", v2, v2s) - addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s) - addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s) - addFormatterTest("%#v", v2, "("+v2t+")"+v2s) - addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s) - addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s) - addFormatterTest("%#+v", v2, "("+v2t+")"+v2s) - addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s) - addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s) + addFormatterTest(line(), "%v", v2, v2s) + addFormatterTest(line(), "%v", pv2, "<*>"+v2s) + addFormatterTest(line(), "%v", &pv2, "<**>"+v2s) + addFormatterTest(line(), "%+v", v2, v2s) + addFormatterTest(line(), "%+v", pv2, "<*>("+v2Addr+")"+v2s) + addFormatterTest(line(), "%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s) + addFormatterTest(line(), "%#v", v2, "("+v2t+")"+v2s) + addFormatterTest(line(), "%#v", pv2, "(*"+v2t+")"+v2s) + addFormatterTest(line(), "%#v", &pv2, "(**"+v2t+")"+v2s) + addFormatterTest(line(), "%#+v", v2, "("+v2t+")"+v2s) + addFormatterTest(line(), "%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s) + addFormatterTest(line(), "%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s) } func addMapFormatterTests() { @@ -775,29 +776,29 @@ func addMapFormatterTests() { vt := "map[string]int" vs := "map[one:1 two:2]" vs2 := "map[two:2 one:1]" - addFormatterTest("%v", v, vs, vs2) - addFormatterTest("%v", pv, "<*>"+vs, "<*>"+vs2) - addFormatterTest("%v", &pv, "<**>"+vs, "<**>"+vs2) - addFormatterTest("%+v", nilMap, "") - addFormatterTest("%+v", nv, "") - addFormatterTest("%+v", v, vs, vs2) - addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs, "<*>("+vAddr+")"+vs2) - addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs, + addFormatterTest(line(), "%v", v, vs, vs2) + addFormatterTest(line(), "%v", pv, "<*>"+vs, "<*>"+vs2) + addFormatterTest(line(), "%v", &pv, "<**>"+vs, "<**>"+vs2) + addFormatterTest(line(), "%+v", nilMap, "") + addFormatterTest(line(), "%+v", nv, "") + addFormatterTest(line(), "%+v", v, vs, vs2) + addFormatterTest(line(), "%+v", pv, "<*>("+vAddr+")"+vs, "<*>("+vAddr+")"+vs2) + addFormatterTest(line(), "%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs, "<**>("+pvAddr+"->"+vAddr+")"+vs2) - addFormatterTest("%+v", nilMap, "") - addFormatterTest("%+v", nv, "") - addFormatterTest("%#v", v, "("+vt+")"+vs, "("+vt+")"+vs2) - addFormatterTest("%#v", pv, "(*"+vt+")"+vs, "(*"+vt+")"+vs2) - addFormatterTest("%#v", &pv, "(**"+vt+")"+vs, "(**"+vt+")"+vs2) - addFormatterTest("%#v", nilMap, "("+vt+")"+"") - addFormatterTest("%#v", nv, "(*"+vt+")"+"") - addFormatterTest("%#+v", v, "("+vt+")"+vs, "("+vt+")"+vs2) - addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs, + addFormatterTest(line(), "%+v", nilMap, "") + addFormatterTest(line(), "%+v", nv, "") + addFormatterTest(line(), "%#v", v, "("+vt+")"+vs, "("+vt+")"+vs2) + addFormatterTest(line(), "%#v", pv, "(*"+vt+")"+vs, "(*"+vt+")"+vs2) + addFormatterTest(line(), "%#v", &pv, "(**"+vt+")"+vs, "(**"+vt+")"+vs2) + addFormatterTest(line(), "%#v", nilMap, "("+vt+")"+"") + addFormatterTest(line(), "%#v", nv, "(*"+vt+")"+"") + addFormatterTest(line(), "%#+v", v, "("+vt+")"+vs, "("+vt+")"+vs2) + addFormatterTest(line(), "%#+v", pv, "(*"+vt+")("+vAddr+")"+vs, "(*"+vt+")("+vAddr+")"+vs2) - addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs, + addFormatterTest(line(), "%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs2) - addFormatterTest("%#+v", nilMap, "("+vt+")"+"") - addFormatterTest("%#+v", nv, "(*"+vt+")"+"") + addFormatterTest(line(), "%#+v", nilMap, "("+vt+")"+"") + addFormatterTest(line(), "%#+v", nv, "(*"+vt+")"+"") // Map with custom formatter type on pointer receiver only keys and vals. v2 := map[pstringer]pstringer{"one": "1"} @@ -810,22 +811,22 @@ func addMapFormatterTests() { if spew.UnsafeDisabled { v2s = "map[one:1]" } - addFormatterTest("%v", v2, v2s) - addFormatterTest("%v", pv2, "<*>"+v2s) - addFormatterTest("%v", &pv2, "<**>"+v2s) - addFormatterTest("%+v", nv2, "") - addFormatterTest("%+v", v2, v2s) - addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s) - addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s) - addFormatterTest("%+v", nv2, "") - addFormatterTest("%#v", v2, "("+v2t+")"+v2s) - addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s) - addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s) - addFormatterTest("%#v", nv2, "(*"+v2t+")"+"") - addFormatterTest("%#+v", v2, "("+v2t+")"+v2s) - addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s) - addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s) - addFormatterTest("%#+v", nv2, "(*"+v2t+")"+"") + addFormatterTest(line(), "%v", v2, v2s) + addFormatterTest(line(), "%v", pv2, "<*>"+v2s) + addFormatterTest(line(), "%v", &pv2, "<**>"+v2s) + addFormatterTest(line(), "%+v", nv2, "") + addFormatterTest(line(), "%+v", v2, v2s) + addFormatterTest(line(), "%+v", pv2, "<*>("+v2Addr+")"+v2s) + addFormatterTest(line(), "%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s) + addFormatterTest(line(), "%+v", nv2, "") + addFormatterTest(line(), "%#v", v2, "("+v2t+")"+v2s) + addFormatterTest(line(), "%#v", pv2, "(*"+v2t+")"+v2s) + addFormatterTest(line(), "%#v", &pv2, "(**"+v2t+")"+v2s) + addFormatterTest(line(), "%#v", nv2, "(*"+v2t+")"+"") + addFormatterTest(line(), "%#+v", v2, "("+v2t+")"+v2s) + addFormatterTest(line(), "%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s) + addFormatterTest(line(), "%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s) + addFormatterTest(line(), "%#+v", nv2, "(*"+v2t+")"+"") // Map with interface keys and values. v3 := map[interface{}]interface{}{"one": 1} @@ -838,22 +839,22 @@ func addMapFormatterTests() { v3t2 := "int" v3s := "map[one:1]" v3s2 := "map[(" + v3t1 + ")one:(" + v3t2 + ")1]" - addFormatterTest("%v", v3, v3s) - addFormatterTest("%v", pv3, "<*>"+v3s) - addFormatterTest("%v", &pv3, "<**>"+v3s) - addFormatterTest("%+v", nv3, "") - addFormatterTest("%+v", v3, v3s) - addFormatterTest("%+v", pv3, "<*>("+v3Addr+")"+v3s) - addFormatterTest("%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s) - addFormatterTest("%+v", nv3, "") - addFormatterTest("%#v", v3, "("+v3t+")"+v3s2) - addFormatterTest("%#v", pv3, "(*"+v3t+")"+v3s2) - addFormatterTest("%#v", &pv3, "(**"+v3t+")"+v3s2) - addFormatterTest("%#v", nv3, "(*"+v3t+")"+"") - addFormatterTest("%#+v", v3, "("+v3t+")"+v3s2) - addFormatterTest("%#+v", pv3, "(*"+v3t+")("+v3Addr+")"+v3s2) - addFormatterTest("%#+v", &pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")"+v3s2) - addFormatterTest("%#+v", nv3, "(*"+v3t+")"+"") + addFormatterTest(line(), "%v", v3, v3s) + addFormatterTest(line(), "%v", pv3, "<*>"+v3s) + addFormatterTest(line(), "%v", &pv3, "<**>"+v3s) + addFormatterTest(line(), "%+v", nv3, "") + addFormatterTest(line(), "%+v", v3, v3s) + addFormatterTest(line(), "%+v", pv3, "<*>("+v3Addr+")"+v3s) + addFormatterTest(line(), "%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s) + addFormatterTest(line(), "%+v", nv3, "") + addFormatterTest(line(), "%#v", v3, "("+v3t+")"+v3s2) + addFormatterTest(line(), "%#v", pv3, "(*"+v3t+")"+v3s2) + addFormatterTest(line(), "%#v", &pv3, "(**"+v3t+")"+v3s2) + addFormatterTest(line(), "%#v", nv3, "(*"+v3t+")"+"") + addFormatterTest(line(), "%#+v", v3, "("+v3t+")"+v3s2) + addFormatterTest(line(), "%#+v", pv3, "(*"+v3t+")("+v3Addr+")"+v3s2) + addFormatterTest(line(), "%#+v", &pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")"+v3s2) + addFormatterTest(line(), "%#+v", nv3, "(*"+v3t+")"+"") // Map with nil interface value v4 := map[string]interface{}{"nil": nil} @@ -865,22 +866,22 @@ func addMapFormatterTests() { v4t1 := "interface {}" v4s := "map[nil:]" v4s2 := "map[nil:(" + v4t1 + ")]" - addFormatterTest("%v", v4, v4s) - addFormatterTest("%v", pv4, "<*>"+v4s) - addFormatterTest("%v", &pv4, "<**>"+v4s) - addFormatterTest("%+v", nv4, "") - addFormatterTest("%+v", v4, v4s) - addFormatterTest("%+v", pv4, "<*>("+v4Addr+")"+v4s) - addFormatterTest("%+v", &pv4, "<**>("+pv4Addr+"->"+v4Addr+")"+v4s) - addFormatterTest("%+v", nv4, "") - addFormatterTest("%#v", v4, "("+v4t+")"+v4s2) - addFormatterTest("%#v", pv4, "(*"+v4t+")"+v4s2) - addFormatterTest("%#v", &pv4, "(**"+v4t+")"+v4s2) - addFormatterTest("%#v", nv4, "(*"+v4t+")"+"") - addFormatterTest("%#+v", v4, "("+v4t+")"+v4s2) - addFormatterTest("%#+v", pv4, "(*"+v4t+")("+v4Addr+")"+v4s2) - addFormatterTest("%#+v", &pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")"+v4s2) - addFormatterTest("%#+v", nv4, "(*"+v4t+")"+"") + addFormatterTest(line(), "%v", v4, v4s) + addFormatterTest(line(), "%v", pv4, "<*>"+v4s) + addFormatterTest(line(), "%v", &pv4, "<**>"+v4s) + addFormatterTest(line(), "%+v", nv4, "") + addFormatterTest(line(), "%+v", v4, v4s) + addFormatterTest(line(), "%+v", pv4, "<*>("+v4Addr+")"+v4s) + addFormatterTest(line(), "%+v", &pv4, "<**>("+pv4Addr+"->"+v4Addr+")"+v4s) + addFormatterTest(line(), "%+v", nv4, "") + addFormatterTest(line(), "%#v", v4, "("+v4t+")"+v4s2) + addFormatterTest(line(), "%#v", pv4, "(*"+v4t+")"+v4s2) + addFormatterTest(line(), "%#v", &pv4, "(**"+v4t+")"+v4s2) + addFormatterTest(line(), "%#v", nv4, "(*"+v4t+")"+"") + addFormatterTest(line(), "%#+v", v4, "("+v4t+")"+v4s2) + addFormatterTest(line(), "%#+v", pv4, "(*"+v4t+")("+v4Addr+")"+v4s2) + addFormatterTest(line(), "%#+v", &pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")"+v4s2) + addFormatterTest(line(), "%#+v", nv4, "(*"+v4t+")"+"") } func addStructFormatterTests() { @@ -900,22 +901,22 @@ func addStructFormatterTests() { vs := "{127 255}" vs2 := "{a:127 b:255}" vs3 := "{a:(" + vt2 + ")127 b:(" + vt3 + ")255}" - addFormatterTest("%v", v, vs) - addFormatterTest("%v", pv, "<*>"+vs) - addFormatterTest("%v", &pv, "<**>"+vs) - addFormatterTest("%+v", nv, "") - addFormatterTest("%+v", v, vs2) - addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs2) - addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs2) - addFormatterTest("%+v", nv, "") - addFormatterTest("%#v", v, "("+vt+")"+vs3) - addFormatterTest("%#v", pv, "(*"+vt+")"+vs3) - addFormatterTest("%#v", &pv, "(**"+vt+")"+vs3) - addFormatterTest("%#v", nv, "(*"+vt+")"+"") - addFormatterTest("%#+v", v, "("+vt+")"+vs3) - addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs3) - addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs3) - addFormatterTest("%#+v", nv, "(*"+vt+")"+"") + addFormatterTest(line(), "%v", v, vs) + addFormatterTest(line(), "%v", pv, "<*>"+vs) + addFormatterTest(line(), "%v", &pv, "<**>"+vs) + addFormatterTest(line(), "%+v", nv, "") + addFormatterTest(line(), "%+v", v, vs2) + addFormatterTest(line(), "%+v", pv, "<*>("+vAddr+")"+vs2) + addFormatterTest(line(), "%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs2) + addFormatterTest(line(), "%+v", nv, "") + addFormatterTest(line(), "%#v", v, "("+vt+")"+vs3) + addFormatterTest(line(), "%#v", pv, "(*"+vt+")"+vs3) + addFormatterTest(line(), "%#v", &pv, "(**"+vt+")"+vs3) + addFormatterTest(line(), "%#v", nv, "(*"+vt+")"+"") + addFormatterTest(line(), "%#+v", v, "("+vt+")"+vs3) + addFormatterTest(line(), "%#+v", pv, "(*"+vt+")("+vAddr+")"+vs3) + addFormatterTest(line(), "%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs3) + addFormatterTest(line(), "%#+v", nv, "(*"+vt+")"+"") // Struct that contains another struct. type s2 struct { @@ -936,22 +937,22 @@ func addStructFormatterTests() { v2s2 := "{s1:{a:127 b:255} b:true}" v2s3 := "{s1:(" + v2t2 + "){a:(" + v2t3 + ")127 b:(" + v2t4 + ")255} b:(" + v2t5 + ")true}" - addFormatterTest("%v", v2, v2s) - addFormatterTest("%v", pv2, "<*>"+v2s) - addFormatterTest("%v", &pv2, "<**>"+v2s) - addFormatterTest("%+v", nv2, "") - addFormatterTest("%+v", v2, v2s2) - addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s2) - addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s2) - addFormatterTest("%+v", nv2, "") - addFormatterTest("%#v", v2, "("+v2t+")"+v2s3) - addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s3) - addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s3) - addFormatterTest("%#v", nv2, "(*"+v2t+")"+"") - addFormatterTest("%#+v", v2, "("+v2t+")"+v2s3) - addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s3) - addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s3) - addFormatterTest("%#+v", nv2, "(*"+v2t+")"+"") + addFormatterTest(line(), "%v", v2, v2s) + addFormatterTest(line(), "%v", pv2, "<*>"+v2s) + addFormatterTest(line(), "%v", &pv2, "<**>"+v2s) + addFormatterTest(line(), "%+v", nv2, "") + addFormatterTest(line(), "%+v", v2, v2s2) + addFormatterTest(line(), "%+v", pv2, "<*>("+v2Addr+")"+v2s2) + addFormatterTest(line(), "%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s2) + addFormatterTest(line(), "%+v", nv2, "") + addFormatterTest(line(), "%#v", v2, "("+v2t+")"+v2s3) + addFormatterTest(line(), "%#v", pv2, "(*"+v2t+")"+v2s3) + addFormatterTest(line(), "%#v", &pv2, "(**"+v2t+")"+v2s3) + addFormatterTest(line(), "%#v", nv2, "(*"+v2t+")"+"") + addFormatterTest(line(), "%#+v", v2, "("+v2t+")"+v2s3) + addFormatterTest(line(), "%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s3) + addFormatterTest(line(), "%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s3) + addFormatterTest(line(), "%#+v", nv2, "(*"+v2t+")"+"") // Struct that contains custom type with Stringer pointer interface via both // exported and unexported fields. @@ -980,22 +981,22 @@ func addStructFormatterTests() { v3s3 = "{s:(" + v3t2 + ")test S:(" + v3t2 + ")test2}" v3s3p = "{s:(" + v3t2 + ")test S:(" + v3t2 + ")stringer test2}" } - addFormatterTest("%v", v3, v3s) - addFormatterTest("%v", pv3, "<*>"+v3sp) - addFormatterTest("%v", &pv3, "<**>"+v3sp) - addFormatterTest("%+v", nv3, "") - addFormatterTest("%+v", v3, v3s2) - addFormatterTest("%+v", pv3, "<*>("+v3Addr+")"+v3s2p) - addFormatterTest("%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s2p) - addFormatterTest("%+v", nv3, "") - addFormatterTest("%#v", v3, "("+v3t+")"+v3s3) - addFormatterTest("%#v", pv3, "(*"+v3t+")"+v3s3p) - addFormatterTest("%#v", &pv3, "(**"+v3t+")"+v3s3p) - addFormatterTest("%#v", nv3, "(*"+v3t+")"+"") - addFormatterTest("%#+v", v3, "("+v3t+")"+v3s3) - addFormatterTest("%#+v", pv3, "(*"+v3t+")("+v3Addr+")"+v3s3p) - addFormatterTest("%#+v", &pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")"+v3s3p) - addFormatterTest("%#+v", nv3, "(*"+v3t+")"+"") + addFormatterTest(line(), "%v", v3, v3s) + addFormatterTest(line(), "%v", pv3, "<*>"+v3sp) + addFormatterTest(line(), "%v", &pv3, "<**>"+v3sp) + addFormatterTest(line(), "%+v", nv3, "") + addFormatterTest(line(), "%+v", v3, v3s2) + addFormatterTest(line(), "%+v", pv3, "<*>("+v3Addr+")"+v3s2p) + addFormatterTest(line(), "%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s2p) + addFormatterTest(line(), "%+v", nv3, "") + addFormatterTest(line(), "%#v", v3, "("+v3t+")"+v3s3) + addFormatterTest(line(), "%#v", pv3, "(*"+v3t+")"+v3s3p) + addFormatterTest(line(), "%#v", &pv3, "(**"+v3t+")"+v3s3p) + addFormatterTest(line(), "%#v", nv3, "(*"+v3t+")"+"") + addFormatterTest(line(), "%#+v", v3, "("+v3t+")"+v3s3) + addFormatterTest(line(), "%#+v", pv3, "(*"+v3t+")("+v3Addr+")"+v3s3p) + addFormatterTest(line(), "%#+v", &pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")"+v3s3p) + addFormatterTest(line(), "%#+v", nv3, "(*"+v3t+")"+"") // Struct that contains embedded struct and field to same struct. e := embed{"embedstr"} @@ -1015,22 +1016,22 @@ func addStructFormatterTests() { "){a:(" + v4t3 + ")embedstr}}" v4s4 := "{embed:(*" + v4t2 + ")(" + eAddr + "){a:(" + v4t3 + ")embedstr} e:(*" + v4t2 + ")(" + eAddr + "){a:(" + v4t3 + ")embedstr}}" - addFormatterTest("%v", v4, v4s) - addFormatterTest("%v", pv4, "<*>"+v4s) - addFormatterTest("%v", &pv4, "<**>"+v4s) - addFormatterTest("%+v", nv4, "") - addFormatterTest("%+v", v4, v4s2) - addFormatterTest("%+v", pv4, "<*>("+v4Addr+")"+v4s2) - addFormatterTest("%+v", &pv4, "<**>("+pv4Addr+"->"+v4Addr+")"+v4s2) - addFormatterTest("%+v", nv4, "") - addFormatterTest("%#v", v4, "("+v4t+")"+v4s3) - addFormatterTest("%#v", pv4, "(*"+v4t+")"+v4s3) - addFormatterTest("%#v", &pv4, "(**"+v4t+")"+v4s3) - addFormatterTest("%#v", nv4, "(*"+v4t+")"+"") - addFormatterTest("%#+v", v4, "("+v4t+")"+v4s4) - addFormatterTest("%#+v", pv4, "(*"+v4t+")("+v4Addr+")"+v4s4) - addFormatterTest("%#+v", &pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")"+v4s4) - addFormatterTest("%#+v", nv4, "(*"+v4t+")"+"") + addFormatterTest(line(), "%v", v4, v4s) + addFormatterTest(line(), "%v", pv4, "<*>"+v4s) + addFormatterTest(line(), "%v", &pv4, "<**>"+v4s) + addFormatterTest(line(), "%+v", nv4, "") + addFormatterTest(line(), "%+v", v4, v4s2) + addFormatterTest(line(), "%+v", pv4, "<*>("+v4Addr+")"+v4s2) + addFormatterTest(line(), "%+v", &pv4, "<**>("+pv4Addr+"->"+v4Addr+")"+v4s2) + addFormatterTest(line(), "%+v", nv4, "") + addFormatterTest(line(), "%#v", v4, "("+v4t+")"+v4s3) + addFormatterTest(line(), "%#v", pv4, "(*"+v4t+")"+v4s3) + addFormatterTest(line(), "%#v", &pv4, "(**"+v4t+")"+v4s3) + addFormatterTest(line(), "%#v", nv4, "(*"+v4t+")"+"") + addFormatterTest(line(), "%#+v", v4, "("+v4t+")"+v4s4) + addFormatterTest(line(), "%#+v", pv4, "(*"+v4t+")("+v4Addr+")"+v4s4) + addFormatterTest(line(), "%#+v", &pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")"+v4s4) + addFormatterTest(line(), "%#+v", nv4, "(*"+v4t+")"+"") } func addUintptrFormatterTests() { @@ -1042,22 +1043,22 @@ func addUintptrFormatterTests() { pvAddr := fmt.Sprintf("%p", &pv) vt := "uintptr" vs := "" - addFormatterTest("%v", v, vs) - addFormatterTest("%v", pv, "<*>"+vs) - addFormatterTest("%v", &pv, "<**>"+vs) - addFormatterTest("%+v", nv, "") - addFormatterTest("%+v", v, vs) - addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs) - addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs) - addFormatterTest("%+v", nv, "") - addFormatterTest("%#v", v, "("+vt+")"+vs) - addFormatterTest("%#v", pv, "(*"+vt+")"+vs) - addFormatterTest("%#v", &pv, "(**"+vt+")"+vs) - addFormatterTest("%#v", nv, "(*"+vt+")"+"") - addFormatterTest("%#+v", v, "("+vt+")"+vs) - addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs) - addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs) - addFormatterTest("%#+v", nv, "(*"+vt+")"+"") + addFormatterTest(line(), "%v", v, vs) + addFormatterTest(line(), "%v", pv, "<*>"+vs) + addFormatterTest(line(), "%v", &pv, "<**>"+vs) + addFormatterTest(line(), "%+v", nv, "") + addFormatterTest(line(), "%+v", v, vs) + addFormatterTest(line(), "%+v", pv, "<*>("+vAddr+")"+vs) + addFormatterTest(line(), "%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs) + addFormatterTest(line(), "%+v", nv, "") + addFormatterTest(line(), "%#v", v, "("+vt+")"+vs) + addFormatterTest(line(), "%#v", pv, "(*"+vt+")"+vs) + addFormatterTest(line(), "%#v", &pv, "(**"+vt+")"+vs) + addFormatterTest(line(), "%#v", nv, "(*"+vt+")"+"") + addFormatterTest(line(), "%#+v", v, "("+vt+")"+vs) + addFormatterTest(line(), "%#+v", pv, "(*"+vt+")("+vAddr+")"+vs) + addFormatterTest(line(), "%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs) + addFormatterTest(line(), "%#+v", nv, "(*"+vt+")"+"") // Address of real variable. i := 1 @@ -1067,18 +1068,18 @@ func addUintptrFormatterTests() { pv2Addr := fmt.Sprintf("%p", &pv2) v2t := "uintptr" v2s := fmt.Sprintf("%p", &i) - addFormatterTest("%v", v2, v2s) - addFormatterTest("%v", pv2, "<*>"+v2s) - addFormatterTest("%v", &pv2, "<**>"+v2s) - addFormatterTest("%+v", v2, v2s) - addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s) - addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s) - addFormatterTest("%#v", v2, "("+v2t+")"+v2s) - addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s) - addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s) - addFormatterTest("%#+v", v2, "("+v2t+")"+v2s) - addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s) - addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s) + addFormatterTest(line(), "%v", v2, v2s) + addFormatterTest(line(), "%v", pv2, "<*>"+v2s) + addFormatterTest(line(), "%v", &pv2, "<**>"+v2s) + addFormatterTest(line(), "%+v", v2, v2s) + addFormatterTest(line(), "%+v", pv2, "<*>("+v2Addr+")"+v2s) + addFormatterTest(line(), "%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s) + addFormatterTest(line(), "%#v", v2, "("+v2t+")"+v2s) + addFormatterTest(line(), "%#v", pv2, "(*"+v2t+")"+v2s) + addFormatterTest(line(), "%#v", &pv2, "(**"+v2t+")"+v2s) + addFormatterTest(line(), "%#+v", v2, "("+v2t+")"+v2s) + addFormatterTest(line(), "%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s) + addFormatterTest(line(), "%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s) } func addUnsafePointerFormatterTests() { @@ -1090,22 +1091,22 @@ func addUnsafePointerFormatterTests() { pvAddr := fmt.Sprintf("%p", &pv) vt := "unsafe.Pointer" vs := "" - addFormatterTest("%v", v, vs) - addFormatterTest("%v", pv, "<*>"+vs) - addFormatterTest("%v", &pv, "<**>"+vs) - addFormatterTest("%+v", nv, "") - addFormatterTest("%+v", v, vs) - addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs) - addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs) - addFormatterTest("%+v", nv, "") - addFormatterTest("%#v", v, "("+vt+")"+vs) - addFormatterTest("%#v", pv, "(*"+vt+")"+vs) - addFormatterTest("%#v", &pv, "(**"+vt+")"+vs) - addFormatterTest("%#v", nv, "(*"+vt+")"+"") - addFormatterTest("%#+v", v, "("+vt+")"+vs) - addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs) - addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs) - addFormatterTest("%#+v", nv, "(*"+vt+")"+"") + addFormatterTest(line(), "%v", v, vs) + addFormatterTest(line(), "%v", pv, "<*>"+vs) + addFormatterTest(line(), "%v", &pv, "<**>"+vs) + addFormatterTest(line(), "%+v", nv, "") + addFormatterTest(line(), "%+v", v, vs) + addFormatterTest(line(), "%+v", pv, "<*>("+vAddr+")"+vs) + addFormatterTest(line(), "%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs) + addFormatterTest(line(), "%+v", nv, "") + addFormatterTest(line(), "%#v", v, "("+vt+")"+vs) + addFormatterTest(line(), "%#v", pv, "(*"+vt+")"+vs) + addFormatterTest(line(), "%#v", &pv, "(**"+vt+")"+vs) + addFormatterTest(line(), "%#v", nv, "(*"+vt+")"+"") + addFormatterTest(line(), "%#+v", v, "("+vt+")"+vs) + addFormatterTest(line(), "%#+v", pv, "(*"+vt+")("+vAddr+")"+vs) + addFormatterTest(line(), "%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs) + addFormatterTest(line(), "%#+v", nv, "(*"+vt+")"+"") // Address of real variable. i := 1 @@ -1115,18 +1116,18 @@ func addUnsafePointerFormatterTests() { pv2Addr := fmt.Sprintf("%p", &pv2) v2t := "unsafe.Pointer" v2s := fmt.Sprintf("%p", &i) - addFormatterTest("%v", v2, v2s) - addFormatterTest("%v", pv2, "<*>"+v2s) - addFormatterTest("%v", &pv2, "<**>"+v2s) - addFormatterTest("%+v", v2, v2s) - addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s) - addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s) - addFormatterTest("%#v", v2, "("+v2t+")"+v2s) - addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s) - addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s) - addFormatterTest("%#+v", v2, "("+v2t+")"+v2s) - addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s) - addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s) + addFormatterTest(line(), "%v", v2, v2s) + addFormatterTest(line(), "%v", pv2, "<*>"+v2s) + addFormatterTest(line(), "%v", &pv2, "<**>"+v2s) + addFormatterTest(line(), "%+v", v2, v2s) + addFormatterTest(line(), "%+v", pv2, "<*>("+v2Addr+")"+v2s) + addFormatterTest(line(), "%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s) + addFormatterTest(line(), "%#v", v2, "("+v2t+")"+v2s) + addFormatterTest(line(), "%#v", pv2, "(*"+v2t+")"+v2s) + addFormatterTest(line(), "%#v", &pv2, "(**"+v2t+")"+v2s) + addFormatterTest(line(), "%#+v", v2, "("+v2t+")"+v2s) + addFormatterTest(line(), "%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s) + addFormatterTest(line(), "%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s) } func addChanFormatterTests() { @@ -1138,22 +1139,22 @@ func addChanFormatterTests() { pvAddr := fmt.Sprintf("%p", &pv) vt := "chan int" vs := "" - addFormatterTest("%v", v, vs) - addFormatterTest("%v", pv, "<*>"+vs) - addFormatterTest("%v", &pv, "<**>"+vs) - addFormatterTest("%+v", nv, "") - addFormatterTest("%+v", v, vs) - addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs) - addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs) - addFormatterTest("%+v", nv, "") - addFormatterTest("%#v", v, "("+vt+")"+vs) - addFormatterTest("%#v", pv, "(*"+vt+")"+vs) - addFormatterTest("%#v", &pv, "(**"+vt+")"+vs) - addFormatterTest("%#v", nv, "(*"+vt+")"+"") - addFormatterTest("%#+v", v, "("+vt+")"+vs) - addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs) - addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs) - addFormatterTest("%#+v", nv, "(*"+vt+")"+"") + addFormatterTest(line(), "%v", v, vs) + addFormatterTest(line(), "%v", pv, "<*>"+vs) + addFormatterTest(line(), "%v", &pv, "<**>"+vs) + addFormatterTest(line(), "%+v", nv, "") + addFormatterTest(line(), "%+v", v, vs) + addFormatterTest(line(), "%+v", pv, "<*>("+vAddr+")"+vs) + addFormatterTest(line(), "%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs) + addFormatterTest(line(), "%+v", nv, "") + addFormatterTest(line(), "%#v", v, "("+vt+")"+vs) + addFormatterTest(line(), "%#v", pv, "(*"+vt+")"+vs) + addFormatterTest(line(), "%#v", &pv, "(**"+vt+")"+vs) + addFormatterTest(line(), "%#v", nv, "(*"+vt+")"+"") + addFormatterTest(line(), "%#+v", v, "("+vt+")"+vs) + addFormatterTest(line(), "%#+v", pv, "(*"+vt+")("+vAddr+")"+vs) + addFormatterTest(line(), "%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs) + addFormatterTest(line(), "%#+v", nv, "(*"+vt+")"+"") // Real channel. v2 := make(chan int) @@ -1162,18 +1163,18 @@ func addChanFormatterTests() { pv2Addr := fmt.Sprintf("%p", &pv2) v2t := "chan int" v2s := fmt.Sprintf("%p", v2) - addFormatterTest("%v", v2, v2s) - addFormatterTest("%v", pv2, "<*>"+v2s) - addFormatterTest("%v", &pv2, "<**>"+v2s) - addFormatterTest("%+v", v2, v2s) - addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s) - addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s) - addFormatterTest("%#v", v2, "("+v2t+")"+v2s) - addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s) - addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s) - addFormatterTest("%#+v", v2, "("+v2t+")"+v2s) - addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s) - addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s) + addFormatterTest(line(), "%v", v2, v2s) + addFormatterTest(line(), "%v", pv2, "<*>"+v2s) + addFormatterTest(line(), "%v", &pv2, "<**>"+v2s) + addFormatterTest(line(), "%+v", v2, v2s) + addFormatterTest(line(), "%+v", pv2, "<*>("+v2Addr+")"+v2s) + addFormatterTest(line(), "%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s) + addFormatterTest(line(), "%#v", v2, "("+v2t+")"+v2s) + addFormatterTest(line(), "%#v", pv2, "(*"+v2t+")"+v2s) + addFormatterTest(line(), "%#v", &pv2, "(**"+v2t+")"+v2s) + addFormatterTest(line(), "%#+v", v2, "("+v2t+")"+v2s) + addFormatterTest(line(), "%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s) + addFormatterTest(line(), "%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s) } func addFuncFormatterTests() { @@ -1185,22 +1186,22 @@ func addFuncFormatterTests() { pvAddr := fmt.Sprintf("%p", &pv) vt := "func()" vs := fmt.Sprintf("%p", v) - addFormatterTest("%v", v, vs) - addFormatterTest("%v", pv, "<*>"+vs) - addFormatterTest("%v", &pv, "<**>"+vs) - addFormatterTest("%+v", nv, "") - addFormatterTest("%+v", v, vs) - addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs) - addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs) - addFormatterTest("%+v", nv, "") - addFormatterTest("%#v", v, "("+vt+")"+vs) - addFormatterTest("%#v", pv, "(*"+vt+")"+vs) - addFormatterTest("%#v", &pv, "(**"+vt+")"+vs) - addFormatterTest("%#v", nv, "(*"+vt+")"+"") - addFormatterTest("%#+v", v, "("+vt+")"+vs) - addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs) - addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs) - addFormatterTest("%#+v", nv, "(*"+vt+")"+"") + addFormatterTest(line(), "%v", v, vs) + addFormatterTest(line(), "%v", pv, "<*>"+vs) + addFormatterTest(line(), "%v", &pv, "<**>"+vs) + addFormatterTest(line(), "%+v", nv, "") + addFormatterTest(line(), "%+v", v, vs) + addFormatterTest(line(), "%+v", pv, "<*>("+vAddr+")"+vs) + addFormatterTest(line(), "%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs) + addFormatterTest(line(), "%+v", nv, "") + addFormatterTest(line(), "%#v", v, "("+vt+")"+vs) + addFormatterTest(line(), "%#v", pv, "(*"+vt+")"+vs) + addFormatterTest(line(), "%#v", &pv, "(**"+vt+")"+vs) + addFormatterTest(line(), "%#v", nv, "(*"+vt+")"+"") + addFormatterTest(line(), "%#+v", v, "("+vt+")"+vs) + addFormatterTest(line(), "%#+v", pv, "(*"+vt+")("+vAddr+")"+vs) + addFormatterTest(line(), "%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs) + addFormatterTest(line(), "%#+v", nv, "(*"+vt+")"+"") // Function with param and no returns. v2 := TestFormatter @@ -1210,22 +1211,22 @@ func addFuncFormatterTests() { pv2Addr := fmt.Sprintf("%p", &pv2) v2t := "func(*testing.T)" v2s := fmt.Sprintf("%p", v2) - addFormatterTest("%v", v2, v2s) - addFormatterTest("%v", pv2, "<*>"+v2s) - addFormatterTest("%v", &pv2, "<**>"+v2s) - addFormatterTest("%+v", nv2, "") - addFormatterTest("%+v", v2, v2s) - addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s) - addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s) - addFormatterTest("%+v", nv2, "") - addFormatterTest("%#v", v2, "("+v2t+")"+v2s) - addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s) - addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s) - addFormatterTest("%#v", nv2, "(*"+v2t+")"+"") - addFormatterTest("%#+v", v2, "("+v2t+")"+v2s) - addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s) - addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s) - addFormatterTest("%#+v", nv2, "(*"+v2t+")"+"") + addFormatterTest(line(), "%v", v2, v2s) + addFormatterTest(line(), "%v", pv2, "<*>"+v2s) + addFormatterTest(line(), "%v", &pv2, "<**>"+v2s) + addFormatterTest(line(), "%+v", nv2, "") + addFormatterTest(line(), "%+v", v2, v2s) + addFormatterTest(line(), "%+v", pv2, "<*>("+v2Addr+")"+v2s) + addFormatterTest(line(), "%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s) + addFormatterTest(line(), "%+v", nv2, "") + addFormatterTest(line(), "%#v", v2, "("+v2t+")"+v2s) + addFormatterTest(line(), "%#v", pv2, "(*"+v2t+")"+v2s) + addFormatterTest(line(), "%#v", &pv2, "(**"+v2t+")"+v2s) + addFormatterTest(line(), "%#v", nv2, "(*"+v2t+")"+"") + addFormatterTest(line(), "%#+v", v2, "("+v2t+")"+v2s) + addFormatterTest(line(), "%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s) + addFormatterTest(line(), "%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s) + addFormatterTest(line(), "%#+v", nv2, "(*"+v2t+")"+"") // Function with multiple params and multiple returns. var v3 = func(i int, s string) (b bool, err error) { @@ -1237,22 +1238,22 @@ func addFuncFormatterTests() { pv3Addr := fmt.Sprintf("%p", &pv3) v3t := "func(int, string) (bool, error)" v3s := fmt.Sprintf("%p", v3) - addFormatterTest("%v", v3, v3s) - addFormatterTest("%v", pv3, "<*>"+v3s) - addFormatterTest("%v", &pv3, "<**>"+v3s) - addFormatterTest("%+v", nv3, "") - addFormatterTest("%+v", v3, v3s) - addFormatterTest("%+v", pv3, "<*>("+v3Addr+")"+v3s) - addFormatterTest("%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s) - addFormatterTest("%+v", nv3, "") - addFormatterTest("%#v", v3, "("+v3t+")"+v3s) - addFormatterTest("%#v", pv3, "(*"+v3t+")"+v3s) - addFormatterTest("%#v", &pv3, "(**"+v3t+")"+v3s) - addFormatterTest("%#v", nv3, "(*"+v3t+")"+"") - addFormatterTest("%#+v", v3, "("+v3t+")"+v3s) - addFormatterTest("%#+v", pv3, "(*"+v3t+")("+v3Addr+")"+v3s) - addFormatterTest("%#+v", &pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")"+v3s) - addFormatterTest("%#+v", nv3, "(*"+v3t+")"+"") + addFormatterTest(line(), "%v", v3, v3s) + addFormatterTest(line(), "%v", pv3, "<*>"+v3s) + addFormatterTest(line(), "%v", &pv3, "<**>"+v3s) + addFormatterTest(line(), "%+v", nv3, "") + addFormatterTest(line(), "%+v", v3, v3s) + addFormatterTest(line(), "%+v", pv3, "<*>("+v3Addr+")"+v3s) + addFormatterTest(line(), "%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s) + addFormatterTest(line(), "%+v", nv3, "") + addFormatterTest(line(), "%#v", v3, "("+v3t+")"+v3s) + addFormatterTest(line(), "%#v", pv3, "(*"+v3t+")"+v3s) + addFormatterTest(line(), "%#v", &pv3, "(**"+v3t+")"+v3s) + addFormatterTest(line(), "%#v", nv3, "(*"+v3t+")"+"") + addFormatterTest(line(), "%#+v", v3, "("+v3t+")"+v3s) + addFormatterTest(line(), "%#+v", pv3, "(*"+v3t+")("+v3Addr+")"+v3s) + addFormatterTest(line(), "%#+v", &pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")"+v3s) + addFormatterTest(line(), "%#+v", nv3, "(*"+v3t+")"+"") } func addCircularFormatterTests() { @@ -1275,18 +1276,18 @@ func addCircularFormatterTests() { vs7 := "{c:(*" + vt + ")(" + vAddr + "){c:(*" + vt + ")(" + vAddr + ")}}" vs8 := "{c:(*" + vt + ")(" + vAddr + ")}" - addFormatterTest("%v", v, vs) - addFormatterTest("%v", pv, "<*>"+vs2) - addFormatterTest("%v", &pv, "<**>"+vs2) - addFormatterTest("%+v", v, vs3) - addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs4) - addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs4) - addFormatterTest("%#v", v, "("+vt+")"+vs5) - addFormatterTest("%#v", pv, "(*"+vt+")"+vs6) - addFormatterTest("%#v", &pv, "(**"+vt+")"+vs6) - addFormatterTest("%#+v", v, "("+vt+")"+vs7) - addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs8) - addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs8) + addFormatterTest(line(), "%v", v, vs) + addFormatterTest(line(), "%v", pv, "<*>"+vs2) + addFormatterTest(line(), "%v", &pv, "<**>"+vs2) + addFormatterTest(line(), "%+v", v, vs3) + addFormatterTest(line(), "%+v", pv, "<*>("+vAddr+")"+vs4) + addFormatterTest(line(), "%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs4) + addFormatterTest(line(), "%#v", v, "("+vt+")"+vs5) + addFormatterTest(line(), "%#v", pv, "(*"+vt+")"+vs6) + addFormatterTest(line(), "%#v", &pv, "(**"+vt+")"+vs6) + addFormatterTest(line(), "%#+v", v, "("+vt+")"+vs7) + addFormatterTest(line(), "%#+v", pv, "(*"+vt+")("+vAddr+")"+vs8) + addFormatterTest(line(), "%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs8) // Structs that are circular through cross referencing. v2 := xref1{nil} @@ -1311,18 +1312,18 @@ func addCircularFormatterTests() { ")}}}" v2s8 := "{ps2:(*" + v2t2 + ")(" + ts2Addr + "){ps1:(*" + v2t + ")(" + v2Addr + ")}}" - addFormatterTest("%v", v2, v2s) - addFormatterTest("%v", pv2, "<*>"+v2s2) - addFormatterTest("%v", &pv2, "<**>"+v2s2) - addFormatterTest("%+v", v2, v2s3) - addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s4) - addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s4) - addFormatterTest("%#v", v2, "("+v2t+")"+v2s5) - addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s6) - addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s6) - addFormatterTest("%#+v", v2, "("+v2t+")"+v2s7) - addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s8) - addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s8) + addFormatterTest(line(), "%v", v2, v2s) + addFormatterTest(line(), "%v", pv2, "<*>"+v2s2) + addFormatterTest(line(), "%v", &pv2, "<**>"+v2s2) + addFormatterTest(line(), "%+v", v2, v2s3) + addFormatterTest(line(), "%+v", pv2, "<*>("+v2Addr+")"+v2s4) + addFormatterTest(line(), "%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s4) + addFormatterTest(line(), "%#v", v2, "("+v2t+")"+v2s5) + addFormatterTest(line(), "%#v", pv2, "(*"+v2t+")"+v2s6) + addFormatterTest(line(), "%#v", &pv2, "(**"+v2t+")"+v2s6) + addFormatterTest(line(), "%#+v", v2, "("+v2t+")"+v2s7) + addFormatterTest(line(), "%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s8) + addFormatterTest(line(), "%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s8) // Structs that are indirectly circular. v3 := indirCir1{nil} @@ -1353,18 +1354,18 @@ func addCircularFormatterTests() { ")(" + tic2Addr + ")}}}}" v3s8 := "{ps2:(*" + v3t2 + ")(" + tic2Addr + "){ps3:(*" + v3t3 + ")(" + tic3Addr + "){ps1:(*" + v3t + ")(" + v3Addr + ")}}}" - addFormatterTest("%v", v3, v3s) - addFormatterTest("%v", pv3, "<*>"+v3s2) - addFormatterTest("%v", &pv3, "<**>"+v3s2) - addFormatterTest("%+v", v3, v3s3) - addFormatterTest("%+v", pv3, "<*>("+v3Addr+")"+v3s4) - addFormatterTest("%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s4) - addFormatterTest("%#v", v3, "("+v3t+")"+v3s5) - addFormatterTest("%#v", pv3, "(*"+v3t+")"+v3s6) - addFormatterTest("%#v", &pv3, "(**"+v3t+")"+v3s6) - addFormatterTest("%#+v", v3, "("+v3t+")"+v3s7) - addFormatterTest("%#+v", pv3, "(*"+v3t+")("+v3Addr+")"+v3s8) - addFormatterTest("%#+v", &pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")"+v3s8) + addFormatterTest(line(), "%v", v3, v3s) + addFormatterTest(line(), "%v", pv3, "<*>"+v3s2) + addFormatterTest(line(), "%v", &pv3, "<**>"+v3s2) + addFormatterTest(line(), "%+v", v3, v3s3) + addFormatterTest(line(), "%+v", pv3, "<*>("+v3Addr+")"+v3s4) + addFormatterTest(line(), "%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s4) + addFormatterTest(line(), "%#v", v3, "("+v3t+")"+v3s5) + addFormatterTest(line(), "%#v", pv3, "(*"+v3t+")"+v3s6) + addFormatterTest(line(), "%#v", &pv3, "(**"+v3t+")"+v3s6) + addFormatterTest(line(), "%#+v", v3, "("+v3t+")"+v3s7) + addFormatterTest(line(), "%#+v", pv3, "(*"+v3t+")("+v3Addr+")"+v3s8) + addFormatterTest(line(), "%#+v", &pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")"+v3s8) } func addPanicFormatterTests() { @@ -1376,22 +1377,22 @@ func addPanicFormatterTests() { pvAddr := fmt.Sprintf("%p", &pv) vt := "spew_test.panicer" vs := "(PANIC=test panic)127" - addFormatterTest("%v", v, vs) - addFormatterTest("%v", pv, "<*>"+vs) - addFormatterTest("%v", &pv, "<**>"+vs) - addFormatterTest("%v", nv, "") - addFormatterTest("%+v", v, vs) - addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs) - addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs) - addFormatterTest("%+v", nv, "") - addFormatterTest("%#v", v, "("+vt+")"+vs) - addFormatterTest("%#v", pv, "(*"+vt+")"+vs) - addFormatterTest("%#v", &pv, "(**"+vt+")"+vs) - addFormatterTest("%#v", nv, "(*"+vt+")"+"") - addFormatterTest("%#+v", v, "("+vt+")"+vs) - addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs) - addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs) - addFormatterTest("%#+v", nv, "(*"+vt+")"+"") + addFormatterTest(line(), "%v", v, vs) + addFormatterTest(line(), "%v", pv, "<*>"+vs) + addFormatterTest(line(), "%v", &pv, "<**>"+vs) + addFormatterTest(line(), "%v", nv, "") + addFormatterTest(line(), "%+v", v, vs) + addFormatterTest(line(), "%+v", pv, "<*>("+vAddr+")"+vs) + addFormatterTest(line(), "%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs) + addFormatterTest(line(), "%+v", nv, "") + addFormatterTest(line(), "%#v", v, "("+vt+")"+vs) + addFormatterTest(line(), "%#v", pv, "(*"+vt+")"+vs) + addFormatterTest(line(), "%#v", &pv, "(**"+vt+")"+vs) + addFormatterTest(line(), "%#v", nv, "(*"+vt+")"+"") + addFormatterTest(line(), "%#+v", v, "("+vt+")"+vs) + addFormatterTest(line(), "%#+v", pv, "(*"+vt+")("+vAddr+")"+vs) + addFormatterTest(line(), "%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs) + addFormatterTest(line(), "%#+v", nv, "(*"+vt+")"+"") } func addErrorFormatterTests() { @@ -1403,22 +1404,22 @@ func addErrorFormatterTests() { pvAddr := fmt.Sprintf("%p", &pv) vt := "spew_test.customError" vs := "error: 127" - addFormatterTest("%v", v, vs) - addFormatterTest("%v", pv, "<*>"+vs) - addFormatterTest("%v", &pv, "<**>"+vs) - addFormatterTest("%v", nv, "") - addFormatterTest("%+v", v, vs) - addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs) - addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs) - addFormatterTest("%+v", nv, "") - addFormatterTest("%#v", v, "("+vt+")"+vs) - addFormatterTest("%#v", pv, "(*"+vt+")"+vs) - addFormatterTest("%#v", &pv, "(**"+vt+")"+vs) - addFormatterTest("%#v", nv, "(*"+vt+")"+"") - addFormatterTest("%#+v", v, "("+vt+")"+vs) - addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs) - addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs) - addFormatterTest("%#+v", nv, "(*"+vt+")"+"") + addFormatterTest(line(), "%v", v, vs) + addFormatterTest(line(), "%v", pv, "<*>"+vs) + addFormatterTest(line(), "%v", &pv, "<**>"+vs) + addFormatterTest(line(), "%v", nv, "") + addFormatterTest(line(), "%+v", v, vs) + addFormatterTest(line(), "%+v", pv, "<*>("+vAddr+")"+vs) + addFormatterTest(line(), "%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs) + addFormatterTest(line(), "%+v", nv, "") + addFormatterTest(line(), "%#v", v, "("+vt+")"+vs) + addFormatterTest(line(), "%#v", pv, "(*"+vt+")"+vs) + addFormatterTest(line(), "%#v", &pv, "(**"+vt+")"+vs) + addFormatterTest(line(), "%#v", nv, "(*"+vt+")"+"") + addFormatterTest(line(), "%#+v", v, "("+vt+")"+vs) + addFormatterTest(line(), "%#+v", pv, "(*"+vt+")("+vAddr+")"+vs) + addFormatterTest(line(), "%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs) + addFormatterTest(line(), "%#+v", nv, "(*"+vt+")"+"") } func addPassthroughFormatterTests() { @@ -1428,9 +1429,9 @@ func addPassthroughFormatterTests() { vAddr := fmt.Sprintf("%x", pv) pvAddr := fmt.Sprintf("%x", &pv) vs := "ffffffff" - addFormatterTest("%x", v, vs) - addFormatterTest("%x", pv, vAddr) - addFormatterTest("%x", &pv, pvAddr) + addFormatterTest(line(), "%x", v, vs) + addFormatterTest(line(), "%x", pv, vAddr) + addFormatterTest(line(), "%x", &pv, pvAddr) // %#x passthrough with uint. v2 := int(2147483647) @@ -1438,27 +1439,27 @@ func addPassthroughFormatterTests() { v2Addr := fmt.Sprintf("%#x", pv2) pv2Addr := fmt.Sprintf("%#x", &pv2) v2s := "0x7fffffff" - addFormatterTest("%#x", v2, v2s) - addFormatterTest("%#x", pv2, v2Addr) - addFormatterTest("%#x", &pv2, pv2Addr) + addFormatterTest(line(), "%#x", v2, v2s) + addFormatterTest(line(), "%#x", pv2, v2Addr) + addFormatterTest(line(), "%#x", &pv2, pv2Addr) // %f passthrough with precision. - addFormatterTest("%.2f", 3.1415, "3.14") - addFormatterTest("%.3f", 3.1415, "3.142") - addFormatterTest("%.4f", 3.1415, "3.1415") + addFormatterTest(line(), "%.2f", 3.1415, "3.14") + addFormatterTest(line(), "%.3f", 3.1415, "3.142") + addFormatterTest(line(), "%.4f", 3.1415, "3.1415") // %f passthrough with width and precision. - addFormatterTest("%5.2f", 3.1415, " 3.14") - addFormatterTest("%6.3f", 3.1415, " 3.142") - addFormatterTest("%7.4f", 3.1415, " 3.1415") + addFormatterTest(line(), "%5.2f", 3.1415, " 3.14") + addFormatterTest(line(), "%6.3f", 3.1415, " 3.142") + addFormatterTest(line(), "%7.4f", 3.1415, " 3.1415") // %d passthrough with width. - addFormatterTest("%3d", 127, "127") - addFormatterTest("%4d", 127, " 127") - addFormatterTest("%5d", 127, " 127") + addFormatterTest(line(), "%3d", 127, "127") + addFormatterTest(line(), "%4d", 127, " 127") + addFormatterTest(line(), "%5d", 127, " 127") // %q passthrough with string. - addFormatterTest("%q", "test", "\"test\"") + addFormatterTest(line(), "%q", "test", "\"test\"") } // TestFormatter executes all of the tests described by formatterTests. @@ -1485,13 +1486,13 @@ func TestFormatter(t *testing.T) { addPassthroughFormatterTests() t.Logf("Running %d tests", len(formatterTests)) - for i, test := range formatterTests { + for _, test := range formatterTests { buf := new(bytes.Buffer) spew.Fprintf(buf, test.format, test.in) s := buf.String() if testFailed(s, test.wants) { - t.Errorf("Formatter #%d format: %s got: %s %s", i, test.format, s, - stringizeWants(test.wants)) + t.Errorf("testcase on line %s: format: %q\n got: %s\nwant: %s", test.line, test.format, s, + stringizeWants(test.wants, "\n or: %s")) continue } } diff --git a/spew/internalunsafe_test.go b/spew/internalunsafe_test.go index 80dc221..bc4740b 100644 --- a/spew/internalunsafe_test.go +++ b/spew/internalunsafe_test.go @@ -16,6 +16,7 @@ // when the code is not running on Google App Engine, compiled by GopherJS, and // "-tags safe" is not added to the go build command line. The "disableunsafe" // tag is deprecated and thus should not be used. +//go:build !js && !appengine && !safe && !disableunsafe && go1.4 // +build !js,!appengine,!safe,!disableunsafe,go1.4 /* @@ -46,7 +47,7 @@ func changeKind(v *reflect.Value, readOnly bool) { *flags |= flagKindMask } -// TestAddedReflectValue tests functionaly of the dump and formatter code which +// TestAddedReflectValue tests functionally of the dump and formatter code which // falls back to the standard fmt library for new types that might get added to // the language. func TestAddedReflectValue(t *testing.T) { diff --git a/spew/spew.go b/spew/spew.go index 32c0e33..e08558f 100644 --- a/spew/spew.go +++ b/spew/spew.go @@ -14,7 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -package spew +package spew // github.com/thockin/go-spew/spew import ( "fmt" diff --git a/spew/spew_test.go b/spew/spew_test.go index b70466c..5447750 100644 --- a/spew/spew_test.go +++ b/spew/spew_test.go @@ -21,9 +21,12 @@ import ( "fmt" "io/ioutil" "os" + "reflect" + "runtime" + "strings" "testing" - "github.com/davecgh/go-spew/spew" + "github.com/thockin/go-spew/spew" ) // spewFunc is used to identify which public function of the spew package or @@ -89,6 +92,7 @@ func (f spewFunc) String() string { // spewTest is used to describe a test to be performed against the public // functions of the spew package or ConfigState. type spewTest struct { + line string // use line() to fill this cs *spew.ConfigState f spewFunc format string @@ -132,6 +136,10 @@ func initSpewTests() { scsContinue := &spew.ConfigState{Indent: " ", ContinueOnMethod: true} scsNoPtrAddr := &spew.ConfigState{DisablePointerAddresses: true} scsNoCap := &spew.ConfigState{DisableCapacities: true} + scsTrailingComma := &spew.ConfigState{Indent: " ", TrailingCommas: true} + scsNoUnexported := &spew.ConfigState{Indent: " ", DisableUnexported: true} + scsQuotes := &spew.ConfigState{QuoteStrings: true} + scsClean := &spew.CleanConfig // Variables for tests on types which implement Stringer interface with and // without a pointer receiver. @@ -154,64 +162,134 @@ func initSpewTests() { dt := depthTester{indirCir1{nil}, [1]string{"arr"}, []string{"slice"}, map[string]int{"one": 1}} + // commatester is to test trailing commas + type commaTester struct { + slice []interface{} + m map[string]int + } + // Variable for tests on types which implement error interface. te := customError(10) + // unexported fields. + tunexp := struct { + X int + y int + }{123, 456} + + // Variable for tests on anonymous functions. + tfn := func() {} + spewTests = []spewTest{ - {scsDefault, fCSFdump, "", int8(127), "(int8) 127\n"}, - {scsDefault, fCSFprint, "", int16(32767), "32767"}, - {scsDefault, fCSFprintf, "%v", int32(2147483647), "2147483647"}, - {scsDefault, fCSFprintln, "", int(2147483647), "2147483647\n"}, - {scsDefault, fCSPrint, "", int64(9223372036854775807), "9223372036854775807"}, - {scsDefault, fCSPrintln, "", uint8(255), "255\n"}, - {scsDefault, fCSSdump, "", uint8(64), "(uint8) 64\n"}, - {scsDefault, fCSSprint, "", complex(1, 2), "(1+2i)"}, - {scsDefault, fCSSprintf, "%v", complex(float32(3), 4), "(3+4i)"}, - {scsDefault, fCSSprintln, "", complex(float64(5), 6), "(5+6i)\n"}, - {scsDefault, fCSErrorf, "%#v", uint16(65535), "(uint16)65535"}, - {scsDefault, fCSNewFormatter, "%v", uint32(4294967295), "4294967295"}, - {scsDefault, fErrorf, "%v", uint64(18446744073709551615), "18446744073709551615"}, - {scsDefault, fFprint, "", float32(3.14), "3.14"}, - {scsDefault, fFprintln, "", float64(6.28), "6.28\n"}, - {scsDefault, fPrint, "", true, "true"}, - {scsDefault, fPrintln, "", false, "false\n"}, - {scsDefault, fSdump, "", complex(-10, -20), "(complex128) (-10-20i)\n"}, - {scsDefault, fSprint, "", complex(-1, -2), "(-1-2i)"}, - {scsDefault, fSprintf, "%v", complex(float32(-3), -4), "(-3-4i)"}, - {scsDefault, fSprintln, "", complex(float64(-5), -6), "(-5-6i)\n"}, - {scsNoMethods, fCSFprint, "", ts, "test"}, - {scsNoMethods, fCSFprint, "", &ts, "<*>test"}, - {scsNoMethods, fCSFprint, "", tps, "test"}, - {scsNoMethods, fCSFprint, "", &tps, "<*>test"}, - {scsNoPmethods, fCSFprint, "", ts, "stringer test"}, - {scsNoPmethods, fCSFprint, "", &ts, "<*>stringer test"}, - {scsNoPmethods, fCSFprint, "", tps, "test"}, - {scsNoPmethods, fCSFprint, "", &tps, "<*>stringer test"}, - {scsMaxDepth, fCSFprint, "", dt, "{{} [] [] map[]}"}, - {scsMaxDepth, fCSFdump, "", dt, "(spew_test.depthTester) {\n" + + {line(), scsDefault, fCSFdump, "", int8(127), "(int8) 127\n"}, + {line(), scsDefault, fCSFprint, "", int16(32767), "32767"}, + {line(), scsDefault, fCSFprintf, "%v", int32(2147483647), "2147483647"}, + {line(), scsDefault, fCSFprintln, "", int(2147483647), "2147483647\n"}, + {line(), scsDefault, fCSPrint, "", int64(9223372036854775807), "9223372036854775807"}, + {line(), scsDefault, fCSPrintln, "", uint8(255), "255\n"}, + {line(), scsDefault, fCSSdump, "", uint8(64), "(uint8) 64\n"}, + {line(), scsDefault, fCSSprint, "", complex(1, 2), "(1+2i)"}, + {line(), scsDefault, fCSSprintf, "%v", complex(float32(3), 4), "(3+4i)"}, + {line(), scsDefault, fCSSprintln, "", complex(float64(5), 6), "(5+6i)\n"}, + {line(), scsDefault, fCSErrorf, "%#v", uint16(65535), "(uint16)65535"}, + {line(), scsDefault, fCSNewFormatter, "%v", uint32(4294967295), "4294967295"}, + {line(), scsDefault, fErrorf, "%v", uint64(18446744073709551615), "18446744073709551615"}, + {line(), scsDefault, fFprint, "", float32(3.14), "3.14"}, + {line(), scsDefault, fFprintln, "", float64(6.28), "6.28\n"}, + {line(), scsDefault, fPrint, "", true, "true"}, + {line(), scsDefault, fPrintln, "", false, "false\n"}, + {line(), scsDefault, fSdump, "", complex(-10, -20), "(complex128) (-10-20i)\n"}, + {line(), scsDefault, fSprint, "", complex(-1, -2), "(-1-2i)"}, + {line(), scsDefault, fSprintf, "%v", complex(float32(-3), -4), "(-3-4i)"}, + {line(), scsDefault, fSprintln, "", complex(float64(-5), -6), "(-5-6i)\n"}, + {line(), scsNoMethods, fCSFprint, "", ts, "test"}, + {line(), scsNoMethods, fCSFprint, "", &ts, "<*>test"}, + {line(), scsNoMethods, fCSFprint, "", tps, "test"}, + {line(), scsNoMethods, fCSFprint, "", &tps, "<*>test"}, + {line(), scsNoPmethods, fCSFprint, "", ts, "stringer test"}, + {line(), scsNoPmethods, fCSFprint, "", &ts, "<*>stringer test"}, + {line(), scsNoPmethods, fCSFprint, "", tps, "test"}, + {line(), scsNoPmethods, fCSFprint, "", &tps, "<*>stringer test"}, + {line(), scsMaxDepth, fCSFprint, "", dt, "{{} [] [] map[]}"}, + {line(), scsMaxDepth, fCSFdump, "", dt, "(spew_test.depthTester) {\n" + " ic: (spew_test.indirCir1) {\n \n },\n" + " arr: ([1]string) (len=1 cap=1) {\n \n },\n" + " slice: ([]string) (len=1 cap=1) {\n \n },\n" + " m: (map[string]int) (len=1) {\n \n }\n}\n"}, - {scsContinue, fCSFprint, "", ts, "(stringer test) test"}, - {scsContinue, fCSFdump, "", ts, "(spew_test.stringer) " + + {line(), scsContinue, fCSFprint, "", ts, "(stringer test) test"}, + {line(), scsContinue, fCSFdump, "", ts, "(spew_test.stringer) " + "(len=4) (stringer test) \"test\"\n"}, - {scsContinue, fCSFprint, "", te, "(error: 10) 10"}, - {scsContinue, fCSFdump, "", te, "(spew_test.customError) " + + {line(), scsContinue, fCSFprint, "", te, "(error: 10) 10"}, + {line(), scsContinue, fCSFdump, "", te, "(spew_test.customError) " + "(error: 10) 10\n"}, - {scsNoPtrAddr, fCSFprint, "", tptr, "<*>{<*>{}}"}, - {scsNoPtrAddr, fCSSdump, "", tptr, "(*spew_test.ptrTester)({\ns: (*struct {})({\n})\n})\n"}, - {scsNoCap, fCSSdump, "", make([]string, 0, 10), "([]string) {\n}\n"}, - {scsNoCap, fCSSdump, "", make([]string, 1, 10), "([]string) (len=1) {\n(string) \"\"\n}\n"}, + {line(), scsNoPtrAddr, fCSFprint, "", tptr, "<*>{<*>{}}"}, + {line(), scsNoPtrAddr, fCSSdump, "", tptr, "(*spew_test.ptrTester)({\ns: (*struct {})({\n})\n})\n"}, + {line(), scsNoCap, fCSSdump, "", make([]string, 0, 10), "([]string) {\n}\n"}, + {line(), scsNoCap, fCSSdump, "", make([]string, 1, 10), "([]string) (len=1) {\n(string) \"\"\n}\n"}, + {line(), scsTrailingComma, fCSFdump, "", commaTester{ + slice: []interface{}{ + map[string]int{"one": 1}, + }, + m: map[string]int{"one": 1}, + }, + "(spew_test.commaTester) {\n" + + " slice: ([]interface {}) (len=1 cap=1) {\n" + + " (map[string]int) (len=1) {\n" + + " (string) (len=3) \"one\": (int) 1,\n" + + " },\n" + + " },\n" + + " m: (map[string]int) (len=1) {\n" + + " (string) (len=3) \"one\": (int) 1,\n" + + " },\n" + + "}\n"}, + {line(), scsNoUnexported, fCSSdump, "", tunexp, "(struct { X int; y int }) {\n X: (int) 123,\n}\n"}, + {line(), scsNoUnexported, fCSSprintln, "", tunexp, "{123}\n"}, + {line(), scsNoUnexported, fCSSprintf, "%v", tunexp, "{123}"}, + {line(), scsNoUnexported, fCSSprintf, "%#v", tunexp, "(struct { X int; y int }){X:(int)123}"}, + {line(), scsQuotes, fCSSdump, "", ts, "(spew_test.stringer) (len=4) \"stringer test\"\n"}, + {line(), scsQuotes, fCSSprintln, "", ts, "\"stringer test\"\n"}, + {line(), scsQuotes, fCSSprintf, "%v", ts, `"stringer test"`}, + {line(), scsQuotes, fCSSprintf, "%#v", ts, `(spew_test.stringer)"stringer test"`}, + {line(), scsClean, fCSSdump, "", make([]string, 0, 10), "[]\n"}, + {line(), scsClean, fCSSdump, "", make([]string, 2, 10), "[\n \"\",\n \"\"\n]\n"}, + {line(), scsClean, fCSSprintln, "", make([]int, 2, 10), "[0,0]\n"}, + {line(), scsClean, fCSSprintf, "%v", make([]int, 2, 10), "[0,0]"}, + {line(), scsClean, fCSSprintf, "%#v", make([]int, 2, 10), "([]int)[0,0]"}, + {line(), scsClean, fCSSprintln, "", make([]string, 1, 10), "[\"\"]\n"}, + {line(), scsClean, fCSSprintf, "%v", make([]string, 1, 10), `[""]`}, + {line(), scsClean, fCSSprintf, "%#v", make([]string, 1, 10), `([]string)[""]`}, + {line(), scsClean, fCSSdump, "", TestSpew, + fmt.Sprintf("spew_test.TestSpew[spew_test.go:%d]\n", funcLine(reflect.ValueOf(TestSpew).Pointer()))}, + {line(), scsClean, fCSSprintln, "", TestSpew, + fmt.Sprintf("spew_test.TestSpew[spew_test.go:%d]\n", funcLine(reflect.ValueOf(TestSpew).Pointer()))}, + {line(), scsClean, fCSSprintf, "%v", TestSpew, + fmt.Sprintf("spew_test.TestSpew[spew_test.go:%d]", funcLine(reflect.ValueOf(TestSpew).Pointer()))}, + {line(), scsClean, fCSSprintf, "%#v", TestSpew, + fmt.Sprintf("(func(*testing.T))spew_test.TestSpew[spew_test.go:%d]", funcLine(reflect.ValueOf(TestSpew).Pointer()))}, + {line(), scsClean, fCSSprintln, "", tfn, + fmt.Sprintf("spew_test.initSpewTests.func1[spew_test.go:%d]\n", funcLine(reflect.ValueOf(tfn).Pointer()))}, + {line(), scsClean, fCSSprintf, "%v", tfn, + fmt.Sprintf("spew_test.initSpewTests.func1[spew_test.go:%d]", funcLine(reflect.ValueOf(tfn).Pointer()))}, + {line(), scsClean, fCSSprintf, "%#v", tfn, + fmt.Sprintf("(func())spew_test.initSpewTests.func1[spew_test.go:%d]", funcLine(reflect.ValueOf(tfn).Pointer()))}, } } +func funcLine(p uintptr) int { + fn := runtime.FuncForPC(p) + if fn == nil { + return -1 + } + _, line := fn.FileLine(p) + return line +} + // TestSpew executes all of the tests described by spewTests. func TestSpew(t *testing.T) { initSpewTests() t.Logf("Running %d tests", len(spewTests)) - for i, test := range spewTests { + for _, test := range spewTests { buf := new(bytes.Buffer) switch test.f { case fCSFdump: @@ -229,7 +307,7 @@ func TestSpew(t *testing.T) { case fCSPrint: b, err := redirStdout(func() { test.cs.Print(test.in) }) if err != nil { - t.Errorf("%v #%d %v", test.f, i, err) + t.Errorf("line %s: %v %v", test.line, test.f, err) continue } buf.Write(b) @@ -237,7 +315,7 @@ func TestSpew(t *testing.T) { case fCSPrintln: b, err := redirStdout(func() { test.cs.Println(test.in) }) if err != nil { - t.Errorf("%v #%d %v", test.f, i, err) + t.Errorf("line %s: %v %v", test.line, test.f, err) continue } buf.Write(b) @@ -278,7 +356,7 @@ func TestSpew(t *testing.T) { case fPrint: b, err := redirStdout(func() { spew.Print(test.in) }) if err != nil { - t.Errorf("%v #%d %v", test.f, i, err) + t.Errorf("line %s: %v %v", test.line, test.f, err) continue } buf.Write(b) @@ -286,7 +364,7 @@ func TestSpew(t *testing.T) { case fPrintln: b, err := redirStdout(func() { spew.Println(test.in) }) if err != nil { - t.Errorf("%v #%d %v", test.f, i, err) + t.Errorf("line %s: %v %v", test.line, test.f, err) continue } buf.Write(b) @@ -308,12 +386,16 @@ func TestSpew(t *testing.T) { buf.WriteString(str) default: - t.Errorf("%v #%d unrecognized function", test.f, i) + t.Errorf("line %s: %v unrecognized function", test.line, test.f) continue } s := buf.String() if test.want != s { - t.Errorf("ConfigState #%d\n got: %s want: %s", i, s, test.want) + nl := "" + if !strings.HasSuffix(s, "\n") { + nl = "\n" + } + t.Errorf("testcase on line %s:\n got: %s%swant: %s", test.line, s, nl, test.want) continue } }