fix int-overflow issue in gconv.String when converting int64 to string; add more unit test cases for package gconv

This commit is contained in:
John
2019-03-15 00:22:39 +08:00
parent cb8362d447
commit 320e0db417
4 changed files with 159 additions and 20 deletions

View File

@ -13,6 +13,7 @@ package gconv
import (
"encoding/json"
"github.com/gogf/gf/g/encoding/gbinary"
"reflect"
"strconv"
"strings"
)
@ -22,6 +23,16 @@ type apiString interface {
String() string
}
var (
// 为空的字符串
emptyStringMap = map[string]struct{}{
"" : struct {}{},
"0" : struct {}{},
"off" : struct {}{},
"false" : struct {}{},
}
)
// 将变量i转换为字符串指定的类型t非必须参数extraParams用以额外的参数传递
func Convert(i interface{}, t string, extraParams...interface{}) interface{} {
switch t {
@ -63,6 +74,7 @@ func Convert(i interface{}, t string, extraParams...interface{}) interface{} {
}
}
// 转换为二进制[]byte
func Bytes(i interface{}) []byte {
if i == nil {
return nil
@ -80,11 +92,11 @@ func String(i interface{}) string {
return ""
}
switch value := i.(type) {
case int: return strconv.Itoa(value)
case int: return strconv.FormatInt(int64(value), 10)
case int8: return strconv.Itoa(int(value))
case int16: return strconv.Itoa(int(value))
case int32: return strconv.Itoa(int(value))
case int64: return strconv.Itoa(int(value))
case int64: return strconv.FormatInt(int64(value), 10)
case uint: return strconv.FormatUint(uint64(value), 10)
case uint8: return strconv.FormatUint(uint64(value), 10)
case uint16: return strconv.FormatUint(uint64(value), 10)
@ -107,7 +119,7 @@ func String(i interface{}) string {
}
}
//false: "", 0, false, off
//false: false, "", 0, "false", "off", empty slice/map
func Bool(i interface{}) bool {
if i == nil {
return false
@ -115,10 +127,27 @@ func Bool(i interface{}) bool {
if v, ok := i.(bool); ok {
return v
}
if s := String(i); s != "" && s != "0" && s != "false" && s != "off" {
if s, ok := i.(string); ok {
if _, ok := emptyStringMap[s]; ok {
return false
}
return true
}
return false
rv := reflect.ValueOf(i)
switch rv.Kind() {
case reflect.Ptr: return !rv.IsNil()
case reflect.Map: fallthrough
case reflect.Array: fallthrough
case reflect.Slice: return rv.Len() != 0
case reflect.Struct: return true
default:
s := String(i)
if _, ok := emptyStringMap[s]; ok {
return false
}
return true
}
}
func Int(i interface{}) int {

View File

@ -15,20 +15,23 @@ import (
func Test_Basic(t *testing.T) {
gtest.Case(t, func() {
value := 123.456
gtest.AssertEQ(gconv.Int(value), int(123))
gtest.AssertEQ(gconv.Int8(value), int8(123))
gtest.AssertEQ(gconv.Int16(value), int16(123))
gtest.AssertEQ(gconv.Int32(value), int32(123))
gtest.AssertEQ(gconv.Int64(value), int64(123))
gtest.AssertEQ(gconv.Uint(value), uint(123))
gtest.AssertEQ(gconv.Uint8(value), uint8(123))
gtest.AssertEQ(gconv.Uint16(value), uint16(123))
gtest.AssertEQ(gconv.Uint32(value), uint32(123))
gtest.AssertEQ(gconv.Uint64(value), uint64(123))
gtest.AssertEQ(gconv.Float32(value), float32(123.456))
gtest.AssertEQ(gconv.Float64(value), float64(123.456))
gtest.AssertEQ(gconv.Bool(value), true)
gtest.AssertEQ(gconv.String(value), "123.456")
vint := 123.456
vint64 := 1552578474888
gtest.AssertEQ(gconv.Int(vint), int(123))
gtest.AssertEQ(gconv.Int8(vint), int8(123))
gtest.AssertEQ(gconv.Int16(vint), int16(123))
gtest.AssertEQ(gconv.Int32(vint), int32(123))
gtest.AssertEQ(gconv.Int64(vint), int64(123))
gtest.AssertEQ(gconv.Int64(vint), int64(123))
gtest.AssertEQ(gconv.Uint(vint), uint(123))
gtest.AssertEQ(gconv.Uint8(vint), uint8(123))
gtest.AssertEQ(gconv.Uint16(vint), uint16(123))
gtest.AssertEQ(gconv.Uint32(vint), uint32(123))
gtest.AssertEQ(gconv.Uint64(vint), uint64(123))
gtest.AssertEQ(gconv.Float32(vint), float32(123.456))
gtest.AssertEQ(gconv.Float64(vint), float64(123.456))
gtest.AssertEQ(gconv.Bool(vint), true)
gtest.AssertEQ(gconv.String(vint), "123.456")
gtest.AssertEQ(gconv.String(vint64), "1552578474888")
})
}

View File

@ -0,0 +1,42 @@
// Copyright 2018 gf Author(https://github.com/gogf/gf). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package gconv_test
import (
"github.com/gogf/gf/g/util/gconv"
"github.com/gogf/gf/g/test/gtest"
"testing"
)
type boolStruct struct {
}
func Test_Bool(t *testing.T) {
gtest.Case(t, func() {
var i interface{} = nil
gtest.AssertEQ(gconv.Bool(i), false)
gtest.AssertEQ(gconv.Bool(false), false)
gtest.AssertEQ(gconv.Bool(nil), false)
gtest.AssertEQ(gconv.Bool(0), false)
gtest.AssertEQ(gconv.Bool("0"), false)
gtest.AssertEQ(gconv.Bool(""), false)
gtest.AssertEQ(gconv.Bool("false"), false)
gtest.AssertEQ(gconv.Bool("off"), false)
gtest.AssertEQ(gconv.Bool([]byte{}), false)
gtest.AssertEQ(gconv.Bool([]string{}), false)
gtest.AssertEQ(gconv.Bool([]interface{}{}), false)
gtest.AssertEQ(gconv.Bool([]map[int]int{}), false)
gtest.AssertEQ(gconv.Bool("1"), true)
gtest.AssertEQ(gconv.Bool("on"), true)
gtest.AssertEQ(gconv.Bool(1), true)
gtest.AssertEQ(gconv.Bool(123.456), true)
gtest.AssertEQ(gconv.Bool(boolStruct{}), true)
gtest.AssertEQ(gconv.Bool(&boolStruct{}), true)
})
}

View File

@ -0,0 +1,65 @@
// Copyright 2018 gf Author(https://github.com/gogf/gf). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package gconv_test
import (
"github.com/gogf/gf/g/util/gconv"
"github.com/gogf/gf/g/test/gtest"
"testing"
)
type stringStruct1 struct {
Name string
}
type stringStruct2 struct {
Name string
}
func (s *stringStruct1) String() string {
return s.Name
}
func Test_String(t *testing.T) {
gtest.Case(t, func() {
gtest.AssertEQ(gconv.String(int(123)), "123")
gtest.AssertEQ(gconv.String(int(-123)), "-123")
gtest.AssertEQ(gconv.String(int8(123)), "123")
gtest.AssertEQ(gconv.String(int8(-123)), "-123")
gtest.AssertEQ(gconv.String(int16(123)), "123")
gtest.AssertEQ(gconv.String(int16(-123)), "-123")
gtest.AssertEQ(gconv.String(int32(123)), "123")
gtest.AssertEQ(gconv.String(int32(-123)), "-123")
gtest.AssertEQ(gconv.String(int64(123)), "123")
gtest.AssertEQ(gconv.String(int64(-123)), "-123")
gtest.AssertEQ(gconv.String(int64(1552578474888)), "1552578474888")
gtest.AssertEQ(gconv.String(int64(-1552578474888)), "-1552578474888")
gtest.AssertEQ(gconv.String(uint(123)), "123")
gtest.AssertEQ(gconv.String(uint8(123)), "123")
gtest.AssertEQ(gconv.String(uint16(123)), "123")
gtest.AssertEQ(gconv.String(uint32(123)), "123")
gtest.AssertEQ(gconv.String(uint64(155257847488898765)), "155257847488898765")
gtest.AssertEQ(gconv.String(float32(123.456)), "123.456")
gtest.AssertEQ(gconv.String(float32(-123.456)), "-123.456")
gtest.AssertEQ(gconv.String(float64(1552578474888.456)), "1552578474888.456")
gtest.AssertEQ(gconv.String(float64(-1552578474888.456)), "-1552578474888.456")
gtest.AssertEQ(gconv.String(true), "true")
gtest.AssertEQ(gconv.String(false), "false")
gtest.AssertEQ(gconv.String([]byte("bytes")), "bytes")
gtest.AssertEQ(gconv.String(stringStruct1{"john"}), `{"Name":"john"}`)
gtest.AssertEQ(gconv.String(&stringStruct1{"john"}), "john")
gtest.AssertEQ(gconv.String(stringStruct2{"john"}), `{"Name":"john"}`)
gtest.AssertEQ(gconv.String(&stringStruct2{"john"}), `{"Name":"john"}`)
})
}