mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-08 14:42:27 +08:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
62c570d29b | ||
|
|
4e5d3c2603 | ||
|
|
561b590e13 | ||
|
|
f2ed3c6270 | ||
|
|
fee6cb17f3 | ||
|
|
7d39d1319b | ||
|
|
59d7281967 | ||
|
|
bdf052819d | ||
|
|
0148af4839 | ||
|
|
99b74e6fc6 | ||
|
|
499c1df9bd | ||
|
|
6af13a01de | ||
|
|
0c4b512084 | ||
|
|
4848647918 | ||
|
|
45fc84d1f2 |
22
.github/workflows/codecov.yml
vendored
Normal file
22
.github/workflows/codecov.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
name: Test and coverage
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 2
|
||||||
|
- uses: actions/setup-go@v2
|
||||||
|
with:
|
||||||
|
go-version: "1.16"
|
||||||
|
- name: Run coverage
|
||||||
|
run: go test -v ./... -race -coverprofile=coverage.txt -covermode=atomic
|
||||||
|
- name: Upload coverage to Codecov
|
||||||
|
run: bash <(curl -s https://codecov.io/bash)
|
||||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1,3 +1,6 @@
|
|||||||
.idea/*
|
.idea/*
|
||||||
.vscode/*
|
.vscode/*
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
cryptor/*.txt
|
||||||
|
fileutil/*.txt
|
||||||
|
cryptor/*.pem
|
||||||
16
README.md
16
README.md
@@ -5,6 +5,12 @@
|
|||||||
</p>
|
</p>
|
||||||
<div align="center" style="text-align: center;">
|
<div align="center" style="text-align: center;">
|
||||||
|
|
||||||
|

|
||||||
|
[](https://github.com/duke-git/lancet/releases)
|
||||||
|
[](https://pkg.go.dev/github.com/duke-git/lancet)
|
||||||
|
[](https://goreportcard.com/report/github.com/duke-git/lancet)
|
||||||
|
[](https://codecov.io/gh/duke-git/lancet)
|
||||||
|
[](https://github.com/duke-git/lancet/blob/main/LICENSE)
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -53,7 +59,7 @@ func main() {
|
|||||||
|
|
||||||
### API Documentation
|
### API Documentation
|
||||||
|
|
||||||
#### 1. convertor contains some functions for data convertion.
|
#### 1. convertor contains some functions for data convertion
|
||||||
|
|
||||||
- Support conversion between commonly used data types.
|
- Support conversion between commonly used data types.
|
||||||
- Usage: import "github.com/duke-git/lancet/cryptor"
|
- Usage: import "github.com/duke-git/lancet/cryptor"
|
||||||
@@ -91,7 +97,7 @@ func ToString(value interface{}) string //convert value to string
|
|||||||
func StructToMap(value interface{}) (map[string]interface{}, error) //convert struct to map, only convert exported field, tag `json` should be set
|
func StructToMap(value interface{}) (map[string]interface{}, error) //convert struct to map, only convert exported field, tag `json` should be set
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 2. cryptor is for data encryption and decryption.
|
#### 2. cryptor is for data encryption and decryption
|
||||||
|
|
||||||
- Support md5, hmac, aes, des, ras.
|
- Support md5, hmac, aes, des, ras.
|
||||||
- Usage: import "github.com/duke-git/lancet/cryptor"
|
- Usage: import "github.com/duke-git/lancet/cryptor"
|
||||||
@@ -284,7 +290,7 @@ func HttpPatch(url string, params ...interface{}) (*http.Response, error) //http
|
|||||||
func ConvertMapToQueryString(param map[string]interface{}) string //convert map to url query string
|
func ConvertMapToQueryString(param map[string]interface{}) string //convert map to url query string
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 7. random is for rand string and int generation.
|
#### 7. random is for rand string and int generation
|
||||||
|
|
||||||
- Generate random string and int.
|
- Generate random string and int.
|
||||||
- Usage: import "github.com/duke-git/lancet/random".
|
- Usage: import "github.com/duke-git/lancet/random".
|
||||||
@@ -336,7 +342,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- Function list:
|
- Function list:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func Contain(slice interface{}, value interface{}) bool //check if the value is in the slice or not
|
func Contain(slice interface{}, value interface{}) bool //check if the value is in the slice or not
|
||||||
@@ -379,7 +385,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- Function list:
|
- Function list:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func After(s, char string) string //create substring in source string after position when char first appear
|
func After(s, char string) string //create substring in source string after position when char first appear
|
||||||
|
|||||||
@@ -5,6 +5,12 @@
|
|||||||
</p>
|
</p>
|
||||||
<div align="center" style="text-align: center;">
|
<div align="center" style="text-align: center;">
|
||||||
|
|
||||||
|

|
||||||
|
[](https://github.com/duke-git/lancet/releases)
|
||||||
|
[](https://pkg.go.dev/github.com/duke-git/lancet)
|
||||||
|
[](https://goreportcard.com/report/github.com/duke-git/lancet)
|
||||||
|
[](https://codecov.io/gh/duke-git/lancet)
|
||||||
|
[](https://github.com/duke-git/lancet/blob/main/LICENSE)
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -57,7 +63,7 @@ func main() {
|
|||||||
#### 1. convertor数据转换包
|
#### 1. convertor数据转换包
|
||||||
|
|
||||||
- 转换函数支持常用数据类型之间的转换
|
- 转换函数支持常用数据类型之间的转换
|
||||||
- 导入包:import "github.com/duke-git/lancet/cryptor"
|
- 导入包:import "github.com/duke-git/lancet/convertor"
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ func ToBool(s string) (bool, error) {
|
|||||||
return strconv.ParseBool(s)
|
return strconv.ParseBool(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToBool convert interface to bytes
|
// ToBytes convert interface to bytes
|
||||||
func ToBytes(data interface{}) ([]byte, error) {
|
func ToBytes(data interface{}) ([]byte, error) {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
enc := gob.NewEncoder(&buf)
|
enc := gob.NewEncoder(&buf)
|
||||||
|
|||||||
@@ -2,9 +2,10 @@ package convertor
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/utils"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/duke-git/lancet/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestToChar(t *testing.T) {
|
func TestToChar(t *testing.T) {
|
||||||
@@ -58,8 +59,12 @@ func TestToBytes(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestToInt(t *testing.T) {
|
func TestToInt(t *testing.T) {
|
||||||
cases := []interface{}{"123", "-123", 123, "abc", false, "111111111111111111111111111111111111111"}
|
cases := []interface{}{"123", "-123", 123,
|
||||||
expected := []int64{123, -123, 123, 0, 0, 0}
|
uint(123), uint8(123), uint16(123), uint32(123), uint64(123),
|
||||||
|
float32(12.3), float64(12.3),
|
||||||
|
"abc", false, "111111111111111111111111111111111111111"}
|
||||||
|
|
||||||
|
expected := []int64{123, -123, 123, 123, 123, 123, 123, 123, 12, 12, 0, 0, 0}
|
||||||
|
|
||||||
for i := 0; i < len(cases); i++ {
|
for i := 0; i < len(cases); i++ {
|
||||||
res, _ := ToInt(cases[i])
|
res, _ := ToInt(cases[i])
|
||||||
@@ -71,8 +76,14 @@ func TestToInt(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestToFloat(t *testing.T) {
|
func TestToFloat(t *testing.T) {
|
||||||
cases := []interface{}{"", "-1", "-.11", "1.23e3", ".123e10", "abc"}
|
cases := []interface{}{
|
||||||
expected := []float64{0, -1, -0.11, 1230, 0.123e10, 0}
|
"", "-1", "-.11", "1.23e3", ".123e10", "abc",
|
||||||
|
int(0), int8(1), int16(-1), int32(123), int64(123),
|
||||||
|
uint(123), uint8(123), uint16(123), uint32(123), uint64(123),
|
||||||
|
float64(12.3), float32(12.3),
|
||||||
|
}
|
||||||
|
expected := []float64{0, -1, -0.11, 1230, 0.123e10, 0,
|
||||||
|
0, 1, -1, 123, 123, 123, 123, 123, 123, 123, 12.3, 12.300000190734863}
|
||||||
|
|
||||||
for i := 0; i < len(cases); i++ {
|
for i := 0; i < len(cases); i++ {
|
||||||
res, _ := ToFloat(cases[i])
|
res, _ := ToFloat(cases[i])
|
||||||
@@ -84,41 +95,37 @@ func TestToFloat(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestToString(t *testing.T) {
|
func TestToString(t *testing.T) {
|
||||||
// basic type
|
|
||||||
toString(t, "a1", "a1")
|
|
||||||
toString(t, 111, "111")
|
|
||||||
toString(t, 111.01, "111.01")
|
|
||||||
toString(t, true, "true")
|
|
||||||
//toString(t, 1.5+10i, "(1.5+10i)")
|
|
||||||
|
|
||||||
// slice
|
|
||||||
aSlice := []int{1, 2, 3}
|
|
||||||
toString(t, aSlice, "[1,2,3]")
|
|
||||||
|
|
||||||
// map
|
// map
|
||||||
aMap := make(map[string]int)
|
aMap := make(map[string]int)
|
||||||
aMap["a"] = 1
|
aMap["a"] = 1
|
||||||
aMap["b"] = 2
|
aMap["b"] = 2
|
||||||
aMap["c"] = 3
|
aMap["c"] = 3
|
||||||
|
|
||||||
toString(t, aMap, "{\"a\":1,\"b\":2,\"c\":3}")
|
|
||||||
|
|
||||||
// struct
|
// struct
|
||||||
type TestStruct struct {
|
type TestStruct struct {
|
||||||
Name string
|
Name string
|
||||||
}
|
}
|
||||||
aStruct := TestStruct{Name: "TestStruct"}
|
aStruct := TestStruct{Name: "TestStruct"}
|
||||||
toString(t, aStruct, "{\"Name\":\"TestStruct\"}")
|
|
||||||
}
|
|
||||||
|
|
||||||
func toString(t *testing.T, test interface{}, expected string) {
|
cases := []interface{}{
|
||||||
res := ToString(test)
|
int(0), int8(1), int16(-1), int32(123), int64(123),
|
||||||
if res != expected {
|
uint(123), uint8(123), uint16(123), uint32(123), uint64(123),
|
||||||
utils.LogFailedTestInfo(t, "ToString", test, expected, res)
|
float64(12.3), float32(12.3),
|
||||||
t.FailNow()
|
true, false,
|
||||||
|
[]int{1, 2, 3}, aMap, aStruct, []byte{104, 101, 108, 108, 111}}
|
||||||
|
|
||||||
|
expected := []string{"0", "1", "-1", "123", "123", "123", "123", "123",
|
||||||
|
"123", "123", "12.3", "12.300000190734863", "true", "false",
|
||||||
|
"[1,2,3]", "{\"a\":1,\"b\":2,\"c\":3}", "{\"Name\":\"TestStruct\"}", "hello"}
|
||||||
|
|
||||||
|
for i := 0; i < len(cases); i++ {
|
||||||
|
res := ToString(cases[i])
|
||||||
|
if res != expected[i] {
|
||||||
|
utils.LogFailedTestInfo(t, "ToString", cases[i], expected[i], res)
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToJson(t *testing.T) {
|
func TestToJson(t *testing.T) {
|
||||||
// map
|
// map
|
||||||
aMap := make(map[string]int)
|
aMap := make(map[string]int)
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ func AesCbcEncrypt(data, key []byte) []byte {
|
|||||||
return encrypted
|
return encrypted
|
||||||
}
|
}
|
||||||
|
|
||||||
// AesEcbDecrypt decrypt data with key use AES CBC algorithm
|
// AesCbcDecrypt decrypt data with key use AES CBC algorithm
|
||||||
// len(key) should be 16, 24 or 32
|
// len(key) should be 16, 24 or 32
|
||||||
func AesCbcDecrypt(encrypted, key []byte) []byte {
|
func AesCbcDecrypt(encrypted, key []byte) []byte {
|
||||||
block, _ := aes.NewCipher(key)
|
block, _ := aes.NewCipher(key)
|
||||||
|
|||||||
@@ -21,13 +21,13 @@ func Base64StdEncode(s string) string {
|
|||||||
return base64.StdEncoding.EncodeToString([]byte(s))
|
return base64.StdEncoding.EncodeToString([]byte(s))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Base64StdEncode decode a base64 encoded string
|
// Base64StdDecode decode a base64 encoded string
|
||||||
func Base64StdDecode(s string) string {
|
func Base64StdDecode(s string) string {
|
||||||
b, _ := base64.StdEncoding.DecodeString(s)
|
b, _ := base64.StdEncoding.DecodeString(s)
|
||||||
return string(b)
|
return string(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Md5Str return the md5 value of string
|
// Md5String return the md5 value of string
|
||||||
func Md5String(s string) string {
|
func Md5String(s string) string {
|
||||||
h := md5.New()
|
h := md5.New()
|
||||||
h.Write([]byte(s))
|
h.Write([]byte(s))
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
// Use of this source code is governed by MIT license.
|
// Use of this source code is governed by MIT license.
|
||||||
|
|
||||||
// Package datetime implements some functions to format date and time.
|
// Package datetime implements some functions to format date and time.
|
||||||
|
|
||||||
// Note:
|
// Note:
|
||||||
// 1. `format` param in FormatTimeToStr function should be as flow:
|
// 1. `format` param in FormatTimeToStr function should be as flow:
|
||||||
//"yyyy-mm-dd hh:mm:ss"
|
//"yyyy-mm-dd hh:mm:ss"
|
||||||
@@ -23,7 +22,6 @@
|
|||||||
//"mm"
|
//"mm"
|
||||||
//"hh:mm:ss"
|
//"hh:mm:ss"
|
||||||
//"mm:ss"
|
//"mm:ss"
|
||||||
|
|
||||||
package datetime
|
package datetime
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
// Use of this source code is governed by MIT license.
|
// Use of this source code is governed by MIT license.
|
||||||
|
|
||||||
// Package fileutil implements some basic functions for file operations
|
// Package fileutil implements some basic functions for file operations
|
||||||
|
|
||||||
package fileutil
|
package fileutil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -12,13 +11,13 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsFileExists checks if a file or directory exists
|
// IsExist checks if a file or directory exists
|
||||||
func IsExist(path string) bool {
|
func IsExist(path string) bool {
|
||||||
_, err := os.Stat(path)
|
_, err := os.Stat(path)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if errors.Is(err, os.ErrExist) {
|
if errors.Is(err, os.ErrNotExist) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
@@ -35,7 +34,7 @@ func CreateFile(path string) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsFileExists checks if the path is directy or not
|
// IsDir checks if the path is directory or not
|
||||||
func IsDir(path string) bool {
|
func IsDir(path string) bool {
|
||||||
file, err := os.Stat(path)
|
file, err := os.Stat(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -70,9 +69,8 @@ func CopyFile(srcFilePath string, dstFilePath string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
return nil
|
return nil
|
||||||
} else {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
package fileutil
|
package fileutil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/duke-git/lancet/utils"
|
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/duke-git/lancet/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestIsExist(t *testing.T) {
|
func TestIsExist(t *testing.T) {
|
||||||
cases := []string{"./", "./a.txt"}
|
cases := []string{"./", "./file.go", "./a.txt"}
|
||||||
expected := []bool{true, false}
|
expected := []bool{true, true, false}
|
||||||
|
|
||||||
for i := 0; i < len(cases); i++ {
|
for i := 0; i < len(cases); i++ {
|
||||||
res := IsExist(cases[i])
|
res := IsExist(cases[i])
|
||||||
@@ -86,11 +87,11 @@ func TestCopyFile(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestListFileNames(t *testing.T) {
|
func TestListFileNames(t *testing.T) {
|
||||||
filesInCurrentPath, err := ListFileNames("./")
|
filesInCurrentPath, err := ListFileNames("../datetime/")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
expected := []string{"file.go", "file_test.go"}
|
expected := []string{"datetime.go", "datetime_test.go"}
|
||||||
if !reflect.DeepEqual(filesInCurrentPath, expected) {
|
if !reflect.DeepEqual(filesInCurrentPath, expected) {
|
||||||
utils.LogFailedTestInfo(t, "ToChar", "./", expected, filesInCurrentPath)
|
utils.LogFailedTestInfo(t, "ToChar", "./", expected, filesInCurrentPath)
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
|
|||||||
@@ -14,4 +14,4 @@ func Comma(v interface{}, symbol string) string {
|
|||||||
return symbol + commaString(s[:dotIndex]) + s[dotIndex:]
|
return symbol + commaString(s[:dotIndex]) + s[dotIndex:]
|
||||||
}
|
}
|
||||||
return symbol + commaString(s)
|
return symbol + commaString(s)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +1,28 @@
|
|||||||
package formatter
|
package formatter
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/duke-git/lancet/utils"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/duke-git/lancet/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestComma(t *testing.T) {
|
func TestComma(t *testing.T) {
|
||||||
comma(t, "", "","")
|
comma(t, "", "", "")
|
||||||
comma(t, "aa", "","")
|
comma(t, "aa", "", "")
|
||||||
comma(t, "123", "","123")
|
comma(t, "aa.a", "", "")
|
||||||
comma(t, "12345", "","12,345")
|
comma(t, []int{1}, "", "")
|
||||||
comma(t, 12345, "","12,345")
|
comma(t, "123", "", "123")
|
||||||
comma(t, 12345, "$","$12,345")
|
comma(t, "12345", "", "12,345")
|
||||||
comma(t, 12345, "¥","¥12,345")
|
comma(t, 12345, "", "12,345")
|
||||||
comma(t, 12345.6789, "","12,345.6789")
|
comma(t, 12345, "$", "$12,345")
|
||||||
|
comma(t, 12345, "¥", "¥12,345")
|
||||||
|
comma(t, 12345.6789, "", "12,345.6789")
|
||||||
}
|
}
|
||||||
|
|
||||||
func comma(t *testing.T, test interface{}, symbol string, expected interface{}) {
|
func comma(t *testing.T, test interface{}, symbol string, expected interface{}) {
|
||||||
res:= Comma(test, symbol)
|
res := Comma(test, symbol)
|
||||||
if res != expected {
|
if res != expected {
|
||||||
utils.LogFailedTestInfo(t, "Comma", test, expected, res)
|
utils.LogFailedTestInfo(t, "Comma", test, expected, res)
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,22 +18,23 @@ func numString(value interface{}) string {
|
|||||||
switch reflect.TypeOf(value).Kind() {
|
switch reflect.TypeOf(value).Kind() {
|
||||||
case reflect.Int, reflect.Int64, reflect.Float32, reflect.Float64:
|
case reflect.Int, reflect.Int64, reflect.Float32, reflect.Float64:
|
||||||
return fmt.Sprintf("%v", value)
|
return fmt.Sprintf("%v", value)
|
||||||
case reflect.String: {
|
case reflect.String:
|
||||||
sv := fmt.Sprintf("%v", value)
|
{
|
||||||
if strings.Contains(sv, ".") {
|
sv := fmt.Sprintf("%v", value)
|
||||||
_, err := strconv.ParseFloat(sv, 64)
|
if strings.Contains(sv, ".") {
|
||||||
if err == nil {
|
_, err := strconv.ParseFloat(sv, 64)
|
||||||
return sv
|
if err == nil {
|
||||||
}
|
return sv
|
||||||
}else {
|
}
|
||||||
_, err := strconv.ParseInt(sv, 10, 64)
|
} else {
|
||||||
if err == nil {
|
_, err := strconv.ParseInt(sv, 10, 64)
|
||||||
return sv
|
if err == nil {
|
||||||
|
return sv
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ func GetPublicIpInfo() (*PublicIpInfo, error) {
|
|||||||
return &ip, nil
|
return &ip, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PublicIpInfo public ip info: country, region, isp, city, lat, lon, ip
|
||||||
type PublicIpInfo struct {
|
type PublicIpInfo struct {
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
Country string `json:"country"`
|
Country string `json:"country"`
|
||||||
|
|||||||
@@ -2,9 +2,10 @@ package netutil
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/utils"
|
|
||||||
"net"
|
"net"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/duke-git/lancet/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGetInternalIp(t *testing.T) {
|
func TestGetInternalIp(t *testing.T) {
|
||||||
|
|||||||
@@ -4,12 +4,18 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"github.com/duke-git/lancet/utils"
|
|
||||||
"log"
|
"log"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/duke-git/lancet/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestHttpGet(t *testing.T) {
|
func TestHttpGet(t *testing.T) {
|
||||||
|
_, e := HttpGet("", nil)
|
||||||
|
if e == nil {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
|
||||||
url := "https://gutendex.com/books?"
|
url := "https://gutendex.com/books?"
|
||||||
queryParams := make(map[string]interface{})
|
queryParams := make(map[string]interface{})
|
||||||
queryParams["ids"] = "1"
|
queryParams["ids"] = "1"
|
||||||
|
|||||||
@@ -2,10 +2,11 @@ package random
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/utils"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"regexp"
|
"regexp"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/duke-git/lancet/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRandString(t *testing.T) {
|
func TestRandString(t *testing.T) {
|
||||||
@@ -21,26 +22,44 @@ func TestRandString(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestRandInt(t *testing.T) {
|
func TestRandInt(t *testing.T) {
|
||||||
randInt := RandInt(1, 10)
|
res1 := RandInt(1, 10)
|
||||||
|
if res1 < 1 || res1 >= 10 {
|
||||||
|
utils.LogFailedTestInfo(t, "RandInt", "RandInt(1, 10)", "RandInt(1, 10) should between [1, 10) ", res1)
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
|
||||||
if randInt < 1 || randInt >= 10 {
|
res2 := RandInt(1, 1)
|
||||||
utils.LogFailedTestInfo(t, "RandInt", "RandInt(1, 10)", "RandInt(1, 10) should between [1, 10) ", randInt)
|
if res2 != 1 {
|
||||||
|
utils.LogFailedTestInfo(t, "RandInt", "RandInt(1, 1)", "RandInt(1, 1) should be 1 ", res2)
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
res3 := RandInt(10, 1)
|
||||||
|
if res3 < 1 || res3 >= 10 {
|
||||||
|
utils.LogFailedTestInfo(t, "RandInt", "RandInt(10, 1)", "RandInt(10, 1) should between [1, 10) ", res3)
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRandBytes(t *testing.T) {
|
func TestRandBytes(t *testing.T) {
|
||||||
randBytes := RandBytes(4)
|
randBytes := RandBytes(4)
|
||||||
|
|
||||||
if len(randBytes) != 4 {
|
if len(randBytes) != 4 {
|
||||||
utils.LogFailedTestInfo(t, "RandBytes", "RandBytes(4)", "RandBytes(4) should return 4 element of []bytes", randBytes)
|
utils.LogFailedTestInfo(t, "RandBytes", "RandBytes(4)", "RandBytes(4) should return 4 element of []bytes", randBytes)
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
v := reflect.ValueOf(randBytes)
|
v := reflect.ValueOf(randBytes)
|
||||||
et := v.Type().Elem()
|
et := v.Type().Elem()
|
||||||
if v.Kind() != reflect.Slice || et.Kind() != reflect.Uint8 {
|
if v.Kind() != reflect.Slice || et.Kind() != reflect.Uint8 {
|
||||||
utils.LogFailedTestInfo(t, "RandBytes", "RandBytes(4)", "RandBytes(4) should return 4 element of []bytes", randBytes)
|
utils.LogFailedTestInfo(t, "RandBytes", "RandBytes(4)", "RandBytes(4) should return 4 element of []bytes", randBytes)
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
randErr := RandBytes(0)
|
||||||
|
if randErr != nil {
|
||||||
|
utils.LogFailedTestInfo(t, "RandBytes", "RandBytes(0)", "RandBytes(0) should return nil", randErr)
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,17 +137,16 @@ func Map(slice, function interface{}) interface{} {
|
|||||||
// The function signature should be func(index int, value1, value2 interface{}) interface{} .
|
// The function signature should be func(index int, value1, value2 interface{}) interface{} .
|
||||||
func Reduce(slice, function, zero interface{}) interface{} {
|
func Reduce(slice, function, zero interface{}) interface{} {
|
||||||
sv := sliceValue(slice)
|
sv := sliceValue(slice)
|
||||||
|
elementType := sv.Type().Elem()
|
||||||
|
|
||||||
len := sv.Len()
|
len := sv.Len()
|
||||||
if len == 0 {
|
if len == 0 {
|
||||||
return zero
|
return zero
|
||||||
} else if len == 1 {
|
} else if len == 1 {
|
||||||
return sv.Index(0)
|
return sv.Index(0).Interface()
|
||||||
}
|
}
|
||||||
|
|
||||||
elementType := sv.Type().Elem()
|
|
||||||
fn := functionValue(function)
|
fn := functionValue(function)
|
||||||
|
|
||||||
if checkSliceCallbackFuncSignature(fn, elementType, elementType, elementType) {
|
if checkSliceCallbackFuncSignature(fn, elementType, elementType, elementType) {
|
||||||
t := elementType.String()
|
t := elementType.String()
|
||||||
panic("Reduce function must be of type func(int, " + t + ", " + t + ")" + t)
|
panic("Reduce function must be of type func(int, " + t + ", " + t + ")" + t)
|
||||||
|
|||||||
@@ -14,6 +14,15 @@ func TestContain(t *testing.T) {
|
|||||||
|
|
||||||
var t2 []string
|
var t2 []string
|
||||||
contain(t, t2, "1", false)
|
contain(t, t2, "1", false)
|
||||||
|
|
||||||
|
m := make(map[string]int)
|
||||||
|
m["a"] = 1
|
||||||
|
contain(t, m, "a", true)
|
||||||
|
contain(t, m, "b", false)
|
||||||
|
|
||||||
|
s := "hello"
|
||||||
|
contain(t, s, "h", true)
|
||||||
|
contain(t, s, "s", false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func contain(t *testing.T, test interface{}, value interface{}, expected bool) {
|
func contain(t *testing.T, test interface{}, value interface{}, expected bool) {
|
||||||
@@ -167,28 +176,21 @@ func TestMap(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestReduce(t *testing.T) {
|
func TestReduce(t *testing.T) {
|
||||||
s1 := []int{1, 2, 3, 4}
|
cases := [][]int{
|
||||||
f1 := func(i, v1, v2 int) int {
|
{},
|
||||||
|
{1},
|
||||||
|
{1, 2, 3, 4}}
|
||||||
|
expected := []int{0, 1, 10}
|
||||||
|
f := func(i, v1, v2 int) int {
|
||||||
return v1 + v2
|
return v1 + v2
|
||||||
}
|
}
|
||||||
e1 := 10
|
for i := 0; i < len(cases); i++ {
|
||||||
r1 := Reduce(s1, f1, 0)
|
res := Reduce(cases[i], f, 0)
|
||||||
if e1 != r1 {
|
if res != expected[i] {
|
||||||
utils.LogFailedTestInfo(t, "Reduce", s1, e1, r1)
|
utils.LogFailedTestInfo(t, "Reduce", cases[i], expected[i], res)
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// failed Reduce function should be func(i int, v1, v2 int) int
|
|
||||||
//s1 := []int{1, 2, 3, 4}
|
|
||||||
//f1 := func(i string, v1, v2 int) int { //i should be int
|
|
||||||
// return v1+v2
|
|
||||||
//}
|
|
||||||
//e1 := 10
|
|
||||||
//r1 := Reduce(s1, f1, 0)
|
|
||||||
//if e1 != r1 {
|
|
||||||
// utils.LogFailedTestInfo(t, "Reduce", s1, e1, r1)
|
|
||||||
// t.FailNow()
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIntSlice(t *testing.T) {
|
func TestIntSlice(t *testing.T) {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// LogFailedTestInfo log test failed info for internal use
|
||||||
func LogFailedTestInfo(t *testing.T, testCase, input, expected, result interface{}) {
|
func LogFailedTestInfo(t *testing.T, testCase, input, expected, result interface{}) {
|
||||||
errInfo := fmt.Sprintf("Test case %v: input is %+v, expected %v, but result is %v", testCase, input, expected, result)
|
errInfo := fmt.Sprintf("Test case %v: input is %+v, expected %v, but result is %v", testCase, input, expected, result)
|
||||||
t.Error(errInfo)
|
t.Error(errInfo)
|
||||||
|
|||||||
@@ -26,11 +26,7 @@ func IsNumberStr(s string) bool {
|
|||||||
// IsFloatStr check if the string can convert to a float.
|
// IsFloatStr check if the string can convert to a float.
|
||||||
func IsFloatStr(s string) bool {
|
func IsFloatStr(s string) bool {
|
||||||
_, e := strconv.ParseFloat(s, 64)
|
_, e := strconv.ParseFloat(s, 64)
|
||||||
|
return e == nil
|
||||||
if e != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsIntStr check if the string can convert to a integer.
|
// IsIntStr check if the string can convert to a integer.
|
||||||
@@ -42,10 +38,7 @@ func IsIntStr(s string) bool {
|
|||||||
// IsIp check if the string is a ip address.
|
// IsIp check if the string is a ip address.
|
||||||
func IsIp(ipstr string) bool {
|
func IsIp(ipstr string) bool {
|
||||||
ip := net.ParseIP(ipstr)
|
ip := net.ParseIP(ipstr)
|
||||||
if ip == nil {
|
return ip != nil
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsIpV4 check if the string is a ipv4 address.
|
// IsIpV4 check if the string is a ipv4 address.
|
||||||
@@ -123,9 +116,9 @@ func IsChinesePhone(phone string) bool {
|
|||||||
|
|
||||||
// IsCreditCard check if the string is credit card.
|
// IsCreditCard check if the string is credit card.
|
||||||
func IsCreditCard(creditCart string) bool {
|
func IsCreditCard(creditCart string) bool {
|
||||||
pattern := `^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|(222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\d{3})\\d{11}|6[27][0-9]{14})$`
|
pattern := `^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|(222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\d{3})\\d{11}|6[27][0-9]{14})$`
|
||||||
reg := regexp.MustCompile(pattern)
|
reg := regexp.MustCompile(pattern)
|
||||||
return reg.MatchString(creditCart)
|
return reg.MatchString(creditCart)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsBase64 check if the string is base64 string.
|
// IsBase64 check if the string is base64 string.
|
||||||
@@ -191,4 +184,3 @@ func IsWeakPassword(password string) bool {
|
|||||||
|
|
||||||
return (num || letter) && !special
|
return (num || letter) && !special
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ func isCreditCard(t *testing.T, source string, expected bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestIsBase64(t *testing.T) {
|
func TestIsBase64(t *testing.T) {
|
||||||
isBase64(t, "aGVsbG8", true)
|
isBase64(t, "aGVsbG8=", true)
|
||||||
isBase64(t, "123456", false)
|
isBase64(t, "123456", false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user