unitauto

package
v1.1.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 14, 2024 License: Apache-2.0 Imports: 18 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var Addr = ":" + fmt.Sprint(Port)
View Source
var BASE_CLASS_MAP = map[string]any{
	"any":         (any)(nil),
	"interface{}": (interface{})(nil),
	"bool":        false,
	"byte":        byte(0),
	"int":         int(0),
	"int8":        int8(0),
	"int16":       int16(0),
	"int32":       int32(0),
	"int64":       int64(0),
	"uint":        uint(0),
	"uint8":       uint8(0),
	"uint16":      uint16(0),
	"uint32":      uint32(0),
	"uint64":      uint64(0),
	"float32":     float32(0),
	"float64":     float64(0),
	"string":      "",
}
View Source
var CLASS_MAP = map[string]any{
	"any":               (any)(nil),
	"interface{}":       (interface{})(nil),
	"bool":              false,
	"byte":              byte(0),
	"int":               int(0),
	"int8":              int8(0),
	"int16":             int16(0),
	"int32":             int32(0),
	"int64":             int64(0),
	"uint":              uint(0),
	"uint8":             uint8(0),
	"uint16":            uint16(0),
	"uint32":            uint32(0),
	"uint64":            uint64(0),
	"float32":           float32(0),
	"float64":           float64(0),
	"string":            "",
	"[]bool":            []bool{},
	"[]byte":            []byte{},
	"[]int":             []int{},
	"[]int8":            []int8{},
	"[]int16":           []int16{},
	"[]int32":           []int32{},
	"[]int64":           []int64{},
	"[]uint":            []uint{},
	"[]uint8":           []uint8{},
	"[]uint16":          []uint16{},
	"[]uint32":          []uint32{},
	"[]uint64":          []uint64{},
	"[]float32":         []float32{},
	"[]float64":         []float64{},
	"[]string":          []string{},
	"[]any":             []any{},
	"map":               map[any]any{},
	"map[any]any":       map[any]any{},
	"map[string]any":    map[string]any{},
	"map[string]string": map[string]string{},
	"Array":             types.Array{},
	"*Array":            &types.Array{},
	"List":              list.List{},
	"*List":             &list.List{},
	"Map":               types.Map{},
	"*Map":              &types.Map{},
}
View Source
var CODE_SERVER_ERROR = 500
View Source
var CODE_SUCCESS = 200
View Source
var DEFAULT_MODULE_PATH = "github.com/TommyLemon/unitauto-go"
View Source
var DEFAULT_TYPE_VALUE_MAP = map[reflect.Type]any{}
View Source
var Debug = true // 改为 false 不打日志
View Source
var GetArgList = func(req map[string]any, arrKey string) []Argument {
	if req == nil {
		return nil
	}
	var arr = GetArr(req, arrKey)
	var l = len(arr)
	if arr == nil || l <= 0 {
		return nil
	}

	var lst = []Argument{}
	for i := 0; i < l; i++ {
		var item = arr[i]
		var t = reflect.TypeOf(item)
		var ts = t.String()
		if t.Kind() == reflect.Bool || IsNumType(ts) || IsArrType(ts) {
			lst = append(lst, NewArgument("", item))
		} else if t.Kind() == reflect.String {
			var str = item.(string)
			var index = strings.Index(str, ":")
			var typ = ""
			var value = str
			if index >= 0 {
				typ = str[0:index]
				value = str[index+1:]
			}

			lst = append(lst, NewArgument(typ, value))
		} else if t == TYPE_MAP_STRING_ANY {
			var m = item.(map[string]any)
			var agt = Argument{}
			agt.Type = GetStr(m, KEY_AT_TYPE)
			if len(agt.Type) <= 0 {
				agt.Type = GetStr(m, KEY_TYPE)
			}
			agt.Value = m[KEY_VALUE]
			agt.Reuse = GetBool(m, KEY_REUSE)
			agt.Global = GetBool(m, KEY_GLOBAL)
			lst = append(lst, agt)
		} else if t == TYPE_MAP_STRING_INTERFACE {
			var m = item.(map[string]interface{})
			var agt = Argument{}
			agt.Type = GetStr(m, KEY_AT_TYPE)
			if len(agt.Type) <= 0 {
				agt.Type = GetStr(m, KEY_TYPE)
			}
			agt.Value = m[KEY_VALUE]
			agt.Reuse = GetBool(m, KEY_REUSE)
			agt.Global = GetBool(m, KEY_GLOBAL)
			lst = append(lst, agt)
		} else {
			var agt = Argument{}
			tp, err := getType("", item, true)
			if err == nil {
				agt.Type = tp.String()
			} else {
				agt.Type = "any"
			}

			agt.Value = item
			lst = append(lst, agt)
		}
	}

	if len(lst) <= 0 {
		return nil
	}
	return lst
}
View Source
var GetInstance = func(typ reflect.Type, value any, classArgs []Argument, reuse bool) (any, error) {
	return GetInvokeInstance(typ, value, classArgs, reuse)
}

