Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f2f5388906 | ||
|
|
9eca340c7e | ||
|
|
376746f4db | ||
|
|
efc24c452f | ||
|
|
78cef077e5 | ||
|
|
0420e35a30 | ||
|
|
0b18560901 | ||
|
|
7b29f09e37 |
@@ -6,8 +6,7 @@ import (
|
|||||||
|
|
||||||
"crypto/aes"
|
"crypto/aes"
|
||||||
"crypto/cipher"
|
"crypto/cipher"
|
||||||
|
"crypto/rand"
|
||||||
"math/rand/v2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// DefaultAESKey 默认AES密钥(16字节)
|
// DefaultAESKey 默认AES密钥(16字节)
|
||||||
@@ -19,8 +18,7 @@ func GenerateAESKey(length int) ([]byte, error) {
|
|||||||
return nil, fmt.Errorf("invalid key length: %d, must be 16, 24, or 32 bytes", length)
|
return nil, fmt.Errorf("invalid key length: %d, must be 16, 24, or 32 bytes", length)
|
||||||
}
|
}
|
||||||
key := make([]byte, length)
|
key := make([]byte, length)
|
||||||
src := rand.ChaCha8{}
|
_, err := rand.Read(key)
|
||||||
_, err := src.Read(key)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -42,23 +40,44 @@ func PKCS5UnPadding(origData []byte) []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AesEncrypt AES加密
|
// AesEncrypt AES加密
|
||||||
func AesEncrypt(origData, key []byte) ([]byte, error) {
|
func AesEncrypt(plainText, key, iv []byte) ([]byte, error) {
|
||||||
|
if plainText == nil {
|
||||||
|
return nil, fmt.Errorf("plain text is nil")
|
||||||
|
}
|
||||||
|
if key == nil {
|
||||||
|
return nil, fmt.Errorf("key is nil")
|
||||||
|
}
|
||||||
|
|
||||||
block, err := aes.NewCipher(key)
|
block, err := aes.NewCipher(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
//AES分组长度为128位,所以blockSize=16,单位字节
|
// AES分组长度为128位,所以blockSize=16,单位字节
|
||||||
blockSize := block.BlockSize()
|
blockSize := block.BlockSize()
|
||||||
origData = PKCS5Padding(origData, blockSize)
|
|
||||||
blockMode := cipher.NewCBCEncrypter(block, key[:blockSize]) //初始向量的长度必须等于块block的长度16字节
|
if iv == nil {
|
||||||
crypted := make([]byte, len(origData))
|
// 初始向量的长度必须等于块block的长度16字节
|
||||||
blockMode.CryptBlocks(crypted, origData)
|
iv = key[:blockSize]
|
||||||
return crypted, nil
|
}
|
||||||
|
|
||||||
|
plainText = PKCS5Padding(plainText, blockSize)
|
||||||
|
|
||||||
|
blockMode := cipher.NewCBCEncrypter(block, iv)
|
||||||
|
cryptedText := make([]byte, len(plainText))
|
||||||
|
blockMode.CryptBlocks(cryptedText, plainText)
|
||||||
|
return cryptedText, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AesDecrypt AES解密
|
// AesDecrypt AES解密
|
||||||
func AesDecrypt(crypted, key []byte) ([]byte, error) {
|
func AesDecrypt(cryptedText, key, iv []byte) ([]byte, error) {
|
||||||
|
if cryptedText == nil {
|
||||||
|
return nil, fmt.Errorf("crypted text is nil")
|
||||||
|
}
|
||||||
|
if key == nil {
|
||||||
|
return nil, fmt.Errorf("key is nil")
|
||||||
|
}
|
||||||
|
|
||||||
block, err := aes.NewCipher(key)
|
block, err := aes.NewCipher(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -66,9 +85,16 @@ func AesDecrypt(crypted, key []byte) ([]byte, error) {
|
|||||||
|
|
||||||
//AES分组长度为128位,所以blockSize=16,单位字节
|
//AES分组长度为128位,所以blockSize=16,单位字节
|
||||||
blockSize := block.BlockSize()
|
blockSize := block.BlockSize()
|
||||||
blockMode := cipher.NewCBCDecrypter(block, key[:blockSize]) //初始向量的长度必须等于块block的长度16字节
|
|
||||||
origData := make([]byte, len(crypted))
|
if iv == nil {
|
||||||
blockMode.CryptBlocks(origData, crypted)
|
// 初始向量的长度必须等于块block的长度16字节
|
||||||
origData = PKCS5UnPadding(origData)
|
iv = key[:blockSize]
|
||||||
return origData, nil
|
}
|
||||||
|
|
||||||
|
blockMode := cipher.NewCBCDecrypter(block, iv)
|
||||||
|
|
||||||
|
plainText := make([]byte, len(cryptedText))
|
||||||
|
blockMode.CryptBlocks(plainText, cryptedText)
|
||||||
|
plainText = PKCS5UnPadding(plainText)
|
||||||
|
return plainText, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ func TestDecryptAES(t *testing.T) {
|
|||||||
aesKey = DefaultAESKey
|
aesKey = DefaultAESKey
|
||||||
|
|
||||||
plainText := []byte("cloud123456")
|
plainText := []byte("cloud123456")
|
||||||
encryptText, err := AesEncrypt(plainText, aesKey)
|
encryptText, err := AesEncrypt(plainText, aesKey, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
return
|
return
|
||||||
@@ -30,7 +30,7 @@ func TestDecryptAES(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
decryptText, err := AesDecrypt(bytesPass, aesKey)
|
decryptText, err := AesDecrypt(bytesPass, aesKey, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -1,14 +1,9 @@
|
|||||||
package crypto
|
package crypto
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"crypto/aes"
|
|
||||||
"crypto/cipher"
|
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
|
|
||||||
"encoding/base64"
|
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
@@ -59,44 +54,3 @@ func GenerateSalt(length int) (string, error) {
|
|||||||
}
|
}
|
||||||
return hex.EncodeToString(salt), nil
|
return hex.EncodeToString(salt), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecryptAES AES解密函数
|
|
||||||
func DecryptAES(cipherText, key string) (string, error) {
|
|
||||||
// 将密文从Base64解码
|
|
||||||
cipherData, err := base64.StdEncoding.DecodeString(cipherText)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建AES块
|
|
||||||
block, err := aes.NewCipher([]byte(key))
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查密文长度是否为块大小的倍数
|
|
||||||
if len(cipherData)%aes.BlockSize != 0 {
|
|
||||||
return "", fmt.Errorf("ciphertext is not a multiple of the block size")
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建CBC解密器
|
|
||||||
iv := cipherData[:aes.BlockSize] // 提取IV
|
|
||||||
cipherData = cipherData[aes.BlockSize:]
|
|
||||||
mode := cipher.NewCBCDecrypter(block, iv)
|
|
||||||
|
|
||||||
// 解密
|
|
||||||
plainText := make([]byte, len(cipherData))
|
|
||||||
mode.CryptBlocks(plainText, cipherData)
|
|
||||||
|
|
||||||
// 去除填充
|
|
||||||
plainText = pkcs7Unpad(plainText)
|
|
||||||
|
|
||||||
return string(plainText), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// pkcs7Unpad PKCS7填充去除
|
|
||||||
func pkcs7Unpad(data []byte) []byte {
|
|
||||||
length := len(data)
|
|
||||||
padding := int(data[length-1])
|
|
||||||
return data[:length-padding]
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -26,6 +26,15 @@ func TestVerifyPassword(t *testing.T) {
|
|||||||
assert.True(t, bMatched)
|
assert.True(t, bMatched)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestVerifyPasswordWithSalt_CorrectPassword(t *testing.T) {
|
||||||
|
password := "securePassword"
|
||||||
|
salt, _ := GenerateSalt(16)
|
||||||
|
hashedPassword, _ := HashPasswordWithSalt(password, salt)
|
||||||
|
|
||||||
|
result := VerifyPasswordWithSalt(password, salt, hashedPassword)
|
||||||
|
assert.True(t, result, "Password verification should succeed with correct password and salt")
|
||||||
|
}
|
||||||
|
|
||||||
func TestJwtToken(t *testing.T) {
|
func TestJwtToken(t *testing.T) {
|
||||||
const bearerWord string = "Bearer"
|
const bearerWord string = "Bearer"
|
||||||
token := "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjowfQ.XgcKAAjHbA6o4sxxbEaMi05ingWvKdCNnyW9wowbJvs"
|
token := "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjowfQ.XgcKAAjHbA6o4sxxbEaMi05ingWvKdCNnyW9wowbJvs"
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ require (
|
|||||||
github.com/go-kratos/kratos/v2 v2.8.4
|
github.com/go-kratos/kratos/v2 v2.8.4
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
github.com/stretchr/testify v1.10.0
|
github.com/stretchr/testify v1.10.0
|
||||||
github.com/tx7do/go-utils v1.1.16
|
github.com/tx7do/go-utils v1.1.19
|
||||||
go.opentelemetry.io/otel v1.35.0
|
go.opentelemetry.io/otel v1.35.0
|
||||||
google.golang.org/protobuf v1.36.6
|
google.golang.org/protobuf v1.36.6
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
package entgo
|
package entgo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/tx7do/go-utils/stringcase"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
"entgo.io/ent/dialect"
|
"entgo.io/ent/dialect"
|
||||||
"entgo.io/ent/dialect/sql"
|
"entgo.io/ent/dialect/sql"
|
||||||
|
|
||||||
"github.com/go-kratos/kratos/v2/encoding"
|
"github.com/go-kratos/kratos/v2/encoding"
|
||||||
|
|
||||||
|
"github.com/tx7do/go-utils/stringcase"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FilterOp int
|
type FilterOp int
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
|
|
||||||
"github.com/go-kratos/kratos/v2/encoding"
|
"github.com/go-kratos/kratos/v2/encoding"
|
||||||
_ "github.com/go-kratos/kratos/v2/encoding/json"
|
_ "github.com/go-kratos/kratos/v2/encoding/json"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
4
tag.bat
4
tag.bat
@@ -1,9 +1,9 @@
|
|||||||
git tag v1.1.17
|
git tag v1.1.20
|
||||||
|
|
||||||
git tag bank_card/v1.1.5
|
git tag bank_card/v1.1.5
|
||||||
git tag geoip/v1.1.5
|
git tag geoip/v1.1.5
|
||||||
|
|
||||||
git tag entgo/v1.1.26
|
git tag entgo/v1.1.27
|
||||||
git tag gorm/v1.1.5
|
git tag gorm/v1.1.5
|
||||||
|
|
||||||
git push origin --tags
|
git push origin --tags
|
||||||
|
|||||||
@@ -9,10 +9,20 @@ import (
|
|||||||
"github.com/tx7do/go-utils/trans"
|
"github.com/tx7do/go-utils/trans"
|
||||||
)
|
)
|
||||||
|
|
||||||
var DefaultTimeLocation *time.Location
|
var defaultTimeLocation *time.Location
|
||||||
|
|
||||||
func RefreshDefaultTimeLocation(name string) {
|
func RefreshDefaultTimeLocation(name string) *time.Location {
|
||||||
DefaultTimeLocation, _ = time.LoadLocation(name)
|
if defaultTimeLocation == nil {
|
||||||
|
defaultTimeLocation, _ = time.LoadLocation(name)
|
||||||
|
}
|
||||||
|
return defaultTimeLocation
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetDefaultTimeLocation() *time.Location {
|
||||||
|
if defaultTimeLocation == nil {
|
||||||
|
RefreshDefaultTimeLocation(DefaultTimeLocationName)
|
||||||
|
}
|
||||||
|
return defaultTimeLocation
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnixMilliToStringPtr 毫秒时间戳 -> 字符串
|
// UnixMilliToStringPtr 毫秒时间戳 -> 字符串
|
||||||
@@ -26,6 +36,10 @@ func UnixMilliToStringPtr(tm *int64) *string {
|
|||||||
|
|
||||||
// StringToUnixMilliInt64Ptr 字符串 -> 毫秒时间戳
|
// StringToUnixMilliInt64Ptr 字符串 -> 毫秒时间戳
|
||||||
func StringToUnixMilliInt64Ptr(tm *string) *int64 {
|
func StringToUnixMilliInt64Ptr(tm *string) *int64 {
|
||||||
|
if tm == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
theTime := StringTimeToTime(tm)
|
theTime := StringTimeToTime(tm)
|
||||||
if theTime == nil {
|
if theTime == nil {
|
||||||
return nil
|
return nil
|
||||||
@@ -43,24 +57,20 @@ func StringTimeToTime(str *string) *time.Time {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if DefaultTimeLocation == nil {
|
|
||||||
RefreshDefaultTimeLocation(DefaultTimeLocationName)
|
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
var theTime time.Time
|
var theTime time.Time
|
||||||
|
|
||||||
theTime, err = time.ParseInLocation(TimeLayout, *str, DefaultTimeLocation)
|
theTime, err = time.ParseInLocation(TimeLayout, *str, GetDefaultTimeLocation())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return &theTime
|
return &theTime
|
||||||
}
|
}
|
||||||
|
|
||||||
theTime, err = time.ParseInLocation(DateLayout, *str, DefaultTimeLocation)
|
theTime, err = time.ParseInLocation(DateLayout, *str, GetDefaultTimeLocation())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return &theTime
|
return &theTime
|
||||||
}
|
}
|
||||||
|
|
||||||
theTime, err = time.ParseInLocation(ClockLayout, *str, DefaultTimeLocation)
|
theTime, err = time.ParseInLocation(ClockLayout, *str, GetDefaultTimeLocation())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return &theTime
|
return &theTime
|
||||||
}
|
}
|
||||||
@@ -85,24 +95,20 @@ func StringDateToTime(str *string) *time.Time {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if DefaultTimeLocation == nil {
|
|
||||||
RefreshDefaultTimeLocation(DefaultTimeLocationName)
|
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
var theTime time.Time
|
var theTime time.Time
|
||||||
|
|
||||||
theTime, err = time.ParseInLocation(TimeLayout, *str, DefaultTimeLocation)
|
theTime, err = time.ParseInLocation(TimeLayout, *str, GetDefaultTimeLocation())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return &theTime
|
return &theTime
|
||||||
}
|
}
|
||||||
|
|
||||||
theTime, err = time.ParseInLocation(DateLayout, *str, DefaultTimeLocation)
|
theTime, err = time.ParseInLocation(DateLayout, *str, GetDefaultTimeLocation())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return &theTime
|
return &theTime
|
||||||
}
|
}
|
||||||
|
|
||||||
theTime, err = time.ParseInLocation(ClockLayout, *str, DefaultTimeLocation)
|
theTime, err = time.ParseInLocation(ClockLayout, *str, GetDefaultTimeLocation())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return &theTime
|
return &theTime
|
||||||
}
|
}
|
||||||
@@ -138,7 +144,16 @@ func FloatToDurationpb(duration *float64, timePrecision time.Duration) *duration
|
|||||||
if duration == nil {
|
if duration == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return durationpb.New(time.Duration(*duration) * timePrecision)
|
return durationpb.New(time.Duration(*duration * float64(timePrecision)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func Float64ToDurationpb(d float64) *durationpb.Duration {
|
||||||
|
duration := time.Duration(d * float64(time.Second))
|
||||||
|
return durationpb.New(duration)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SecondToDurationpb(seconds *float64) *durationpb.Duration {
|
||||||
|
return FloatToDurationpb(seconds, time.Second)
|
||||||
}
|
}
|
||||||
|
|
||||||
func DurationpbToFloat(duration *durationpb.Duration, timePrecision time.Duration) *float64 {
|
func DurationpbToFloat(duration *durationpb.Duration, timePrecision time.Duration) *float64 {
|
||||||
@@ -180,3 +195,12 @@ func DurationpbToDuration(duration *durationpb.Duration) *time.Duration {
|
|||||||
d := duration.AsDuration()
|
d := duration.AsDuration()
|
||||||
return &d
|
return &d
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func DurationpbSecond(duration *durationpb.Duration) *float64 {
|
||||||
|
if duration == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
seconds := duration.AsDuration().Seconds()
|
||||||
|
secondsInt64 := seconds
|
||||||
|
return &secondsInt64
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,9 +2,11 @@ package timeutil
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"google.golang.org/protobuf/types/known/timestamppb"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/tx7do/go-utils/trans"
|
"github.com/tx7do/go-utils/trans"
|
||||||
"google.golang.org/protobuf/types/known/durationpb"
|
"google.golang.org/protobuf/types/known/durationpb"
|
||||||
)
|
)
|
||||||
@@ -28,11 +30,152 @@ func TestUnixMilliToStringPtr(t *testing.T) {
|
|||||||
|
|
||||||
fmt.Println(StringTimeToTime(trans.Ptr("2023-03-08 00:00:00")).UnixMilli())
|
fmt.Println(StringTimeToTime(trans.Ptr("2023-03-08 00:00:00")).UnixMilli())
|
||||||
fmt.Println(StringDateToTime(trans.Ptr("2023-03-07")).UnixMilli())
|
fmt.Println(StringDateToTime(trans.Ptr("2023-03-07")).UnixMilli())
|
||||||
|
|
||||||
|
// 测试有效输入
|
||||||
|
now = time.Now().UnixMilli()
|
||||||
|
result := UnixMilliToStringPtr(&now)
|
||||||
|
assert.NotNil(t, result)
|
||||||
|
expected := time.UnixMilli(now).Format(TimeLayout)
|
||||||
|
assert.Equal(t, expected, *result)
|
||||||
|
|
||||||
|
// 测试空输入
|
||||||
|
result = UnixMilliToStringPtr(nil)
|
||||||
|
assert.Nil(t, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStringToUnixMilliInt64Ptr(t *testing.T) {
|
||||||
|
// 测试有效输入
|
||||||
|
input := "2023-03-09 00:00:00"
|
||||||
|
expected := time.Date(2023, 3, 9, 0, 0, 0, 0, GetDefaultTimeLocation()).UnixMilli()
|
||||||
|
result := StringToUnixMilliInt64Ptr(&input)
|
||||||
|
assert.NotNil(t, result)
|
||||||
|
assert.Equal(t, expected, *result)
|
||||||
|
|
||||||
|
// 测试无效输入
|
||||||
|
invalidInput := "invalid-date"
|
||||||
|
result = StringToUnixMilliInt64Ptr(&invalidInput)
|
||||||
|
assert.Nil(t, result)
|
||||||
|
|
||||||
|
// 测试空字符串输入
|
||||||
|
emptyInput := ""
|
||||||
|
result = StringToUnixMilliInt64Ptr(&emptyInput)
|
||||||
|
assert.Nil(t, result)
|
||||||
|
|
||||||
|
// 测试空指针输入
|
||||||
|
result = StringToUnixMilliInt64Ptr(nil)
|
||||||
|
assert.Nil(t, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStringTimeToTime(t *testing.T) {
|
||||||
|
// 测试有效时间字符串输入
|
||||||
|
input := "2023-03-09 12:34:56"
|
||||||
|
expected := time.Date(2023, 3, 9, 12, 34, 56, 0, GetDefaultTimeLocation())
|
||||||
|
result := StringTimeToTime(&input)
|
||||||
|
assert.NotNil(t, result)
|
||||||
|
assert.Equal(t, expected, *result)
|
||||||
|
|
||||||
|
// 测试有效日期字符串输入
|
||||||
|
input = "2023-03-09"
|
||||||
|
expected = time.Date(2023, 3, 9, 0, 0, 0, 0, GetDefaultTimeLocation())
|
||||||
|
result = StringTimeToTime(&input)
|
||||||
|
assert.NotNil(t, result)
|
||||||
|
assert.Equal(t, expected, *result)
|
||||||
|
|
||||||
|
// 测试无效时间字符串输入
|
||||||
|
invalidInput := "invalid-date"
|
||||||
|
result = StringTimeToTime(&invalidInput)
|
||||||
|
assert.Nil(t, result)
|
||||||
|
|
||||||
|
// 测试空字符串输入
|
||||||
|
emptyInput := ""
|
||||||
|
result = StringTimeToTime(&emptyInput)
|
||||||
|
assert.Nil(t, result)
|
||||||
|
|
||||||
|
// 测试空指针输入
|
||||||
|
result = StringTimeToTime(nil)
|
||||||
|
assert.Nil(t, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTimeToTimeString(t *testing.T) {
|
||||||
|
// 测试非空输入
|
||||||
|
now := time.Now()
|
||||||
|
result := TimeToTimeString(&now)
|
||||||
|
assert.NotNil(t, result)
|
||||||
|
expected := now.Format(TimeLayout)
|
||||||
|
assert.Equal(t, expected, *result)
|
||||||
|
|
||||||
|
// 测试空输入
|
||||||
|
result = TimeToTimeString(nil)
|
||||||
|
assert.Nil(t, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStringDateToTime(t *testing.T) {
|
||||||
|
// 测试有效日期字符串输入
|
||||||
|
input := "2023-03-09"
|
||||||
|
expected := time.Date(2023, 3, 9, 0, 0, 0, 0, GetDefaultTimeLocation())
|
||||||
|
result := StringDateToTime(&input)
|
||||||
|
assert.NotNil(t, result)
|
||||||
|
assert.Equal(t, expected, *result)
|
||||||
|
|
||||||
|
// 测试无效日期字符串输入
|
||||||
|
invalidInput := "invalid-date"
|
||||||
|
result = StringDateToTime(&invalidInput)
|
||||||
|
assert.Nil(t, result)
|
||||||
|
|
||||||
|
// 测试空字符串输入
|
||||||
|
emptyInput := ""
|
||||||
|
result = StringDateToTime(&emptyInput)
|
||||||
|
assert.Nil(t, result)
|
||||||
|
|
||||||
|
// 测试空指针输入
|
||||||
|
result = StringDateToTime(nil)
|
||||||
|
assert.Nil(t, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTimeToDateString(t *testing.T) {
|
func TestTimeToDateString(t *testing.T) {
|
||||||
fmt.Println(*TimeToTimeString(trans.Time(time.Now())))
|
fmt.Println(*TimeToTimeString(trans.Time(time.Now())))
|
||||||
fmt.Println(*TimeToDateString(trans.Time(time.Now())))
|
fmt.Println(*TimeToDateString(trans.Time(time.Now())))
|
||||||
|
|
||||||
|
// 测试非空输入
|
||||||
|
now := time.Now()
|
||||||
|
result := TimeToDateString(&now)
|
||||||
|
assert.NotNil(t, result)
|
||||||
|
expected := now.Format(DateLayout)
|
||||||
|
assert.Equal(t, expected, *result)
|
||||||
|
|
||||||
|
// 测试空输入
|
||||||
|
result = TimeToDateString(nil)
|
||||||
|
assert.Nil(t, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTimestamppbToTime(t *testing.T) {
|
||||||
|
// 测试有效输入
|
||||||
|
timestamp := timestamppb.Now()
|
||||||
|
result := TimestamppbToTime(timestamp)
|
||||||
|
assert.NotNil(t, result)
|
||||||
|
assert.Equal(t, timestamp.AsTime(), *result)
|
||||||
|
|
||||||
|
// 测试零时间输入
|
||||||
|
zeroTimestamp := timestamppb.New(time.Time{})
|
||||||
|
result = TimestamppbToTime(zeroTimestamp)
|
||||||
|
assert.NotNil(t, result)
|
||||||
|
assert.Equal(t, time.Time{}, *result)
|
||||||
|
|
||||||
|
// 测试空输入
|
||||||
|
result = TimestamppbToTime(nil)
|
||||||
|
assert.Nil(t, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTimeToTimestamppb(t *testing.T) {
|
||||||
|
// 测试非空输入
|
||||||
|
now := time.Now()
|
||||||
|
result := TimeToTimestamppb(&now)
|
||||||
|
assert.NotNil(t, result)
|
||||||
|
assert.Equal(t, timestamppb.New(now), result)
|
||||||
|
|
||||||
|
// 测试空输入
|
||||||
|
result = TimeToTimestamppb(nil)
|
||||||
|
assert.Nil(t, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDurationpb(t *testing.T) {
|
func TestDurationpb(t *testing.T) {
|
||||||
@@ -56,3 +199,109 @@ func TestDurationpb(t *testing.T) {
|
|||||||
fmt.Println(NumberToDurationpb(trans.Ptr(100.0), time.Minute).String())
|
fmt.Println(NumberToDurationpb(trans.Ptr(100.0), time.Minute).String())
|
||||||
fmt.Println(*DurationpbToNumber[float64](durationpb.New(100*time.Minute), time.Minute))
|
fmt.Println(*DurationpbToNumber[float64](durationpb.New(100*time.Minute), time.Minute))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFloatToDurationpb(t *testing.T) {
|
||||||
|
// 测试有效输入
|
||||||
|
input := 1.5 // 1.5秒
|
||||||
|
timePrecision := time.Second
|
||||||
|
expected := durationpb.New(1500 * time.Millisecond)
|
||||||
|
result := FloatToDurationpb(&input, timePrecision)
|
||||||
|
assert.NotNil(t, result)
|
||||||
|
assert.Equal(t, expected, result)
|
||||||
|
|
||||||
|
// 测试零输入
|
||||||
|
input = 0.0
|
||||||
|
expected = durationpb.New(0)
|
||||||
|
result = FloatToDurationpb(&input, timePrecision)
|
||||||
|
assert.NotNil(t, result)
|
||||||
|
assert.Equal(t, expected, result)
|
||||||
|
|
||||||
|
// 测试空输入
|
||||||
|
result = FloatToDurationpb(nil, timePrecision)
|
||||||
|
assert.Nil(t, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDurationToDurationpb(t *testing.T) {
|
||||||
|
// 测试非空输入
|
||||||
|
duration := time.Duration(5 * time.Second)
|
||||||
|
result := DurationToDurationpb(&duration)
|
||||||
|
assert.NotNil(t, result)
|
||||||
|
assert.Equal(t, durationpb.New(duration), result)
|
||||||
|
|
||||||
|
// 测试空输入
|
||||||
|
result = DurationToDurationpb(nil)
|
||||||
|
assert.Nil(t, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDurationpbToDuration(t *testing.T) {
|
||||||
|
// 测试非空输入
|
||||||
|
durationpbValue := durationpb.New(5 * time.Second)
|
||||||
|
result := DurationpbToDuration(durationpbValue)
|
||||||
|
assert.NotNil(t, result)
|
||||||
|
assert.Equal(t, 5*time.Second, *result)
|
||||||
|
|
||||||
|
// 测试空输入
|
||||||
|
result = DurationpbToDuration(nil)
|
||||||
|
assert.Nil(t, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFloat64ToDurationpb(t *testing.T) {
|
||||||
|
// 测试有效输入
|
||||||
|
input := 1.5 // 1.5秒
|
||||||
|
expected := durationpb.New(1500 * time.Millisecond)
|
||||||
|
result := Float64ToDurationpb(input)
|
||||||
|
assert.NotNil(t, result)
|
||||||
|
assert.Equal(t, expected, result)
|
||||||
|
|
||||||
|
// 测试零输入
|
||||||
|
input = 0.0
|
||||||
|
expected = durationpb.New(0)
|
||||||
|
result = Float64ToDurationpb(input)
|
||||||
|
assert.NotNil(t, result)
|
||||||
|
assert.Equal(t, expected, result)
|
||||||
|
|
||||||
|
// 测试负数输入
|
||||||
|
input = -2.5 // -2.5秒
|
||||||
|
expected = durationpb.New(-2500 * time.Millisecond)
|
||||||
|
result = Float64ToDurationpb(input)
|
||||||
|
assert.NotNil(t, result)
|
||||||
|
assert.Equal(t, expected, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSecondToDurationpb(t *testing.T) {
|
||||||
|
// 测试有效输入
|
||||||
|
input := 2.5 // 2.5秒
|
||||||
|
expected := durationpb.New(2500 * time.Millisecond)
|
||||||
|
result := SecondToDurationpb(&input)
|
||||||
|
assert.NotNil(t, result)
|
||||||
|
assert.Equal(t, expected, result)
|
||||||
|
|
||||||
|
// 测试零输入
|
||||||
|
input = 0.0
|
||||||
|
expected = durationpb.New(0)
|
||||||
|
result = SecondToDurationpb(&input)
|
||||||
|
assert.NotNil(t, result)
|
||||||
|
assert.Equal(t, expected, result)
|
||||||
|
|
||||||
|
// 测试空输入
|
||||||
|
result = SecondToDurationpb(nil)
|
||||||
|
assert.Nil(t, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDurationpbSecond(t *testing.T) {
|
||||||
|
// 测试非空输入
|
||||||
|
duration := durationpb.New(5 * time.Second)
|
||||||
|
result := DurationpbSecond(duration)
|
||||||
|
assert.NotNil(t, result)
|
||||||
|
assert.Equal(t, 5.0, *result, "应返回正确的秒数")
|
||||||
|
|
||||||
|
// 测试零输入
|
||||||
|
duration = durationpb.New(0)
|
||||||
|
result = DurationpbSecond(duration)
|
||||||
|
assert.NotNil(t, result)
|
||||||
|
assert.Equal(t, 0.0, *result, "应返回零秒")
|
||||||
|
|
||||||
|
// 测试空输入
|
||||||
|
result = DurationpbSecond(nil)
|
||||||
|
assert.Nil(t, result, "空输入应返回nil")
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user