github.com/filecoin-project/specs-actors/v4@v4.0.2/support/mock/exports.go (about)

     1  package mock
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"testing"
     7  
     8  	"github.com/ipfs/go-cid"
     9  )
    10  
    11  func CheckActorExports(t *testing.T, act interface{ Exports() []interface{} }) {
    12  	for i, m := range act.Exports() {
    13  		if i == 0 { // Send is implicit
    14  			continue
    15  		}
    16  
    17  		if m == nil {
    18  			continue
    19  		}
    20  
    21  		t.Run(fmt.Sprintf("method%d-type", i), func(t *testing.T) {
    22  			mrt := Runtime{t: t}
    23  			mrt.verifyExportedMethodType(reflect.ValueOf(m))
    24  		})
    25  
    26  		t.Run(fmt.Sprintf("method%d-unsafe-input", i), func(t *testing.T) {
    27  			paramsType := reflect.ValueOf(m).Type().In(1)
    28  			checkUnsafeInputs(t, paramsType.String(), paramsType)
    29  		})
    30  	}
    31  }
    32  
    33  var tCID = reflect.TypeOf(new(cid.Cid)).Elem()
    34  
    35  func checkUnsafeInputs(t *testing.T, name string, typ reflect.Type) {
    36  	switch typ.Kind() {
    37  	case reflect.Array:
    38  		fallthrough
    39  	case reflect.Slice:
    40  		fallthrough
    41  	case reflect.Map:
    42  		fallthrough
    43  	case reflect.Ptr:
    44  		checkUnsafeInputs(t, name+".elem", typ.Elem())
    45  
    46  	case reflect.Struct:
    47  		if typ == tCID {
    48  			t.Fatal("method has unchecked CID input at ", name)
    49  		}
    50  
    51  		for i := 0; i < typ.NumField(); i++ {
    52  			f := typ.Field(i)
    53  
    54  			if f.Tag.Get("checked") == "true" {
    55  				if f.Type != tCID {
    56  					t.Fatal("expected checked value to be cid.Cid")
    57  				}
    58  
    59  				continue
    60  			}
    61  
    62  			checkUnsafeInputs(t, name+"."+f.Name, f.Type)
    63  		}
    64  
    65  	case reflect.Interface:
    66  		t.Fatal("method has unsafe interface{} input parameter")
    67  	}
    68  }