GetInstance 不能在 static 代码块赋值,否则 MethodUtil 子类中 static 代码块对它赋值的代码不会执行!

View Source
var GetInstanceValue = func(typ reflect.Type, val any, reuse bool, proxy InterfaceProxy) (any, bool) {
	if val != nil && typ == reflect.TypeOf(val) {
		return val, true
	}
	if reuse {
		var v = INSTANCE_MAP[typ] //必须精确对应值,否则去除缓存的和需要的很可能不符
		if v != nil {
			return v, true
		}
	}

	var v = reflect.Zero(typ) // .New(typ)
	var toVal, err = Convert(val, v)
	if err == nil {
		return toVal, true
	}
	return v, false

}
View Source
var GetInvokeClass = func(pkgName string, clsName string) (any, error) {
	var cls any
	if len(clsName) <= 0 {
		cls = CLASS_MAP[pkgName]
	} else {
		cls = CLASS_MAP[clsName]
		if cls == nil && len(pkgName) > 0 {
			cls = CLASS_MAP[pkgName+"."+clsName]
		}
	}

	if cls != nil {
		var v = reflect.ValueOf(cls)
		var k = v.Kind()
		if k == reflect.Struct || k == reflect.Func || k == reflect.Pointer {
			return cls, nil
		}
	}

	o, err := LoadClass(pkgName, clsName, false)
	if err != nil {
		return nil, err
	}

	return o, err
}

* GetInvokeClass 获取类

  • @param pkgName 包名
  • @param clsName 类名
View Source
var INSTANCE_MAP = map[reflect.Type]any{}
View Source
var InvokeMethodByStr = func(request string, instance any, listener Listener[any]) error {
	if obj, err := ParseMap(request); err != nil {
		return err
	} else {
		return InvokeMethod(obj, instance, listener)
	}
}

InvokeMethodByStr 执行方法

