"io"
"math"
"reflect"
- "runtime"
"strings"
"testing"
"time"
return "String(p)"
}
+// Fn is a function type with a String method.
+type Fn func() int
+
+func (fn Fn) String() string { return "String(fn)" }
+
+var fnValue Fn
+
+// U is a type with two unexported function fields.
+type U struct {
+ u func() string
+ fn Fn
+}
+
var barray = [5]renamedUint8{1, 2, 3, 4, 5}
var bslice = barray[:]
// go syntax
{"%#v", A{1, 2, "a", []int{1, 2}}, `fmt_test.A{i:1, j:0x2, s:"a", x:[]int{1, 2}}`},
{"%#v", new(byte), "(*uint8)(0xPTR)"},
- {"%#v", TestFmtInterface, "(func(*testing.T))(0xPTR)"},
{"%#v", make(chan int), "(chan int)(0xPTR)"},
{"%#v", uint64(1<<64 - 1), "0xffffffffffffffff"},
{"%#v", 1000000000, "1000000000"},
{"%#v", 1.2345678, "1.2345678"},
{"%#v", float32(1.2345678), "1.2345678"},
+ // functions
+ {"%v", TestFmtInterface, "0xPTR"}, // simple function
+ {"%v", reflect.ValueOf(TestFmtInterface), "0xPTR"},
+ {"%v", G.GoString, "0xPTR"}, // method expression
+ {"%v", reflect.ValueOf(G.GoString), "0xPTR"},
+ {"%v", G(23).GoString, "0xPTR"}, // method value
+ {"%v", reflect.ValueOf(G(23).GoString), "0xPTR"},
+ {"%v", reflect.ValueOf(G(23)).Method(0), "0xPTR"},
+ {"%v", Fn.String, "0xPTR"}, // method of function type
+ {"%v", reflect.ValueOf(Fn.String), "0xPTR"},
+ {"%v", fnValue, "String(fn)"}, // variable of function type with String method
+ {"%v", reflect.ValueOf(fnValue), "String(fn)"},
+ {"%v", [1]Fn{fnValue}, "[String(fn)]"}, // array of function type with String method
+ {"%v", reflect.ValueOf([1]Fn{fnValue}), "[String(fn)]"},
+ {"%v", fnValue.String, "0xPTR"}, // method value from function type
+ {"%v", reflect.ValueOf(fnValue.String), "0xPTR"},
+ {"%v", reflect.ValueOf(fnValue).Method(0), "0xPTR"},
+ {"%v", U{}.u, "<nil>"}, // unexported function field
+ {"%v", reflect.ValueOf(U{}.u), "<nil>"},
+ {"%v", reflect.ValueOf(U{}).Field(0), "<nil>"},
+ {"%v", U{fn: fnValue}.fn, "String(fn)"}, // unexported field of function type with String method
+ {"%v", reflect.ValueOf(U{fn: fnValue}.fn), "String(fn)"},
+ {"%v", reflect.ValueOf(U{fn: fnValue}).Field(1), "<nil>"},
+
+ // functions with go syntax
+ {"%#v", TestFmtInterface, "(func(*testing.T))(0xPTR)"}, // simple function
+ {"%#v", reflect.ValueOf(TestFmtInterface), "(func(*testing.T))(0xPTR)"},
+ {"%#v", G.GoString, "(func(fmt_test.G) string)(0xPTR)"}, // method expression
+ {"%#v", reflect.ValueOf(G.GoString), "(func(fmt_test.G) string)(0xPTR)"},
+ {"%#v", G(23).GoString, "(func() string)(0xPTR)"}, // method value
+ {"%#v", reflect.ValueOf(G(23).GoString), "(func() string)(0xPTR)"},
+ {"%#v", reflect.ValueOf(G(23)).Method(0), "(func() string)(0xPTR)"},
+ {"%#v", Fn.String, "(func(fmt_test.Fn) string)(0xPTR)"}, // method of function type
+ {"%#v", reflect.ValueOf(Fn.String), "(func(fmt_test.Fn) string)(0xPTR)"},
+ {"%#v", fnValue, "(fmt_test.Fn)(nil)"}, // variable of function type with String method
+ {"%#v", reflect.ValueOf(fnValue), "(fmt_test.Fn)(nil)"},
+ {"%#v", [1]Fn{fnValue}, "[1]fmt_test.Fn{(fmt_test.Fn)(nil)}"}, // array of function type with String method
+ {"%#v", reflect.ValueOf([1]Fn{fnValue}), "[1]fmt_test.Fn{(fmt_test.Fn)(nil)}"},
+ {"%#v", fnValue.String, "(func() string)(0xPTR)"}, // method value from function type
+ {"%#v", reflect.ValueOf(fnValue.String), "(func() string)(0xPTR)"},
+ {"%#v", reflect.ValueOf(fnValue).Method(0), "(func() string)(0xPTR)"},
+ {"%#v", U{}.u, "(func() string)(nil)"}, // unexported function field
+ {"%#v", reflect.ValueOf(U{}.u), "(func() string)(nil)"},
+ {"%#v", reflect.ValueOf(U{}).Field(0), "(func() string)(nil)"},
+ {"%#v", U{fn: fnValue}.fn, "(fmt_test.Fn)(nil)"}, // unexported field of function type with String method
+ {"%#v", reflect.ValueOf(U{fn: fnValue}.fn), "(fmt_test.Fn)(nil)"},
+ {"%#v", reflect.ValueOf(U{fn: fnValue}).Field(1), "(fmt_test.Fn)(nil)"},
+
// Whole number floats are printed without decimals. See Issue 27634.
{"%#v", 1.0, "1"},
{"%#v", 1000000.0, "1e+06"},
{0, `Fprintf(buf, "%s")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%s", "hello") }},
{0, `Fprintf(buf, "%x")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%x", 7) }},
{0, `Fprintf(buf, "%x")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%x", 1<<16) }},
+ {1, `Fprintf(buf, "%x")`, func() { mallocBuf.Reset(); i := 1 << 16; Fprintf(&mallocBuf, "%x", i) }}, // not constant
+ {4, `Fprintf(buf, "%v")`, func() { mallocBuf.Reset(); s := []int{1, 2}; Fprintf(&mallocBuf, "%v", s) }},
+ {1, `Fprintf(buf, "%v")`, func() { mallocBuf.Reset(); type P struct{ x, y int }; Fprintf(&mallocBuf, "%v", P{1, 2}) }},
{2, `Fprintf(buf, "%80000s")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%80000s", "hello") }}, // large buffer (>64KB)
// If the interface value doesn't need to allocate, amortized allocation overhead should be zero.
{0, `Fprintf(buf, "%x %x %x")`, func() {
switch {
case testing.Short():
t.Skip("skipping malloc count in short mode")
- case runtime.GOMAXPROCS(0) > 1:
- t.Skip("skipping; GOMAXPROCS>1")
case race.Enabled:
t.Skip("skipping malloc count under race detector")
}