diff --git a/builtin/assertion.go b/builtin/assertion.go index 30ecfdd5..31110221 100644 --- a/builtin/assertion.go +++ b/builtin/assertion.go @@ -49,8 +49,37 @@ func EndsWith(t assert.TestingT, expected, actual interface{}, msgAndArgs ...int } func EqualLength(t assert.TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { - if !assert.IsType(t, 129, expected, fmt.Sprintf("expected type is not int, got %#v", expected)) { - return false + length, err := convertInt(expected) + if err != nil { + return assert.Fail(t, fmt.Sprintf("expected type is not int, got %#v", expected), msgAndArgs...) + } + + return assert.Len(t, actual, length, msgAndArgs...) +} + +func convertInt(value interface{}) (int, error) { + switch v := value.(type) { + case int: + return v, nil + case int8: + return int(v), nil + case int16: + return int(v), nil + case int32: + return int(v), nil + case int64: + return int(v), nil + case uint: + return int(v), nil + case uint8: + return int(v), nil + case uint16: + return int(v), nil + case uint32: + return int(v), nil + case uint64: + return int(v), nil + default: + return 0, fmt.Errorf("unsupported int convertion for %v(%T)", v, v) } - return assert.Len(t, actual, expected.(int), msgAndArgs...) } diff --git a/convert.go b/convert.go index 66cfd343..80280226 100644 --- a/convert.go +++ b/convert.go @@ -80,7 +80,9 @@ func loadFromJSON(path string) (*TCase, error) { } tc := &TCase{} - err = json.Unmarshal(file, tc) + decoder := json.NewDecoder(bytes.NewReader(file)) + decoder.UseNumber() + err = decoder.Decode(tc) return tc, err } diff --git a/convert_test.go b/convert_test.go index eaad39d2..8b9dbb9e 100644 --- a/convert_test.go +++ b/convert_test.go @@ -83,10 +83,7 @@ func TestDumpAndLoadYAML(t *testing.T) { if !assert.NoError(t, err) { t.Fail() } - if !assert.Equal(t, tc.Config.Name, demoTestCase.Config.Name) { - t.Fail() - } - if !assert.Equal(t, tc.Config.BaseURL, demoTestCase.Config.BaseURL) { + if !assert.Equal(t, tc.Config, demoTestCase.Config) { t.Fail() } if !assert.Equal(t, tc.TestSteps[1].Name, demoTestCase.TestSteps[1].Name()) { diff --git a/parser.go b/parser.go index f5179cb3..df6a356a 100644 --- a/parser.go +++ b/parser.go @@ -1,6 +1,7 @@ package httpboomer import ( + "encoding/json" "fmt" "log" "net/url" @@ -61,6 +62,11 @@ func parseData(raw interface{}, variablesMapping map[string]interface{}) (interf rawValue := reflect.ValueOf(raw) switch rawValue.Kind() { case reflect.String: + // json.Number + if rawValue, ok := raw.(json.Number); ok { + return parseJSONNumber(rawValue) + } + // other string value := rawValue.String() value = strings.TrimSpace(value) return parseString(value, variablesMapping) @@ -97,6 +103,16 @@ func parseData(raw interface{}, variablesMapping map[string]interface{}) (interf } } +func parseJSONNumber(raw json.Number) (interface{}, error) { + if strings.Contains(raw.String(), ".") { + // float64 + return raw.Float64() + } else { + // int64 + return raw.Int64() + } +} + const ( regexVariable = `[a-zA-Z_]\w*` // variable name should start with a letter or underscore regexFunctionName = `[a-zA-Z_]\w*` // function name should start with a letter or underscore @@ -252,17 +268,26 @@ func callFunc(funcName string, arguments ...interface{}) (interface{}, error) { argumentsValue := make([]reflect.Value, len(arguments)) for index, argument := range arguments { - // ensure each argument type match + argumentValue := reflect.ValueOf(argument) expectArgumentType := funcValue.Type().In(index) actualArgumentType := reflect.TypeOf(argument) - if expectArgumentType != actualArgumentType { - // function argument type not match - err := fmt.Errorf("function %s argument %d type not match, expect %v, actual %v", + + // type match + if expectArgumentType == actualArgumentType { + argumentsValue[index] = argumentValue + continue + } + + // type not match, check if convertible + if !actualArgumentType.ConvertibleTo(expectArgumentType) { + // function argument type not match and not convertible + err := fmt.Errorf("function %s argument %d type is neither match nor convertible, expect %v, actual %v", funcName, index, expectArgumentType, actualArgumentType) log.Printf("[callFunction] error: %s", err.Error()) return nil, err } - argumentsValue[index] = reflect.ValueOf(argument) + // convert argument to expect type + argumentsValue[index] = argumentValue.Convert(expectArgumentType) } log.Printf("[callFunction] func: %v, input arguments: %v", funcName, arguments)