Files
aego/modules/physics/editor/shapes_test.go
sanspie 5eb1832907
ci-platforms / darwin amd64 smoke (push) Skipped
ci / build (amd64, linux, ubuntu-24.04) (push) Failing after 15m28s
ci / release (push) Skipped
ci-platforms / windows amd64 smoke (push) Skipped
ci-platforms / darwin arm64 smoke (push) Skipped
ci / checks (push) Successful in 7m47s
Complete Stage 12 for v0.12.0
2026-11-05 11:46:53 +03:00

79 lines
2.7 KiB
Go

package editor
import (
"errors"
"testing"
"aego/contracts/shapes2d"
"aego/core/mathx"
"aego/editor/core/history/commands"
"aego/engine"
"aego/engine/module"
"aego/modules/physics"
"aego/modules/physics/components"
"aego/scene"
)
// The geometry service is read by lighting in EditWorld as well as PlayWorld.
// Exercise actual History commands so Undo cannot leave a stale shadow contour.
func TestShapeProviderFollowsGizmoRemoveUndoRedoWithoutSolver(t *testing.T) {
s, p := fixture(t)
h := s.Create(s.Root(), "Box")
*scene.Add[components.BoxCollider2D](s, h) = components.DefaultBox()
s.Flush()
w, m := engine.NewWorld("edit"), physics.New()
ctx := &module.AttachContext{World: w, Scene: s, Editor: true}
if err := m.AttachWorld(ctx); err != nil {
t.Fatal(err)
}
t.Cleanup(func() { m.DetachWorld(ctx) })
provider, ok := engine.ServiceOf[shapes2d.Provider](w, shapes2d.ServiceID)
if !ok || physics.SimOf(w) != nil {
t.Fatal("EditWorld must provide geometry without starting physics")
}
read := func() shapes2d.Buffer {
t.Helper()
var out shapes2d.Buffer
if err := provider.Append(s.ID(h), components.NameBox, &out); err != nil {
t.Fatal(err)
}
return out
}
before := read()
g := &colliderGizmo{p: p, kind: components.KindBox, td: p.types[components.KindBox]}
hist := drag(t, s, h, g, 4, mathx.Vec2{X: 1.5})
after := read()
if hist.Cursor() != 1 || after.Contours[0].Revision <= before.Contours[0].Revision || after.Points[1].X != 1.5 {
t.Fatal("gizmo transaction did not update local geometry")
}
if err := hist.Undo(); err != nil {
t.Fatal(err)
}
undo := read()
if undo.Contours[0].ID != before.Contours[0].ID || undo.Contours[0].Revision <= after.Contours[0].Revision || undo.Points[1] != before.Points[1] {
t.Fatal("Undo retained modified geometry or changed its stable identity")
}
if err := hist.Redo(); err != nil {
t.Fatal(err)
}
redo := read()
if redo.Contours[0].Revision <= undo.Contours[0].Revision || redo.Points[1] != after.Points[1] {
t.Fatal("Redo did not invalidate geometry")
}
cmd := commands.NewMutation("Remove collider", commands.EnvFor(s), commands.RemoveComp(s.ID(h), p.types[components.KindBox]))
if err := hist.Exec(cmd); err != nil {
t.Fatal(err)
}
var missing shapes2d.Buffer
if err := provider.Append(s.ID(h), components.NameBox, &missing); !errors.Is(err, shapes2d.ErrMissingShape) || len(missing.Contours) != 0 {
t.Fatalf("removed component retained geometry: %v", err)
}
if err := hist.Undo(); err != nil {
t.Fatal(err)
}
restored := read()
if restored.Contours[0].ID != before.Contours[0].ID || restored.Contours[0].Revision <= redo.Contours[0].Revision || restored.Points[1] != redo.Points[1] {
t.Fatal("undoing removal restored a stale shape generation")
}
}