From 6026234f2b83bade0c5d18320806c81fd102b53f Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 18 Jan 2013 01:43:32 -0600 Subject: [PATCH] Add tests for public package and SpewState funcs. --- spew/spew_test.go | 201 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 spew/spew_test.go diff --git a/spew/spew_test.go b/spew/spew_test.go new file mode 100644 index 0000000..47557dd --- /dev/null +++ b/spew/spew_test.go @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2013 Dave Collins + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +package spew_test + +import ( + "bytes" + "fmt" + "github.com/davecgh/go-spew/spew" + "io/ioutil" + "os" + "testing" +) + +// spewFunc is used to identify which public function of the spew package or +// SpewState a test applies to. +type spewFunc int + +const ( + fSSFdump spewFunc = iota + fSSFprint + fSSFprintf + fSSFprintln + fSSPrint + fSSPrintln + fSSErrorf + fSSNewFormatter + fErrorf + fFprint + fFprintln + fPrint + fPrintln +) + +// Map of spewFunc values to names for pretty printing. +var spewFuncStrings = map[spewFunc]string{ + fSSFdump: "SpewState.Fdump", + fSSFprint: "SpewState.Fprint", + fSSFprintf: "SpewState.Fprintf", + fSSFprintln: "SpewState.Fprintln", + fSSPrint: "SpewState.Print", + fSSPrintln: "SpewState.Println", + fSSErrorf: "SpewState.Errorf", + fSSNewFormatter: "SpewState.NewFormatter", + fErrorf: "spew.Errorf", + fFprint: "spew.Fprint", + fFprintln: "spew.Fprintln", + fPrint: "spew.Print", + fPrintln: "spew.Println", +} + +func (f spewFunc) String() string { + if s, ok := spewFuncStrings[f]; ok { + return s + } + return fmt.Sprintf("Unknown spewFunc (%d)", int(f)) +} + +// spewTest is used to describe a test to be performed against the public +// functions of the spew package or SpewState. +type spewTest struct { + f spewFunc + format string + in interface{} + want string +} + +// spewTests houses the tests to be performed against the public functions of +// the spew package and SpewState. +// +// These tests are only intended to ensure the public functions are exercised +// and are intentionally not exhaustive of types. The exhaustive type +// tests are handled in the dump and format tests. +var spewTests = []spewTest{ + {fSSFdump, "", int8(127), "(int8) 127\n"}, + {fSSFprint, "", int16(32767), "32767"}, + {fSSFprintf, "%v", int32(2147483647), "2147483647"}, + {fSSFprintln, "", int(2147483647), "2147483647\n"}, + {fSSPrint, "", int64(9223372036854775807), "9223372036854775807"}, + {fSSPrintln, "", uint8(255), "255\n"}, + {fSSErrorf, "%#v", uint16(65535), "(uint16)65535"}, + {fSSNewFormatter, "%v", uint32(4294967295), "4294967295"}, + {fErrorf, "%v", uint64(18446744073709551615), "18446744073709551615"}, + {fFprint, "", float32(3.14), "3.14"}, + {fFprintln, "", float64(6.28), "6.28\n"}, + {fPrint, "", true, "true"}, + {fPrintln, "", false, "false\n"}, +} + +// redirStdout is a helper function to return the standard output from f as a +// byte slice. +func redirStdout(f func()) ([]byte, error) { + tempFile, err := ioutil.TempFile("", "ss-test") + if err != nil { + return nil, err + } + fileName := tempFile.Name() + defer os.Remove(fileName) // Ignore error + + origStdout := os.Stdout + os.Stdout = tempFile + f() + os.Stdout = origStdout + tempFile.Close() + + return ioutil.ReadFile(fileName) +} + +// TestSpew executes all of the tests described by spewTests. +func TestSpew(t *testing.T) { + ss := new(spew.SpewState) + + t.Logf("Running %d tests", len(spewTests)) + for i, test := range spewTests { + buf := new(bytes.Buffer) + switch test.f { + case fSSFdump: + ss.Fdump(buf, test.in) + + case fSSFprint: + ss.Fprint(buf, test.in) + + case fSSFprintf: + ss.Fprintf(buf, test.format, test.in) + + case fSSFprintln: + ss.Fprintln(buf, test.in) + + case fSSPrint: + b, err := redirStdout(func() { ss.Print(test.in) }) + if err != nil { + t.Errorf("%v #%d %v", test.f, i, err) + continue + } + buf.Write(b) + + case fSSPrintln: + b, err := redirStdout(func() { ss.Println(test.in) }) + if err != nil { + t.Errorf("%v #%d %v", test.f, i, err) + continue + } + buf.Write(b) + + case fSSErrorf: + err := ss.Errorf(test.format, test.in) + buf.WriteString(err.Error()) + + case fSSNewFormatter: + fmt.Fprintf(buf, test.format, ss.NewFormatter(test.in)) + + case fErrorf: + err := spew.Errorf(test.format, test.in) + buf.WriteString(err.Error()) + + case fFprint: + spew.Fprint(buf, test.in) + + case fFprintln: + spew.Fprintln(buf, test.in) + + case fPrint: + b, err := redirStdout(func() { spew.Print(test.in) }) + if err != nil { + t.Errorf("%v #%d %v", test.f, i, err) + continue + } + buf.Write(b) + + case fPrintln: + b, err := redirStdout(func() { spew.Println(test.in) }) + if err != nil { + t.Errorf("%v #%d %v", test.f, i, err) + continue + } + buf.Write(b) + + default: + t.Errorf("%v #%d unrecognized function", test.f, i) + continue + } + s := buf.String() + if test.want != s { + t.Errorf("SpewState #%d\n got: %s want: %s", i, s, test.want) + continue + } + } +}