github.com/v2pro/plz@v0.0.0-20221028024117-e5f9aec5b631/test/go_above_19.go (about)

     1  //+build go1.9
     2  
     3  package test
     4  
     5  import (
     6  	"github.com/v2pro/plz/reflect2"
     7  	"runtime"
     8  	"testing"
     9  	"sync"
    10  )
    11  
    12  var helpersField reflect2.StructField
    13  var muField reflect2.StructField
    14  
    15  func init() {
    16  	testingType := reflect2.TypeOfPtr((*testing.T)(nil)).Elem()
    17  	structType := testingType.(reflect2.StructType)
    18  	helpersField = structType.FieldByName("helpers")
    19  	muField = structType.FieldByName("mu")
    20  }
    21  
    22  func Helper() {
    23  	t := CurrentT()
    24  	t.Helper()
    25  	mu := muField.Get(t).(*sync.RWMutex)
    26  	mu.Lock()
    27  	defer mu.Unlock()
    28  	helpers := *helpersField.Get(t).(*map[string]struct{})
    29  	helpers[callerName(1)] = struct{}{}
    30  }
    31  
    32  // callerName gives the function name (qualified with a package path)
    33  // for the caller after skip frames (where 0 means the current function).
    34  func callerName(skip int) string {
    35  	// Make room for the skip PC.
    36  	var pc [2]uintptr
    37  	n := runtime.Callers(skip+2, pc[:]) // skip + runtime.Callers + callerName
    38  	if n == 0 {
    39  		panic("testing: zero callers found")
    40  	}
    41  	frames := runtime.CallersFrames(pc[:n])
    42  	frame, _ := frames.Next()
    43  	return frame.Function
    44  }