View Source
var InvokeReflectMethod = func(typ reflect.Value, instance any, pkgName string, clsName string, methodName string,
	methodArgs []Argument, listener Listener[any]) error {

	var startTime = time.Now().UnixMilli()
	_, err := getInvokeResult(typ, nil, methodName, methodArgs, func(data any, method *reflect.Method, proxy *InterfaceProxy, extras ...any) error {
		var result = NewSuccessResult()
		if data != nil {
			switch data.(type) {
			case map[string]any:
				var m = data.(map[string]any)
				for k, v := range m {
					result[k] = v
				}
			}
		}

		result[KEY_LANGUAGE] = "Go"
		if instance != nil {
			result[KEY_THIS] = parseJson(reflect.TypeOf(instance), instance)
		}

		if listener != nil {
			err := listener(result, nil, nil)
			if err != nil {
				return err
			}
		}

		return nil
	})

	if err != nil {
		completeWithError(pkgName, clsName, methodName, startTime, err, listener)
		return err
	}
	return nil
}
View Source
var IsInit = true // 你的项目不需要这些默认测试配置,可以改为 false,然后在项目中配置需要的
View Source
var KEY_ARGS = "args"
View Source
var KEY_AT_TYPE = "@type"
View Source
var KEY_CALLBACK = "callback"
View Source
var KEY_CALL_LIST = "call()[]"
View Source
var KEY_CALL_MAP = "call(){}"
View Source
var KEY_CLASS = "class"
View Source
var KEY_CLASS_ARGS = "classArgs"
View Source
var KEY_CLASS_LIST = "classList"
View Source
var KEY_CLASS_TOTAL = "classTotal"
View Source
var KEY_CODE = "code"
View Source
var KEY_CONSTRUCTOR = "constructor"
View Source
var KEY_GLOBAL = "global"
View Source
var KEY_LANGUAGE = "language"
View Source
var KEY_METHOD = "method"
View Source
var KEY_METHOD_ARGS = "methodArgs"
View Source
var KEY_METHOD_LIST = "methodList"
View Source
var KEY_METHOD_TOTAL = "methodTotal"
View Source
var KEY_MOCK = "mock"
View Source
var KEY_MSG = "msg"
View Source
var KEY_NAME = "name"
View Source
var KEY_PACKAGE = "package"
View Source
var KEY_PACKAGE_LIST = "packageList"
View Source
var KEY_PACKAGE_TOTAL = "packageTotal"
View Source
var KEY_QUERY = "query"
View Source
var KEY_RETURN = "return"
View Source
var KEY_REUSE = "reuse"
View Source
var KEY_STATIC = "static"
View Source
var KEY_THIS = "this"
View Source
var KEY_TIME = "@time"
View Source
var KEY_TIMEOUT = "timeout"
View Source
var KEY_TIME_DETAIL = "time:start|duration|end"
View Source
var KEY_TYPE = "type"
View Source
var KEY_UI = "ui"
View Source
var KEY_VALUE = "value"
View Source
var KEY_WARN = "warn"
View Source
var LoadClass = func(packageOrFileName string, className string, ignoreError bool) (types.Object, error) {
	return FindClass(packageOrFileName, className, ignoreError)
}

LoadClass 不能在 static 代码块赋值,否则 MethodUtil 子类中 static 代码块对它赋值的代码不会执行!

View Source
var LoadClassList = func(packageOrFileName string, className string, ignoreError bool, limit int, offset int) ([]types.Object, error) {
	return FindClassList(packageOrFileName, className, ignoreError, limit, offset, false)
}
View Source
var LoadStruct = func(packageOrFileName string, className string, ignoreError bool) (reflect.Type, error) {
	if s, err := FindClass(packageOrFileName, className, ignoreError); err != nil {
		return nil, err
	} else {
		return reflect.TypeOf(reflect.ValueOf(s)), nil
	}
}
View Source
var LoadStructList = func(packageOrFileName string, className string, ignoreError bool, limit int, offset int) ([]reflect.Type, error) {
	var lst, err = FindClassList(packageOrFileName, className, ignoreError, limit, offset, true)
	if err != nil || len(lst) <= 0 {
		return nil, err
	}

	var nl = make([]reflect.Type, len(lst))
	for i, s := range lst {
		nl[i] = reflect.TypeOf(reflect.ValueOf(s))
	}
	return nl, nil
}
View Source
var MSG_SUCCESS = "success"
View Source
var NewErrorResult = func(err error) map[string]any {
	result := map[string]any{}
	result[KEY_CODE] = CODE_SERVER_ERROR
	result[KEY_MSG] = err.Error()
	return result
}
View Source
var NewSuccessResult = func() map[string]any {
	result := map[string]any{}
	result[KEY_CODE] = CODE_SUCCESS
	result[KEY_MSG] = MSG_SUCCESS
	return result
}
View Source
var PATTERN_NAME, _ = regexp.Compile("^[0-9a-zA-Z_]+$")
View Source
var PATTERN_UPPER_CASE, _ = regexp.Compile("^[A-Z]+$")
View Source
var PRIMITIVE_CLASS_MAP = map[string]any{
	"any":         (any)(nil),
	"interface{}": (interface{})(nil),
	"bool":        false,
	"byte":        byte(0),
	"int":         int(0),
	"int8":        int8(0),
	"int16":       int16(0),
	"int32":       int32(0),
	"int64":       int64(0),
	"uint":        uint(0),
	"uint8":       uint8(0),
	"uint16":      uint16(0),
	"uint32":      uint32(0),
	"uint64":      uint64(0),
	"float32":     float32(0),
	"float64":     float64(0),
	"string":      "",
}
View Source
var ParseArr = func(str string) ([]any, error) {
	if str == "" {
		return nil, nil
	}
	arr := []any{}

	if err := json.Unmarshal([]byte(str), &arr); err != nil {
		return nil, err
	}
	return arr, nil
}

