Files
sanspie 17cb5e4291 Stage 2-5: assets, scene/ECS, editor, 3D, and Aego Script
Stage 2: render pipeline and UI toolkit over gpu/platform.
Stage 3: schema registry, asset pipeline + runtime loader, scene graph and ECS.
Stage 4: editor — docking, inspector, scene/game views, play mode, asset browser, console, profiler; 4.5 adds the 3D foundation (mixed 2D/3D spaces, meshes, depth).
Stage 5: Aego Script — compiler (lexer/parser/types/resolver/checker/asm/compiler), bytecode with verifier and register VM, instance runtime, stdlib, native bindings, and editor/CLI integration (aego run/edit/check/test/dump).
2026-10-08 13:17:28 +03:00

49 lines
1.2 KiB
Go

package source
import (
"testing"
"unicode/utf8"
)
func TestLineColOffsetRoundTrip(t *testing.T) {
src := []byte("package p\nvar имя = \"é\"\r\n\tx\n")
m := NewManager()
id := m.Add("a.aes", src)
for off := 0; off <= len(src); off++ {
line, col := m.LineCol(id, uint32(off))
want := off
for want > 0 && want < len(src) && !utf8.RuneStart(src[want]) {
want--
}
if got := m.Offset(id, line, col); int(got) != want {
t.Fatalf("offset %d -> %d:%d -> %d, want %d", off, line, col, got, want)
}
}
}
func TestAddReplacesKeepsID(t *testing.T) {
m := NewManager()
a := m.Add("x.aes", []byte("one"))
b := m.Add("x.aes", []byte("two\nlines"))
if a != b {
t.Fatalf("ids differ %d %d", a, b)
}
if m.LineCount(a) != 2 || string(m.Source(a)) != "two\nlines" {
t.Fatal("source was not replaced")
}
if m.Path(NoFile) != "" || m.Source(99) != nil {
t.Fatal("unknown ids must be empty")
}
}
func TestSpanTo(t *testing.T) {
a := Span{File: 1, Start: 4, End: 6}
b := Span{File: 1, Start: 1, End: 5}
if got := a.To(b); got.Start != 1 || got.End != 6 {
t.Fatalf("join = %+v", got)
}
if got := a.To(Span{File: 2}); got != a {
t.Fatal("different files must not join")
}
}