Add config option AlwaysIncludeTrailingComma, which forces the writing of commas

in arrays/slices/maps. Useful in tests to avoid false positives when diffing.
This commit is contained in:
Alexander Staubo 2016-11-21 13:06:06 -05:00
parent 346938d642
commit 74bd53c438
3 changed files with 41 additions and 15 deletions

View File

@ -76,6 +76,11 @@ type ConfigState struct {
// data structures in tests.
DisableCapacities bool
// AlwaysIncludeTrailingComma specifies whether to always include a trailing
// comma, Go-style. This is useful to avoid false positives when diffing data
// structures in tests.
AlwaysIncludeTrailingComma 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

View File

@ -236,11 +236,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))
}
}
@ -392,11 +388,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--
@ -419,11 +411,7 @@ func (d *dumpState) dump(v reflect.Value) {
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--
@ -448,6 +436,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.AlwaysIncludeTrailingComma {
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{}) {

View File

@ -132,6 +132,7 @@ func initSpewTests() {
scsContinue := &spew.ConfigState{Indent: " ", ContinueOnMethod: true}
scsNoPtrAddr := &spew.ConfigState{DisablePointerAddresses: true}
scsNoCap := &spew.ConfigState{DisableCapacities: true}
scsTrailingComma := &spew.ConfigState{Indent: " ", AlwaysIncludeTrailingComma: true}
// Variables for tests on types which implement Stringer interface with and
// without a pointer receiver.
@ -154,6 +155,12 @@ 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)
@ -203,6 +210,22 @@ func initSpewTests() {
{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"},
{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"},
}
}