From 1b6950b8d99eab0c69a91d3ff92fbb216b6e7a01 Mon Sep 17 00:00:00 2001 From: xing Date: Fri, 13 Jan 2023 12:31:35 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=96=87=E4=BB=B6=E7=BB=93?= =?UTF-8?q?=E6=9E=84=E3=80=81=E6=B5=8B=E8=AF=95=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- helper/func.go | 273 ------------------ helper/func_test.go | 628 ----------------------------------------- helper/html.go | 105 +++++++ helper/html_test.go | 140 ++++++++- helper/slice.go | 145 ++++++++++ helper/slice_test.go | 479 +++++++++++++++++++++++++++++++ helper/strings.go | 30 ++ helper/strings_test.go | 23 ++ model/query_test.go | 160 +++++------ 9 files changed, 1001 insertions(+), 982 deletions(-) create mode 100644 helper/slice.go create mode 100644 helper/slice_test.go create mode 100644 helper/strings.go create mode 100644 helper/strings_test.go diff --git a/helper/func.go b/helper/func.go index d45a9a7..cf63c43 100644 --- a/helper/func.go +++ b/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(`()`) -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("", 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(``, 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 -} diff --git a/helper/func_test.go b/helper/func_test.go index 5fe8a39..76f2b21 100644 --- a/helper/func_test.go +++ b/helper/func_test.go @@ -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: "

pppppffff

", - allowable: "

", - }, - want: "

pppppffff

", - }, - } - 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: "

pppppffff

", - allowable: "

", - }, - want: "

pppppffff

", - }, - } - 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(`

pppppffff

`, "

") - } -} -func BenchmarkStripTagsX(b *testing.B) { - for i := 0; i < b.N; i++ { - StripTagsX(`

pppppffff

`, "

") - } -} - -func TestCloseHtmlTag(t *testing.T) { - type args struct { - str string - } - tests := []struct { - name string - args args - want string - }{ - { - name: "t1", - args: args{str: `

GRANT privileges ON databasename.tablename TO 'username'@'h...

继续阅读

`}, - want: "
", - }, - { - name: "t2", - args: args{str: `
`}, - want: "
", - }, - } - 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{"
", "

", "", ""}}, - want: []string{"

", "

"}, - }, - { - name: "t2", - args: args{s: []string{"

", "
", "
", "", ""}}, - want: []string{"
"}, - }, - { - name: "t3", - args: args{s: []string{"
", "
"}}, - want: []string{}, - }, - { - name: "t4", - args: args{s: []string{"
", "

"}}, - want: []string{"

", "

"}, - }, - } - 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) - } - }) - } -} diff --git a/helper/html.go b/helper/html.go index 3fc2bd2..f729dc4 100644 --- a/helper/html.go +++ b/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(`()`) +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("", 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(``, 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++ + } +} diff --git a/helper/html_test.go b/helper/html_test.go index 6b0a6e5..f812053 100644 --- a/helper/html_test.go +++ b/helper/html_test.go @@ -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: "

pppppffff

", + allowable: "

", + }, + want: "

pppppffff

", + }, + } + 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: "

pppppffff

", + allowable: "

", + }, + want: "

pppppffff

", + }, + } + 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(`

pppppffff

`, "

") + } +} +func BenchmarkStripTagsX(b *testing.B) { + for i := 0; i < b.N; i++ { + StripTagsX(`

pppppffff

`, "

") + } +} + +func TestCloseHtmlTag(t *testing.T) { + type args struct { + str string + } + tests := []struct { + name string + args args + want string + }{ + { + name: "t1", + args: args{str: `

GRANT privileges ON databasename.tablename TO 'username'@'h...

继续阅读

`}, + want: "
", + }, + { + name: "t2", + args: args{str: `
`}, + want: "
", + }, + } + 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{"
", "

", "", ""}}, + want: []string{"

", "

"}, + }, + { + name: "t2", + args: args{s: []string{"

", "
", "
", "", ""}}, + want: []string{"
"}, + }, + { + name: "t3", + args: args{s: []string{"
", "
"}}, + want: []string{}, + }, + { + name: "t4", + args: args{s: []string{"
", "

"}}, + want: []string{"

", "

"}, + }, + } + 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) + } + }) + } +} diff --git a/helper/slice.go b/helper/slice.go new file mode 100644 index 0000000..08255ec --- /dev/null +++ b/helper/slice.go @@ -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 +} diff --git a/helper/slice_test.go b/helper/slice_test.go new file mode 100644 index 0000000..8eba735 --- /dev/null +++ b/helper/slice_test.go @@ -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) + } + }) + } +} diff --git a/helper/strings.go b/helper/strings.go new file mode 100644 index 0000000..8deff9f --- /dev/null +++ b/helper/strings.go @@ -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)) +} diff --git a/helper/strings_test.go b/helper/strings_test.go new file mode 100644 index 0000000..ff97690 --- /dev/null +++ b/helper/strings_test.go @@ -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) + } + }) + } +} diff --git a/model/query_test.go b/model/query_test.go index 9373094..e6d60d6 100644 --- a/model/query_test.go +++ b/model/query_test.go @@ -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