* ParseArr 把 JSON 字符串转 Array

  • @param json
  • @return
View Source
var ParseMap = func(str string) (map[string]any, error) {
	if str == "" {
		return nil, nil
	}
	m := map[string]any{}

	if err := json.Unmarshal([]byte(str), &m); err != nil {
		return nil, err
	}
	return m, nil
}

* ParseMap 把 JSON 字符串转 Struct

  • @param json
  • @return
View Source
var Port = 8082
View Source
var TAG = "MethodUtil"

*方法/函数的工具类

  • @author Lemon
View Source
var TYPE_ANY = reflect.TypeOf((any)(nil))
View Source
var TYPE_ARR_ANY = reflect.TypeOf([]any{})
View Source
var TYPE_ARR_BOOL = reflect.TypeOf([]bool{})
View Source
var TYPE_ARR_BYTE = reflect.TypeOf([]byte{})
View Source
var TYPE_ARR_FLOAT32 = reflect.TypeOf([]float32{})
View Source
var TYPE_ARR_FLOAT64 = reflect.TypeOf([]float64{})
View Source
var TYPE_ARR_INT = reflect.TypeOf([]int{})
View Source
var TYPE_ARR_INT16 = reflect.TypeOf([]int16{})
View Source
var TYPE_ARR_INT32 = reflect.TypeOf([]int32{})
View Source
var TYPE_ARR_INT64 = reflect.TypeOf([]int64{})
View Source
var TYPE_ARR_INT8 = reflect.TypeOf([]int8{})
View Source
var TYPE_ARR_INTERFACE = reflect.TypeOf([]interface{}{})
View Source
var TYPE_ARR_MAP_STRING_ANY = reflect.TypeOf([]map[string]any{})
View Source
var TYPE_ARR_MAP_STRING_INTERFACE = reflect.TypeOf([]map[string]interface{}{})
View Source
var TYPE_ARR_STRING = reflect.TypeOf([]string{})
View Source
var TYPE_ARR_UINT = reflect.TypeOf([]uint{})
View Source
var TYPE_ARR_UINT16 = reflect.TypeOf([]uint16{})
View Source
var TYPE_ARR_UINT32 = reflect.TypeOf([]uint32{})
View Source
var TYPE_ARR_UINT64 = reflect.TypeOf([]uint64{})
View Source
var TYPE_ARR_UINT8 = reflect.TypeOf([]uint8{})
View Source
var TYPE_BOOL = reflect.TypeOf(false)
View Source
var TYPE_BYTE = reflect.TypeOf(byte(0))
View Source
var TYPE_ERROR = reflect.TypeOf(errors.New(""))
View Source
var TYPE_FLOAT32 = reflect.TypeOf(float32(0.0))
View Source
var TYPE_FLOAT64 = reflect.TypeOf(float64(0.0))
View Source
var TYPE_FUNC = reflect.TypeOf(func() {})
View Source
var TYPE_INT = reflect.TypeOf(int(0))
View Source
var TYPE_INT16 = reflect.TypeOf(int16(0))
View Source
var TYPE_INT32 = reflect.TypeOf(int32(0))
View Source
var TYPE_INT64 = reflect.TypeOf(int64(0))
View Source
var TYPE_INT8 = reflect.TypeOf(int8(0))
View Source
var TYPE_INTERFACE = TYPE_ANY
View Source
var TYPE_INTERFACE_PROXY = reflect.TypeOf(InterfaceProxy{})
View Source
var TYPE_MAP_ANY_ANY = reflect.TypeOf(map[any]any{})
View Source
var TYPE_MAP_INTERFACE_INTERFACE = reflect.TypeOf(map[interface{}]interface{}{})
View Source
var TYPE_MAP_STRING_ANY = reflect.TypeOf(map[string]any{})
View Source
var TYPE_MAP_STRING_INTERFACE = reflect.TypeOf(map[string]interface{}{})
View Source
var TYPE_METHOD = reflect.TypeOf(reflect.Method{})
View Source
var TYPE_STRING = reflect.TypeOf("")
View Source
var TYPE_UINT = reflect.TypeOf(uint(0))
View Source
var TYPE_UINT16 = reflect.TypeOf(uint16(0))
View Source
var TYPE_UINT32 = reflect.TypeOf(uint32(0))
View Source
var TYPE_UINT64 = reflect.TypeOf(uint64(0))
View Source
var TYPE_UINT8 = reflect.TypeOf(uint8(0))
View Source
var ToJSONString = func(str any) (string, error) {
	if str == nil {
		return "", nil
	}

	if bytes, err := json.Marshal(&str); err != nil {
		return "", err
	} else {
		return string(bytes), nil
	}
}

