2023-06-06 21:18:40 +02:00
|
|
|
package wmo
|
|
|
|
|
|
|
|
import (
|
2023-06-10 18:35:56 +02:00
|
|
|
"context"
|
|
|
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
2023-06-06 21:18:40 +02:00
|
|
|
"go.mongodb.org/mongo-driver/mongo"
|
|
|
|
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
2023-06-07 16:58:17 +02:00
|
|
|
"gogs.mikescher.com/BlackForestBytes/goext/rfctime"
|
|
|
|
"gogs.mikescher.com/BlackForestBytes/goext/timeext"
|
2023-06-06 21:18:40 +02:00
|
|
|
"gogs.mikescher.com/BlackForestBytes/goext/tst"
|
2023-06-10 18:35:56 +02:00
|
|
|
"reflect"
|
2023-06-06 21:18:40 +02:00
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestReflectionGetFieldType(t *testing.T) {
|
|
|
|
|
|
|
|
type IDType string
|
|
|
|
|
|
|
|
type TestData struct {
|
|
|
|
ID IDType `bson:"_id"`
|
|
|
|
CDate time.Time `bson:"cdate"`
|
|
|
|
Sub struct {
|
|
|
|
A string `bson:"a"`
|
|
|
|
} `bson:"sub"`
|
2023-09-12 10:47:41 +02:00
|
|
|
SubPtr *struct {
|
|
|
|
A string `bson:"a"`
|
|
|
|
} `bson:"subPtr"`
|
2023-06-07 16:58:17 +02:00
|
|
|
Str string `bson:"str"`
|
|
|
|
Ptr *int `bson:"ptr"`
|
|
|
|
MDate rfctime.RFC3339NanoTime `bson:"mdate"`
|
2023-06-06 21:18:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
coll := W[TestData](&mongo.Collection{})
|
|
|
|
|
|
|
|
coll.init()
|
|
|
|
|
|
|
|
t0 := time.Now()
|
2023-06-07 16:58:17 +02:00
|
|
|
t1 := rfctime.NewRFC3339Nano(t0)
|
2023-06-06 21:18:40 +02:00
|
|
|
|
|
|
|
d := TestData{
|
|
|
|
ID: "1",
|
|
|
|
CDate: t0,
|
|
|
|
Sub: struct {
|
|
|
|
A string `bson:"a"`
|
|
|
|
}{
|
|
|
|
A: "2",
|
|
|
|
},
|
2023-09-12 10:47:41 +02:00
|
|
|
SubPtr: &struct {
|
|
|
|
A string `bson:"a"`
|
|
|
|
}{
|
|
|
|
A: "4",
|
|
|
|
},
|
2023-06-07 16:58:17 +02:00
|
|
|
Str: "3",
|
|
|
|
Ptr: langext.Ptr(4),
|
|
|
|
MDate: t1,
|
2023-06-06 21:18:40 +02:00
|
|
|
}
|
|
|
|
|
2023-06-11 16:35:20 +02:00
|
|
|
gft := func(k string) fullTypeRef {
|
|
|
|
v, err := coll.getFieldType(k)
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("%s: %v", "failed to getFieldType", err)
|
|
|
|
}
|
|
|
|
return v
|
|
|
|
}
|
|
|
|
|
|
|
|
gfv := func(k string) any {
|
|
|
|
v, err := coll.getFieldValue(d, k)
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("%s: %v", "failed to getFieldType", err)
|
|
|
|
}
|
|
|
|
return v
|
|
|
|
}
|
|
|
|
|
|
|
|
tst.AssertEqual(t, gft("_id").Kind.String(), "string")
|
|
|
|
tst.AssertEqual(t, gft("_id").Type.String(), "wmo.IDType")
|
|
|
|
tst.AssertEqual(t, gft("_id").Name, "ID")
|
|
|
|
tst.AssertEqual(t, gft("_id").IsPointer, false)
|
|
|
|
tst.AssertEqual(t, gfv("_id").(IDType), "1")
|
|
|
|
|
|
|
|
tst.AssertEqual(t, gft("cdate").Kind.String(), "struct")
|
|
|
|
tst.AssertEqual(t, gft("cdate").Type.String(), "time.Time")
|
|
|
|
tst.AssertEqual(t, gft("cdate").Name, "CDate")
|
|
|
|
tst.AssertEqual(t, gft("cdate").IsPointer, false)
|
|
|
|
tst.AssertEqual(t, gfv("cdate").(time.Time), t0)
|
|
|
|
|
|
|
|
tst.AssertEqual(t, gft("sub.a").Kind.String(), "string")
|
|
|
|
tst.AssertEqual(t, gft("sub.a").Type.String(), "string")
|
|
|
|
tst.AssertEqual(t, gft("sub.a").Name, "A")
|
|
|
|
tst.AssertEqual(t, gft("sub.a").IsPointer, false)
|
|
|
|
tst.AssertEqual(t, gfv("sub.a").(string), "2")
|
|
|
|
|
2023-09-12 10:47:41 +02:00
|
|
|
tst.AssertEqual(t, gft("subPtr.a").Kind.String(), "string")
|
|
|
|
tst.AssertEqual(t, gft("subPtr.a").Type.String(), "string")
|
|
|
|
tst.AssertEqual(t, gft("subPtr.a").Name, "A")
|
|
|
|
tst.AssertEqual(t, gft("subPtr.a").IsPointer, false)
|
|
|
|
tst.AssertEqual(t, gfv("subPtr.a").(string), "4")
|
|
|
|
|
2023-06-11 16:35:20 +02:00
|
|
|
tst.AssertEqual(t, gft("str").Kind.String(), "string")
|
|
|
|
tst.AssertEqual(t, gft("str").Type.String(), "string")
|
|
|
|
tst.AssertEqual(t, gft("str").Name, "Str")
|
|
|
|
tst.AssertEqual(t, gft("str").IsPointer, false)
|
|
|
|
tst.AssertEqual(t, gfv("str").(string), "3")
|
|
|
|
|
|
|
|
tst.AssertEqual(t, gft("ptr").Kind.String(), "int")
|
|
|
|
tst.AssertEqual(t, gft("ptr").Type.String(), "int")
|
|
|
|
tst.AssertEqual(t, gft("ptr").Name, "Ptr")
|
|
|
|
tst.AssertEqual(t, gft("ptr").IsPointer, true)
|
|
|
|
tst.AssertEqual(t, *gfv("ptr").(*int), 4)
|
2023-06-06 21:18:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestReflectionGetTokenValueAsMongoType(t *testing.T) {
|
|
|
|
|
|
|
|
type IDType string
|
|
|
|
|
2023-09-12 11:39:51 +02:00
|
|
|
type RecurseiveType struct {
|
|
|
|
Other int `bson:"other"`
|
|
|
|
Inner *RecurseiveType `bson:"inner"`
|
|
|
|
}
|
|
|
|
|
2023-06-06 21:18:40 +02:00
|
|
|
type TestData struct {
|
|
|
|
ID IDType `bson:"_id"`
|
|
|
|
CDate time.Time `bson:"cdate"`
|
|
|
|
Sub struct {
|
|
|
|
A string `bson:"a"`
|
|
|
|
} `bson:"sub"`
|
2023-09-12 11:39:51 +02:00
|
|
|
SubPtr *struct {
|
2023-09-12 10:47:41 +02:00
|
|
|
A string `bson:"a"`
|
|
|
|
} `bson:"subPtr"`
|
2023-06-07 16:58:17 +02:00
|
|
|
Str string `bson:"str"`
|
|
|
|
Ptr *int `bson:"ptr"`
|
|
|
|
Num int `bson:"num"`
|
|
|
|
MDate rfctime.RFC3339NanoTime `bson:"mdate"`
|
2023-09-12 11:39:51 +02:00
|
|
|
Rec RecurseiveType `bson:"rec"`
|
2023-06-06 21:18:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
coll := W[TestData](&mongo.Collection{})
|
|
|
|
|
|
|
|
coll.init()
|
|
|
|
|
|
|
|
gtvasmt := func(value string, fieldName string) any {
|
|
|
|
v, err := coll.getTokenValueAsMongoType(value, fieldName)
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("%s", "failed to getTokenValueAsMongoType")
|
2023-06-07 16:58:17 +02:00
|
|
|
t.Errorf("%v+", err)
|
2023-06-06 21:18:40 +02:00
|
|
|
}
|
|
|
|
return v
|
|
|
|
}
|
|
|
|
|
2023-06-07 16:58:17 +02:00
|
|
|
tx, err := time.Parse(time.RFC3339Nano, "2009-11-10T23:00:00Z")
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("%v", err)
|
|
|
|
}
|
|
|
|
|
2023-06-06 21:18:40 +02:00
|
|
|
tst.AssertEqual(t, gtvasmt("hello", "str").(string), "hello")
|
2023-09-12 10:47:41 +02:00
|
|
|
tst.AssertEqual(t, gtvasmt("hello", "sub.a").(string), "hello")
|
|
|
|
tst.AssertEqual(t, gtvasmt("hello", "subPtr.a").(string), "hello")
|
2023-09-12 11:39:51 +02:00
|
|
|
tst.AssertEqual(t, gtvasmt("4", "rec.other").(int), 4)
|
2023-06-06 21:18:40 +02:00
|
|
|
tst.AssertEqual(t, gtvasmt("4", "num").(int), 4)
|
|
|
|
tst.AssertEqual(t, gtvasmt("asdf", "_id").(IDType), "asdf")
|
|
|
|
tst.AssertEqual(t, gtvasmt("", "ptr").(*int), nil)
|
|
|
|
tst.AssertEqual(t, *(gtvasmt("123", "ptr").(*int)), 123)
|
2023-06-07 16:58:17 +02:00
|
|
|
tst.AssertEqual(t, gtvasmt("2009-11-10T23:00:00Z", "cdate").(time.Time), tx)
|
|
|
|
tst.AssertEqual(t, gtvasmt("2009-11-10T23:00:00Z", "mdate").(rfctime.RFC3339NanoTime), rfctime.NewRFC3339Nano(tx))
|
2023-06-06 21:18:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestReflectionGetFieldValueAsTokenString(t *testing.T) {
|
|
|
|
|
|
|
|
type IDType string
|
|
|
|
|
|
|
|
type TestData struct {
|
|
|
|
ID IDType `bson:"_id"`
|
|
|
|
CDate time.Time `bson:"cdate"`
|
|
|
|
Sub struct {
|
|
|
|
A string `bson:"a"`
|
|
|
|
} `bson:"sub"`
|
2023-06-07 16:58:17 +02:00
|
|
|
Str string `bson:"str"`
|
|
|
|
Ptr *int `bson:"ptr"`
|
|
|
|
Num int `bson:"num"`
|
|
|
|
Ptr2 *int `bson:"ptr2"`
|
|
|
|
FFF float64 `bson:"fff"`
|
|
|
|
MDate rfctime.RFC3339NanoTime `bson:"mdate"`
|
2023-06-06 21:18:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
coll := W[TestData](&mongo.Collection{})
|
|
|
|
|
|
|
|
coll.init()
|
|
|
|
|
2023-06-07 16:58:17 +02:00
|
|
|
t0 := time.Date(2000, 1, 1, 12, 0, 0, 0, timeext.TimezoneBerlin)
|
|
|
|
t1 := rfctime.NewRFC3339Nano(t0)
|
2023-06-06 21:18:40 +02:00
|
|
|
|
|
|
|
d := TestData{
|
|
|
|
ID: "1",
|
|
|
|
CDate: t0,
|
2023-06-07 16:58:17 +02:00
|
|
|
MDate: t1,
|
2023-06-06 21:18:40 +02:00
|
|
|
Sub: struct {
|
|
|
|
A string `bson:"a"`
|
|
|
|
}{
|
|
|
|
A: "2",
|
|
|
|
},
|
|
|
|
Str: "3",
|
|
|
|
Ptr: langext.Ptr(4),
|
|
|
|
Num: 22,
|
|
|
|
FFF: 22.5,
|
|
|
|
Ptr2: nil,
|
|
|
|
}
|
|
|
|
|
|
|
|
gfvats := func(value TestData, fieldName string) string {
|
|
|
|
v, err := coll.getFieldValueAsTokenString(value, fieldName)
|
|
|
|
if err != nil {
|
2023-06-07 16:58:17 +02:00
|
|
|
t.Errorf("%s: %v", "failed to getTokenValueAsMongoType", err)
|
2023-06-06 21:18:40 +02:00
|
|
|
}
|
|
|
|
return v
|
|
|
|
}
|
|
|
|
|
|
|
|
tst.AssertEqual(t, gfvats(d, "str"), "3")
|
|
|
|
tst.AssertEqual(t, gfvats(d, "num"), "22")
|
|
|
|
tst.AssertEqual(t, gfvats(d, "_id"), "1")
|
|
|
|
tst.AssertEqual(t, gfvats(d, "ptr"), "4")
|
|
|
|
tst.AssertEqual(t, gfvats(d, "ptr2"), "")
|
|
|
|
tst.AssertEqual(t, gfvats(d, "fff"), "22.5")
|
2023-06-07 16:58:17 +02:00
|
|
|
tst.AssertEqual(t, gfvats(d, "cdate"), t0.Format(time.RFC3339Nano))
|
|
|
|
tst.AssertEqual(t, gfvats(d, "mdate"), t0.Format(time.RFC3339Nano))
|
2023-06-06 21:18:40 +02:00
|
|
|
}
|
2023-06-10 18:35:56 +02:00
|
|
|
|
|
|
|
func TestReflectionWithInterface(t *testing.T) {
|
|
|
|
|
|
|
|
type TestData struct {
|
|
|
|
ID primitive.ObjectID `bson:"_id"`
|
|
|
|
CDate time.Time `bson:"cdate"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type TestInterface interface {
|
|
|
|
}
|
|
|
|
|
|
|
|
coll1 := W[TestInterface](&mongo.Collection{})
|
|
|
|
|
|
|
|
tst.AssertTrue(t, coll1.coll != nil)
|
|
|
|
tst.AssertEqual(t, 0, len(coll1.implDataTypeMap))
|
|
|
|
|
|
|
|
df := func(ctx context.Context, dec Decodable) (TestInterface, error) {
|
|
|
|
return TestData{}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
coll2 := W[TestInterface](&mongo.Collection{}).WithDecodeFunc(df, TestData{})
|
|
|
|
|
|
|
|
tst.AssertTrue(t, coll2.coll != nil)
|
|
|
|
tst.AssertEqual(t, 1, len(coll2.implDataTypeMap))
|
|
|
|
|
|
|
|
tst.AssertEqual(t, "ID", coll2.implDataTypeMap[reflect.TypeOf(TestData{})]["_id"].Name)
|
|
|
|
tst.AssertEqual(t, "CDate", coll2.implDataTypeMap[reflect.TypeOf(TestData{})]["cdate"].Name)
|
|
|
|
}
|