Move SpewState methods to ConfigState.
Rather than stuffing a ConfigState instance into a separate SpewState, just add the functionality directly to the ConfigState. This provides simpler syntax for the consumer. One side effect of this change is that, unlike a zero value SpewState, a zero value ConfigState doesn't provide default values which means the Indent field is set to provide no indentation. The consumer is now expected to set the indent to their desired value when declaring an instance of ConfigState. Alternatively, the consumer can call a new function, NewDefaultConfig, which returns a ConfigState with default values, including a default indentation of a single space. For example, to change the indent to a tab, the previous syntax was: ss := new(spew.SpewState) // or var ss spew.SpewState scs := ss.Config() scs.Indent = "\t" scs.Dump(whatever) The new syntax is simply: scs := spew.ConfigState{Indent: "\t"} scs.Dump(whatever)
This commit is contained in:
parent
6026234f2b
commit
13fc9b8d2f
188
spew/config.go
188
spew/config.go
|
@ -16,12 +16,30 @@
|
|||
|
||||
package spew
|
||||
|
||||
// ConfigState is used to describe configuration options used by spew to format
|
||||
// and display values. There is a global instance, Config, that is used to
|
||||
// control all top-level Formatter and Dump functionality. In addition, each
|
||||
// SpewState instance provides access to a unique ConfigState which can be used
|
||||
// to control the configuration of that particular instance.
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
// ConfigState houses the configuration options used by spew to format and
|
||||
// display values. There is a global instance, Config, that is used to control
|
||||
// all top-level Formatter and Dump functionality. Each ConfigState instance
|
||||
// provides methods equivalent to the top-level functions.
|
||||
//
|
||||
// The zero value for ConfigState provides no indentation. You would typically
|
||||
// want to set it to a space or a tab.
|
||||
//
|
||||
// Alternatively, you can use NewDefaultConfig to get a ConfigState instance
|
||||
// with default settings. See the documentation of NewDefaultConfig for default
|
||||
// values.
|
||||
type ConfigState struct {
|
||||
// Indent specifies the string to use for each indentation level. The
|
||||
// global config instance that all top-level functions use set this to a
|
||||
// single space by default. If you would like more indentation, you might
|
||||
// set this to a tab with "\t" or perhaps two spaces with " ".
|
||||
Indent string
|
||||
|
||||
// MaxDepth controls the maximum number of levels to descend into nested
|
||||
// data structures. The default, 0, means there is no limit.
|
||||
//
|
||||
|
@ -30,11 +48,6 @@ type ConfigState struct {
|
|||
// nested data structures.
|
||||
MaxDepth int
|
||||
|
||||
// Indent specifies the string to use for each indentation level. It is
|
||||
// a single space by default. If you would like more indentation, you might
|
||||
// set this to a tab with "\t" or perhaps two spaces with " ".
|
||||
Indent string
|
||||
|
||||
// DisableMethods specifies whether or not error and Stringer interfaces are
|
||||
// invoked for types that implement them.
|
||||
DisableMethods bool
|
||||
|
@ -55,4 +68,157 @@ type ConfigState struct {
|
|||
// The configuration can be changed by modifying the contents of spew.Config.
|
||||
var Config ConfigState = ConfigState{Indent: " "}
|
||||
|
||||
var defaultConfig = ConfigState{Indent: " "}
|
||||
// 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
|
||||
// for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Errorf(format, c.NewFormatter(a), c.NewFormatter(b))
|
||||
func (c *ConfigState) Errorf(format string, a ...interface{}) (err error) {
|
||||
return fmt.Errorf(format, c.convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were
|
||||
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
||||
// the number of bytes written and any write error encountered. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Fprint(w, c.NewFormatter(a), c.NewFormatter(b))
|
||||
func (c *ConfigState) Fprint(w io.Writer, a ...interface{}) (n int, err error) {
|
||||
return fmt.Fprint(w, c.convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were
|
||||
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
||||
// the number of bytes written and any write error encountered. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Fprintf(w, format, c.NewFormatter(a), c.NewFormatter(b))
|
||||
func (c *ConfigState) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
|
||||
return fmt.Fprintf(w, format, c.convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it
|
||||
// passed with a Formatter interface returned by c.NewFormatter. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Fprintln(w, c.NewFormatter(a), c.NewFormatter(b))
|
||||
func (c *ConfigState) Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
|
||||
return fmt.Fprintln(w, c.convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Print is a wrapper for fmt.Print that treats each argument as if it were
|
||||
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
||||
// the number of bytes written and any write error encountered. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Print(c.NewFormatter(a), c.NewFormatter(b))
|
||||
func (c *ConfigState) Print(a ...interface{}) (n int, err error) {
|
||||
return fmt.Print(c.convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Printf is a wrapper for fmt.Printf that treats each argument as if it were
|
||||
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
||||
// the number of bytes written and any write error encountered. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Printf(format, c.NewFormatter(a), c.NewFormatter(b))
|
||||
func (c *ConfigState) Printf(format string, a ...interface{}) (n int, err error) {
|
||||
return fmt.Printf(format, c.convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Println is a wrapper for fmt.Println that treats each argument as if it were
|
||||
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
||||
// the number of bytes written and any write error encountered. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Println(c.NewFormatter(a), c.NewFormatter(b))
|
||||
func (c *ConfigState) Println(a ...interface{}) (n int, err error) {
|
||||
return fmt.Println(c.convertArgs(a)...)
|
||||
}
|
||||
|
||||
/*
|
||||
NewFormatter returns a custom formatter that satisfies the fmt.Formatter
|
||||
interface. As a result, it integrates cleanly with standard fmt package
|
||||
printing functions. The formatter is useful for inline printing of smaller data
|
||||
types similar to the standard %v format specifier.
|
||||
|
||||
The custom formatter only responds to the %v (most compact), %+v (adds pointer
|
||||
addresses), %#v (adds types), and %#+v (adds types and pointer addresses) verb
|
||||
combinations. Any other verbs such as %x and %q will be sent to the the
|
||||
standard fmt package for formatting. In addition, the custom formatter ignores
|
||||
the width and precision arguments (however they will still work on the format
|
||||
specifiers not handled by the custom formatter).
|
||||
|
||||
Typically this function shouldn't be called directly. It is much easier to make
|
||||
use of the custom formatter by calling one of the convenience functions such as
|
||||
c.Printf, c.Println, or c.Printf.
|
||||
*/
|
||||
func (c *ConfigState) NewFormatter(v interface{}) fmt.Formatter {
|
||||
return newFormatter(c, v)
|
||||
}
|
||||
|
||||
// Fdump formats and displays the passed arguments to io.Writer w. It formats
|
||||
// exactly the same as Dump.
|
||||
func (c *ConfigState) Fdump(w io.Writer, a ...interface{}) {
|
||||
fdump(c, w, a...)
|
||||
}
|
||||
|
||||
/*
|
||||
Dump displays the passed parameters to standard out with newlines, customizable
|
||||
indentation, and additional debug information such as complete types and all
|
||||
pointer addresses used to indirect to the final value. It provides the
|
||||
following features over the built-in printing facilities provided by the fmt
|
||||
package:
|
||||
|
||||
* Pointers are dereferenced and followed
|
||||
* Circular data structures are detected and handled properly
|
||||
* Custom Stringer/error interfaces are optionally invoked, including
|
||||
on unexported types
|
||||
* Custom types which only implement the Stringer/error interfaces via
|
||||
a pointer receiver are optionally invoked when passing non-pointer
|
||||
variables
|
||||
|
||||
The configuration options are controlled by modifying the public members
|
||||
of c. See ConfigState for options documentation.
|
||||
|
||||
See Fdump if you would prefer dumping to an arbitrary io.Writer.
|
||||
*/
|
||||
func (c *ConfigState) Dump(a ...interface{}) {
|
||||
fdump(c, os.Stdout, a...)
|
||||
}
|
||||
|
||||
// convertArgs accepts a slice of arguments and returns a slice of the same
|
||||
// length with each argument converted to a spew Formatter interface using
|
||||
// the ConfigState associated with s.
|
||||
func (c *ConfigState) convertArgs(args []interface{}) (formatters []interface{}) {
|
||||
formatters = make([]interface{}, len(args))
|
||||
for index, arg := range args {
|
||||
formatters[index] = newFormatter(c, arg)
|
||||
}
|
||||
return formatters
|
||||
}
|
||||
|
||||
// NewDefaultConfig returns a ConfigState with the following default settings.
|
||||
//
|
||||
// Indent: " "
|
||||
// MaxDepth: 0
|
||||
// DisableMethods: false
|
||||
// DisablePointerMethods: false
|
||||
func NewDefaultConfig() *ConfigState {
|
||||
return &ConfigState{Indent: " "}
|
||||
}
|
||||
|
|
|
@ -65,10 +65,9 @@ Configuration of spew is handled by fields in the ConfigState type. For
|
|||
convenience, all of the top-level functions use a global state available
|
||||
via the spew.Config global.
|
||||
|
||||
It is also possible to create a SpewState instance which provides a unique
|
||||
ConfigState accessible via the Config method. The methods of SpewState are
|
||||
It is also possible to create a ConfigState instance that provides methods
|
||||
equivalent to the top-level functions. This allows concurrent configuration
|
||||
options. See the SpewState documentation for more details.
|
||||
options. See the ConfigState documentation for more details.
|
||||
|
||||
The following configuration options are available:
|
||||
* MaxDepth
|
||||
|
|
|
@ -131,20 +131,16 @@ func ExamplePrintf() {
|
|||
// circular: {1 <*>{1 <*><shown>}}
|
||||
}
|
||||
|
||||
// This example demonstrates how to use a SpewState.
|
||||
func ExampleSpewState() {
|
||||
// A SpewState does not need initialization.
|
||||
ss := new(spew.SpewState) // or var ss spew.SpewState
|
||||
// This example demonstrates how to use a ConfigState.
|
||||
func ExampleConfigState() {
|
||||
// Modify the indent level of the ConfigState only. The global
|
||||
// configuration is not modified.
|
||||
scs := spew.ConfigState{Indent: "\t"}
|
||||
|
||||
// Modify the indent level of the SpewState only. The global configuration
|
||||
// is not modified.
|
||||
ssc := ss.Config()
|
||||
ssc.Indent = "\t"
|
||||
|
||||
// Output using the SpewState instance.
|
||||
// Output using the ConfigState instance.
|
||||
v := map[string]int{"one": 1}
|
||||
ss.Printf("v: %v\n", v)
|
||||
ss.Dump(v)
|
||||
scs.Printf("v: %v\n", v)
|
||||
scs.Dump(v)
|
||||
|
||||
// Output:
|
||||
// v: map[one:1]
|
||||
|
@ -153,27 +149,23 @@ func ExampleSpewState() {
|
|||
// }
|
||||
}
|
||||
|
||||
// This example demonstrates how to use a SpewState.Dump to dump variables to
|
||||
// This example demonstrates how to use ConfigState.Dump to dump variables to
|
||||
// stdout
|
||||
func ExampleSpewState_Dump() {
|
||||
func ExampleConfigState_Dump() {
|
||||
// See the top-level Dump example for details on the types used in this
|
||||
// example.
|
||||
|
||||
// A SpewState does not need initialization.
|
||||
ss := new(spew.SpewState) // or var ss spew.SpewState
|
||||
ss2 := new(spew.SpewState) // or var ss2 spew.SpewState
|
||||
|
||||
// Modify the indent level of the first SpewState only.
|
||||
ssc := ss.Config()
|
||||
ssc.Indent = "\t"
|
||||
// Create two ConfigState instances with different indentation.
|
||||
scs := spew.ConfigState{Indent: "\t"}
|
||||
scs2 := spew.ConfigState{Indent: " "}
|
||||
|
||||
// Setup some sample data structures for the example.
|
||||
bar := Bar{Flag(flagTwo), uintptr(0)}
|
||||
s1 := Foo{bar, map[interface{}]interface{}{"one": true}}
|
||||
|
||||
// Dump using the SpewState instances.
|
||||
ss.Dump(s1)
|
||||
ss2.Dump(s1)
|
||||
// Dump using the ConfigState instances.
|
||||
scs.Dump(s1)
|
||||
scs2.Dump(s1)
|
||||
|
||||
// Output:
|
||||
// (spew_test.Foo) {
|
||||
|
@ -197,26 +189,28 @@ func ExampleSpewState_Dump() {
|
|||
//
|
||||
}
|
||||
|
||||
// This example demonstrates how to use SpewState.Printf to display a variable
|
||||
// This example demonstrates how to use ConfigState.Printf to display a variable
|
||||
// with a format string and inline formatting.
|
||||
func ExampleSpewState_Printf() {
|
||||
func ExampleConfigState_Printf() {
|
||||
// See the top-level Dump example for details on the types used in this
|
||||
// example.
|
||||
|
||||
// A SpewState does not need initialization.
|
||||
ss := new(spew.SpewState) // or var ss spew.SpewState
|
||||
ss2 := new(spew.SpewState) // or var ss2 spew.SpewState
|
||||
// Create two ConfigState instances and modify the method handling of the
|
||||
// first ConfigState only.
|
||||
scs := spew.NewDefaultConfig()
|
||||
scs2 := spew.NewDefaultConfig()
|
||||
scs.DisableMethods = true
|
||||
|
||||
// Modify the method handling of the first SpewState only.
|
||||
ssc := ss.Config()
|
||||
ssc.DisableMethods = true
|
||||
// Alternatively
|
||||
// scs := spew.ConfigState{Indent: " ", DisableMethods: true}
|
||||
// scs2 := spew.ConfigState{Indent: " "}
|
||||
|
||||
// This is of type Flag which implements a Stringer and has raw value 1.
|
||||
f := flagTwo
|
||||
|
||||
// Dump using the SpewState instances.
|
||||
ss.Printf("f: %v\n", f)
|
||||
ss2.Printf("f: %v\n", f)
|
||||
// Dump using the ConfigState instances.
|
||||
scs.Printf("f: %v\n", f)
|
||||
scs2.Printf("f: %v\n", f)
|
||||
|
||||
// Output:
|
||||
// f: 1
|
||||
|
|
177
spew/spew.go
177
spew/spew.go
|
@ -19,7 +19,6 @@ package spew
|
|||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were
|
||||
|
@ -114,179 +113,3 @@ func convertArgs(args []interface{}) (formatters []interface{}) {
|
|||
}
|
||||
return formatters
|
||||
}
|
||||
|
||||
// SpewState provides a context which can have its own configuration options.
|
||||
// The configuration options can be manipulated via the Config method. The
|
||||
// methods of SpewState are equivalent to the top-level functions.
|
||||
//
|
||||
// A SpewState does not need any special initialization, so new(SpewState) or
|
||||
// just declaring a SpewState variable, is sufficient to initialilize a
|
||||
// SpewState using the default configuration options.
|
||||
type SpewState struct {
|
||||
cs *ConfigState
|
||||
}
|
||||
|
||||
// Config returns a pointer to the active ConfigState for the SpewState
|
||||
// instance. Set the fields of the returned structure to the desired
|
||||
// configuration settings for the instance.
|
||||
func (s *SpewState) Config() (cs *ConfigState) {
|
||||
if s.cs == nil {
|
||||
cs := defaultConfig
|
||||
s.cs = &cs
|
||||
}
|
||||
return s.cs
|
||||
}
|
||||
|
||||
// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were
|
||||
// passed with a Formatter interface returned by s.NewFormatter. It returns
|
||||
// the formatted string as a value that satisfies error. See NewFormatter
|
||||
// for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Errorf(format, s.NewFormatter(a), s.NewFormatter(b))
|
||||
func (s *SpewState) Errorf(format string, a ...interface{}) (err error) {
|
||||
return fmt.Errorf(format, s.convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were
|
||||
// passed with a Formatter interface returned by s.NewFormatter. It returns
|
||||
// the number of bytes written and any write error encountered. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Fprint(w, s.NewFormatter(a), s.NewFormatter(b))
|
||||
func (s *SpewState) Fprint(w io.Writer, a ...interface{}) (n int, err error) {
|
||||
return fmt.Fprint(w, s.convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were
|
||||
// passed with a Formatter interface returned by s.NewFormatter. It returns
|
||||
// the number of bytes written and any write error encountered. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Fprintf(w, format, s.NewFormatter(a), s.NewFormatter(b))
|
||||
func (s *SpewState) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
|
||||
return fmt.Fprintf(w, format, s.convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it
|
||||
// passed with a Formatter interface returned by s.NewFormatter. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Fprintln(w, s.NewFormatter(a), s.NewFormatter(b))
|
||||
func (s *SpewState) Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
|
||||
return fmt.Fprintln(w, s.convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Print is a wrapper for fmt.Print that treats each argument as if it were
|
||||
// passed with a Formatter interface returned by s.NewFormatter. It returns
|
||||
// the number of bytes written and any write error encountered. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Print(s.NewFormatter(a), s.NewFormatter(b))
|
||||
func (s *SpewState) Print(a ...interface{}) (n int, err error) {
|
||||
return fmt.Print(s.convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Printf is a wrapper for fmt.Printf that treats each argument as if it were
|
||||
// passed with a Formatter interface returned by s.NewFormatter. It returns
|
||||
// the number of bytes written and any write error encountered. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Printf(format, s.NewFormatter(a), s.NewFormatter(b))
|
||||
func (s *SpewState) Printf(format string, a ...interface{}) (n int, err error) {
|
||||
return fmt.Printf(format, s.convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Println is a wrapper for fmt.Println that treats each argument as if it were
|
||||
// passed with a Formatter interface returned by s.NewFormatter. It returns
|
||||
// the number of bytes written and any write error encountered. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Println(s.NewFormatter(a), s.NewFormatter(b))
|
||||
func (s *SpewState) Println(a ...interface{}) (n int, err error) {
|
||||
return fmt.Println(s.convertArgs(a)...)
|
||||
}
|
||||
|
||||
/*
|
||||
NewFormatter returns a custom formatter that satisfies the fmt.Formatter
|
||||
interface. As a result, it integrates cleanly with standard fmt package
|
||||
printing functions. The formatter is useful for inline printing of smaller data
|
||||
types similar to the standard %v format specifier.
|
||||
|
||||
The custom formatter only responds to the %v (most compact), %+v (adds pointer
|
||||
addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb
|
||||
combinations. Any other verbs such as %x and %q will be sent to the the
|
||||
standard fmt package for formatting. In addition, the custom formatter ignores
|
||||
the width and precision arguments (however they will still work on the format
|
||||
specifiers not handled by the custom formatter).
|
||||
|
||||
Typically this function shouldn't be called directly. It is much easier to make
|
||||
use of the custom formatter by calling one of the convenience functions such as
|
||||
s.Printf, s.Println, or s.Printf.
|
||||
*/
|
||||
func (s *SpewState) NewFormatter(v interface{}) fmt.Formatter {
|
||||
// The Config method creates the config state if needed, so call it instead
|
||||
// of using s.cs directly to ensure the zero value SpewState is sane.
|
||||
return newFormatter(s.Config(), v)
|
||||
}
|
||||
|
||||
// Fdump formats and displays the passed arguments to io.Writer w. It formats
|
||||
// exactly the same as Dump.
|
||||
func (s *SpewState) Fdump(w io.Writer, a ...interface{}) {
|
||||
// The Config method creates the config state if needed, so call it instead
|
||||
// of using s.cs directly to ensure the zero value SpewState is sane.
|
||||
fdump(s.Config(), w, a...)
|
||||
}
|
||||
|
||||
/*
|
||||
Dump displays the passed parameters to standard out with newlines, customizable
|
||||
indentation, and additional debug information such as complete types and all
|
||||
pointer addresses used to indirect to the final value. It provides the
|
||||
following features over the built-in printing facilities provided by the fmt
|
||||
package:
|
||||
|
||||
* Pointers are dereferenced and followed
|
||||
* Circular data structures are detected and handled properly
|
||||
* Custom Stringer/error interfaces are optionally invoked, including
|
||||
on unexported types
|
||||
* Custom types which only implement the Stringer/error interfaces via
|
||||
a pointer receiver are optionally invoked when passing non-pointer
|
||||
variables
|
||||
|
||||
The configuration options are controlled by accessing the ConfigState associated
|
||||
with s via the Config method. See ConfigState for options documentation.
|
||||
|
||||
See Fdump if you would prefer dumping to an arbitrary io.Writer.
|
||||
*/
|
||||
func (s *SpewState) Dump(a ...interface{}) {
|
||||
// The Config method creates the config state if needed, so call it instead
|
||||
// of using s.cs directly to ensure the zero value SpewState is sane.
|
||||
fdump(s.Config(), os.Stdout, a...)
|
||||
}
|
||||
|
||||
// convertArgs accepts a slice of arguments and returns a slice of the same
|
||||
// length with each argument converted to a spew Formatter interface using
|
||||
// the ConfigState associated with s.
|
||||
func (s *SpewState) convertArgs(args []interface{}) (formatters []interface{}) {
|
||||
// The Config method creates the config state if needed, so call it instead
|
||||
// of using s.cs directly to ensure the zero value SpewState is sane.
|
||||
cs := s.Config()
|
||||
formatters = make([]interface{}, len(args))
|
||||
for index, arg := range args {
|
||||
formatters[index] = newFormatter(cs, arg)
|
||||
}
|
||||
return formatters
|
||||
}
|
||||
|
|
|
@ -26,18 +26,18 @@ import (
|
|||
)
|
||||
|
||||
// spewFunc is used to identify which public function of the spew package or
|
||||
// SpewState a test applies to.
|
||||
// ConfigState a test applies to.
|
||||
type spewFunc int
|
||||
|
||||
const (
|
||||
fSSFdump spewFunc = iota
|
||||
fSSFprint
|
||||
fSSFprintf
|
||||
fSSFprintln
|
||||
fSSPrint
|
||||
fSSPrintln
|
||||
fSSErrorf
|
||||
fSSNewFormatter
|
||||
fCSFdump spewFunc = iota
|
||||
fCSFprint
|
||||
fCSFprintf
|
||||
fCSFprintln
|
||||
fCSPrint
|
||||
fCSPrintln
|
||||
fCSErrorf
|
||||
fCSNewFormatter
|
||||
fErrorf
|
||||
fFprint
|
||||
fFprintln
|
||||
|
@ -47,14 +47,14 @@ const (
|
|||
|
||||
// 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",
|
||||
fCSFdump: "ConfigState.Fdump",
|
||||
fCSFprint: "ConfigState.Fprint",
|
||||
fCSFprintf: "ConfigState.Fprintf",
|
||||
fCSFprintln: "ConfigState.Fprintln",
|
||||
fCSPrint: "ConfigState.Print",
|
||||
fCSPrintln: "ConfigState.Println",
|
||||
fCSErrorf: "ConfigState.Errorf",
|
||||
fCSNewFormatter: "ConfigState.NewFormatter",
|
||||
fErrorf: "spew.Errorf",
|
||||
fFprint: "spew.Fprint",
|
||||
fFprintln: "spew.Fprintln",
|
||||
|
@ -70,7 +70,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 SpewState.
|
||||
// functions of the spew package or ConfigState.
|
||||
type spewTest struct {
|
||||
f spewFunc
|
||||
format string
|
||||
|
@ -79,20 +79,20 @@ type spewTest struct {
|
|||
}
|
||||
|
||||
// spewTests houses the tests to be performed against the public functions of
|
||||
// the spew package and SpewState.
|
||||
// the spew package and ConfigState.
|
||||
//
|
||||
// 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"},
|
||||
{fCSFdump, "", int8(127), "(int8) 127\n"},
|
||||
{fCSFprint, "", int16(32767), "32767"},
|
||||
{fCSFprintf, "%v", int32(2147483647), "2147483647"},
|
||||
{fCSFprintln, "", int(2147483647), "2147483647\n"},
|
||||
{fCSPrint, "", int64(9223372036854775807), "9223372036854775807"},
|
||||
{fCSPrintln, "", uint8(255), "255\n"},
|
||||
{fCSErrorf, "%#v", uint16(65535), "(uint16)65535"},
|
||||
{fCSNewFormatter, "%v", uint32(4294967295), "4294967295"},
|
||||
{fErrorf, "%v", uint64(18446744073709551615), "18446744073709551615"},
|
||||
{fFprint, "", float32(3.14), "3.14"},
|
||||
{fFprintln, "", float64(6.28), "6.28\n"},
|
||||
|
@ -121,46 +121,46 @@ func redirStdout(f func()) ([]byte, error) {
|
|||
|
||||
// TestSpew executes all of the tests described by spewTests.
|
||||
func TestSpew(t *testing.T) {
|
||||
ss := new(spew.SpewState)
|
||||
scs := spew.NewDefaultConfig()
|
||||
|
||||
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 fCSFdump:
|
||||
scs.Fdump(buf, test.in)
|
||||
|
||||
case fSSFprint:
|
||||
ss.Fprint(buf, test.in)
|
||||
case fCSFprint:
|
||||
scs.Fprint(buf, test.in)
|
||||
|
||||
case fSSFprintf:
|
||||
ss.Fprintf(buf, test.format, test.in)
|
||||
case fCSFprintf:
|
||||
scs.Fprintf(buf, test.format, test.in)
|
||||
|
||||
case fSSFprintln:
|
||||
ss.Fprintln(buf, test.in)
|
||||
case fCSFprintln:
|
||||
scs.Fprintln(buf, test.in)
|
||||
|
||||
case fSSPrint:
|
||||
b, err := redirStdout(func() { ss.Print(test.in) })
|
||||
case fCSPrint:
|
||||
b, err := redirStdout(func() { scs.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) })
|
||||
case fCSPrintln:
|
||||
b, err := redirStdout(func() { scs.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)
|
||||
case fCSErrorf:
|
||||
err := scs.Errorf(test.format, test.in)
|
||||
buf.WriteString(err.Error())
|
||||
|
||||
case fSSNewFormatter:
|
||||
fmt.Fprintf(buf, test.format, ss.NewFormatter(test.in))
|
||||
case fCSNewFormatter:
|
||||
fmt.Fprintf(buf, test.format, scs.NewFormatter(test.in))
|
||||
|
||||
case fErrorf:
|
||||
err := spew.Errorf(test.format, test.in)
|
||||
|
@ -194,7 +194,7 @@ func TestSpew(t *testing.T) {
|
|||
}
|
||||
s := buf.String()
|
||||
if test.want != s {
|
||||
t.Errorf("SpewState #%d\n got: %s want: %s", i, s, test.want)
|
||||
t.Errorf("ConfigState #%d\n got: %s want: %s", i, s, test.want)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue