diff --git a/src/fmt/fmt_test.go b/src/fmt/fmt_test.go index b7f9ccd494d..82daf627717 100644 --- a/src/fmt/fmt_test.go +++ b/src/fmt/fmt_test.go @@ -11,7 +11,6 @@ import ( "io" "math" "reflect" - "runtime" "strings" "testing" "time" @@ -112,6 +111,19 @@ func (p *P) String() string { 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[:] @@ -714,7 +726,6 @@ var fmtTests = []struct { // 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"}, @@ -737,6 +748,54 @@ var fmtTests = []struct { {"%#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, ""}, // unexported function field + {"%v", reflect.ValueOf(U{}.u), ""}, + {"%v", reflect.ValueOf(U{}).Field(0), ""}, + {"%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), ""}, + + // 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"}, @@ -1438,6 +1497,9 @@ var mallocTest = []struct { {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() { @@ -1452,8 +1514,6 @@ func TestCountMallocs(t *testing.T) { 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") }