优化文件结构、测试文件
This commit is contained in:
parent
c66b0080af
commit
1b6950b8d9
273
helper/func.go
273
helper/func.go
@ -1,15 +1,10 @@
|
||||
package helper
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"fmt"
|
||||
"github.com/dlclark/regexp2"
|
||||
"io"
|
||||
"math/rand"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type IntNumber interface {
|
||||
@ -40,224 +35,6 @@ func StructColumn[T any, M any](arr []M, field string) (r []T) {
|
||||
return
|
||||
}
|
||||
|
||||
func RangeSlice[T IntNumber](start, end, step T) []T {
|
||||
if step == 0 {
|
||||
panic("step can't be 0")
|
||||
}
|
||||
l := int((end-start+1)/step + 1)
|
||||
if l < 0 {
|
||||
l = 0 - l
|
||||
}
|
||||
r := make([]T, 0, l)
|
||||
for i := start; ; {
|
||||
r = append(r, i)
|
||||
i = i + step
|
||||
if (step > 0 && i > end) || (step < 0 && i < end) {
|
||||
break
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func StrJoin(s ...string) (str string) {
|
||||
if len(s) == 1 {
|
||||
return s[0]
|
||||
} else if len(s) > 1 {
|
||||
b := strings.Builder{}
|
||||
for _, s2 := range s {
|
||||
b.WriteString(s2)
|
||||
}
|
||||
str = b.String()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func SlicePagination[T any](arr []T, page, pageSize int) []T {
|
||||
start := (page - 1) * pageSize
|
||||
l := len(arr)
|
||||
if start > l {
|
||||
start = l
|
||||
}
|
||||
end := page * pageSize
|
||||
if l < end {
|
||||
end = l
|
||||
}
|
||||
return arr[start:end]
|
||||
}
|
||||
|
||||
func StringMd5(str string) string {
|
||||
h := md5.New()
|
||||
_, err := io.WriteString(h, str)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf("%x", h.Sum(nil))
|
||||
}
|
||||
|
||||
var allHtmlTag = regexp.MustCompile("</?.*>")
|
||||
|
||||
func StripTags(str, allowable string) string {
|
||||
html := ""
|
||||
if allowable == "" {
|
||||
return allHtmlTag.ReplaceAllString(str, "")
|
||||
}
|
||||
r := strings.Split(allowable, ">")
|
||||
re := ""
|
||||
for _, reg := range r {
|
||||
if reg == "" {
|
||||
continue
|
||||
}
|
||||
tag := strings.TrimLeft(reg, "<")
|
||||
ree := fmt.Sprintf(`%s|\/%s`, tag, tag)
|
||||
re = fmt.Sprintf("%s|%s", re, ree)
|
||||
}
|
||||
ree := strings.Trim(re, "|")
|
||||
reg := fmt.Sprintf("<(?!%s).*?>", ree)
|
||||
compile, err := regexp2.Compile(reg, regexp2.IgnoreCase)
|
||||
if err != nil {
|
||||
return str
|
||||
}
|
||||
html, err = compile.Replace(str, "", 0, -1)
|
||||
if err != nil {
|
||||
return str
|
||||
}
|
||||
return html
|
||||
}
|
||||
|
||||
var tag = regexp.MustCompile(`<(.*?)>`)
|
||||
|
||||
func StripTagsX(str, allowable string) string {
|
||||
if allowable == "" {
|
||||
return allHtmlTag.ReplaceAllString(str, "")
|
||||
}
|
||||
tags := tag.ReplaceAllString(allowable, "$1|")
|
||||
or := strings.TrimRight(tags, "|")
|
||||
reg := fmt.Sprintf(`<(/?(%s).*?)>`, or)
|
||||
regx := fmt.Sprintf(`\{\[(/?(%s).*?)\]\}`, or)
|
||||
cp, err := regexp.Compile(reg)
|
||||
if err != nil {
|
||||
return str
|
||||
}
|
||||
rep := cp.ReplaceAllString(str, "{[$1]}")
|
||||
tmp := tag.ReplaceAllString(rep, "")
|
||||
rex, err := regexp.Compile(regx)
|
||||
if err != nil {
|
||||
return str
|
||||
}
|
||||
html := rex.ReplaceAllString(tmp, "<$1>")
|
||||
return html
|
||||
}
|
||||
|
||||
var tagx = regexp.MustCompile(`(</?[a-z0-9]+?)( |>)`)
|
||||
var selfCloseTags = map[string]string{"area": "", "base": "", "basefont": "", "br": "", "col": "", "command": "", "embed": "", "frame": "", "hr": "", "img": "", "input": "", "isindex": "", "link": "", "meta": "", "param": "", "source": "", "track": "", "wbr": ""}
|
||||
|
||||
func CloseHtmlTag(str string) string {
|
||||
tags := tag.FindAllString(str, -1)
|
||||
if len(tags) < 1 {
|
||||
return str
|
||||
}
|
||||
var tagss = make([]string, 0, len(tags))
|
||||
for _, s := range tags {
|
||||
ss := strings.TrimSpace(tagx.FindString(s))
|
||||
if ss[len(ss)-1] != '>' {
|
||||
ss = fmt.Sprintf("%s>", ss)
|
||||
if _, ok := selfCloseTags[ss]; ok {
|
||||
continue
|
||||
}
|
||||
}
|
||||
tagss = append(tagss, ss)
|
||||
}
|
||||
r := SliceMap(SliceReverse(ClearClosedTag(tagss)), func(s string) string {
|
||||
return fmt.Sprintf("</%s>", strings.Trim(s, "<>"))
|
||||
})
|
||||
return strings.Join(r, "")
|
||||
}
|
||||
|
||||
func ClearClosedTag(s []string) []string {
|
||||
i := 0
|
||||
for {
|
||||
if len(s[i:]) < 2 {
|
||||
return s
|
||||
}
|
||||
l := s[i]
|
||||
r := fmt.Sprintf(`</%s>`, strings.Trim(l, "<>"))
|
||||
if s[i+1] == r {
|
||||
if len(s[i+1:]) > 1 {
|
||||
ss := s[:i]
|
||||
s = append(ss, s[i+2:]...)
|
||||
|
||||
} else {
|
||||
s = s[:i]
|
||||
}
|
||||
i = 0
|
||||
continue
|
||||
}
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
func SliceMap[T, R any](arr []T, fn func(T) R) []R {
|
||||
r := make([]R, 0, len(arr))
|
||||
for _, t := range arr {
|
||||
r = append(r, fn(t))
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func SliceFilter[T any](arr []T, fn func(T) bool) []T {
|
||||
var r []T
|
||||
for _, t := range arr {
|
||||
if fn(t) {
|
||||
r = append(r, t)
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func SliceReduce[T, R any](arr []T, fn func(T, R) R, r R) R {
|
||||
for _, t := range arr {
|
||||
r = fn(t, r)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func SliceReverse[T any](arr []T) []T {
|
||||
var r = make([]T, 0, len(arr))
|
||||
for i := len(arr); i > 0; i-- {
|
||||
r = append(r, arr[i-1])
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func SliceSelfReverse[T any](arr []T) []T {
|
||||
l := len(arr)
|
||||
half := l / 2
|
||||
for i := 0; i < half; i++ {
|
||||
arr[i], arr[l-i-1] = arr[l-i-1], arr[i]
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
func SimpleSliceToMap[K comparable, V any](arr []V, fn func(V) K) map[K]V {
|
||||
return SliceToMap(arr, func(v V) (K, V) {
|
||||
return fn(v), v
|
||||
}, true)
|
||||
}
|
||||
|
||||
func SliceToMap[K comparable, V, T any](arr []V, fn func(V) (K, T), isCoverPrev bool) map[K]T {
|
||||
m := make(map[K]T)
|
||||
for _, v := range arr {
|
||||
k, r := fn(v)
|
||||
if !isCoverPrev {
|
||||
if _, ok := m[k]; ok {
|
||||
continue
|
||||
}
|
||||
}
|
||||
m[k] = r
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func RandNum[T IntNumber](start, end T) T {
|
||||
end++
|
||||
return T(rand.Int63n(int64(end-start))) + start
|
||||
@ -317,56 +94,6 @@ func Sum[T IntNumber | ~float64 | ~float32](a ...T) T {
|
||||
return s
|
||||
}
|
||||
|
||||
func SliceChunk[T any](arr []T, size int) [][]T {
|
||||
var r [][]T
|
||||
i := 0
|
||||
for {
|
||||
if len(arr) <= size+i {
|
||||
r = append(r, arr[i:])
|
||||
break
|
||||
}
|
||||
r = append(r, arr[i:i+size])
|
||||
i += size
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func NumberToString[T IntNumber | ~float64 | ~float32](n T) string {
|
||||
return fmt.Sprintf("%v", n)
|
||||
}
|
||||
|
||||
func Slice[T any](arr []T, offset, length int) (r []T) {
|
||||
l := len(arr)
|
||||
if length == 0 {
|
||||
length = l - offset
|
||||
}
|
||||
if l > offset && l >= offset+length {
|
||||
r = append(make([]T, 0, length), arr[offset:offset+length]...)
|
||||
arr = append(arr[:offset], arr[offset+length:]...)
|
||||
} else if l <= offset {
|
||||
return
|
||||
} else if l > offset && l < offset+length {
|
||||
r = append(make([]T, 0, length), arr[offset:]...)
|
||||
arr = arr[:offset]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func Comb[T any](arr []T, m int) (r [][]T) {
|
||||
if m == 1 {
|
||||
for _, t := range arr {
|
||||
r = append(r, []T{t})
|
||||
}
|
||||
return
|
||||
}
|
||||
l := len(arr) - m
|
||||
for i := 0; i <= l; i++ {
|
||||
next := Slice(arr, i+1, 0)
|
||||
nexRes := Comb(next, m-1)
|
||||
for _, re := range nexRes {
|
||||
t := append([]T{arr[i]}, re...)
|
||||
r = append(r, t)
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
@ -74,382 +74,6 @@ func TestStructColumn(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRangeSlice(t *testing.T) {
|
||||
type args struct {
|
||||
start int
|
||||
end int
|
||||
step int
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want []int
|
||||
}{
|
||||
{
|
||||
name: "t1",
|
||||
args: args{
|
||||
start: 1,
|
||||
end: 5,
|
||||
step: 1,
|
||||
},
|
||||
want: []int{1, 2, 3, 4, 5},
|
||||
},
|
||||
{
|
||||
name: "t2",
|
||||
args: args{
|
||||
start: 0,
|
||||
end: 5,
|
||||
step: 2,
|
||||
},
|
||||
want: []int{0, 2, 4},
|
||||
},
|
||||
{
|
||||
name: "t3",
|
||||
args: args{
|
||||
start: 1,
|
||||
end: 11,
|
||||
step: 3,
|
||||
},
|
||||
want: []int{1, 4, 7, 10},
|
||||
},
|
||||
{
|
||||
name: "t4",
|
||||
args: args{
|
||||
start: 0,
|
||||
end: -5,
|
||||
step: -1,
|
||||
},
|
||||
want: []int{0, -1, -2, -3, -4, -5},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := RangeSlice(tt.args.start, tt.args.end, tt.args.step); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("RangeSlice() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestStrJoin(t *testing.T) {
|
||||
type args struct {
|
||||
s []string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantStr string
|
||||
}{
|
||||
{name: "t1", args: args{s: []string{"a", "b", "c"}}, wantStr: "abc"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if gotStr := StrJoin(tt.args.s...); gotStr != tt.wantStr {
|
||||
t.Errorf("StrJoin() = %v, want %v", gotStr, tt.wantStr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSlicePagination(t *testing.T) {
|
||||
arr := RangeSlice[int](1, 10, 1)
|
||||
type args struct {
|
||||
arr []int
|
||||
page int
|
||||
pageSize int
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want []int
|
||||
}{
|
||||
{
|
||||
name: "t1",
|
||||
args: args{
|
||||
arr: arr,
|
||||
page: 1,
|
||||
pageSize: 2,
|
||||
},
|
||||
want: RangeSlice[int](1, 2, 1),
|
||||
}, {
|
||||
name: "t2",
|
||||
args: args{
|
||||
arr: arr,
|
||||
page: 2,
|
||||
pageSize: 2,
|
||||
},
|
||||
want: RangeSlice[int](3, 4, 1),
|
||||
}, {
|
||||
name: "t3",
|
||||
args: args{
|
||||
arr: arr,
|
||||
page: 4,
|
||||
pageSize: 3,
|
||||
},
|
||||
want: []int{10},
|
||||
}, {
|
||||
name: "t4",
|
||||
args: args{
|
||||
arr: arr,
|
||||
page: 5,
|
||||
pageSize: 3,
|
||||
},
|
||||
want: []int{},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := SlicePagination(tt.args.arr, tt.args.page, tt.args.pageSize); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("SlicePagination() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestStripTags(t *testing.T) {
|
||||
type args struct {
|
||||
str string
|
||||
allowable string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "t1",
|
||||
args: args{
|
||||
str: "<p>ppppp<span>ffff</span></p><img />",
|
||||
allowable: "<p><img>",
|
||||
},
|
||||
want: "<p>pppppffff</p><img />",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := StripTags(tt.args.str, tt.args.allowable); got != tt.want {
|
||||
t.Errorf("StripTags() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestStripTagsX(t *testing.T) {
|
||||
type args struct {
|
||||
str string
|
||||
allowable string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "t1",
|
||||
args: args{
|
||||
str: "<p>ppppp<span>ffff</span></p><img />",
|
||||
allowable: "<p><img>",
|
||||
},
|
||||
want: "<p>pppppffff</p><img />",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := StripTagsX(tt.args.str, tt.args.allowable); got != tt.want {
|
||||
t.Errorf("StripTagsX() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkStripTags(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
StripTags(`<p>ppppp<span>ffff</span></p><img />`, "<p><img>")
|
||||
}
|
||||
}
|
||||
func BenchmarkStripTagsX(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
StripTagsX(`<p>ppppp<span>ffff</span></p><img />`, "<p><img>")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCloseHtmlTag(t *testing.T) {
|
||||
type args struct {
|
||||
str string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "t1",
|
||||
args: args{str: `<pre class="wp-block-preformatted">GRANT privileges ON databasename.tablename TO 'username'@'h...<p class="read-more"><a href="/p/305">继续阅读</a></p>`},
|
||||
want: "</pre>",
|
||||
},
|
||||
{
|
||||
name: "t2",
|
||||
args: args{str: `<pre><div>`},
|
||||
want: "</div></pre>",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := CloseHtmlTag(tt.args.str); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("CloseHtmlTag() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_clearTag(t *testing.T) {
|
||||
type args struct {
|
||||
s []string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want []string
|
||||
}{
|
||||
{
|
||||
name: "t1",
|
||||
args: args{s: []string{"<pre>", "<p>", "<span>", "</span>"}},
|
||||
want: []string{"<pre>", "<p>"},
|
||||
},
|
||||
{
|
||||
name: "t2",
|
||||
args: args{s: []string{"<pre>", "</pre>", "<div>", "<span>", "</span>"}},
|
||||
want: []string{"<div>"},
|
||||
},
|
||||
{
|
||||
name: "t3",
|
||||
args: args{s: []string{"<pre>", "</pre>"}},
|
||||
want: []string{},
|
||||
},
|
||||
{
|
||||
name: "t4",
|
||||
args: args{s: []string{"<pre>", "<p>"}},
|
||||
want: []string{"<pre>", "<p>"},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := ClearClosedTag(tt.args.s); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("ClearClosedTag() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSliceReduce(t *testing.T) {
|
||||
type args struct {
|
||||
arr []int
|
||||
fn func(int, int) int
|
||||
r int
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want int
|
||||
}{
|
||||
{
|
||||
name: "t1",
|
||||
args: args{arr: RangeSlice(1, 10, 1), fn: func(i int, i2 int) int {
|
||||
return i + i2
|
||||
}},
|
||||
want: 55,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := SliceReduce(tt.args.arr, tt.args.fn, tt.args.r); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("SliceReduce() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSliceFilter(t *testing.T) {
|
||||
type args struct {
|
||||
arr []int
|
||||
fn func(int) bool
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want []int
|
||||
}{
|
||||
{
|
||||
name: "t1",
|
||||
args: args{arr: RangeSlice(1, 10, 1), fn: func(i int) bool {
|
||||
return i > 4
|
||||
}},
|
||||
want: RangeSlice(5, 10, 1),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := SliceFilter(tt.args.arr, tt.args.fn); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("SliceFilter() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSliceMap(t *testing.T) {
|
||||
type args struct {
|
||||
arr []int8
|
||||
fn func(int8) int
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want []int
|
||||
}{
|
||||
{
|
||||
name: "t1",
|
||||
args: args{
|
||||
arr: RangeSlice[int8](1, 10, 1),
|
||||
fn: func(i int8) int {
|
||||
return int(i)
|
||||
},
|
||||
},
|
||||
want: RangeSlice(1, 10, 1),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := SliceMap(tt.args.arr, tt.args.fn); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("SliceMap() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSliceReverse(t *testing.T) {
|
||||
type args struct {
|
||||
arr []int
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want []int
|
||||
}{
|
||||
{
|
||||
name: "t1",
|
||||
args: args{arr: RangeSlice(1, 10, 1)},
|
||||
want: RangeSlice(10, 1, -1),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := SliceReverse(tt.args.arr); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("SliceReverse() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestToInterface(t *testing.T) {
|
||||
type args struct {
|
||||
v int
|
||||
@ -474,111 +98,6 @@ func TestToInterface(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSliceSelfReverse(t *testing.T) {
|
||||
type args struct {
|
||||
arr []int
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want []int
|
||||
}{
|
||||
{
|
||||
name: "t1",
|
||||
args: args{
|
||||
arr: RangeSlice(1, 10, 1),
|
||||
},
|
||||
want: RangeSlice(10, 1, -1),
|
||||
}, {
|
||||
name: "t2",
|
||||
args: args{
|
||||
arr: RangeSlice(1, 9, 1),
|
||||
},
|
||||
want: RangeSlice(9, 1, -1),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := SliceSelfReverse(tt.args.arr); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("SliceSelfReverse() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSliceToMap(t *testing.T) {
|
||||
type ss struct {
|
||||
id int
|
||||
v string
|
||||
}
|
||||
type args struct {
|
||||
arr []ss
|
||||
fn func(ss) (int, ss)
|
||||
isCoverPrev bool
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want map[int]ss
|
||||
}{
|
||||
{
|
||||
name: "t1",
|
||||
args: args{
|
||||
arr: []ss{{1, "k1"}, {2, "v2"}, {2, "v3"}},
|
||||
fn: func(s ss) (int, ss) {
|
||||
return s.id, s
|
||||
},
|
||||
isCoverPrev: true,
|
||||
},
|
||||
want: map[int]ss{1: {1, "k1"}, 2: {2, "v3"}},
|
||||
}, {
|
||||
name: "t2",
|
||||
args: args{
|
||||
arr: []ss{{1, "k1"}, {2, "v2"}, {2, "v3"}},
|
||||
fn: func(s ss) (int, ss) {
|
||||
return s.id, s
|
||||
},
|
||||
isCoverPrev: false,
|
||||
},
|
||||
want: map[int]ss{1: {1, "k1"}, 2: {2, "v2"}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := SliceToMap(tt.args.arr, tt.args.fn, tt.args.isCoverPrev); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("SliceToMap() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSimpleSliceToMap(t *testing.T) {
|
||||
type args struct {
|
||||
arr []int
|
||||
fn func(int) int
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want map[int]int
|
||||
}{
|
||||
{
|
||||
name: "t1",
|
||||
args: args{arr: []int{1, 2, 3}, fn: func(i int) int {
|
||||
return i
|
||||
}},
|
||||
want: map[int]int{1: 1, 2: 2, 3: 3},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := SimpleSliceToMap(tt.args.arr, tt.args.fn); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("SimpleSliceToMap() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRandNum(t *testing.T) {
|
||||
type args struct {
|
||||
start int
|
||||
@ -709,42 +228,6 @@ func TestMax(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSliceChunk(t *testing.T) {
|
||||
type args struct {
|
||||
arr []int
|
||||
size int
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want [][]int
|
||||
}{
|
||||
{
|
||||
name: "t1",
|
||||
args: args{
|
||||
arr: RangeSlice(1, 7, 1),
|
||||
size: 2,
|
||||
},
|
||||
want: [][]int{{1, 2}, {3, 4}, {5, 6}, {7}},
|
||||
},
|
||||
{
|
||||
name: "t2",
|
||||
args: args{
|
||||
arr: RangeSlice(1, 8, 1),
|
||||
size: 2,
|
||||
},
|
||||
want: [][]int{{1, 2}, {3, 4}, {5, 6}, {7, 8}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := SliceChunk(tt.args.arr, tt.args.size); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("SliceChunk() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSum(t *testing.T) {
|
||||
type args struct {
|
||||
a []int
|
||||
@ -797,114 +280,3 @@ func TestNumberToString(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSlice(t *testing.T) {
|
||||
type args struct {
|
||||
arr []int
|
||||
offset int
|
||||
length int
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantR []int
|
||||
}{
|
||||
{
|
||||
name: "t1",
|
||||
args: args{
|
||||
arr: RangeSlice(1, 10, 1),
|
||||
offset: 3,
|
||||
length: 2,
|
||||
},
|
||||
wantR: RangeSlice(4, 5, 1),
|
||||
},
|
||||
{
|
||||
name: "t2",
|
||||
args: args{
|
||||
arr: RangeSlice(1, 10, 1),
|
||||
offset: 3,
|
||||
length: 0,
|
||||
},
|
||||
wantR: RangeSlice(4, 10, 1),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if gotR := Slice(tt.args.arr, tt.args.offset, tt.args.length); !reflect.DeepEqual(gotR, tt.wantR) {
|
||||
t.Errorf("Slice() = %v, want %v", gotR, tt.wantR)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestComb(t *testing.T) {
|
||||
type args struct {
|
||||
arr []int
|
||||
m int
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantR [][]int
|
||||
}{
|
||||
{
|
||||
name: "t1",
|
||||
args: args{
|
||||
arr: RangeSlice(1, 5, 1),
|
||||
m: 2,
|
||||
},
|
||||
wantR: [][]int{
|
||||
{1, 2},
|
||||
{1, 3},
|
||||
{1, 4},
|
||||
{1, 5},
|
||||
{2, 3},
|
||||
{2, 4},
|
||||
{2, 5},
|
||||
{3, 4},
|
||||
{3, 5},
|
||||
{4, 5},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "t2",
|
||||
args: args{
|
||||
arr: RangeSlice(1, 5, 1),
|
||||
m: 3,
|
||||
},
|
||||
wantR: [][]int{
|
||||
{1, 2, 3},
|
||||
{1, 2, 4},
|
||||
{1, 2, 5},
|
||||
{1, 3, 4},
|
||||
{1, 3, 5},
|
||||
{1, 4, 5},
|
||||
{2, 3, 4},
|
||||
{2, 3, 5},
|
||||
{2, 4, 5},
|
||||
{3, 4, 5},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "t3",
|
||||
args: args{
|
||||
arr: RangeSlice(1, 5, 1),
|
||||
m: 4,
|
||||
},
|
||||
wantR: [][]int{
|
||||
{1, 2, 3, 4},
|
||||
{1, 2, 3, 5},
|
||||
{1, 2, 4, 5},
|
||||
{1, 3, 4, 5},
|
||||
{2, 3, 4, 5},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if gotR := Comb(tt.args.arr, tt.args.m); !reflect.DeepEqual(gotR, tt.wantR) {
|
||||
t.Errorf("Comb() = %v, want %v", gotR, tt.wantR)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
105
helper/html.go
105
helper/html.go
@ -1,6 +1,9 @@
|
||||
package helper
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/dlclark/regexp2"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@ -58,3 +61,105 @@ func htmlSpecialCharsDecode(text string, flags int) string {
|
||||
}
|
||||
return text
|
||||
}
|
||||
|
||||
var allHtmlTag = regexp.MustCompile("</?.*>")
|
||||
|
||||
func StripTags(str, allowable string) string {
|
||||
html := ""
|
||||
if allowable == "" {
|
||||
return allHtmlTag.ReplaceAllString(str, "")
|
||||
}
|
||||
r := strings.Split(allowable, ">")
|
||||
re := ""
|
||||
for _, reg := range r {
|
||||
if reg == "" {
|
||||
continue
|
||||
}
|
||||
tag := strings.TrimLeft(reg, "<")
|
||||
ree := fmt.Sprintf(`%s|\/%s`, tag, tag)
|
||||
re = fmt.Sprintf("%s|%s", re, ree)
|
||||
}
|
||||
ree := strings.Trim(re, "|")
|
||||
reg := fmt.Sprintf("<(?!%s).*?>", ree)
|
||||
compile, err := regexp2.Compile(reg, regexp2.IgnoreCase)
|
||||
if err != nil {
|
||||
return str
|
||||
}
|
||||
html, err = compile.Replace(str, "", 0, -1)
|
||||
if err != nil {
|
||||
return str
|
||||
}
|
||||
return html
|
||||
}
|
||||
|
||||
var tag = regexp.MustCompile(`<(.*?)>`)
|
||||
|
||||
func StripTagsX(str, allowable string) string {
|
||||
if allowable == "" {
|
||||
return allHtmlTag.ReplaceAllString(str, "")
|
||||
}
|
||||
tags := tag.ReplaceAllString(allowable, "$1|")
|
||||
or := strings.TrimRight(tags, "|")
|
||||
reg := fmt.Sprintf(`<(/?(%s).*?)>`, or)
|
||||
regx := fmt.Sprintf(`\{\[(/?(%s).*?)\]\}`, or)
|
||||
cp, err := regexp.Compile(reg)
|
||||
if err != nil {
|
||||
return str
|
||||
}
|
||||
rep := cp.ReplaceAllString(str, "{[$1]}")
|
||||
tmp := tag.ReplaceAllString(rep, "")
|
||||
rex, err := regexp.Compile(regx)
|
||||
if err != nil {
|
||||
return str
|
||||
}
|
||||
html := rex.ReplaceAllString(tmp, "<$1>")
|
||||
return html
|
||||
}
|
||||
|
||||
var tagx = regexp.MustCompile(`(</?[a-z0-9]+?)( |>)`)
|
||||
var selfCloseTags = map[string]string{"area": "", "base": "", "basefont": "", "br": "", "col": "", "command": "", "embed": "", "frame": "", "hr": "", "img": "", "input": "", "isindex": "", "link": "", "meta": "", "param": "", "source": "", "track": "", "wbr": ""}
|
||||
|
||||
func CloseHtmlTag(str string) string {
|
||||
tags := tag.FindAllString(str, -1)
|
||||
if len(tags) < 1 {
|
||||
return str
|
||||
}
|
||||
var tagss = make([]string, 0, len(tags))
|
||||
for _, s := range tags {
|
||||
ss := strings.TrimSpace(tagx.FindString(s))
|
||||
if ss[len(ss)-1] != '>' {
|
||||
ss = fmt.Sprintf("%s>", ss)
|
||||
if _, ok := selfCloseTags[ss]; ok {
|
||||
continue
|
||||
}
|
||||
}
|
||||
tagss = append(tagss, ss)
|
||||
}
|
||||
r := SliceMap(SliceReverse(ClearClosedTag(tagss)), func(s string) string {
|
||||
return fmt.Sprintf("</%s>", strings.Trim(s, "<>"))
|
||||
})
|
||||
return strings.Join(r, "")
|
||||
}
|
||||
|
||||
func ClearClosedTag(s []string) []string {
|
||||
i := 0
|
||||
for {
|
||||
if len(s[i:]) < 2 {
|
||||
return s
|
||||
}
|
||||
l := s[i]
|
||||
r := fmt.Sprintf(`</%s>`, strings.Trim(l, "<>"))
|
||||
if s[i+1] == r {
|
||||
if len(s[i+1:]) > 1 {
|
||||
ss := s[:i]
|
||||
s = append(ss, s[i+2:]...)
|
||||
|
||||
} else {
|
||||
s = s[:i]
|
||||
}
|
||||
i = 0
|
||||
continue
|
||||
}
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
package helper
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_htmlSpecialChars(t *testing.T) {
|
||||
type args struct {
|
||||
@ -90,3 +93,138 @@ func Test_htmlSpecialCharsDecode(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestStripTags(t *testing.T) {
|
||||
type args struct {
|
||||
str string
|
||||
allowable string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "t1",
|
||||
args: args{
|
||||
str: "<p>ppppp<span>ffff</span></p><img />",
|
||||
allowable: "<p><img>",
|
||||
},
|
||||
want: "<p>pppppffff</p><img />",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := StripTags(tt.args.str, tt.args.allowable); got != tt.want {
|
||||
t.Errorf("StripTags() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestStripTagsX(t *testing.T) {
|
||||
type args struct {
|
||||
str string
|
||||
allowable string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "t1",
|
||||
args: args{
|
||||
str: "<p>ppppp<span>ffff</span></p><img />",
|
||||
allowable: "<p><img>",
|
||||
},
|
||||
want: "<p>pppppffff</p><img />",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := StripTagsX(tt.args.str, tt.args.allowable); got != tt.want {
|
||||
t.Errorf("StripTagsX() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkStripTags(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
StripTags(`<p>ppppp<span>ffff</span></p><img />`, "<p><img>")
|
||||
}
|
||||
}
|
||||
func BenchmarkStripTagsX(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
StripTagsX(`<p>ppppp<span>ffff</span></p><img />`, "<p><img>")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCloseHtmlTag(t *testing.T) {
|
||||
type args struct {
|
||||
str string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "t1",
|
||||
args: args{str: `<pre class="wp-block-preformatted">GRANT privileges ON databasename.tablename TO 'username'@'h...<p class="read-more"><a href="/p/305">继续阅读</a></p>`},
|
||||
want: "</pre>",
|
||||
},
|
||||
{
|
||||
name: "t2",
|
||||
args: args{str: `<pre><div>`},
|
||||
want: "</div></pre>",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := CloseHtmlTag(tt.args.str); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("CloseHtmlTag() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_clearTag(t *testing.T) {
|
||||
type args struct {
|
||||
s []string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want []string
|
||||
}{
|
||||
{
|
||||
name: "t1",
|
||||
args: args{s: []string{"<pre>", "<p>", "<span>", "</span>"}},
|
||||
want: []string{"<pre>", "<p>"},
|
||||
},
|
||||
{
|
||||
name: "t2",
|
||||
args: args{s: []string{"<pre>", "</pre>", "<div>", "<span>", "</span>"}},
|
||||
want: []string{"<div>"},
|
||||
},
|
||||
{
|
||||
name: "t3",
|
||||
args: args{s: []string{"<pre>", "</pre>"}},
|
||||
want: []string{},
|
||||
},
|
||||
{
|
||||
name: "t4",
|
||||
args: args{s: []string{"<pre>", "<p>"}},
|
||||
want: []string{"<pre>", "<p>"},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := ClearClosedTag(tt.args.s); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("ClearClosedTag() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
145
helper/slice.go
Normal file
145
helper/slice.go
Normal file
@ -0,0 +1,145 @@
|
||||
package helper
|
||||
|
||||
func SliceMap[T, R any](arr []T, fn func(T) R) []R {
|
||||
r := make([]R, 0, len(arr))
|
||||
for _, t := range arr {
|
||||
r = append(r, fn(t))
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func SliceFilter[T any](arr []T, fn func(T) bool) []T {
|
||||
var r []T
|
||||
for _, t := range arr {
|
||||
if fn(t) {
|
||||
r = append(r, t)
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func SliceReduce[T, R any](arr []T, fn func(T, R) R, r R) R {
|
||||
for _, t := range arr {
|
||||
r = fn(t, r)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func SliceReverse[T any](arr []T) []T {
|
||||
var r = make([]T, 0, len(arr))
|
||||
for i := len(arr); i > 0; i-- {
|
||||
r = append(r, arr[i-1])
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func SliceSelfReverse[T any](arr []T) []T {
|
||||
l := len(arr)
|
||||
half := l / 2
|
||||
for i := 0; i < half; i++ {
|
||||
arr[i], arr[l-i-1] = arr[l-i-1], arr[i]
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
func SimpleSliceToMap[K comparable, V any](arr []V, fn func(V) K) map[K]V {
|
||||
return SliceToMap(arr, func(v V) (K, V) {
|
||||
return fn(v), v
|
||||
}, true)
|
||||
}
|
||||
|
||||
func SliceToMap[K comparable, V, T any](arr []V, fn func(V) (K, T), isCoverPrev bool) map[K]T {
|
||||
m := make(map[K]T)
|
||||
for _, v := range arr {
|
||||
k, r := fn(v)
|
||||
if !isCoverPrev {
|
||||
if _, ok := m[k]; ok {
|
||||
continue
|
||||
}
|
||||
}
|
||||
m[k] = r
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func RangeSlice[T IntNumber](start, end, step T) []T {
|
||||
if step == 0 {
|
||||
panic("step can't be 0")
|
||||
}
|
||||
l := int((end-start+1)/step + 1)
|
||||
if l < 0 {
|
||||
l = 0 - l
|
||||
}
|
||||
r := make([]T, 0, l)
|
||||
for i := start; ; {
|
||||
r = append(r, i)
|
||||
i = i + step
|
||||
if (step > 0 && i > end) || (step < 0 && i < end) {
|
||||
break
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func SlicePagination[T any](arr []T, page, pageSize int) []T {
|
||||
start := (page - 1) * pageSize
|
||||
l := len(arr)
|
||||
if start > l {
|
||||
start = l
|
||||
}
|
||||
end := page * pageSize
|
||||
if l < end {
|
||||
end = l
|
||||
}
|
||||
return arr[start:end]
|
||||
}
|
||||
|
||||
func SliceChunk[T any](arr []T, size int) [][]T {
|
||||
var r [][]T
|
||||
i := 0
|
||||
for {
|
||||
if len(arr) <= size+i {
|
||||
r = append(r, arr[i:])
|
||||
break
|
||||
}
|
||||
r = append(r, arr[i:i+size])
|
||||
i += size
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func Slice[T any](arr []T, offset, length int) (r []T) {
|
||||
l := len(arr)
|
||||
if length == 0 {
|
||||
length = l - offset
|
||||
}
|
||||
if l > offset && l >= offset+length {
|
||||
r = append(make([]T, 0, length), arr[offset:offset+length]...)
|
||||
arr = append(arr[:offset], arr[offset+length:]...)
|
||||
} else if l <= offset {
|
||||
return
|
||||
} else if l > offset && l < offset+length {
|
||||
r = append(make([]T, 0, length), arr[offset:]...)
|
||||
arr = arr[:offset]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func Comb[T any](arr []T, m int) (r [][]T) {
|
||||
if m == 1 {
|
||||
for _, t := range arr {
|
||||
r = append(r, []T{t})
|
||||
}
|
||||
return
|
||||
}
|
||||
l := len(arr) - m
|
||||
for i := 0; i <= l; i++ {
|
||||
next := Slice(arr, i+1, 0)
|
||||
nexRes := Comb(next, m-1)
|
||||
for _, re := range nexRes {
|
||||
t := append([]T{arr[i]}, re...)
|
||||
r = append(r, t)
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
479
helper/slice_test.go
Normal file
479
helper/slice_test.go
Normal file
@ -0,0 +1,479 @@
|
||||
package helper
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSlicePagination(t *testing.T) {
|
||||
arr := RangeSlice[int](1, 10, 1)
|
||||
type args struct {
|
||||
arr []int
|
||||
page int
|
||||
pageSize int
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want []int
|
||||
}{
|
||||
{
|
||||
name: "t1",
|
||||
args: args{
|
||||
arr: arr,
|
||||
page: 1,
|
||||
pageSize: 2,
|
||||
},
|
||||
want: RangeSlice[int](1, 2, 1),
|
||||
}, {
|
||||
name: "t2",
|
||||
args: args{
|
||||
arr: arr,
|
||||
page: 2,
|
||||
pageSize: 2,
|
||||
},
|
||||
want: RangeSlice[int](3, 4, 1),
|
||||
}, {
|
||||
name: "t3",
|
||||
args: args{
|
||||
arr: arr,
|
||||
page: 4,
|
||||
pageSize: 3,
|
||||
},
|
||||
want: []int{10},
|
||||
}, {
|
||||
name: "t4",
|
||||
args: args{
|
||||
arr: arr,
|
||||
page: 5,
|
||||
pageSize: 3,
|
||||
},
|
||||
want: []int{},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := SlicePagination(tt.args.arr, tt.args.page, tt.args.pageSize); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("SlicePagination() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSliceReduce(t *testing.T) {
|
||||
type args struct {
|
||||
arr []int
|
||||
fn func(int, int) int
|
||||
r int
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want int
|
||||
}{
|
||||
{
|
||||
name: "t1",
|
||||
args: args{arr: RangeSlice(1, 10, 1), fn: func(i int, i2 int) int {
|
||||
return i + i2
|
||||
}},
|
||||
want: 55,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := SliceReduce(tt.args.arr, tt.args.fn, tt.args.r); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("SliceReduce() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSliceFilter(t *testing.T) {
|
||||
type args struct {
|
||||
arr []int
|
||||
fn func(int) bool
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want []int
|
||||
}{
|
||||
{
|
||||
name: "t1",
|
||||
args: args{arr: RangeSlice(1, 10, 1), fn: func(i int) bool {
|
||||
return i > 4
|
||||
}},
|
||||
want: RangeSlice(5, 10, 1),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := SliceFilter(tt.args.arr, tt.args.fn); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("SliceFilter() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSliceMap(t *testing.T) {
|
||||
type args struct {
|
||||
arr []int8
|
||||
fn func(int8) int
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want []int
|
||||
}{
|
||||
{
|
||||
name: "t1",
|
||||
args: args{
|
||||
arr: RangeSlice[int8](1, 10, 1),
|
||||
fn: func(i int8) int {
|
||||
return int(i)
|
||||
},
|
||||
},
|
||||
want: RangeSlice(1, 10, 1),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := SliceMap(tt.args.arr, tt.args.fn); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("SliceMap() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSliceReverse(t *testing.T) {
|
||||
type args struct {
|
||||
arr []int
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want []int
|
||||
}{
|
||||
{
|
||||
name: "t1",
|
||||
args: args{arr: RangeSlice(1, 10, 1)},
|
||||
want: RangeSlice(10, 1, -1),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := SliceReverse(tt.args.arr); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("SliceReverse() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRangeSlice(t *testing.T) {
|
||||
type args struct {
|
||||
start int
|
||||
end int
|
||||
step int
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want []int
|
||||
}{
|
||||
{
|
||||
name: "t1",
|
||||
args: args{
|
||||
start: 1,
|
||||
end: 5,
|
||||
step: 1,
|
||||
},
|
||||
want: []int{1, 2, 3, 4, 5},
|
||||
},
|
||||
{
|
||||
name: "t2",
|
||||
args: args{
|
||||
start: 0,
|
||||
end: 5,
|
||||
step: 2,
|
||||
},
|
||||
want: []int{0, 2, 4},
|
||||
},
|
||||
{
|
||||
name: "t3",
|
||||
args: args{
|
||||
start: 1,
|
||||
end: 11,
|
||||
step: 3,
|
||||
},
|
||||
want: []int{1, 4, 7, 10},
|
||||
},
|
||||
{
|
||||
name: "t4",
|
||||
args: args{
|
||||
start: 0,
|
||||
end: -5,
|
||||
step: -1,
|
||||
},
|
||||
want: []int{0, -1, -2, -3, -4, -5},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := RangeSlice(tt.args.start, tt.args.end, tt.args.step); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("RangeSlice() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSlice(t *testing.T) {
|
||||
type args struct {
|
||||
arr []int
|
||||
offset int
|
||||
length int
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantR []int
|
||||
}{
|
||||
{
|
||||
name: "t1",
|
||||
args: args{
|
||||
arr: RangeSlice(1, 10, 1),
|
||||
offset: 3,
|
||||
length: 2,
|
||||
},
|
||||
wantR: RangeSlice(4, 5, 1),
|
||||
},
|
||||
{
|
||||
name: "t2",
|
||||
args: args{
|
||||
arr: RangeSlice(1, 10, 1),
|
||||
offset: 3,
|
||||
length: 0,
|
||||
},
|
||||
wantR: RangeSlice(4, 10, 1),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if gotR := Slice(tt.args.arr, tt.args.offset, tt.args.length); !reflect.DeepEqual(gotR, tt.wantR) {
|
||||
t.Errorf("Slice() = %v, want %v", gotR, tt.wantR)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestComb(t *testing.T) {
|
||||
type args struct {
|
||||
arr []int
|
||||
m int
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantR [][]int
|
||||
}{
|
||||
{
|
||||
name: "t1",
|
||||
args: args{
|
||||
arr: RangeSlice(1, 5, 1),
|
||||
m: 2,
|
||||
},
|
||||
wantR: [][]int{
|
||||
{1, 2},
|
||||
{1, 3},
|
||||
{1, 4},
|
||||
{1, 5},
|
||||
{2, 3},
|
||||
{2, 4},
|
||||
{2, 5},
|
||||
{3, 4},
|
||||
{3, 5},
|
||||
{4, 5},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "t2",
|
||||
args: args{
|
||||
arr: RangeSlice(1, 5, 1),
|
||||
m: 3,
|
||||
},
|
||||
wantR: [][]int{
|
||||
{1, 2, 3},
|
||||
{1, 2, 4},
|
||||
{1, 2, 5},
|
||||
{1, 3, 4},
|
||||
{1, 3, 5},
|
||||
{1, 4, 5},
|
||||
{2, 3, 4},
|
||||
{2, 3, 5},
|
||||
{2, 4, 5},
|
||||
{3, 4, 5},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "t3",
|
||||
args: args{
|
||||
arr: RangeSlice(1, 5, 1),
|
||||
m: 4,
|
||||
},
|
||||
wantR: [][]int{
|
||||
{1, 2, 3, 4},
|
||||
{1, 2, 3, 5},
|
||||
{1, 2, 4, 5},
|
||||
{1, 3, 4, 5},
|
||||
{2, 3, 4, 5},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if gotR := Comb(tt.args.arr, tt.args.m); !reflect.DeepEqual(gotR, tt.wantR) {
|
||||
t.Errorf("Comb() = %v, want %v", gotR, tt.wantR)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSliceChunk(t *testing.T) {
|
||||
type args struct {
|
||||
arr []int
|
||||
size int
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want [][]int
|
||||
}{
|
||||
{
|
||||
name: "t1",
|
||||
args: args{
|
||||
arr: RangeSlice(1, 7, 1),
|
||||
size: 2,
|
||||
},
|
||||
want: [][]int{{1, 2}, {3, 4}, {5, 6}, {7}},
|
||||
},
|
||||
{
|
||||
name: "t2",
|
||||
args: args{
|
||||
arr: RangeSlice(1, 8, 1),
|
||||
size: 2,
|
||||
},
|
||||
want: [][]int{{1, 2}, {3, 4}, {5, 6}, {7, 8}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := SliceChunk(tt.args.arr, tt.args.size); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("SliceChunk() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSimpleSliceToMap(t *testing.T) {
|
||||
type args struct {
|
||||
arr []int
|
||||
fn func(int) int
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want map[int]int
|
||||
}{
|
||||
{
|
||||
name: "t1",
|
||||
args: args{arr: []int{1, 2, 3}, fn: func(i int) int {
|
||||
return i
|
||||
}},
|
||||
want: map[int]int{1: 1, 2: 2, 3: 3},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := SimpleSliceToMap(tt.args.arr, tt.args.fn); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("SimpleSliceToMap() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSliceToMap(t *testing.T) {
|
||||
type ss struct {
|
||||
id int
|
||||
v string
|
||||
}
|
||||
type args struct {
|
||||
arr []ss
|
||||
fn func(ss) (int, ss)
|
||||
isCoverPrev bool
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want map[int]ss
|
||||
}{
|
||||
{
|
||||
name: "t1",
|
||||
args: args{
|
||||
arr: []ss{{1, "k1"}, {2, "v2"}, {2, "v3"}},
|
||||
fn: func(s ss) (int, ss) {
|
||||
return s.id, s
|
||||
},
|
||||
isCoverPrev: true,
|
||||
},
|
||||
want: map[int]ss{1: {1, "k1"}, 2: {2, "v3"}},
|
||||
}, {
|
||||
name: "t2",
|
||||
args: args{
|
||||
arr: []ss{{1, "k1"}, {2, "v2"}, {2, "v3"}},
|
||||
fn: func(s ss) (int, ss) {
|
||||
return s.id, s
|
||||
},
|
||||
isCoverPrev: false,
|
||||
},
|
||||
want: map[int]ss{1: {1, "k1"}, 2: {2, "v2"}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := SliceToMap(tt.args.arr, tt.args.fn, tt.args.isCoverPrev); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("SliceToMap() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSliceSelfReverse(t *testing.T) {
|
||||
type args struct {
|
||||
arr []int
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want []int
|
||||
}{
|
||||
{
|
||||
name: "t1",
|
||||
args: args{
|
||||
arr: RangeSlice(1, 10, 1),
|
||||
},
|
||||
want: RangeSlice(10, 1, -1),
|
||||
}, {
|
||||
name: "t2",
|
||||
args: args{
|
||||
arr: RangeSlice(1, 9, 1),
|
||||
},
|
||||
want: RangeSlice(9, 1, -1),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := SliceSelfReverse(tt.args.arr); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("SliceSelfReverse() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
30
helper/strings.go
Normal file
30
helper/strings.go
Normal file
@ -0,0 +1,30 @@
|
||||
package helper
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func StrJoin(s ...string) (str string) {
|
||||
if len(s) == 1 {
|
||||
return s[0]
|
||||
} else if len(s) > 1 {
|
||||
b := strings.Builder{}
|
||||
for _, s2 := range s {
|
||||
b.WriteString(s2)
|
||||
}
|
||||
str = b.String()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func StringMd5(str string) string {
|
||||
h := md5.New()
|
||||
_, err := io.WriteString(h, str)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf("%x", h.Sum(nil))
|
||||
}
|
23
helper/strings_test.go
Normal file
23
helper/strings_test.go
Normal file
@ -0,0 +1,23 @@
|
||||
package helper
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestStrJoin(t *testing.T) {
|
||||
type args struct {
|
||||
s []string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantStr string
|
||||
}{
|
||||
{name: "t1", args: args{s: []string{"a", "b", "c"}}, wantStr: "abc"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if gotStr := StrJoin(tt.args.s...); gotStr != tt.wantStr {
|
||||
t.Errorf("StrJoin() = %v, want %v", gotStr, tt.wantStr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -2,9 +2,11 @@ package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"github/fthvgb1/wp-go/helper"
|
||||
"github/fthvgb1/wp-go/internal/config"
|
||||
"github/fthvgb1/wp-go/internal/db"
|
||||
wp2 "github/fthvgb1/wp-go/internal/models"
|
||||
"github/fthvgb1/wp-go/internal/models"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
@ -34,7 +36,7 @@ func TestFind(t *testing.T) {
|
||||
in [][]any
|
||||
}
|
||||
type posts struct {
|
||||
wp2.Posts
|
||||
models.Posts
|
||||
N int `db:"n"`
|
||||
}
|
||||
tests := []struct {
|
||||
@ -105,7 +107,7 @@ func TestFind(t *testing.T) {
|
||||
in: nil,
|
||||
},
|
||||
wantR: func() []posts {
|
||||
r, err := Select[posts](ctx, "select post_status,count(*) n from "+wp2.Posts{}.Table()+" where ID<1000 group by post_status having n>1")
|
||||
r, err := Select[posts](ctx, "select post_status,count(*) n from "+models.Posts{}.Table()+" where ID<1000 group by post_status having n>1")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -150,10 +152,10 @@ func TestFind(t *testing.T) {
|
||||
group: "a.post_author",
|
||||
order: SqlBuilder{{"n", "desc"}},
|
||||
join: SqlBuilder{
|
||||
{"a", "left join", wp2.Users{}.Table() + " b", "a.post_author=b.ID"},
|
||||
{"a", "left join", models.Users{}.Table() + " b", "a.post_author=b.ID"},
|
||||
{"left join", "wp_term_relationships c", "a.Id=c.object_id"},
|
||||
{"left join", wp2.TermTaxonomy{}.Table() + " d", "c.term_taxonomy_id=d.term_taxonomy_id"},
|
||||
{"left join", wp2.Terms{}.Table() + " e", "d.term_id=e.term_id"},
|
||||
{"left join", models.TermTaxonomy{}.Table() + " d", "c.term_taxonomy_id=d.term_taxonomy_id"},
|
||||
{"left join", models.Terms{}.Table() + " e", "d.term_id=e.term_id"},
|
||||
},
|
||||
having: SqlBuilder{{"n", ">", "0", "int"}},
|
||||
limit: 10,
|
||||
@ -191,7 +193,7 @@ func TestFindOneById(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want wp2.Posts
|
||||
want models.Posts
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
@ -199,10 +201,12 @@ func TestFindOneById(t *testing.T) {
|
||||
args: args{
|
||||
1,
|
||||
},
|
||||
want: func() wp2.Posts {
|
||||
r, err := Get[wp2.Posts](ctx, "select * from "+wp2.Posts{}.Table()+" where ID=?", 1)
|
||||
if err != nil {
|
||||
want: func() models.Posts {
|
||||
r, err := Get[models.Posts](ctx, "select * from "+models.Posts{}.Table()+" where ID=?", 1)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
panic(err)
|
||||
} else if err == sql.ErrNoRows {
|
||||
err = nil
|
||||
}
|
||||
return r
|
||||
}(),
|
||||
@ -211,7 +215,10 @@ func TestFindOneById(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := FindOneById[wp2.Posts](ctx, tt.args.id)
|
||||
got, err := FindOneById[models.Posts](ctx, tt.args.id)
|
||||
if err == sql.ErrNoRows {
|
||||
err = nil
|
||||
}
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("FindOneById() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
@ -233,7 +240,7 @@ func TestFirstOne(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want wp2.Posts
|
||||
want models.Posts
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
@ -245,10 +252,12 @@ func TestFirstOne(t *testing.T) {
|
||||
in: nil,
|
||||
},
|
||||
wantErr: false,
|
||||
want: func() wp2.Posts {
|
||||
r, err := Get[wp2.Posts](ctx, "select * from "+wp2.Posts{}.Table()+" where post_status='publish' order by ID desc limit 1")
|
||||
if err != nil {
|
||||
want: func() models.Posts {
|
||||
r, err := Get[models.Posts](ctx, "select * from "+models.Posts{}.Table()+" where post_status='publish' order by ID desc limit 1")
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
panic(err)
|
||||
} else if err == sql.ErrNoRows {
|
||||
err = nil
|
||||
}
|
||||
return r
|
||||
}(),
|
||||
@ -256,7 +265,7 @@ func TestFirstOne(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := FirstOne[wp2.Posts](ctx, tt.args.where, tt.args.fields, tt.args.order, tt.args.in...)
|
||||
got, err := FirstOne[models.Posts](ctx, tt.args.where, tt.args.fields, tt.args.order, tt.args.in...)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("FirstOne() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
@ -268,33 +277,6 @@ func TestFirstOne(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
type args struct {
|
||||
sql string
|
||||
params []any
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantR wp2.Posts
|
||||
wantErr bool
|
||||
}{
|
||||
{},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
gotR, err := Get[wp2.Posts](ctx, tt.args.sql, tt.args.params...)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("Get() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(gotR, tt.wantR) {
|
||||
t.Errorf("Get() gotR = %v, want %v", gotR, tt.wantR)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLastOne(t *testing.T) {
|
||||
type args struct {
|
||||
where ParseWhere
|
||||
@ -304,7 +286,7 @@ func TestLastOne(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want wp2.Posts
|
||||
want models.Posts
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
@ -316,8 +298,8 @@ func TestLastOne(t *testing.T) {
|
||||
fields: "*",
|
||||
in: nil,
|
||||
},
|
||||
want: func() wp2.Posts {
|
||||
r, err := Get[wp2.Posts](ctx, "select * from "+wp2.Posts{}.Table()+" where post_status='publish' order by "+wp2.Posts{}.PrimaryKey()+" desc limit 1")
|
||||
want: func() models.Posts {
|
||||
r, err := Get[models.Posts](ctx, "select * from "+models.Posts{}.Table()+" where post_status='publish' order by "+models.Posts{}.PrimaryKey()+" desc limit 1")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -327,7 +309,7 @@ func TestLastOne(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := LastOne[wp2.Posts](ctx, tt.args.where, tt.args.fields, tt.args.in...)
|
||||
got, err := LastOne[models.Posts](ctx, tt.args.where, tt.args.fields, tt.args.in...)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("LastOne() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
@ -339,33 +321,6 @@ func TestLastOne(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSelect(t *testing.T) {
|
||||
type args struct {
|
||||
sql string
|
||||
params []any
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want []wp2.Posts
|
||||
wantErr bool
|
||||
}{
|
||||
{},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := Select[wp2.Posts](ctx, tt.args.sql, tt.args.params...)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("Select() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("Select() got = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSimpleFind(t *testing.T) {
|
||||
type args struct {
|
||||
where ParseWhere
|
||||
@ -375,14 +330,33 @@ func TestSimpleFind(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want []wp2.Posts
|
||||
want []models.Posts
|
||||
wantErr bool
|
||||
}{
|
||||
{},
|
||||
{
|
||||
name: "t1",
|
||||
args: args{
|
||||
where: SqlBuilder{
|
||||
{"ID", "in", ""},
|
||||
},
|
||||
fields: "*",
|
||||
in: [][]any{{1, 2}},
|
||||
},
|
||||
want: func() (r []models.Posts) {
|
||||
r, err := Select[models.Posts](ctx, "select * from "+models.Posts{}.Table()+" where ID in (?,?)", 1, 2)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
panic(err)
|
||||
} else if err == sql.ErrNoRows {
|
||||
err = nil
|
||||
}
|
||||
return
|
||||
}(),
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := SimpleFind[wp2.Posts](ctx, tt.args.where, tt.args.fields, tt.args.in...)
|
||||
got, err := SimpleFind[models.Posts](ctx, tt.args.where, tt.args.fields, tt.args.in...)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("SimpleFind() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
@ -409,15 +383,41 @@ func TestSimplePagination(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantR []wp2.Posts
|
||||
wantR []models.Posts
|
||||
wantTotal int
|
||||
wantErr bool
|
||||
}{
|
||||
{},
|
||||
{
|
||||
name: "t1",
|
||||
args: args{
|
||||
where: SqlBuilder{
|
||||
{"ID", "in", ""},
|
||||
},
|
||||
fields: "*",
|
||||
group: "",
|
||||
page: 1,
|
||||
pageSize: 5,
|
||||
order: nil,
|
||||
join: nil,
|
||||
having: nil,
|
||||
in: [][]any{helper.SliceMap[int, any](helper.RangeSlice(431, 440, 1), helper.ToAny[int])},
|
||||
},
|
||||
wantR: func() (r []models.Posts) {
|
||||
r, err := Select[models.Posts](ctx, "select * from "+models.Posts{}.Table()+" where ID in (?,?,?,?,?)", helper.SliceMap[int, any](helper.RangeSlice(431, 435, 1), helper.ToAny[int])...)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
panic(err)
|
||||
} else if err == sql.ErrNoRows {
|
||||
err = nil
|
||||
}
|
||||
return
|
||||
}(),
|
||||
wantTotal: 10,
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
gotR, gotTotal, err := SimplePagination[wp2.Posts](ctx, tt.args.where, tt.args.fields, tt.args.group, tt.args.page, tt.args.pageSize, tt.args.order, tt.args.join, tt.args.having, tt.args.in...)
|
||||
gotR, gotTotal, err := SimplePagination[models.Posts](ctx, tt.args.where, tt.args.fields, tt.args.group, tt.args.page, tt.args.pageSize, tt.args.order, tt.args.join, tt.args.having, tt.args.in...)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("SimplePagination() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
|
Loading…
Reference in New Issue
Block a user