优化文件结构、测试文件

This commit is contained in:
xing 2023-01-13 12:31:35 +08:00
parent c66b0080af
commit 1b6950b8d9
9 changed files with 1001 additions and 982 deletions

View File

@ -1,15 +1,10 @@
package helper package helper
import ( import (
"crypto/md5"
"fmt" "fmt"
"github.com/dlclark/regexp2"
"io"
"math/rand" "math/rand"
"reflect" "reflect"
"regexp"
"sort" "sort"
"strings"
) )
type IntNumber interface { type IntNumber interface {
@ -40,224 +35,6 @@ func StructColumn[T any, M any](arr []M, field string) (r []T) {
return 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 { func RandNum[T IntNumber](start, end T) T {
end++ end++
return T(rand.Int63n(int64(end-start))) + start return T(rand.Int63n(int64(end-start))) + start
@ -317,56 +94,6 @@ func Sum[T IntNumber | ~float64 | ~float32](a ...T) T {
return s 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 { func NumberToString[T IntNumber | ~float64 | ~float32](n T) string {
return fmt.Sprintf("%v", n) 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
}

View File

@ -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) { func TestToInterface(t *testing.T) {
type args struct { type args struct {
v int 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) { func TestRandNum(t *testing.T) {
type args struct { type args struct {
start int 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) { func TestSum(t *testing.T) {
type args struct { type args struct {
a []int 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)
}
})
}
}

View File

@ -1,6 +1,9 @@
package helper package helper
import ( import (
"fmt"
"github.com/dlclark/regexp2"
"regexp"
"strings" "strings"
) )
@ -58,3 +61,105 @@ func htmlSpecialCharsDecode(text string, flags int) string {
} }
return text 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++
}
}

View File

@ -1,6 +1,9 @@
package helper package helper
import "testing" import (
"reflect"
"testing"
)
func Test_htmlSpecialChars(t *testing.T) { func Test_htmlSpecialChars(t *testing.T) {
type args struct { 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
View 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
View 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
View 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
View 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)
}
})
}
}

View File

@ -2,9 +2,11 @@ package model
import ( import (
"context" "context"
"database/sql"
"github/fthvgb1/wp-go/helper"
"github/fthvgb1/wp-go/internal/config" "github/fthvgb1/wp-go/internal/config"
"github/fthvgb1/wp-go/internal/db" "github/fthvgb1/wp-go/internal/db"
wp2 "github/fthvgb1/wp-go/internal/models" "github/fthvgb1/wp-go/internal/models"
"reflect" "reflect"
"testing" "testing"
) )
@ -34,7 +36,7 @@ func TestFind(t *testing.T) {
in [][]any in [][]any
} }
type posts struct { type posts struct {
wp2.Posts models.Posts
N int `db:"n"` N int `db:"n"`
} }
tests := []struct { tests := []struct {
@ -105,7 +107,7 @@ func TestFind(t *testing.T) {
in: nil, in: nil,
}, },
wantR: func() []posts { 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 { if err != nil {
panic(err) panic(err)
} }
@ -150,10 +152,10 @@ func TestFind(t *testing.T) {
group: "a.post_author", group: "a.post_author",
order: SqlBuilder{{"n", "desc"}}, order: SqlBuilder{{"n", "desc"}},
join: SqlBuilder{ 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", "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", models.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.Terms{}.Table() + " e", "d.term_id=e.term_id"},
}, },
having: SqlBuilder{{"n", ">", "0", "int"}}, having: SqlBuilder{{"n", ">", "0", "int"}},
limit: 10, limit: 10,
@ -191,7 +193,7 @@ func TestFindOneById(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
args args args args
want wp2.Posts want models.Posts
wantErr bool wantErr bool
}{ }{
{ {
@ -199,10 +201,12 @@ func TestFindOneById(t *testing.T) {
args: args{ args: args{
1, 1,
}, },
want: func() wp2.Posts { want: func() models.Posts {
r, err := Get[wp2.Posts](ctx, "select * from "+wp2.Posts{}.Table()+" where ID=?", 1) r, err := Get[models.Posts](ctx, "select * from "+models.Posts{}.Table()+" where ID=?", 1)
if err != nil { if err != nil && err != sql.ErrNoRows {
panic(err) panic(err)
} else if err == sql.ErrNoRows {
err = nil
} }
return r return r
}(), }(),
@ -211,7 +215,10 @@ func TestFindOneById(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { 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 { if (err != nil) != tt.wantErr {
t.Errorf("FindOneById() error = %v, wantErr %v", err, tt.wantErr) t.Errorf("FindOneById() error = %v, wantErr %v", err, tt.wantErr)
return return
@ -233,7 +240,7 @@ func TestFirstOne(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
args args args args
want wp2.Posts want models.Posts
wantErr bool wantErr bool
}{ }{
{ {
@ -245,10 +252,12 @@ func TestFirstOne(t *testing.T) {
in: nil, in: nil,
}, },
wantErr: false, wantErr: false,
want: func() wp2.Posts { want: func() models.Posts {
r, err := Get[wp2.Posts](ctx, "select * from "+wp2.Posts{}.Table()+" where post_status='publish' order by ID desc limit 1") r, err := Get[models.Posts](ctx, "select * from "+models.Posts{}.Table()+" where post_status='publish' order by ID desc limit 1")
if err != nil { if err != nil && err != sql.ErrNoRows {
panic(err) panic(err)
} else if err == sql.ErrNoRows {
err = nil
} }
return r return r
}(), }(),
@ -256,7 +265,7 @@ func TestFirstOne(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { 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 { if (err != nil) != tt.wantErr {
t.Errorf("FirstOne() error = %v, wantErr %v", err, tt.wantErr) t.Errorf("FirstOne() error = %v, wantErr %v", err, tt.wantErr)
return 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) { func TestLastOne(t *testing.T) {
type args struct { type args struct {
where ParseWhere where ParseWhere
@ -304,7 +286,7 @@ func TestLastOne(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
args args args args
want wp2.Posts want models.Posts
wantErr bool wantErr bool
}{ }{
{ {
@ -316,8 +298,8 @@ func TestLastOne(t *testing.T) {
fields: "*", fields: "*",
in: nil, in: nil,
}, },
want: func() wp2.Posts { want: func() models.Posts {
r, err := Get[wp2.Posts](ctx, "select * from "+wp2.Posts{}.Table()+" where post_status='publish' order by "+wp2.Posts{}.PrimaryKey()+" desc limit 1") 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 { if err != nil {
panic(err) panic(err)
} }
@ -327,7 +309,7 @@ func TestLastOne(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { 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 { if (err != nil) != tt.wantErr {
t.Errorf("LastOne() error = %v, wantErr %v", err, tt.wantErr) t.Errorf("LastOne() error = %v, wantErr %v", err, tt.wantErr)
return 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) { func TestSimpleFind(t *testing.T) {
type args struct { type args struct {
where ParseWhere where ParseWhere
@ -375,14 +330,33 @@ func TestSimpleFind(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
args args args args
want []wp2.Posts want []models.Posts
wantErr bool 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 { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { 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 { if (err != nil) != tt.wantErr {
t.Errorf("SimpleFind() error = %v, wantErr %v", err, tt.wantErr) t.Errorf("SimpleFind() error = %v, wantErr %v", err, tt.wantErr)
return return
@ -409,15 +383,41 @@ func TestSimplePagination(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
args args args args
wantR []wp2.Posts wantR []models.Posts
wantTotal int wantTotal int
wantErr bool 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 { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { 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 { if (err != nil) != tt.wantErr {
t.Errorf("SimplePagination() error = %v, wantErr %v", err, tt.wantErr) t.Errorf("SimplePagination() error = %v, wantErr %v", err, tt.wantErr)
return return