Functions

func ArrToString

func ArrToString(arr []string) string

func Convert

func Convert[T any](rawVal any, toVal T) (T, error)

func Cors added in v1.1.0

func Cors(w http.ResponseWriter, r *http.Request)

Cors 解决前端网页跨域问题

func FindClass

func FindClass(packageOrFileName string, className string, ignoreError bool) (types.Object, error)

* FindClass 提供直接调用的方法

  • @param packageOrFileName
  • @param className
  • @param ignoreError
  • @return
  • @throws ClassNotFoundException
  • @throws IOException

func FindClassList

func FindClassList(packageOrFileName string, className string, ignoreError bool, limit int, offset int, onlyStruct bool) ([]types.Object, error)

* FindClassList

  • @param packageOrFileName
  • @param className
  • @param ignoreError
  • @return
  • @throws ClassNotFoundException

func GetArr

func GetArr(m map[string]any, k string) []any

func GetBool

func GetBool(m map[string]any, k string) bool

func GetInt

func GetInt(m map[string]any, k string) int

func GetInt32

func GetInt32(m map[string]any, k string) int32

func GetInt64

func GetInt64(m map[string]any, k string) int64

func GetInvokeInstance

func GetInvokeInstance(typ reflect.Type, instance any, classArgs []Argument, reuse bool) (any, error)

* GetInvokeInstance 获取实例

  • @param typ
  • @param classArgs
  • @param reuse
  • @return
  • @error

func GetJSONArray

func GetJSONArray(m orderedmap.OrderedMap, k string) []any

func GetJSONList

func GetJSONList(m orderedmap.OrderedMap, k string) list.List

func GetJSONObject

func GetJSONObject(m map[string]any, k string) orderedmap.OrderedMap

func GetList

func GetList(m map[string]any, k string) list.List

func GetMap

func GetMap(m map[string]any, k string) map[string]any

func GetMapArr

func GetMapArr(m map[string]any, k string) []map[string]any

func GetStr

func GetStr(m map[string]any, k string) string

func Handle added in v1.1.0

func Handle(w http.ResponseWriter, r *http.Request)

Handle 处理网络请求

func Init added in v1.1.0

func Init()

Init 初始化默认的测试配置

func InvokeMethod

func InvokeMethod(req map[string]any, instance any, listener Listener[any]) error

