mirror of
https://github.com/zhufuyi/sponge.git
synced 2025-10-05 16:57:07 +08:00
640 lines
11 KiB
Go
640 lines
11 KiB
Go
package query
|
|
|
|
import (
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestPage(t *testing.T) {
|
|
page := DefaultPage(-1)
|
|
t.Log(page.Page(), page.Size(), page.Sort(), page.Offset())
|
|
|
|
SetMaxSize(1)
|
|
|
|
page = NewPage(-1, 100, "id")
|
|
t.Log(page.Page(), page.Size(), page.Sort(), page.Offset())
|
|
}
|
|
|
|
func TestParams_ConvertToPage(t *testing.T) {
|
|
p := &Params{
|
|
Page: 1,
|
|
Size: 50,
|
|
Sort: "age,-name",
|
|
}
|
|
order, limit, offset := p.ConvertToPage()
|
|
t.Logf("order=%s, limit=%d, offset=%d", order, limit, offset)
|
|
|
|
}
|
|
|
|
func TestParams_ConvertToGormConditions(t *testing.T) {
|
|
type args struct {
|
|
columns []Column
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want string
|
|
want1 []interface{}
|
|
wantErr bool
|
|
}{
|
|
// --------------------------- only 1 column query ------------------------------
|
|
{
|
|
name: "1 column eq",
|
|
args: args{
|
|
columns: []Column{
|
|
{
|
|
Name: "name",
|
|
Value: "ZhangSan",
|
|
},
|
|
},
|
|
},
|
|
want: "name = ?",
|
|
want1: []interface{}{"ZhangSan"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "1 column neq",
|
|
args: args{
|
|
columns: []Column{
|
|
{
|
|
Name: "name",
|
|
Value: "ZhangSan",
|
|
//Exp: "neq",
|
|
Exp: "!=",
|
|
},
|
|
},
|
|
},
|
|
want: "name <> ?",
|
|
want1: []interface{}{"ZhangSan"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "1 column gt",
|
|
args: args{
|
|
columns: []Column{
|
|
{
|
|
Name: "age",
|
|
Value: 20,
|
|
//Exp: Gt,
|
|
Exp: ">",
|
|
},
|
|
},
|
|
},
|
|
want: "age > ?",
|
|
want1: []interface{}{20},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "1 column gte",
|
|
args: args{
|
|
columns: []Column{
|
|
{
|
|
Name: "age",
|
|
Value: 20,
|
|
//Exp: Gte,
|
|
Exp: ">=",
|
|
},
|
|
},
|
|
},
|
|
want: "age >= ?",
|
|
want1: []interface{}{20},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "1 column lt",
|
|
args: args{
|
|
columns: []Column{
|
|
{
|
|
Name: "age",
|
|
Value: 20,
|
|
//Exp: Lt,
|
|
Exp: "<",
|
|
},
|
|
},
|
|
},
|
|
want: "age < ?",
|
|
want1: []interface{}{20},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "1 column lte",
|
|
args: args{
|
|
columns: []Column{
|
|
{
|
|
Name: "age",
|
|
Value: 20,
|
|
//Exp: Lte,
|
|
Exp: "<=",
|
|
},
|
|
},
|
|
},
|
|
want: "age <= ?",
|
|
want1: []interface{}{20},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "1 column like",
|
|
args: args{
|
|
columns: []Column{
|
|
{
|
|
Name: "name",
|
|
Value: "Li",
|
|
Exp: Like,
|
|
},
|
|
},
|
|
},
|
|
want: "name LIKE ?",
|
|
want1: []interface{}{"%Li%"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "1 column IN",
|
|
args: args{
|
|
columns: []Column{
|
|
{
|
|
Name: "name",
|
|
Value: "ab,cd,ef",
|
|
Exp: In,
|
|
},
|
|
},
|
|
},
|
|
want: "name IN (?)",
|
|
want1: []interface{}{[]interface{}{"ab", "cd", "ef"}},
|
|
wantErr: false,
|
|
},
|
|
|
|
// --------------------------- query 2 columns ------------------------------
|
|
{
|
|
name: "2 columns eq and",
|
|
args: args{
|
|
columns: []Column{
|
|
{
|
|
Name: "name",
|
|
Value: "ZhangSan",
|
|
},
|
|
{
|
|
Name: "gender",
|
|
Value: "male",
|
|
},
|
|
},
|
|
},
|
|
want: "name = ? AND gender = ?",
|
|
want1: []interface{}{"ZhangSan", "male"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "2 columns neq and",
|
|
args: args{
|
|
columns: []Column{
|
|
{
|
|
Name: "name",
|
|
Value: "ZhangSan",
|
|
//Exp: Neq,
|
|
Exp: "!=",
|
|
},
|
|
{
|
|
Name: "name",
|
|
Value: "LiSi",
|
|
//Exp: Neq,
|
|
Exp: "!=",
|
|
},
|
|
},
|
|
},
|
|
want: "name <> ? AND name <> ?",
|
|
want1: []interface{}{"ZhangSan", "LiSi"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "2 columns gt and",
|
|
args: args{
|
|
columns: []Column{
|
|
{
|
|
Name: "gender",
|
|
Value: "male",
|
|
},
|
|
{
|
|
Name: "age",
|
|
Value: 20,
|
|
//Exp: Gt,
|
|
Exp: ">",
|
|
},
|
|
},
|
|
},
|
|
want: "gender = ? AND age > ?",
|
|
want1: []interface{}{"male", 20},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "2 columns gte and",
|
|
args: args{
|
|
columns: []Column{
|
|
{
|
|
Name: "gender",
|
|
Value: "male",
|
|
},
|
|
{
|
|
Name: "age",
|
|
Value: 20,
|
|
//Exp: Gte,
|
|
Exp: ">=",
|
|
},
|
|
},
|
|
},
|
|
want: "gender = ? AND age >= ?",
|
|
want1: []interface{}{"male", 20},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "2 columns lt and",
|
|
args: args{
|
|
columns: []Column{
|
|
{
|
|
Name: "gender",
|
|
Value: "female",
|
|
},
|
|
{
|
|
Name: "age",
|
|
Value: 20,
|
|
//Exp: Lt,
|
|
Exp: "<",
|
|
},
|
|
},
|
|
},
|
|
want: "gender = ? AND age < ?",
|
|
want1: []interface{}{"female", 20},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "2 columns lte and",
|
|
args: args{
|
|
columns: []Column{
|
|
{
|
|
Name: "gender",
|
|
Value: "female",
|
|
},
|
|
{
|
|
Name: "age",
|
|
Value: 20,
|
|
//Exp: Lte,
|
|
Exp: "<=",
|
|
},
|
|
},
|
|
},
|
|
want: "gender = ? AND age <= ?",
|
|
want1: []interface{}{"female", 20},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "2 columns range and",
|
|
args: args{
|
|
columns: []Column{
|
|
{
|
|
Name: "age",
|
|
Value: 10,
|
|
//Exp: Gte,
|
|
Exp: ">=",
|
|
},
|
|
{
|
|
Name: "age",
|
|
Value: 20,
|
|
//Exp: Lte,
|
|
Exp: "<=",
|
|
},
|
|
},
|
|
},
|
|
want: "age >= ? AND age <= ?",
|
|
want1: []interface{}{10, 20},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "2 columns eq or",
|
|
args: args{
|
|
columns: []Column{
|
|
{
|
|
Name: "name",
|
|
Value: "LiSi",
|
|
//Logic: OR,
|
|
Logic: "||",
|
|
},
|
|
{
|
|
Name: "gender",
|
|
Value: "female",
|
|
},
|
|
},
|
|
},
|
|
want: "name = ? OR gender = ?",
|
|
want1: []interface{}{"LiSi", "female"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "2 columns neq or",
|
|
args: args{
|
|
columns: []Column{
|
|
{
|
|
Name: "name",
|
|
Value: "LiSi",
|
|
//Logic: OR,
|
|
Logic: "||",
|
|
},
|
|
{
|
|
Name: "gender",
|
|
Value: "male",
|
|
//Exp: Neq,
|
|
Exp: "!=",
|
|
},
|
|
},
|
|
},
|
|
want: "name = ? OR gender <> ?",
|
|
want1: []interface{}{"LiSi", "male"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "2 columns eq and in",
|
|
args: args{
|
|
columns: []Column{
|
|
{
|
|
Name: "gender",
|
|
Value: "male",
|
|
//Logic: "&",
|
|
},
|
|
{
|
|
Name: "name",
|
|
Value: "LiSi,ZhangSan,WangWu",
|
|
Exp: In,
|
|
},
|
|
},
|
|
},
|
|
want: "gender = ? AND name IN (?)",
|
|
want1: []interface{}{"male", []interface{}{"LiSi", "ZhangSan", "WangWu"}},
|
|
wantErr: false,
|
|
},
|
|
|
|
// ------------------------------ IN -------------------------------------------------
|
|
{
|
|
name: "3 columns eq and",
|
|
args: args{
|
|
columns: []Column{
|
|
{
|
|
Name: "name",
|
|
Value: "LiSi",
|
|
},
|
|
{
|
|
Name: "name",
|
|
Value: "ZhangSan",
|
|
},
|
|
{
|
|
Name: "name",
|
|
Value: "WangWu",
|
|
},
|
|
},
|
|
},
|
|
want: "name IN (?)",
|
|
want1: []interface{}{[]interface{}{"LiSi", "ZhangSan", "WangWu"}},
|
|
wantErr: false,
|
|
},
|
|
|
|
// ---------------------------- error ----------------------------------------------
|
|
{
|
|
name: "exp type err",
|
|
args: args{
|
|
columns: []Column{
|
|
{
|
|
Name: "gender",
|
|
Value: "male",
|
|
Exp: "xxxxxx",
|
|
},
|
|
},
|
|
},
|
|
want: "",
|
|
want1: nil,
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "logic type err",
|
|
args: args{
|
|
columns: []Column{
|
|
{
|
|
Name: "gender",
|
|
Value: "male",
|
|
Logic: "xxxxxx",
|
|
},
|
|
},
|
|
},
|
|
want: "",
|
|
want1: nil,
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "empty",
|
|
args: args{
|
|
columns: nil,
|
|
},
|
|
want: "",
|
|
want1: nil,
|
|
wantErr: false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
params := &Params{
|
|
Columns: tt.args.columns,
|
|
}
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got, got1, err := params.ConvertToGormConditions()
|
|
if (err != nil) != tt.wantErr {
|
|
t.Errorf("ConvertToGormConditions() error = %v, wantErr %v", err, tt.wantErr)
|
|
return
|
|
}
|
|
if got != tt.want {
|
|
t.Errorf("ConvertToGormConditions() got = %v, want %v", got, tt.want)
|
|
}
|
|
if !reflect.DeepEqual(got1, tt.want1) {
|
|
t.Errorf("ConvertToGormConditions() got1 = %v, want %v", got1, tt.want1)
|
|
}
|
|
|
|
got = strings.Replace(got, "?", "%v", -1)
|
|
t.Logf(got, got1...)
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_getExpsAndLogics(t *testing.T) {
|
|
type args struct {
|
|
keyLen int
|
|
paramSrc string
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want []string
|
|
want1 []string
|
|
}{
|
|
{
|
|
name: "0 columns",
|
|
args: args{
|
|
keyLen: 0,
|
|
paramSrc: "page=0&size=10",
|
|
},
|
|
want: []string{},
|
|
want1: []string{},
|
|
},
|
|
{
|
|
name: "1 columns",
|
|
args: args{
|
|
keyLen: 1,
|
|
paramSrc: "k=name&v=LiSi&page=0&size=10",
|
|
},
|
|
want: []string{""},
|
|
want1: []string{""},
|
|
},
|
|
{
|
|
name: "1 columns gt",
|
|
args: args{
|
|
keyLen: 1,
|
|
paramSrc: "k=age&exp=gt&v=20&page=0&size=10",
|
|
},
|
|
want: []string{"gt"},
|
|
want1: []string{""},
|
|
},
|
|
{
|
|
name: "1 columns gt and",
|
|
args: args{
|
|
keyLen: 1,
|
|
paramSrc: "k=age&exp=gt&v=20&logic=or&page=0&size=10",
|
|
},
|
|
want: []string{"gt"},
|
|
want1: []string{"or"},
|
|
},
|
|
{
|
|
name: "2 columns",
|
|
args: args{
|
|
keyLen: 2,
|
|
paramSrc: "k=name&v=LiSi&k=gender&v=male&page=0&size=10",
|
|
},
|
|
want: []string{"", ""},
|
|
want1: []string{"", ""},
|
|
},
|
|
{
|
|
name: "2 columns gt",
|
|
args: args{
|
|
keyLen: 2,
|
|
paramSrc: "k=name&v=LiSi&k=age&v=20&exp=gt&page=0&size=10",
|
|
},
|
|
want: []string{"", "gt"},
|
|
want1: []string{"", ""},
|
|
},
|
|
{
|
|
name: "3 columns gt or",
|
|
args: args{
|
|
keyLen: 3,
|
|
paramSrc: "k=name&v=LiSi&exp=neq&k=age&v=20&exp=gt&k=gender&v=male&logic=or&page=0&size=10",
|
|
},
|
|
want: []string{"neq", "gt", ""},
|
|
want1: []string{"", "", "or"},
|
|
},
|
|
{
|
|
name: "error",
|
|
args: args{
|
|
keyLen: 1,
|
|
paramSrc: "k=name&exp=gt&v=LiSi&page=0&size=10",
|
|
},
|
|
want: []string{"gt"},
|
|
want1: []string{""},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got, got1 := getExpsAndLogics(tt.args.keyLen, tt.args.paramSrc)
|
|
if !reflect.DeepEqual(got, tt.want) {
|
|
t.Errorf("getExpsAndLogics() got = %v, want %v", got, tt.want)
|
|
}
|
|
if !reflect.DeepEqual(got1, tt.want1) {
|
|
t.Errorf("getExpsAndLogics() got1 = %v, want %v", got1, tt.want1)
|
|
}
|
|
t.Logf("%+v %+v", got, got1)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestConditions_ConvertToGorm(t *testing.T) {
|
|
c := Conditions{
|
|
Columns: []Column{
|
|
{
|
|
Name: "name",
|
|
Value: "ZhangSan",
|
|
},
|
|
{
|
|
Name: "gender",
|
|
Value: "male",
|
|
},
|
|
}}
|
|
str, values, err := c.ConvertToGorm()
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
assert.Equal(t, "name = ? AND gender = ?", str)
|
|
assert.Equal(t, len(values), 2)
|
|
}
|
|
|
|
func TestConditions_checkValid(t *testing.T) {
|
|
// empty error
|
|
c := Conditions{}
|
|
err := c.CheckValid()
|
|
assert.Error(t, err)
|
|
|
|
// value is empty error
|
|
c = Conditions{
|
|
Columns: []Column{
|
|
{
|
|
Name: "foo",
|
|
Value: nil,
|
|
},
|
|
},
|
|
}
|
|
err = c.CheckValid()
|
|
assert.Error(t, err)
|
|
|
|
// exp error
|
|
c = Conditions{
|
|
Columns: []Column{
|
|
{
|
|
Name: "foo",
|
|
Value: "bar",
|
|
Exp: "unknown-exp",
|
|
},
|
|
},
|
|
}
|
|
err = c.CheckValid()
|
|
assert.Error(t, err)
|
|
|
|
// logic error
|
|
c = Conditions{
|
|
Columns: []Column{
|
|
{
|
|
Name: "foo",
|
|
Value: "bar",
|
|
Logic: "unknown-logic",
|
|
},
|
|
},
|
|
}
|
|
err = c.CheckValid()
|
|
assert.Error(t, err)
|
|
|
|
// success
|
|
c = Conditions{
|
|
Columns: []Column{
|
|
{
|
|
Name: "name",
|
|
Value: "ZhangSan",
|
|
},
|
|
{
|
|
Name: "gender",
|
|
Value: "male",
|
|
},
|
|
}}
|
|
err = c.CheckValid()
|
|
assert.NoError(t, err)
|
|
}
|