127 lines
3.2 KiB
Go
127 lines
3.2 KiB
Go
package sceneio
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"aego/core/mathx"
|
|
"aego/scene"
|
|
"aego/schema"
|
|
)
|
|
|
|
type Wheel struct {
|
|
Radius float32 `aego:"radius"`
|
|
Offset mathx.Vec2 `aego:"offset"`
|
|
Locked bool `aego:"locked"`
|
|
}
|
|
|
|
type Chassis struct {
|
|
Front Wheel `aego:"front"`
|
|
Rear Wheel `aego:"rear"`
|
|
Mass float32 `aego:"mass"`
|
|
Axles []Wheel `aego:"axles"`
|
|
}
|
|
|
|
func structRegistry(t *testing.T) *scene.Types {
|
|
t.Helper()
|
|
types := scene.NewTypes(schema.NewRegistry())
|
|
if _, err := schema.RegisterStruct[Wheel](types.Schema(), schema.Name("test.Wheel")); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := scene.RegisterComponent[Chassis](types, schema.Name("test.Chassis")); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := RegisterUnknown(types); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := types.Schema().Freeze(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return types
|
|
}
|
|
|
|
func TestNestedStructRoundTrip(t *testing.T) {
|
|
reg := structRegistry(t)
|
|
s := scene.New(reg, nil, scene.Options{})
|
|
h := s.Create(s.Root(), "Car")
|
|
c := scene.Add[Chassis](s, h)
|
|
c.Mass = 1200
|
|
c.Front = Wheel{Radius: 0.35, Offset: mathx.Vec2{X: 1.2, Y: -0.4}, Locked: true}
|
|
c.Rear = Wheel{Radius: 0.4, Offset: mathx.Vec2{X: -1.2, Y: -0.4}}
|
|
c.Axles = []Wheel{
|
|
{Radius: 0.1, Offset: mathx.Vec2{X: 1}},
|
|
{Radius: 0.2, Locked: true},
|
|
}
|
|
s.Flush()
|
|
|
|
saved := Save(s)
|
|
if !contains(saved, "front={ radius=0.35") {
|
|
t.Fatalf("nested struct not written:\n%s", saved)
|
|
}
|
|
if !contains(saved, "offset=[1.2, -0.4]") {
|
|
t.Fatalf("nested vec2 not written:\n%s", saved)
|
|
}
|
|
if !contains(saved, "locked=true") {
|
|
t.Fatalf("nested bool not written:\n%s", saved)
|
|
}
|
|
|
|
back, report, err := Load(saved, "car.aescene", structRegistry(t), nil, opts())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(report.Warnings) != 0 {
|
|
t.Fatalf("warnings = %+v", report.Warnings)
|
|
}
|
|
car := back.Find(back.Root(), "Car")
|
|
got, ok := scene.Get[Chassis](back, car)
|
|
if !ok {
|
|
t.Fatal("component lost")
|
|
}
|
|
if got.Mass != 1200 {
|
|
t.Fatalf("mass = %v", got.Mass)
|
|
}
|
|
if got.Front != c.Front || got.Rear != c.Rear {
|
|
t.Fatalf("nested structs differ:\nfront %+v vs %+v\nrear %+v vs %+v",
|
|
got.Front, c.Front, got.Rear, c.Rear)
|
|
}
|
|
if len(got.Axles) != 2 || got.Axles[0].Radius != 0.1 || !got.Axles[1].Locked {
|
|
t.Fatalf("list of structs = %+v", got.Axles)
|
|
}
|
|
if string(Save(back)) != string(saved) {
|
|
t.Fatal("second save differs")
|
|
}
|
|
}
|
|
|
|
func TestNestedStructPartialInput(t *testing.T) {
|
|
src := []byte(`scene version=1 {
|
|
node "3f9a0c21d4e84b7d9a1f2b3c4d5e6f70" name="Car" enabled=true layers=1 {
|
|
transform { position=[0, 0] rotation=0 scale=[1, 1] }
|
|
component "test.Chassis" version=1 {
|
|
front={ radius=0.5 }
|
|
mass=900
|
|
}
|
|
}
|
|
}
|
|
`)
|
|
s, _, err := Load(src, "partial.aescene", structRegistry(t), nil, opts())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
car := s.Find(s.Root(), "Car")
|
|
c, ok := scene.Get[Chassis](s, car)
|
|
if !ok {
|
|
t.Fatal("component missing")
|
|
}
|
|
if c.Front.Radius != 0.5 {
|
|
t.Fatalf("radius = %v", c.Front.Radius)
|
|
}
|
|
if c.Front.Offset != (mathx.Vec2{}) || c.Front.Locked {
|
|
t.Fatalf("missing nested fields must stay zero: %+v", c.Front)
|
|
}
|
|
if c.Mass != 900 {
|
|
t.Fatalf("mass = %v", c.Mass)
|
|
}
|
|
if len(c.Axles) != 0 {
|
|
t.Fatalf("absent list must stay empty: %+v", c.Axles)
|
|
}
|
|
}
|