InvokeMethod 执行方法

  • @param req : { "timeout": 0, //超时时间 "package": "unitauto.test", //被测方法所在的包名 "class": "Test", //被测方法所在的 Struct/Func/Method 名 "constructor": "New", //如果有自定义的构造方法,不能用默认构造方法,可以自定义获取实例的方法,传参仍用 classArgs "classArgs": [ //构造方法的参数值,可以和 methodArgs 结构一样。这里用了简化形式,只传值不传类型,注意简化形式只能在所有值完全符合构造方法的类型定义时才可用 nil, nil, 0, nil ], "this": { //当前类示例,和 constructor & classArgs 二选一 "type": "unitauto.test.Test", //不可缺省,且必须全称,指针引用则在最前面加 *,例如 *unitauto.test.Test "value": { //Test 的示例值,会根据 type 来转为 Java 类型,这里执行等价于 json.Unmarshal(value, &unitauto.test.Test{}) "Id": 1, "Name": "Tommy" } }, "method": "Compare", //被测 Func/Method 名 "methodArgs": [ //被测 Func/Method 的参数值 { "typ": "int", //bool, float64, string, []interface{} 都可缺省,自动根据 value 来判断 "value": 1 }, { "typ": "string", //可缺省,自动根据 value 来判断 "value": "APIJSON" }, { "type": "map[string]interface{}", //可缺省,已缓存到 CLASS_MAP "value": {} }, { "typ": "[]int", //不可缺省,且必须全称 "value": [1, 2, 3] }, { "type": "[]apijson.demo.server.model.User", //不可缺省,且必须全称 "value": [ { //apijson.demo.server.model.User "id": 1, "name": "Tommy" }, { //apijson.demo.server.model.User "id": 2, "name": "Lemon" } ] }, { "type": "android.content.Context", //不可缺省,且必须全称 "reuse": true //复用实例池 INSTANCE_MAP 里的 } } } ] }
  • @param instance 默认从 CLASS_MAP 取值,取不到则自动 new
  • @return
  • @error

func IsArrType

func IsArrType(typ string) bool

func IsEmpty

func IsEmpty(s string, trim bool) bool

* IsEmpty 判断字符是否为空

  • @param s
  • @param trim
  • @return

func IsFloatType

func IsFloatType(typ string) bool

func IsIntType

func IsIntType(typ string) bool

func IsMapType

func IsMapType(typ string) bool

func IsName

func IsName(name string) bool

func IsNumType

func IsNumType(typ string) bool

func ListMethod

func ListMethod(req map[string]any) map[string]any

*获取方法列表

  • @param request : { "mock": true, "query": 0, // 0-数据,1-总数,2-全部 "package": "apijson.demo.server", "class": "DemoFunction", "method": "plus", "types": ["Integer", "String", "com.alibaba.fastjson.JSONObject"] //不返回的话,这个接口没意义 "return": true, //返回 class list,方便调试 }
  • @return

func ListMethodByStr

func ListMethodByStr(request string) map[string]any

func Start added in v1.1.0

func Start(port int)

func Test added in v1.1.0

func Test()

func Trim

func Trim(s string) string

* Trim 判断字符是否为空

  • @param s
  • @return

Types

type Argument

type Argument struct {
	Reuse  bool
	Type   string
	Value  any
	Global bool
}

参数,包括类型和值

func NewArgument

func NewArgument(typ string, value any) Argument

type Callback

type Callback func(data any, method reflect.Method, proxy InterfaceProxy, extras ...any) error

type Complete

type Complete func(data any, method reflect.Method, proxy InterfaceProxy, extras ...any) error

type InterfaceProxy

type InterfaceProxy struct {
	orderedmap.OrderedMap
	//OrderedMap map[string]any
	//reflect.Value
	Type        reflect.Type
	CallbackMap map[string]Listener[any] // orderedmap.OrderedMap //
	// contains filtered or unexported fields
}

*

  • 将 interface 转成 JSONObject,便于返回时查看
  • TODO 应该在 ParseMap(json, typ) 时代理 typ 内所有的 interface

func (InterfaceProxy) GetCallback

func (ip InterfaceProxy) GetCallback(method string) Listener[any]

func (InterfaceProxy) GetType

func (ip InterfaceProxy) GetType() reflect.Type

func (*InterfaceProxy) Invoke

func (ip *InterfaceProxy) Invoke(method string, args []any) (any, error)

func (*InterfaceProxy) OnInvoke

func (ip *InterfaceProxy) OnInvoke(method string, types []reflect.Type, args []any, callSuper bool) (any, error)

func (InterfaceProxy) PutCallback

func (ip InterfaceProxy) PutCallback(method string, callback Listener[any])

func (InterfaceProxy) SetType

func (ip InterfaceProxy) SetType(typ reflect.Type)

type Listener

type Listener[T any] func(data T, method *reflect.Method, proxy *InterfaceProxy, extras ...any) error

type Proxy added in v1.1.0

type Proxy struct {
	InterfaceProxy
	// contains filtered or unexported fields
}

func (Proxy) OnFailure added in v1.1.0

func (p Proxy) OnFailure(err error)

func (Proxy) OnSuccess added in v1.1.0

func (p Proxy) OnSuccess(data any)

type SimpleComplete

type SimpleComplete func(data any) error

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL