2023-02-01 15:48:53 +00:00
package model
import (
"context"
2023-02-02 05:19:43 +00:00
"database/sql"
2023-02-21 11:49:13 +00:00
"fmt"
2023-02-01 15:48:53 +00:00
"github.com/fthvgb1/wp-go/helper/number"
"github.com/fthvgb1/wp-go/helper/slice"
"reflect"
"strconv"
"strings"
"testing"
)
func TestFinds ( t * testing . T ) {
type args struct {
ctx context . Context
2023-02-25 15:10:42 +00:00
q QueryCondition
2023-02-01 15:48:53 +00:00
}
type testCase [ T Model ] struct {
name string
args args
wantR [ ] T
wantErr bool
}
tests := [ ] testCase [ post ] {
{
name : "t1" ,
args : args {
ctx : context . Background ( ) ,
q : Conditions (
Where ( SqlBuilder {
{ "post_status" , "publish" } , { "ID" , "in" , "" } } ,
) ,
Order ( SqlBuilder { { "ID" , "desc" } } ) ,
Offset ( 10 ) ,
Limit ( 10 ) ,
In ( [ ] [ ] any { slice . ToAnySlice ( number . Range ( 1 , 1000 , 1 ) ) } ... ) ,
) ,
} ,
wantR : func ( ) [ ] post {
r , err := Select [ post ] ( ctx , "select * from " + post { } . Table ( ) + " where post_status='publish' and ID in (" + strings . Join ( slice . Map ( number . Range ( 1 , 1000 , 1 ) , strconv . Itoa ) , "," ) + ") order by ID desc limit 10 offset 10 " )
if err != nil {
panic ( err )
}
return r
} ( ) ,
wantErr : false ,
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
gotR , err := Finds [ post ] ( tt . args . ctx , tt . args . q )
if ( err != nil ) != tt . wantErr {
t . Errorf ( "Findx() error = %v, wantErr %v" , err , tt . wantErr )
return
}
if ! reflect . DeepEqual ( gotR , tt . wantR ) {
t . Errorf ( "Findx() gotR = %v, want %v" , gotR , tt . wantR )
}
} )
}
}
func TestChunkFind ( t * testing . T ) {
type args struct {
ctx context . Context
perLimit int
2023-02-25 15:10:42 +00:00
q QueryCondition
2023-02-01 15:48:53 +00:00
}
type testCase [ T Model ] struct {
name string
args args
wantR [ ] T
wantErr bool
}
n := 500
tests := [ ] testCase [ post ] {
{
name : "in,orderBy" ,
args : args {
ctx : ctx ,
q : Conditions (
Where ( SqlBuilder { {
"post_status" , "publish" ,
} , { "ID" , "in" , "" } } ) ,
Order ( SqlBuilder { { "ID" , "desc" } } ) ,
In ( [ ] [ ] any { slice . ToAnySlice ( number . Range ( 1 , n , 1 ) ) } ... ) ,
) ,
perLimit : 20 ,
} ,
wantR : func ( ) [ ] post {
r , err := Select [ post ] ( ctx , "select * from " + post { } . Table ( ) + " where post_status='publish' and ID in (" + strings . Join ( slice . Map ( number . Range ( 1 , n , 1 ) , strconv . Itoa ) , "," ) + ") order by ID desc" )
if err != nil {
panic ( err )
}
return r
} ( ) ,
wantErr : false ,
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
gotR , err := ChunkFind [ post ] ( tt . args . ctx , tt . args . perLimit , tt . args . q )
if ( err != nil ) != tt . wantErr {
t . Errorf ( "ChunkFind() error = %v, wantErr %v" , err , tt . wantErr )
return
}
if ! reflect . DeepEqual ( gotR , tt . wantR ) {
t . Errorf ( "ChunkFind() gotR = %v, want %v" , gotR , tt . wantR )
}
} )
}
}
func TestChunk ( t * testing . T ) {
type args [ T Model , R any ] struct {
ctx context . Context
perLimit int
fn func ( rows T ) ( R , bool )
2023-02-25 15:10:42 +00:00
q QueryCondition
2023-02-01 15:48:53 +00:00
}
type testCase [ T Model , R any ] struct {
name string
args args [ T , R ]
wantR [ ] R
wantErr bool
}
n := 500
tests := [ ] testCase [ post , uint64 ] {
{
name : "t1" ,
args : args [ post , uint64 ] {
ctx : ctx ,
perLimit : 20 ,
fn : func ( t post ) ( uint64 , bool ) {
if t . Id > 300 {
return t . Id , true
}
return 0 , false
} ,
q : Conditions (
Where ( SqlBuilder { {
"post_status" , "publish" ,
} , { "ID" , "in" , "" } } ) ,
Order ( SqlBuilder { { "ID" , "desc" } } ) ,
In ( [ ] [ ] any { slice . ToAnySlice ( number . Range ( 1 , n , 1 ) ) } ... ) ,
) ,
} ,
wantR : func ( ) [ ] uint64 {
r , err := Select [ post ] ( ctx , "select * from " + post { } . Table ( ) + " where post_status='publish' and ID in (" + strings . Join ( slice . Map ( number . Range ( 1 , n , 1 ) , strconv . Itoa ) , "," ) + ") order by ID desc" )
if err != nil {
panic ( err )
}
return slice . FilterAndMap ( r , func ( t post ) ( uint64 , bool ) {
if t . Id <= 300 {
return 0 , false
}
return t . Id , true
} )
} ( ) ,
wantErr : false ,
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
gotR , err := Chunk [ post ] ( tt . args . ctx , tt . args . perLimit , tt . args . fn , tt . args . q )
if ( err != nil ) != tt . wantErr {
t . Errorf ( "Chunk() error = %v, wantErr %v" , err , tt . wantErr )
return
}
if ! reflect . DeepEqual ( gotR , tt . wantR ) {
t . Errorf ( "Chunk() gotR = %v, want %v" , gotR , tt . wantR )
}
} )
}
}
2023-02-02 05:19:43 +00:00
func TestPagination ( t * testing . T ) {
type args struct {
2023-02-27 13:34:48 +00:00
ctx context . Context
q QueryCondition
page int
pageSize int
2023-02-02 05:19:43 +00:00
}
type testCase [ T Model ] struct {
name string
args args
want [ ] T
want1 int
wantErr bool
}
tests := [ ] testCase [ post ] {
{
name : "t1" ,
args : args {
ctx : ctx ,
q : Conditions (
Where ( SqlBuilder {
{ "ID" , "in" , "" } ,
} ) ,
In ( [ ] [ ] any { slice . ToAnySlice ( number . Range ( 431 , 440 , 1 ) ) } ... ) ,
) ,
2023-02-27 13:34:48 +00:00
page : 1 ,
pageSize : 5 ,
2023-02-02 05:19:43 +00:00
} ,
want : func ( ) ( r [ ] post ) {
r , err := Select [ post ] ( ctx , "select * from " + post { } . Table ( ) + " where ID in (?,?,?,?,?)" , slice . ToAnySlice ( number . Range ( 431 , 435 , 1 ) ) ... )
if err != nil && err != sql . ErrNoRows {
panic ( err )
} else if err == sql . ErrNoRows {
err = nil
}
return
} ( ) ,
want1 : 10 ,
wantErr : false ,
} ,
}
for _ , tt : = range tests {
t . Run ( tt . name , func ( t * testing . T ) {
2023-02-27 13:34:48 +00:00
got , got1 , err := Pagination [ post ] ( tt . args . ctx , tt . args . q , tt . args . page , tt . args . pageSize )
2023-02-02 05:19:43 +00:00
if ( err != nil ) != tt . wantErr {
t . Errorf ( "Pagination() error = %v, wantErr %v" , err , tt . wantErr )
return
}
if ! reflect . DeepEqual ( got , tt . want ) {
t . Errorf ( "Pagination() got = %v, want %v" , got , tt . want )
}
if got1 != tt . want1 {
t . Errorf ( "Pagination() got1 = %v, want %v" , got1 , tt . want1 )
}
} )
}
}
2023-02-06 10:34:35 +00:00
func TestColumn ( t * testing . T ) {
type args [ V Model , T any ] struct {
ctx context . Context
fn func ( V ) ( T , bool )
2023-02-25 15:10:42 +00:00
q QueryCondition
2023-02-06 10:34:35 +00:00
}
type testCase [ V Model , T any ] struct {
name string
args args [ V , T ]
wantR [ ] T
wantErr bool
}
tests := [ ] testCase [ post , uint64 ] {
{
name : "t1" ,
args : args [ post , uint64 ] {
ctx : ctx ,
fn : func ( t post ) ( uint64 , bool ) {
return t . Id , true
} ,
q : Conditions (
Where ( SqlBuilder {
{ "ID" , "<" , "200" , "int" } ,
} ) ,
) ,
} ,
wantR : [ ] uint64 { 63 , 64 , 190 , 193 } ,
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
gotR , err := Column [ post ] ( tt . args . ctx , tt . args . fn , tt . args . q )
if ( err != nil ) != tt . wantErr {
t . Errorf ( "Column() error = %v, wantErr %v" , err , tt . wantErr )
return
}
if ! reflect . DeepEqual ( gotR , tt . wantR ) {
t . Errorf ( "Column() gotR = %v, want %v" , gotR , tt . wantR )
}
} )
}
}
2023-02-20 17:07:32 +00:00
2023-02-21 10:25:52 +00:00
type options struct {
OptionId uint64 ` gorm:"column:option_id" db:"option_id" json:"option_id" form:"option_id" `
OptionName string ` gorm:"column:option_name" db:"option_name" json:"option_name" form:"option_name" `
OptionValue string ` gorm:"column:option_value" db:"option_value" json:"option_value" form:"option_value" `
Autoload string ` gorm:"column:autoload" db:"autoload" json:"autoload" form:"autoload" `
}
func ( w options ) PrimaryKey ( ) string {
return "option_id"
}
func ( w options ) Table ( ) string {
return "wp_options"
}
func Test_getField ( t * testing . T ) {
{
name := "string"
db := glob
field := "option_value"
q := Conditions ( Where ( SqlBuilder { { "option_name" , "blogname" } } ) )
wantR := "记录并见证自己的成长"
wantErr := false
t . Run ( name , func ( t * testing . T ) {
gotR , err := getField [ options ] ( db , ctx , field , q )
if ( err != nil ) != wantErr {
t . Errorf ( "getField() error = %v, wantErr %v" , err , wantErr )
return
}
if ! reflect . DeepEqual ( gotR , wantR ) {
t . Errorf ( "getField() gotR = %v, want %v" , gotR , wantR )
}
} )
}
{
name := "t2"
db := glob
field := "option_id"
q := Conditions ( Where ( SqlBuilder { { "option_name" , "blogname" } } ) )
wantR := "3"
wantErr := false
t . Run ( name , func ( t * testing . T ) {
gotR , err := getField [ options ] ( db , ctx , field , q )
if ( err != nil ) != wantErr {
t . Errorf ( "getField() error = %v, wantErr %v" , err , wantErr )
return
}
if ! reflect . DeepEqual ( gotR , wantR ) {
t . Errorf ( "getField() gotR = %v, want %v" , gotR , wantR )
}
} )
}
{
name := "count(*)"
db := glob
field := "count(*)"
q := Conditions ( )
2023-02-27 13:34:48 +00:00
wantR := "406"
2023-02-21 10:25:52 +00:00
wantErr := false
t . Run ( name , func ( t * testing . T ) {
gotR , err := getField [ options ] ( db , ctx , field , q )
if ( err != nil ) != wantErr {
t . Errorf ( "getField() error = %v, wantErr %v" , err , wantErr )
return
}
if ! reflect . DeepEqual ( gotR , wantR ) {
t . Errorf ( "getField() gotR = %v, want %v" , gotR , wantR )
}
} )
}
}
func Test_getToStringMap ( t * testing . T ) {
2023-02-20 17:07:32 +00:00
type args struct {
2023-02-21 10:25:52 +00:00
db dbQuery
ctx context . Context
2023-02-25 15:10:42 +00:00
q QueryCondition
2023-02-20 17:07:32 +00:00
}
2023-02-21 10:25:52 +00:00
tests := [ ] struct {
2023-02-20 17:07:32 +00:00
name string
args args
2023-02-21 10:25:52 +00:00
wantR map [ string ] string
2023-02-20 17:07:32 +00:00
wantErr bool
2023-02-21 10:25:52 +00:00
} {
2023-02-20 17:07:32 +00:00
{
name : "t1" ,
args : args {
2023-02-21 10:25:52 +00:00
db : glob ,
ctx : ctx ,
q : Conditions ( Where ( SqlBuilder { { "option_name" , "users_can_register" } } ) ) ,
} ,
wantR : map [ string ] string {
"option_id" : "5" ,
"option_value" : "0" ,
"option_name" : "users_can_register" ,
"autoload" : "yes" ,
} ,
} ,
{
name : "t2" ,
args : args {
db : glob ,
ctx : ctx ,
q : Conditions (
Where ( SqlBuilder { { "option_name" , "users_can_register" } } ) ,
Fields ( "option_id id" ) ,
) ,
} ,
wantR : map [ string ] string {
"id" : "5" ,
2023-02-20 17:07:32 +00:00
} ,
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
2023-02-21 10:25:52 +00:00
gotR , err := getToStringMap [ options ] ( tt . args . db , tt . args . ctx , tt . args . q )
2023-02-20 17:07:32 +00:00
if ( err != nil ) != tt . wantErr {
2023-02-21 10:25:52 +00:00
t . Errorf ( "getToStringMap() error = %v, wantErr %v" , err , tt . wantErr )
2023-02-20 17:07:32 +00:00
return
}
if ! reflect . DeepEqual ( gotR , tt . wantR ) {
2023-02-21 10:25:52 +00:00
t . Errorf ( "getToStringMap() gotR = %v, want %v" , gotR , tt . wantR )
2023-02-20 17:07:32 +00:00
}
} )
}
}
2023-02-21 10:25:52 +00:00
func Test_findToStringMap ( t * testing . T ) {
type args struct {
db dbQuery
ctx context . Context
2023-02-25 15:10:42 +00:00
q QueryCondition
2023-02-21 10:25:52 +00:00
}
tests := [ ] struct {
name string
args args
wantR [ ] map [ string ] string
wantErr bool
} {
{
name : "t1" ,
args : args {
db : glob ,
ctx : ctx ,
q : Conditions ( Where ( SqlBuilder { { "option_id" , "5" } } ) ) ,
} ,
wantR : [ ] map [ string ] string { {
"option_id" : "5" ,
"option_value" : "0" ,
"option_name" : "users_can_register" ,
"autoload" : "yes" ,
} } ,
wantErr : false ,
} ,
{
name : "t2" ,
args : args {
db : glob ,
ctx : ctx ,
q : Conditions (
Where ( SqlBuilder { { "option_id" , "5" } } ) ,
Fields ( "option_value,option_name" ) ,
) ,
} ,
wantR : [ ] map [ string ] string { {
"option_value" : "0" ,
"option_name" : "users_can_register" ,
} } ,
wantErr : false ,
} ,
{
name : "t3" ,
args : args {
db : glob ,
ctx : ctx ,
q : Conditions (
Where ( SqlBuilder { { "option_id" , "5" } } ) ,
Fields ( "option_value v,option_name k" ) ,
) ,
} ,
wantR : [ ] map [ string ] string { {
"v" : "0" ,
"k" : "users_can_register" ,
} } ,
wantErr : false ,
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
gotR , err := findToStringMap [ options ] ( tt . args . db , tt . args . ctx , tt . args . q )
if ( err != nil ) != tt . wantErr {
t . Errorf ( "findToStringMap() error = %v, wantErr %v" , err , tt . wantErr )
return
}
if ! reflect . DeepEqual ( gotR , tt . wantR ) {
t . Errorf ( "findToStringMap() gotR = %v, want %v" , gotR , tt . wantR )
}
} )
}
2023-02-20 17:07:32 +00:00
}
2023-02-21 11:49:13 +00:00
func Test_findScanner ( t * testing . T ) {
type args [ T Model ] struct {
db dbQuery
ctx context . Context
fn func ( T )
2023-02-25 15:10:42 +00:00
q QueryCondition
2023-02-21 11:49:13 +00:00
}
type testCase [ T Model ] struct {
name string
args args [ T ]
wantErr bool
}
tests := [ ] testCase [ options ] {
{
name : "t1" ,
args : args [ options ] { glob , ctx , func ( t options ) {
fmt . Println ( t )
} , Conditions ( Where ( SqlBuilder { { "option_id" , "<" , "10" , "int" } } ) ) } ,
wantErr : false ,
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
if err := findScanner [ options ] ( tt . args . db , tt . args . ctx , tt . args . fn , tt . args . q ) ; ( err != nil ) != tt . wantErr {
t . Errorf ( "findScanner() error = %v, wantErr %v" , err , tt . wantErr )
}
} )
}
}
2023-02-21 12:15:39 +00:00
2023-02-22 11:05:47 +00:00
func BenchmarkSqlxQueryXX ( b * testing . B ) {
for i := 0 ; i < b . N ; i ++ {
var r [ ] options
2023-02-23 03:43:02 +00:00
err := ddb . Select ( & r , "select * from wp_options where option_id<100 and option_id>50" )
2023-02-22 11:05:47 +00:00
if err != nil {
panic ( err )
}
}
}
2023-02-21 12:15:39 +00:00
func BenchmarkScannerXX ( b * testing . B ) {
for i := 0 ; i < b . N ; i ++ {
2023-02-22 11:05:47 +00:00
var r [ ] options
2023-02-21 12:15:39 +00:00
err := findScanner [ options ] ( glob , ctx , func ( t options ) {
2023-02-22 11:05:47 +00:00
r = append ( r , t )
2023-02-21 12:15:39 +00:00
//fmt.Println(t)
2023-02-23 03:43:02 +00:00
} , Conditions ( Where ( SqlBuilder { { "option_id<100" } , { "option_id>50" } } ) ) )
2023-02-21 12:15:39 +00:00
if err != nil {
panic ( err )
}
}
}
func BenchmarkFindsXX ( b * testing . B ) {
for i := 0 ; i < b . N ; i ++ {
2023-02-23 03:43:02 +00:00
_ , err := finds [ options ] ( glob , ctx , Conditions (
Where ( SqlBuilder { { "option_id<100" } , { "option_id>50" } } ) ) ,
)
2023-02-21 12:15:39 +00:00
if err != nil {
panic ( err )
}
}
}
2023-02-21 14:15:35 +00:00
func Test_gets ( t * testing . T ) {
type args struct {
db dbQuery
ctx context . Context
2023-02-25 15:10:42 +00:00
q QueryCondition
2023-02-21 14:15:35 +00:00
}
type testCase [ T Model ] struct {
name string
args args
wantR T
wantErr bool
}
tests := [ ] testCase [ options ] {
{
name : "t1" ,
args : args {
db : glob ,
ctx : ctx ,
q : Conditions ( Where ( SqlBuilder { { "option_name" , "blogname" } } ) ) ,
} ,
wantR : options { 3 , "blogname" , "记录并见证自己的成长" , "yes" } ,
wantErr : false ,
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
gotR , err := gets [ options ] ( tt . args . db , tt . args . ctx , tt . args . q )
if ( err != nil ) != tt . wantErr {
t . Errorf ( "gets() error = %v, wantErr %v" , err , tt . wantErr )
return
}
if ! reflect . DeepEqual ( gotR , tt . wantR ) {
t . Errorf ( "gets() gotR = %v, want %v" , gotR , tt . wantR )
}
} )
}
}
2023-02-22 10:50:27 +00:00
func Test_finds ( t * testing . T ) {
type args struct {
db dbQuery
ctx context . Context
2023-02-25 15:10:42 +00:00
q QueryCondition
2023-02-22 10:50:27 +00:00
}
type testCase [ T Model ] struct {
name string
args args
wantR [ ] T
wantErr bool
}
var u user
tests := [ ] testCase [ options ] {
{
name : "sub query" ,
args : args { db : glob , ctx : ctx , q : Conditions (
From ( "(select * from wp_options where option_id <100) a" ) ,
Where ( SqlBuilder { { "option_id" , ">" , "50" , "int" } } ) ,
) } ,
wantR : func ( ) [ ] options {
r , err := Select [ options ] ( ctx , "select * from (select * from wp_options where option_id <100) a where option_id>50" )
if err != nil {
panic ( err )
}
return r
} ( ) ,
wantErr : false ,
} ,
{
name : "mixed query" ,
args : args { db : glob , ctx : ctx , q : Conditions (
From ( "(select * from wp_options where option_id <100) a" ) ,
Where ( SqlBuilder {
{ "u.ID" , "<" , "50" , "int" } } ) ,
Join ( SqlBuilder {
{ "left join" , user . Table ( u ) + " u" , "a.option_id=u.ID" } ,
} ) ,
Fields ( "u.user_login autoload,option_name,option_value" ) ,
) } ,
wantR : func ( ) [ ] options {
r , err := Select [ options ] ( ctx , "select u.user_login autoload,option_name,option_value from (select * from wp_options where option_id <100) a left join wp_users u on a.option_id=u.ID where `u`.`ID`<50" )
if err != nil {
panic ( err )
}
return r
} ( ) ,
wantErr : false ,
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
gotR , err := finds [ options ] ( tt . args . db , tt . args . ctx , tt . args . q )
if ( err != nil ) != tt . wantErr {
t . Errorf ( "finds() error = %v, wantErr %v" , err , tt . wantErr )
return
}
if ! reflect . DeepEqual ( gotR , tt . wantR ) {
t . Errorf ( "finds() gotR = %v, want %v" , gotR , tt . wantR )
}
} )
}
}
2023-03-05 16:25:17 +00:00
func TestGets ( t * testing . T ) {
type args struct {
ctx context . Context
q QueryCondition
}
type testCase [ T Model ] struct {
name string
args args
want T
wantErr bool
}
tests := [ ] testCase [ options ] {
{
name : "t1" ,
args : args {
ctx : ctx ,
q : Conditions ( Where ( SqlBuilder {
{ "option_id" , "11" } ,
} ) ) ,
} ,
want : options {
OptionId : 11 ,
OptionName : "comments_notify" ,
OptionValue : "1" ,
Autoload : "yes" ,
} ,
wantErr : false ,
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
got , err := Gets [ options ] ( tt . args . ctx , tt . args . q )
gots , _ := gets [ options ] ( glob , tt . args . ctx , tt . args . q )
gotss , _ := GetsFromDB [ options ] ( glob , tt . args . ctx , tt . args . q )
if ( err != nil ) != tt . wantErr {
t . Errorf ( "Gets() error = %v, wantErr %v" , err , tt . wantErr )
return
}
if ! reflect . DeepEqual ( got , gots ) {
t . Errorf ( "Gets() got = %v, want %v" , got , tt . want )
}
if ! reflect . DeepEqual ( got , gotss ) {
t . Errorf ( "Gets() got = %v, want %v" , got , tt . want )
}
if ! reflect . DeepEqual ( got , tt . want ) {
t . Errorf ( "Gets() got = %v, want %v" , got , tt . want )
}
} )
}
}