refactor: use reflect.TypeFor instead of reflect.TypeOf and improve related tests (#2101)

* refactor: using reflect.TypeFor

Signed-off-by: suranmiao <solsui@outlook.com>

* refactor: remove unused reflect.TypeFor calls and improve test assertions

* refactor: simplify TestSetup by removing reflect.TypeFor

* test: enhance test assertions and improve parallel execution in TestSetup

---------

Signed-off-by: suranmiao <solsui@outlook.com>
Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io>
This commit is contained in:
suranmiao
2025-12-10 07:54:54 +08:00
committed by GitHub
parent 8260aad9fd
commit 78382afb14
10 changed files with 75 additions and 123 deletions

View File

@@ -64,8 +64,7 @@ func main() {
wg.Wait() wg.Wait()
log.Println("Done.") log.Println("Done.")
var dummyInterface exchange.IBotExchange totalWrappers := reflect.TypeFor[exchange.IBotExchange]().NumMethod()
totalWrappers := reflect.TypeOf(&dummyInterface).Elem().NumMethod()
log.Println() log.Println()
for name, funcs := range results { for name, funcs := range results {
@@ -89,11 +88,11 @@ func main() {
// error common.ErrNotYetImplemented to verify whether the wrapper function has // error common.ErrNotYetImplemented to verify whether the wrapper function has
// been implemented yet. // been implemented yet.
func testWrappers(e exchange.IBotExchange) ([]string, error) { func testWrappers(e exchange.IBotExchange) ([]string, error) {
iExchange := reflect.TypeOf(&e).Elem() iExchange := reflect.TypeFor[exchange.IBotExchange]()
actualExchange := reflect.ValueOf(e) actualExchange := reflect.ValueOf(e)
errType := reflect.TypeOf(common.ErrNotYetImplemented) errType := reflect.TypeOf(common.ErrNotYetImplemented)
contextParam := reflect.TypeOf((*context.Context)(nil)).Elem() contextParam := reflect.TypeFor[context.Context]()
var funcs []string var funcs []string
for x := range iExchange.NumMethod() { for x := range iExchange.NumMethod() {

View File

@@ -181,7 +181,7 @@ type testCtxKey string
func executeExchangeWrapperTests(ctx context.Context, t *testing.T, exch exchange.IBotExchange, assetParams []assetPair) { func executeExchangeWrapperTests(ctx context.Context, t *testing.T, exch exchange.IBotExchange, assetParams []assetPair) {
t.Helper() t.Helper()
iExchange := reflect.TypeOf(&exch).Elem() iExchange := reflect.TypeFor[exchange.IBotExchange]()
actualExchange := reflect.ValueOf(exch) actualExchange := reflect.ValueOf(exch)
for x := range iExchange.NumMethod() { for x := range iExchange.NumMethod() {
methodName := iExchange.Method(x).Name methodName := iExchange.Method(x).Name
@@ -277,33 +277,33 @@ type MethodArgumentGenerator struct {
} }
var ( var (
currencyPairParam = reflect.TypeOf((*currency.Pair)(nil)).Elem() currencyPairParam = reflect.TypeFor[currency.Pair]()
klineParam = reflect.TypeOf((*kline.Interval)(nil)).Elem() klineParam = reflect.TypeFor[kline.Interval]()
contextParam = reflect.TypeOf((*context.Context)(nil)).Elem() contextParam = reflect.TypeFor[context.Context]()
timeParam = reflect.TypeOf((*time.Time)(nil)).Elem() timeParam = reflect.TypeFor[time.Time]()
codeParam = reflect.TypeOf((*currency.Code)(nil)).Elem() codeParam = reflect.TypeFor[currency.Code]()
currencyPairsParam = reflect.TypeOf((*currency.Pairs)(nil)).Elem() currencyPairsParam = reflect.TypeFor[currency.Pairs]()
withdrawRequestParam = reflect.TypeOf((**withdraw.Request)(nil)).Elem() withdrawRequestParam = reflect.TypeFor[*withdraw.Request]()
stringParam = reflect.TypeOf((*string)(nil)).Elem() stringParam = reflect.TypeFor[string]()
feeBuilderParam = reflect.TypeOf((**exchange.FeeBuilder)(nil)).Elem() feeBuilderParam = reflect.TypeFor[*exchange.FeeBuilder]()
credentialsParam = reflect.TypeOf((**accounts.Credentials)(nil)).Elem() credentialsParam = reflect.TypeFor[*accounts.Credentials]()
orderSideParam = reflect.TypeOf((*order.Side)(nil)).Elem() orderSideParam = reflect.TypeFor[order.Side]()
collateralModeParam = reflect.TypeOf((*collateral.Mode)(nil)).Elem() collateralModeParam = reflect.TypeFor[collateral.Mode]()
marginTypeParam = reflect.TypeOf((*margin.Type)(nil)).Elem() marginTypeParam = reflect.TypeFor[margin.Type]()
int64Param = reflect.TypeOf((*int64)(nil)).Elem() int64Param = reflect.TypeFor[int64]()
float64Param = reflect.TypeOf((*float64)(nil)).Elem() float64Param = reflect.TypeFor[float64]()
// types with asset in params // types with asset in params
assetParam = reflect.TypeOf((*asset.Item)(nil)).Elem() assetParam = reflect.TypeFor[asset.Item]()
orderSubmitParam = reflect.TypeOf((**order.Submit)(nil)).Elem() orderSubmitParam = reflect.TypeFor[*order.Submit]()
orderModifyParam = reflect.TypeOf((**order.Modify)(nil)).Elem() orderModifyParam = reflect.TypeFor[*order.Modify]()
orderCancelParam = reflect.TypeOf((**order.Cancel)(nil)).Elem() orderCancelParam = reflect.TypeFor[*order.Cancel]()
orderCancelsParam = reflect.TypeOf((*[]order.Cancel)(nil)).Elem() orderCancelsParam = reflect.TypeFor[[]order.Cancel]()
getOrdersRequestParam = reflect.TypeOf((**order.MultiOrderRequest)(nil)).Elem() getOrdersRequestParam = reflect.TypeFor[*order.MultiOrderRequest]()
positionChangeRequestParam = reflect.TypeOf((**margin.PositionChangeRequest)(nil)).Elem() positionChangeRequestParam = reflect.TypeFor[*margin.PositionChangeRequest]()
positionSummaryRequestParam = reflect.TypeOf((**futures.PositionSummaryRequest)(nil)).Elem() positionSummaryRequestParam = reflect.TypeFor[*futures.PositionSummaryRequest]()
positionsRequestParam = reflect.TypeOf((**futures.PositionsRequest)(nil)).Elem() positionsRequestParam = reflect.TypeFor[*futures.PositionsRequest]()
latestRateRequest = reflect.TypeOf((**fundingrate.LatestRateRequest)(nil)).Elem() latestRateRequest = reflect.TypeFor[*fundingrate.LatestRateRequest]()
pairKeySliceParam = reflect.TypeOf((*[]key.PairAsset)(nil)).Elem() pairKeySliceParam = reflect.TypeFor[[]key.PairAsset]()
) )
// generateMethodArg determines the argument type and returns a pre-made // generateMethodArg determines the argument type and returns a pre-made

View File

@@ -13,7 +13,6 @@ import (
"net/http/httptest" "net/http/httptest"
"os" "os"
"path/filepath" "path/filepath"
"reflect"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@@ -1530,22 +1529,18 @@ func TestParseEvents(t *testing.T) {
testData[x] = resp testData[x] = resp
} }
v := parseMultipleEvents(testData) v := parseMultipleEvents(testData)
if reflect.TypeOf(v).String() != "*gctrpc.WithdrawalEventsByExchangeResponse" { require.NotNil(t, v, "parseMultipleEvents must not return nil")
t.Fatal("expected type to be *gctrpc.WithdrawalEventsByExchangeResponse") require.Len(t, v.Event, 5, "parseMultipleEvents must return 5 events")
}
if len(testData) < 2 {
t.Fatal("expected at least 2")
}
v = parseSingleEvents(testData[0]) v = parseSingleEvents(testData[0])
if reflect.TypeOf(v).String() != "*gctrpc.WithdrawalEventsByExchangeResponse" { require.NotNil(t, v, "parseSingleEvents must not return nil")
t.Fatal("expected type to be *gctrpc.WithdrawalEventsByExchangeResponse") require.NotEmpty(t, v.Event, "parseSingleEvents must return an event")
} assert.Equal(t, int64(1), v.Event[0].Request.Type, "parseSingleEvents should return an event with the correct request type")
v = parseSingleEvents(testData[1]) v = parseSingleEvents(testData[1])
if v.Event[0].Request.Type != 0 { require.NotNil(t, v, "parseSingleEvents must not return nil")
t.Fatal("Expected second entry in slice to return a Request.Type of Crypto") require.NotEmpty(t, v.Event, "parseSingleEvents must return an event")
} assert.Zero(t, v.Event[0].Request.Type, "parseSingleEvents should return an event with the correct request type")
} }
func TestRPCServerUpsertDataHistoryJob(t *testing.T) { func TestRPCServerUpsertDataHistoryJob(t *testing.T) {

View File

@@ -1084,8 +1084,7 @@ func StringToOrderSide(side string) (Side, error) {
func (s *Side) UnmarshalJSON(data []byte) (err error) { func (s *Side) UnmarshalJSON(data []byte) (err error) {
if !bytes.HasPrefix(data, []byte(`"`)) { if !bytes.HasPrefix(data, []byte(`"`)) {
// Note that we don't need to worry about invalid JSON here, it wouldn't have made it past the deserialiser far // Note that we don't need to worry about invalid JSON here, it wouldn't have made it past the deserialiser far
// TODO: Can use reflect.TypeFor[s]() when it's released, probably 1.21 return &json.UnmarshalTypeError{Value: string(data), Type: reflect.TypeFor[*Side]()}
return &json.UnmarshalTypeError{Value: string(data), Type: reflect.TypeOf(s), Offset: 1}
} }
*s, err = StringToOrderSide(string(data[1 : len(data)-1])) // Remove quotes *s, err = StringToOrderSide(string(data[1 : len(data)-1])) // Remove quotes
return return

View File

@@ -2,7 +2,6 @@ package gct
import ( import (
"os" "os"
"reflect"
"testing" "testing"
"time" "time"
@@ -186,11 +185,7 @@ func TestExchangeOrderSubmit(t *testing.T) {
func TestAllModuleNames(t *testing.T) { func TestAllModuleNames(t *testing.T) {
t.Parallel() t.Parallel()
x := AllModuleNames() require.NotEmpty(t, AllModuleNames(), "AllModuleNames must not return an empty slice")
xType := reflect.TypeOf(x).Kind()
if xType != reflect.Slice {
t.Errorf("AllModuleNames() should return slice instead received: %v", x)
}
} }
func TestExchangeDepositAddress(t *testing.T) { func TestExchangeDepositAddress(t *testing.T) {

View File

@@ -1,18 +1,14 @@
package loader package loader
import ( import (
"reflect"
"testing" "testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
) )
func TestGetModuleMap(t *testing.T) { func TestGetModuleMap(t *testing.T) {
x := GetModuleMap() x := GetModuleMap()
xType := reflect.TypeOf(x).String() require.NotNil(t, x, "GetModuleMap must not return nil")
if xType != "*tengo.ModuleMap" { assert.NotZero(t, x.Len(), "GetModuleMap should return a map with entries")
t.Fatalf("GetModuleMap() should return pointer to ModuleMap instead received: %v", x)
}
if x.Len() == 0 {
t.Fatal("expected GetModuleMap() to contain module results instead received 0 value")
}
} }

View File

@@ -3,7 +3,6 @@ package indicators
import ( import (
"math/rand" "math/rand"
"os" "os"
"reflect"
"testing" "testing"
"time" "time"
@@ -394,42 +393,29 @@ func TestOBV(t *testing.T) {
} }
func TestToFloat64(t *testing.T) { func TestToFloat64(t *testing.T) {
value := 54.0 t.Parallel()
v, err := toFloat64(value) for _, tc := range []struct {
if err != nil { name string
t.Fatal(err) input any
expected float64
expectErr bool
}{
{"float64", 45.67, 45.67, false},
{"int", int(45), 45.0, false},
{"int32", int32(45), 45.0, false},
{"int64", int64(45), 45.0, false},
{"string", "45.67", 0, true},
} {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
result, err := toFloat64(tc.input)
if tc.expectErr {
assert.Error(t, err)
return
} }
if reflect.TypeOf(v).Kind() != reflect.Float64 { require.NoError(t, err)
t.Fatalf("expected toFloat to return kind float64 received: %v", reflect.TypeOf(v).Kind()) assert.Equal(t, tc.expected, result)
} })
v, err = toFloat64(int(value))
if err != nil {
t.Fatal(err)
}
if reflect.TypeOf(v).Kind() != reflect.Float64 {
t.Fatalf("expected toFloat to return kind float64 received: %v", reflect.TypeOf(v).Kind())
}
v, err = toFloat64(int32(value))
if err != nil {
t.Fatal(err)
}
if reflect.TypeOf(v).Kind() != reflect.Float64 {
t.Fatalf("expected toFloat to return kind float64 received: %v", reflect.TypeOf(v).Kind())
}
v, err = toFloat64(int64(value))
if err != nil {
t.Fatal(err)
}
if reflect.TypeOf(v).Kind() != reflect.Float64 {
t.Fatalf("expected toFloat to return kind float64 received: %v", reflect.TypeOf(v).Kind())
}
_, err = toFloat64("54")
if err == nil {
t.Fatalf("attempting to convert a string should fail but test passed")
} }
} }

View File

@@ -1,17 +1,11 @@
package ta package ta
import ( import (
"reflect"
"testing" "testing"
"github.com/stretchr/testify/require"
) )
func TestGetModuleMap(t *testing.T) { func TestGetModuleMap(t *testing.T) {
x := AllModuleNames() require.Len(t, AllModuleNames(), 9, "AllModuleNames must return 9 modules")
xType := reflect.TypeOf(x).Kind()
if xType != reflect.Slice {
t.Fatalf("AllModuleNames() should return slice instead received: %v", x)
}
if len(x) != 9 {
t.Fatalf("unexpected results received expected 9 received: %v", len(x))
}
} }

View File

@@ -4,7 +4,6 @@ import (
"errors" "errors"
"os" "os"
"path/filepath" "path/filepath"
"reflect"
"testing" "testing"
"time" "time"
@@ -33,16 +32,9 @@ func TestNewVM(t *testing.T) {
manager := GctScriptManager{ manager := GctScriptManager{
config: configHelper(true, true, maxTestVirtualMachines), config: configHelper(true, true, maxTestVirtualMachines),
} }
x := manager.New() require.Nil(t, manager.New(), "New must not create a VM when manager not started")
if x != nil {
t.Error("Should not create a VM when manager not started")
}
manager.started = 1 manager.started = 1
x = manager.New() require.NotNil(t, manager.New(), "New must create a VM when manager is started")
xType := reflect.TypeOf(x).String()
if xType != "*vm.VM" {
t.Fatalf("vm.New should return pointer to VM instead received: %v", x)
}
} }
func TestVMLoad(t *testing.T) { func TestVMLoad(t *testing.T) {

View File

@@ -5,7 +5,6 @@ import (
"log" "log"
"os" "os"
"path/filepath" "path/filepath"
"reflect"
"testing" "testing"
objects "github.com/d5/tengo/v2" objects "github.com/d5/tengo/v2"
@@ -72,11 +71,8 @@ func TestMain(m *testing.M) {
} }
func TestSetup(t *testing.T) { func TestSetup(t *testing.T) {
x := Setup() t.Parallel()
xType := reflect.TypeOf(x).String() require.NotNil(t, Setup(), "Setup must not return nil")
if xType != "*gct.Wrapper" {
t.Fatalf("SetupCommunicationManager() should return pointer to Wrapper instead received: %v", x)
}
} }
var ( var (