142 lines
4.6 KiB
Go
142 lines
4.6 KiB
Go
package squirrel
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/Masterminds/squirrel"
|
|
"github.com/matryer/is"
|
|
"go.sour.is/pkg/rsql"
|
|
)
|
|
|
|
type testTable struct {
|
|
Foo string `json:"foo"`
|
|
Bar string `json:"bar"`
|
|
Baz string `json:"baz"`
|
|
Director string `json:"director"`
|
|
Actor string `json:"actor"`
|
|
Year string `json:"year"`
|
|
Genres string `json:"genres"`
|
|
One string `json:"one"`
|
|
Two string `json:"two"`
|
|
Family string `json:"family_name"`
|
|
}
|
|
|
|
func TestQuery(t *testing.T) {
|
|
d := rsql.GetDbColumns(testTable{})
|
|
is := is.New(t)
|
|
|
|
tests := []struct {
|
|
input string
|
|
expect squirrel.Sqlizer
|
|
expectLimit *uint64
|
|
expectOffset *uint64
|
|
expectOrder []string
|
|
fail bool
|
|
}{
|
|
{input: "foo==[1, 2, 3]", expect: squirrel.Eq{"foo": []interface{}{1, 2, 3}}},
|
|
{input: "foo==1,(bar==2;baz==3)", expect: squirrel.Or{squirrel.Eq{"foo": 1}, squirrel.And{squirrel.Eq{"bar": 2}, squirrel.Eq{"baz": 3}}}},
|
|
|
|
{input: "foo==1", expect: squirrel.Eq{"foo": 1}},
|
|
{input: "foo!=1.1", expect: squirrel.NotEq{"foo": 1.1}},
|
|
{input: "foo==true", expect: squirrel.Eq{"foo": true}},
|
|
{input: "foo==null", expect: squirrel.Eq{"foo": nil}},
|
|
{input: "foo>2", expect: squirrel.Gt{"foo": 2}},
|
|
{input: "foo>=2.1", expect: squirrel.GtOrEq{"foo": 2.1}},
|
|
{input: "foo<3", expect: squirrel.Lt{"foo": 3}},
|
|
{input: "foo<=3.1", expect: squirrel.LtOrEq{"foo": 3.1}},
|
|
|
|
{input: "foo=eq=1", expect: squirrel.Eq{"foo": 1}},
|
|
{input: "foo=neq=1.1", expect: squirrel.NotEq{"foo": 1.1}},
|
|
{input: "foo=gt=2", expect: squirrel.Gt{"foo": 2}},
|
|
{input: "foo=ge=2.1", expect: squirrel.GtOrEq{"foo": 2.1}},
|
|
{input: "foo=lt=3", expect: squirrel.Lt{"foo": 3}},
|
|
{input: "foo=le=3.1", expect: squirrel.LtOrEq{"foo": 3.1}},
|
|
|
|
{input: "foo==1;bar==2", expect: squirrel.And{squirrel.Eq{"foo": 1}, squirrel.Eq{"bar": 2}}},
|
|
{input: "foo==1,bar==2", expect: squirrel.Or{squirrel.Eq{"foo": 1}, squirrel.Eq{"bar": 2}}},
|
|
{input: "foo==1,bar==2;baz=3", expect: nil},
|
|
{
|
|
input: `director=='name\'s';actor=eq="name\'s";Year=le=2000,Year>=2010;one <= -1.0, two != true`,
|
|
expect: squirrel.And{
|
|
squirrel.Eq{"director": "name's"},
|
|
squirrel.Eq{"actor": "name's"},
|
|
squirrel.Or{
|
|
squirrel.LtOrEq{"year": 2000},
|
|
squirrel.GtOrEq{"year": 2010},
|
|
},
|
|
squirrel.Or{
|
|
squirrel.LtOrEq{"one": -1.0},
|
|
squirrel.NotEq{"two": true},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
input: `genres==[sci-fi,action] ; genres==[romance,animated,horror] , director~Que*Tarantino`,
|
|
expect: squirrel.And{
|
|
squirrel.Eq{"genres": []interface{}{"sci-fi", "action"}},
|
|
squirrel.Or{
|
|
squirrel.Eq{"genres": []interface{}{"romance", "animated", "horror"}},
|
|
Like{"director", "Que%Tarantino"},
|
|
},
|
|
},
|
|
},
|
|
{input: "", expect: nil},
|
|
{input: "family_name==LUNDY", expect: squirrel.Eq{"family_name": "LUNDY"}},
|
|
{input: "family_name==[1,2,null]", expect: squirrel.Eq{"family_name": []interface{}{1, 2, nil}}},
|
|
{input: "family_name=LUNDY", expect: nil},
|
|
{input: "family_name==LUNDY and family_name==SMITH", expect: squirrel.And{squirrel.Eq{"family_name": "LUNDY"}, squirrel.Eq{"family_name": "SMITH"}}},
|
|
{input: "family_name==LUNDY or family_name==SMITH", expect: squirrel.Or{squirrel.Eq{"family_name": "LUNDY"}, squirrel.Eq{"family_name": "SMITH"}}},
|
|
{input: "foo==1,family_name=LUNDY;baz==2", expect: nil},
|
|
{input: "foo ~ bar*", expect: Like{"foo", "bar%"}},
|
|
{input: "foo ~ [bar*,bin*]", expect: nil, fail: true},
|
|
{input: "foo==1|limit:10", expect: squirrel.Eq{"foo": 1}, expectLimit: ptr(uint64(10))},
|
|
{input: "foo==1|offset:2", expect: squirrel.Eq{"foo": 1}, expectOffset: ptr(uint64(2))},
|
|
{
|
|
input: "foo>=1|limit:10 offset:2 foo:desc",
|
|
expect: squirrel.GtOrEq{"foo": 1},
|
|
expectLimit: ptr(uint64(10)),
|
|
expectOffset: ptr(uint64(2)),
|
|
expectOrder: []string{"foo desc"},
|
|
},
|
|
}
|
|
|
|
for i, tt := range tests {
|
|
q, a, err := Query(tt.input, d)
|
|
if !tt.fail && err != nil {
|
|
t.Error(err)
|
|
}
|
|
if q != nil {
|
|
t.Log(q.ToSql())
|
|
}
|
|
|
|
actual := fmt.Sprintf("%#v", q)
|
|
expect := fmt.Sprintf("%#v", tt.expect)
|
|
if expect != actual {
|
|
t.Errorf("test[%d]: %v\n\tinput and expected are not the same. wanted=%s got=%s", i, tt.input, expect, actual)
|
|
}
|
|
|
|
if limit, ok := a.Limit(); tt.expectLimit != nil {
|
|
is.True(ok)
|
|
is.Equal(limit, *tt.expectLimit)
|
|
} else {
|
|
is.True(!ok)
|
|
}
|
|
|
|
if offset, ok := a.Offset(); tt.expectOffset != nil {
|
|
is.True(ok)
|
|
is.Equal(offset, *tt.expectOffset)
|
|
} else {
|
|
is.True(!ok)
|
|
}
|
|
|
|
if order := a.Order(); tt.expectOrder != nil {
|
|
is.Equal(order, tt.expectOrder)
|
|
} else {
|
|
is.Equal(len(order), 0)
|
|
}
|
|
}
|
|
}
|
|
|
|
func ptr[T any](t T) *T { return &t }
|