Add full suite of tests for Formatter.
This commit is contained in:
parent
73b25df0f5
commit
34805dbdb5
|
@ -0,0 +1,807 @@
|
|||
/*
|
||||
* Copyright (c) 2013 Dave Collins <dave@davec.name>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
Test Summary:
|
||||
NOTE: For each test, a nil pointer, a single pointer and double pointer to the
|
||||
base test element are also tested to ensure proper indirection across all types.
|
||||
|
||||
- Max int8, int16, int32, int64, int
|
||||
- Max uint8, uint16, uint32, uint64, uint
|
||||
- Boolean true and false
|
||||
- Standard complex64 and complex128
|
||||
- Array containing standard ints
|
||||
- Array containing type with custom formatter on pointer receiver only
|
||||
- Slice containing standard float32 values
|
||||
- Slice containing type with custom formatter on pointer receiver only
|
||||
- Standard string
|
||||
- Nil interface
|
||||
- Map with string keys and int vals
|
||||
- Map with custom formatter type on pointer receiver only keys and vals
|
||||
- Map with interface keys and values
|
||||
- Struct with primitives
|
||||
- Struct that contains another struct
|
||||
- Struct that contains custom type with Stringer pointer interface via both
|
||||
exported and unexported fields
|
||||
- Uintptr to 0 (null pointer)
|
||||
- Uintptr address of real variable
|
||||
- Unsafe.Pointer to 0 (null pointer)
|
||||
- Unsafe.Pointer to address of real variable
|
||||
- Nil channel
|
||||
- Standard int channel
|
||||
- Function with no params and no returns
|
||||
- Function with param and no returns
|
||||
- Function with multiple params and multiple returns
|
||||
- Struct that is circular through self referencing
|
||||
- Structs that are circular through cross referencing
|
||||
- Structs that are indirectly circular
|
||||
*/
|
||||
|
||||
package spew_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"testing"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// formatterTest is used to describe a test to be perfomed against NewFormatter.
|
||||
type formatterTest struct {
|
||||
format string
|
||||
in interface{}
|
||||
want string
|
||||
}
|
||||
|
||||
// formatterTests houses all of the tests to be performed against NewFormatter.
|
||||
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{}, want string) {
|
||||
test := formatterTest{format, in, want}
|
||||
formatterTests = append(formatterTests, test)
|
||||
}
|
||||
|
||||
func addIntFormatterTests() {
|
||||
// Max int8.
|
||||
v := int8(127)
|
||||
nv := (*int8)(nil)
|
||||
pv := &v
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vs := "127"
|
||||
addFormatterTest("%v", v, vs)
|
||||
addFormatterTest("%v", pv, "<*>"+vs)
|
||||
addFormatterTest("%v", &pv, "<**>"+vs)
|
||||
addFormatterTest("%v", nv, "<nil>")
|
||||
addFormatterTest("%+v", v, vs)
|
||||
addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
|
||||
addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
|
||||
addFormatterTest("%+v", nv, "<nil>")
|
||||
|
||||
// Max int16.
|
||||
v2 := int16(32767)
|
||||
nv2 := (*int16)(nil)
|
||||
pv2 := &v2
|
||||
v2Addr := fmt.Sprintf("%p", pv2)
|
||||
pv2Addr := fmt.Sprintf("%p", &pv2)
|
||||
v2s := "32767"
|
||||
addFormatterTest("%v", v2, v2s)
|
||||
addFormatterTest("%v", pv2, "<*>"+v2s)
|
||||
addFormatterTest("%v", &pv2, "<**>"+v2s)
|
||||
addFormatterTest("%v", nv2, "<nil>")
|
||||
addFormatterTest("%+v", v2, v2s)
|
||||
addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s)
|
||||
addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s)
|
||||
addFormatterTest("%+v", nv2, "<nil>")
|
||||
|
||||
// Max int32.
|
||||
v3 := int32(2147483647)
|
||||
nv3 := (*int32)(nil)
|
||||
pv3 := &v3
|
||||
v3Addr := fmt.Sprintf("%p", pv3)
|
||||
pv3Addr := fmt.Sprintf("%p", &pv3)
|
||||
v3s := "2147483647"
|
||||
addFormatterTest("%v", v3, v3s)
|
||||
addFormatterTest("%v", pv3, "<*>"+v3s)
|
||||
addFormatterTest("%v", &pv3, "<**>"+v3s)
|
||||
addFormatterTest("%v", nv3, "<nil>")
|
||||
addFormatterTest("%+v", v3, v3s)
|
||||
addFormatterTest("%+v", pv3, "<*>("+v3Addr+")"+v3s)
|
||||
addFormatterTest("%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s)
|
||||
addFormatterTest("%+v", nv3, "<nil>")
|
||||
|
||||
// Max int64.
|
||||
v4 := int64(9223372036854775807)
|
||||
nv4 := (*int64)(nil)
|
||||
pv4 := &v4
|
||||
v4Addr := fmt.Sprintf("%p", pv4)
|
||||
pv4Addr := fmt.Sprintf("%p", &pv4)
|
||||
v4s := "9223372036854775807"
|
||||
addFormatterTest("%v", v4, v4s)
|
||||
addFormatterTest("%v", pv4, "<*>"+v4s)
|
||||
addFormatterTest("%v", &pv4, "<**>"+v4s)
|
||||
addFormatterTest("%v", nv4, "<nil>")
|
||||
addFormatterTest("%+v", v4, v4s)
|
||||
addFormatterTest("%+v", pv4, "<*>("+v4Addr+")"+v4s)
|
||||
addFormatterTest("%+v", &pv4, "<**>("+pv4Addr+"->"+v4Addr+")"+v4s)
|
||||
addFormatterTest("%+v", nv4, "<nil>")
|
||||
|
||||
// Max int.
|
||||
v5 := int(2147483647)
|
||||
nv5 := (*int)(nil)
|
||||
pv5 := &v5
|
||||
v5Addr := fmt.Sprintf("%p", pv5)
|
||||
pv5Addr := fmt.Sprintf("%p", &pv5)
|
||||
v5s := "2147483647"
|
||||
addFormatterTest("%v", v5, v5s)
|
||||
addFormatterTest("%v", pv5, "<*>"+v5s)
|
||||
addFormatterTest("%v", &pv5, "<**>"+v5s)
|
||||
addFormatterTest("%v", nv5, "<nil>")
|
||||
addFormatterTest("%+v", v5, v5s)
|
||||
addFormatterTest("%+v", pv5, "<*>("+v5Addr+")"+v5s)
|
||||
addFormatterTest("%+v", &pv5, "<**>("+pv5Addr+"->"+v5Addr+")"+v5s)
|
||||
addFormatterTest("%+v", nv5, "<nil>")
|
||||
}
|
||||
|
||||
func addUintFormatterTests() {
|
||||
// Max uint8.
|
||||
v := uint8(255)
|
||||
nv := (*uint8)(nil)
|
||||
pv := &v
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vs := "255"
|
||||
addFormatterTest("%v", v, vs)
|
||||
addFormatterTest("%v", pv, "<*>"+vs)
|
||||
addFormatterTest("%v", &pv, "<**>"+vs)
|
||||
addFormatterTest("%v", nv, "<nil>")
|
||||
addFormatterTest("%+v", v, vs)
|
||||
addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
|
||||
addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
|
||||
addFormatterTest("%+v", nv, "<nil>")
|
||||
|
||||
// Max uint16.
|
||||
v2 := uint16(65535)
|
||||
nv2 := (*uint16)(nil)
|
||||
pv2 := &v2
|
||||
v2Addr := fmt.Sprintf("%p", pv2)
|
||||
pv2Addr := fmt.Sprintf("%p", &pv2)
|
||||
v2s := "65535"
|
||||
addFormatterTest("%v", v2, v2s)
|
||||
addFormatterTest("%v", pv2, "<*>"+v2s)
|
||||
addFormatterTest("%v", &pv2, "<**>"+v2s)
|
||||
addFormatterTest("%v", nv2, "<nil>")
|
||||
addFormatterTest("%+v", v2, v2s)
|
||||
addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s)
|
||||
addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s)
|
||||
addFormatterTest("%+v", nv2, "<nil>")
|
||||
|
||||
// Max uint32.
|
||||
v3 := uint32(4294967295)
|
||||
nv3 := (*uint32)(nil)
|
||||
pv3 := &v3
|
||||
v3Addr := fmt.Sprintf("%p", pv3)
|
||||
pv3Addr := fmt.Sprintf("%p", &pv3)
|
||||
v3s := "4294967295"
|
||||
addFormatterTest("%v", v3, v3s)
|
||||
addFormatterTest("%v", pv3, "<*>"+v3s)
|
||||
addFormatterTest("%v", &pv3, "<**>"+v3s)
|
||||
addFormatterTest("%v", nv3, "<nil>")
|
||||
addFormatterTest("%+v", v3, v3s)
|
||||
addFormatterTest("%+v", pv3, "<*>("+v3Addr+")"+v3s)
|
||||
addFormatterTest("%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s)
|
||||
addFormatterTest("%+v", nv3, "<nil>")
|
||||
|
||||
// Max uint64.
|
||||
v4 := uint64(18446744073709551615)
|
||||
nv4 := (*uint64)(nil)
|
||||
pv4 := &v4
|
||||
v4Addr := fmt.Sprintf("%p", pv4)
|
||||
pv4Addr := fmt.Sprintf("%p", &pv4)
|
||||
v4s := "18446744073709551615"
|
||||
addFormatterTest("%v", v4, v4s)
|
||||
addFormatterTest("%v", pv4, "<*>"+v4s)
|
||||
addFormatterTest("%v", &pv4, "<**>"+v4s)
|
||||
addFormatterTest("%v", nv4, "<nil>")
|
||||
addFormatterTest("%+v", v4, v4s)
|
||||
addFormatterTest("%+v", pv4, "<*>("+v4Addr+")"+v4s)
|
||||
addFormatterTest("%+v", &pv4, "<**>("+pv4Addr+"->"+v4Addr+")"+v4s)
|
||||
addFormatterTest("%+v", nv4, "<nil>")
|
||||
|
||||
// Max uint.
|
||||
v5 := uint(4294967295)
|
||||
nv5 := (*uint)(nil)
|
||||
pv5 := &v5
|
||||
v5Addr := fmt.Sprintf("%p", pv5)
|
||||
pv5Addr := fmt.Sprintf("%p", &pv5)
|
||||
v5s := "4294967295"
|
||||
addFormatterTest("%v", v5, v5s)
|
||||
addFormatterTest("%v", pv5, "<*>"+v5s)
|
||||
addFormatterTest("%v", &pv5, "<**>"+v5s)
|
||||
addFormatterTest("%v", nv5, "<nil>")
|
||||
addFormatterTest("%+v", v5, v5s)
|
||||
addFormatterTest("%+v", pv5, "<*>("+v5Addr+")"+v5s)
|
||||
addFormatterTest("%+v", &pv5, "<**>("+pv5Addr+"->"+v5Addr+")"+v5s)
|
||||
addFormatterTest("%+v", nv5, "<nil>")
|
||||
}
|
||||
|
||||
func addBoolFormatterTests() {
|
||||
// Boolean true.
|
||||
v := bool(true)
|
||||
nv := (*bool)(nil)
|
||||
pv := &v
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vs := "true"
|
||||
addFormatterTest("%v", v, vs)
|
||||
addFormatterTest("%v", pv, "<*>"+vs)
|
||||
addFormatterTest("%v", &pv, "<**>"+vs)
|
||||
addFormatterTest("%v", nv, "<nil>")
|
||||
addFormatterTest("%+v", v, vs)
|
||||
addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
|
||||
addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
|
||||
addFormatterTest("%+v", nv, "<nil>")
|
||||
|
||||
// Boolean false.
|
||||
v2 := bool(false)
|
||||
pv2 := &v2
|
||||
v2Addr := fmt.Sprintf("%p", pv2)
|
||||
pv2Addr := fmt.Sprintf("%p", &pv2)
|
||||
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)
|
||||
}
|
||||
|
||||
func addFloatFormatterTests() {
|
||||
// Standard float32.
|
||||
v := float32(3.1415)
|
||||
nv := (*float32)(nil)
|
||||
pv := &v
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vs := "3.1415"
|
||||
addFormatterTest("%v", v, vs)
|
||||
addFormatterTest("%v", pv, "<*>"+vs)
|
||||
addFormatterTest("%v", &pv, "<**>"+vs)
|
||||
addFormatterTest("%v", nv, "<nil>")
|
||||
addFormatterTest("%+v", v, vs)
|
||||
addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
|
||||
addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
|
||||
addFormatterTest("%+v", nv, "<nil>")
|
||||
|
||||
// Standard float64.
|
||||
v2 := float64(3.1415926)
|
||||
nv2 := (*float64)(nil)
|
||||
pv2 := &v2
|
||||
v2Addr := fmt.Sprintf("%p", pv2)
|
||||
pv2Addr := fmt.Sprintf("%p", &pv2)
|
||||
v2s := "3.1415926"
|
||||
addFormatterTest("%v", v2, v2s)
|
||||
addFormatterTest("%v", pv2, "<*>"+v2s)
|
||||
addFormatterTest("%v", &pv2, "<**>"+v2s)
|
||||
addFormatterTest("%+v", nv2, "<nil>")
|
||||
addFormatterTest("%+v", v2, v2s)
|
||||
addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s)
|
||||
addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s)
|
||||
addFormatterTest("%+v", nv2, "<nil>")
|
||||
}
|
||||
|
||||
func addComplexFormatterTests() {
|
||||
// Standard complex64.
|
||||
v := complex(float32(6), -2)
|
||||
nv := (*complex64)(nil)
|
||||
pv := &v
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vs := "(6-2i)"
|
||||
addFormatterTest("%v", v, vs)
|
||||
addFormatterTest("%v", pv, "<*>"+vs)
|
||||
addFormatterTest("%v", &pv, "<**>"+vs)
|
||||
addFormatterTest("%+v", nv, "<nil>")
|
||||
addFormatterTest("%+v", v, vs)
|
||||
addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
|
||||
addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
|
||||
addFormatterTest("%+v", nv, "<nil>")
|
||||
|
||||
// Standard complex128.
|
||||
v2 := complex(float64(-6), 2)
|
||||
nv2 := (*complex128)(nil)
|
||||
pv2 := &v2
|
||||
v2Addr := fmt.Sprintf("%p", pv2)
|
||||
pv2Addr := fmt.Sprintf("%p", &pv2)
|
||||
v2s := "(-6+2i)"
|
||||
addFormatterTest("%v", v2, v2s)
|
||||
addFormatterTest("%v", pv2, "<*>"+v2s)
|
||||
addFormatterTest("%v", &pv2, "<**>"+v2s)
|
||||
addFormatterTest("%+v", nv2, "<nil>")
|
||||
addFormatterTest("%+v", v2, v2s)
|
||||
addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s)
|
||||
addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s)
|
||||
addFormatterTest("%+v", nv2, "<nil>")
|
||||
}
|
||||
|
||||
func addArrayFormatterTests() {
|
||||
// Array containing standard ints.
|
||||
v := [3]int{1, 2, 3}
|
||||
nv := (*[3]int)(nil)
|
||||
pv := &v
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vs := "[1 2 3]"
|
||||
addFormatterTest("%v", v, vs)
|
||||
addFormatterTest("%v", pv, "<*>"+vs)
|
||||
addFormatterTest("%v", &pv, "<**>"+vs)
|
||||
addFormatterTest("%+v", nv, "<nil>")
|
||||
addFormatterTest("%+v", v, vs)
|
||||
addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
|
||||
addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
|
||||
addFormatterTest("%+v", nv, "<nil>")
|
||||
|
||||
// Array containing type with custom formatter on pointer receiver only.
|
||||
v2 := [3]pstringer{"1", "2", "3"}
|
||||
nv2 := (*[3]pstringer)(nil)
|
||||
pv2 := &v2
|
||||
v2Addr := fmt.Sprintf("%p", pv2)
|
||||
pv2Addr := fmt.Sprintf("%p", &pv2)
|
||||
v2s := "[stringer 1 stringer 2 stringer 3]"
|
||||
addFormatterTest("%v", v2, v2s)
|
||||
addFormatterTest("%v", pv2, "<*>"+v2s)
|
||||
addFormatterTest("%v", &pv2, "<**>"+v2s)
|
||||
addFormatterTest("%+v", nv2, "<nil>")
|
||||
addFormatterTest("%+v", v2, v2s)
|
||||
addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s)
|
||||
addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s)
|
||||
addFormatterTest("%+v", nv2, "<nil>")
|
||||
}
|
||||
|
||||
func addSliceFormatterTests() {
|
||||
// Slice containing standard float32 values.
|
||||
v := []float32{3.14, 6.28, 12.56}
|
||||
nv := (*[]float32)(nil)
|
||||
pv := &v
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vs := "[3.14 6.28 12.56]"
|
||||
addFormatterTest("%v", v, vs)
|
||||
addFormatterTest("%v", pv, "<*>"+vs)
|
||||
addFormatterTest("%v", &pv, "<**>"+vs)
|
||||
addFormatterTest("%+v", nv, "<nil>")
|
||||
addFormatterTest("%+v", v, vs)
|
||||
addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
|
||||
addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
|
||||
addFormatterTest("%+v", nv, "<nil>")
|
||||
|
||||
// Slice containing type with custom formatter on pointer receiver only.
|
||||
v2 := []pstringer{"1", "2", "3"}
|
||||
nv2 := (*[]pstringer)(nil)
|
||||
pv2 := &v2
|
||||
v2Addr := fmt.Sprintf("%p", pv2)
|
||||
pv2Addr := fmt.Sprintf("%p", &pv2)
|
||||
v2s := "[stringer 1 stringer 2 stringer 3]"
|
||||
addFormatterTest("%v", v2, v2s)
|
||||
addFormatterTest("%v", pv2, "<*>"+v2s)
|
||||
addFormatterTest("%v", &pv2, "<**>"+v2s)
|
||||
addFormatterTest("%+v", nv2, "<nil>")
|
||||
addFormatterTest("%+v", v2, v2s)
|
||||
addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s)
|
||||
addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s)
|
||||
addFormatterTest("%+v", nv2, "<nil>")
|
||||
}
|
||||
|
||||
func addStringFormatterTests() {
|
||||
// Standard string.
|
||||
v := "test"
|
||||
nv := (*string)(nil)
|
||||
pv := &v
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vs := "test"
|
||||
addFormatterTest("%v", v, vs)
|
||||
addFormatterTest("%v", pv, "<*>"+vs)
|
||||
addFormatterTest("%v", &pv, "<**>"+vs)
|
||||
addFormatterTest("%+v", nv, "<nil>")
|
||||
addFormatterTest("%+v", v, vs)
|
||||
addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
|
||||
addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
|
||||
addFormatterTest("%+v", nv, "<nil>")
|
||||
}
|
||||
|
||||
func addNilInterfaceFormatterTests() {
|
||||
// Nil interface.
|
||||
var v interface{}
|
||||
nv := (*interface{})(nil)
|
||||
pv := &v
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vs := "<nil>"
|
||||
addFormatterTest("%v", v, vs)
|
||||
addFormatterTest("%v", pv, "<*>"+vs)
|
||||
addFormatterTest("%v", &pv, "<**>"+vs)
|
||||
addFormatterTest("%+v", nv, "<nil>")
|
||||
addFormatterTest("%+v", v, vs)
|
||||
addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
|
||||
addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
|
||||
addFormatterTest("%+v", nv, "<nil>")
|
||||
}
|
||||
|
||||
func addMapFormatterTests() {
|
||||
// Map with string keys and int vals.
|
||||
v := map[string]int{"one": 1}
|
||||
nv := (*map[string]int)(nil)
|
||||
pv := &v
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vs := "map[one:1]"
|
||||
addFormatterTest("%v", v, vs)
|
||||
addFormatterTest("%v", pv, "<*>"+vs)
|
||||
addFormatterTest("%v", &pv, "<**>"+vs)
|
||||
addFormatterTest("%+v", nv, "<nil>")
|
||||
addFormatterTest("%+v", v, vs)
|
||||
addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
|
||||
addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
|
||||
addFormatterTest("%+v", nv, "<nil>")
|
||||
|
||||
// Map with custom formatter type on pointer receiver only keys and vals.
|
||||
v2 := map[pstringer]pstringer{"one": "1"}
|
||||
nv2 := (*map[pstringer]pstringer)(nil)
|
||||
pv2 := &v2
|
||||
v2Addr := fmt.Sprintf("%p", pv2)
|
||||
pv2Addr := fmt.Sprintf("%p", &pv2)
|
||||
v2s := "map[stringer one:stringer 1]"
|
||||
addFormatterTest("%v", v2, v2s)
|
||||
addFormatterTest("%v", pv2, "<*>"+v2s)
|
||||
addFormatterTest("%v", &pv2, "<**>"+v2s)
|
||||
addFormatterTest("%+v", nv2, "<nil>")
|
||||
addFormatterTest("%+v", v2, v2s)
|
||||
addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s)
|
||||
addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s)
|
||||
addFormatterTest("%+v", nv2, "<nil>")
|
||||
|
||||
// Map with interface keys and values.
|
||||
v3 := map[interface{}]interface{}{"one": 1}
|
||||
nv3 := (*map[interface{}]interface{})(nil)
|
||||
pv3 := &v3
|
||||
v3Addr := fmt.Sprintf("%p", pv3)
|
||||
pv3Addr := fmt.Sprintf("%p", &pv3)
|
||||
v3s := "map[one:1]"
|
||||
addFormatterTest("%v", v3, v3s)
|
||||
addFormatterTest("%v", pv3, "<*>"+v3s)
|
||||
addFormatterTest("%v", &pv3, "<**>"+v3s)
|
||||
addFormatterTest("%+v", nv3, "<nil>")
|
||||
addFormatterTest("%+v", v3, v3s)
|
||||
addFormatterTest("%+v", pv3, "<*>("+v3Addr+")"+v3s)
|
||||
addFormatterTest("%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s)
|
||||
addFormatterTest("%+v", nv3, "<nil>")
|
||||
}
|
||||
|
||||
func addStructFormatterTests() {
|
||||
// Struct with primitives.
|
||||
type s1 struct {
|
||||
a int8
|
||||
b uint8
|
||||
}
|
||||
v := s1{127, 255}
|
||||
nv := (*s1)(nil)
|
||||
pv := &v
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vs := "{127 255}"
|
||||
vs2 := "{a:127 b:255}"
|
||||
addFormatterTest("%v", v, vs)
|
||||
addFormatterTest("%v", pv, "<*>"+vs)
|
||||
addFormatterTest("%v", &pv, "<**>"+vs)
|
||||
addFormatterTest("%+v", nv, "<nil>")
|
||||
addFormatterTest("%+v", v, vs2)
|
||||
addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs2)
|
||||
addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs2)
|
||||
addFormatterTest("%+v", nv, "<nil>")
|
||||
|
||||
// Struct that contains another struct.
|
||||
type s2 struct {
|
||||
s1 s1
|
||||
b bool
|
||||
}
|
||||
v2 := s2{s1{127, 255}, true}
|
||||
nv2 := (*s2)(nil)
|
||||
pv2 := &v2
|
||||
v2Addr := fmt.Sprintf("%p", pv2)
|
||||
pv2Addr := fmt.Sprintf("%p", &pv2)
|
||||
v2s := "{{127 255} true}"
|
||||
v2s2 := "{s1:{a:127 b:255} b:true}"
|
||||
addFormatterTest("%v", v2, v2s)
|
||||
addFormatterTest("%v", pv2, "<*>"+v2s)
|
||||
addFormatterTest("%v", &pv2, "<**>"+v2s)
|
||||
addFormatterTest("%+v", nv2, "<nil>")
|
||||
addFormatterTest("%+v", v2, v2s2)
|
||||
addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s2)
|
||||
addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s2)
|
||||
addFormatterTest("%+v", nv2, "<nil>")
|
||||
|
||||
// Struct that contains custom type with Stringer pointer interface via both
|
||||
// exported and unexported fields.
|
||||
type s3 struct {
|
||||
s pstringer
|
||||
S pstringer
|
||||
}
|
||||
v3 := s3{"test", "test2"}
|
||||
nv3 := (*s3)(nil)
|
||||
pv3 := &v3
|
||||
v3Addr := fmt.Sprintf("%p", pv3)
|
||||
pv3Addr := fmt.Sprintf("%p", &pv3)
|
||||
v3s := "{stringer test stringer test2}"
|
||||
v3s2 := "{s:stringer test S:stringer test2}"
|
||||
addFormatterTest("%v", v3, v3s)
|
||||
addFormatterTest("%v", pv3, "<*>"+v3s)
|
||||
addFormatterTest("%v", &pv3, "<**>"+v3s)
|
||||
addFormatterTest("%+v", nv3, "<nil>")
|
||||
addFormatterTest("%+v", v3, v3s2)
|
||||
addFormatterTest("%+v", pv3, "<*>("+v3Addr+")"+v3s2)
|
||||
addFormatterTest("%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s2)
|
||||
addFormatterTest("%+v", nv3, "<nil>")
|
||||
}
|
||||
|
||||
func addUintptrFormatterTests() {
|
||||
// Null pointer.
|
||||
v := uintptr(0)
|
||||
nv := (*uintptr)(nil)
|
||||
pv := &v
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vs := "<nil>"
|
||||
addFormatterTest("%v", v, vs)
|
||||
addFormatterTest("%v", pv, "<*>"+vs)
|
||||
addFormatterTest("%v", &pv, "<**>"+vs)
|
||||
addFormatterTest("%+v", nv, "<nil>")
|
||||
addFormatterTest("%+v", v, vs)
|
||||
addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
|
||||
addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
|
||||
addFormatterTest("%+v", nv, "<nil>")
|
||||
|
||||
// Address of real variable.
|
||||
i := 1
|
||||
v2 := uintptr(unsafe.Pointer(&i))
|
||||
pv2 := &v2
|
||||
v2Addr := fmt.Sprintf("%p", pv2)
|
||||
pv2Addr := fmt.Sprintf("%p", &pv2)
|
||||
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)
|
||||
}
|
||||
|
||||
func addUnsafePointerFormatterTests() {
|
||||
// Null pointer.
|
||||
v := unsafe.Pointer(uintptr(0))
|
||||
nv := (*unsafe.Pointer)(nil)
|
||||
pv := &v
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vs := "<nil>"
|
||||
addFormatterTest("%v", v, vs)
|
||||
addFormatterTest("%v", pv, "<*>"+vs)
|
||||
addFormatterTest("%v", &pv, "<**>"+vs)
|
||||
addFormatterTest("%+v", nv, "<nil>")
|
||||
addFormatterTest("%+v", v, vs)
|
||||
addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
|
||||
addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
|
||||
addFormatterTest("%+v", nv, "<nil>")
|
||||
|
||||
// Address of real variable.
|
||||
i := 1
|
||||
v2 := unsafe.Pointer(&i)
|
||||
pv2 := &v2
|
||||
v2Addr := fmt.Sprintf("%p", pv2)
|
||||
pv2Addr := fmt.Sprintf("%p", &pv2)
|
||||
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)
|
||||
}
|
||||
|
||||
func addChanFormatterTests() {
|
||||
// Nil channel.
|
||||
var v chan int
|
||||
pv := &v
|
||||
nv := (*chan int)(nil)
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vs := "<nil>"
|
||||
addFormatterTest("%v", v, vs)
|
||||
addFormatterTest("%v", pv, "<*>"+vs)
|
||||
addFormatterTest("%v", &pv, "<**>"+vs)
|
||||
addFormatterTest("%+v", nv, "<nil>")
|
||||
addFormatterTest("%+v", v, vs)
|
||||
addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
|
||||
addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
|
||||
addFormatterTest("%+v", nv, "<nil>")
|
||||
|
||||
// Real channel.
|
||||
v2 := make(chan int)
|
||||
pv2 := &v2
|
||||
v2Addr := fmt.Sprintf("%p", pv2)
|
||||
pv2Addr := fmt.Sprintf("%p", &pv2)
|
||||
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)
|
||||
}
|
||||
|
||||
func addFuncFormatterTests() {
|
||||
// Function with no params and no returns.
|
||||
v := addIntFormatterTests
|
||||
nv := (*func())(nil)
|
||||
pv := &v
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vs := fmt.Sprintf("%p", v)
|
||||
addFormatterTest("%v", v, vs)
|
||||
addFormatterTest("%v", pv, "<*>"+vs)
|
||||
addFormatterTest("%v", &pv, "<**>"+vs)
|
||||
addFormatterTest("%+v", nv, "<nil>")
|
||||
addFormatterTest("%+v", v, vs)
|
||||
addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
|
||||
addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
|
||||
addFormatterTest("%+v", nv, "<nil>")
|
||||
|
||||
// Function with param and no returns.
|
||||
v2 := TestFormatter
|
||||
nv2 := (*func(*testing.T))(nil)
|
||||
pv2 := &v2
|
||||
v2Addr := fmt.Sprintf("%p", pv2)
|
||||
pv2Addr := fmt.Sprintf("%p", &pv2)
|
||||
v2s := fmt.Sprintf("%p", v2)
|
||||
addFormatterTest("%v", v2, v2s)
|
||||
addFormatterTest("%v", pv2, "<*>"+v2s)
|
||||
addFormatterTest("%v", &pv2, "<**>"+v2s)
|
||||
addFormatterTest("%+v", nv2, "<nil>")
|
||||
addFormatterTest("%+v", v2, v2s)
|
||||
addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s)
|
||||
addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s)
|
||||
addFormatterTest("%+v", nv2, "<nil>")
|
||||
|
||||
// Function with multiple params and multiple returns.
|
||||
var v3 = func(i int, s string) (b bool, err error) {
|
||||
return true, nil
|
||||
}
|
||||
nv3 := (*func(int, string) (bool, error))(nil)
|
||||
pv3 := &v3
|
||||
v3Addr := fmt.Sprintf("%p", pv3)
|
||||
pv3Addr := fmt.Sprintf("%p", &pv3)
|
||||
v3s := fmt.Sprintf("%p", v3)
|
||||
addFormatterTest("%v", v3, v3s)
|
||||
addFormatterTest("%v", pv3, "<*>"+v3s)
|
||||
addFormatterTest("%v", &pv3, "<**>"+v3s)
|
||||
addFormatterTest("%+v", nv3, "<nil>")
|
||||
addFormatterTest("%+v", v3, v3s)
|
||||
addFormatterTest("%+v", pv3, "<*>("+v3Addr+")"+v3s)
|
||||
addFormatterTest("%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s)
|
||||
addFormatterTest("%+v", nv3, "<nil>")
|
||||
}
|
||||
|
||||
func addCircularFormatterTests() {
|
||||
// Struct that is circular through self referencing.
|
||||
type circular struct {
|
||||
c *circular
|
||||
}
|
||||
v := circular{nil}
|
||||
v.c = &v
|
||||
pv := &v
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vs := "{<*>{<*><shown>}}"
|
||||
vs2 := "{<*><shown>}"
|
||||
vs3 := "{c:<*>(" + vAddr + "){c:<*>(" + vAddr + ")<shown>}}"
|
||||
vs4 := "{c:<*>(" + vAddr + ")<shown>}"
|
||||
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)
|
||||
|
||||
// Structs that are circular through cross referencing.
|
||||
v2 := xref1{nil}
|
||||
ts2 := xref2{&v2}
|
||||
v2.ps2 = &ts2
|
||||
pv2 := &v2
|
||||
ts2Addr := fmt.Sprintf("%p", &ts2)
|
||||
v2Addr := fmt.Sprintf("%p", pv2)
|
||||
pv2Addr := fmt.Sprintf("%p", &pv2)
|
||||
v2s := "{<*>{<*>{<*><shown>}}}"
|
||||
v2s2 := "{<*>{<*><shown>}}"
|
||||
v2s3 := "{ps2:<*>(" + ts2Addr + "){ps1:<*>(" + v2Addr + "){ps2:<*>(" +
|
||||
ts2Addr + ")<shown>}}}"
|
||||
v2s4 := "{ps2:<*>(" + ts2Addr + "){ps1:<*>(" + v2Addr + ")<shown>}}"
|
||||
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)
|
||||
|
||||
// Structs that are indirectly circular.
|
||||
v3 := indirCir1{nil}
|
||||
tic2 := indirCir2{nil}
|
||||
tic3 := indirCir3{&v3}
|
||||
tic2.ps3 = &tic3
|
||||
v3.ps2 = &tic2
|
||||
pv3 := &v3
|
||||
tic2Addr := fmt.Sprintf("%p", &tic2)
|
||||
tic3Addr := fmt.Sprintf("%p", &tic3)
|
||||
v3Addr := fmt.Sprintf("%p", pv3)
|
||||
pv3Addr := fmt.Sprintf("%p", &pv3)
|
||||
v3s := "{<*>{<*>{<*>{<*><shown>}}}}"
|
||||
v3s2 := "{<*>{<*>{<*><shown>}}}"
|
||||
v3s3 := "{ps2:<*>(" + tic2Addr + "){ps3:<*>(" + tic3Addr + "){ps1:<*>(" +
|
||||
v3Addr + "){ps2:<*>(" + tic2Addr + ")<shown>}}}}"
|
||||
v3s4 := "{ps2:<*>(" + tic2Addr + "){ps3:<*>(" + tic3Addr + "){ps1:<*>(" +
|
||||
v3Addr + ")<shown>}}}"
|
||||
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)
|
||||
}
|
||||
|
||||
// TestFormatter executes all of the tests described by formatterTests.
|
||||
func TestFormatter(t *testing.T) {
|
||||
// Setup tests.
|
||||
addIntFormatterTests()
|
||||
addUintFormatterTests()
|
||||
addBoolFormatterTests()
|
||||
addFloatFormatterTests()
|
||||
addComplexFormatterTests()
|
||||
addArrayFormatterTests()
|
||||
addSliceFormatterTests()
|
||||
addStringFormatterTests()
|
||||
addNilInterfaceFormatterTests()
|
||||
addMapFormatterTests()
|
||||
addStructFormatterTests()
|
||||
addUintptrFormatterTests()
|
||||
addUnsafePointerFormatterTests()
|
||||
addChanFormatterTests()
|
||||
addFuncFormatterTests()
|
||||
addCircularFormatterTests()
|
||||
|
||||
t.Logf("Running %d tests", len(formatterTests))
|
||||
for i, test := range formatterTests {
|
||||
buf := new(bytes.Buffer)
|
||||
spew.Fprintf(buf, test.format, test.in)
|
||||
s := buf.String()
|
||||
if test.want != s {
|
||||
t.Errorf("Formatter #%d format: %s got: %s want: %s", i,
|
||||
test.format, s, test.want)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue