feat: carry the byte offset and column in SyntaxError
Test / test (push) Canceled after 2m28s

Assisted-by: GLM 5.3 Flash
This commit is contained in:
2026-09-21 23:55:58 +02:00
parent 3cc168f39a
commit 10d49fbe60
5 changed files with 120 additions and 17 deletions
+53
View File
@@ -1220,3 +1220,56 @@ func TestNumberMethods(t *testing.T) {
}
}
}
func TestSyntaxErrorPosition(t *testing.T) {
src := []byte("alpha = 1\nbeta x = 2\n")
_, err := ParseMap(src)
se, ok := errors.AsType[*SyntaxError](err)
if !ok {
t.Fatalf("err = %v, want a SyntaxError", err)
}
if se.Line != 2 {
t.Errorf("Line = %d, want 2", se.Line)
}
if want := strings.Index(string(src), "x"); se.Offset != want {
t.Errorf("Offset = %d, want %d", se.Offset, want)
}
if se.Column != 6 {
t.Errorf("Column = %d, want 6", se.Column)
}
want := "beta x = 2\n ^"
if got := se.SourceLine(src); got != want {
t.Errorf("SourceLine =\n%s\nwant:\n%s", got, want)
}
}
func TestSyntaxErrorUTF8Offset(t *testing.T) {
src := []byte("a = \"ok\"\nb = \"\xff\xfe\"\n")
_, err := ParseMap(src)
se, ok := errors.AsType[*SyntaxError](err)
if !ok {
t.Fatalf("err = %v, want a SyntaxError", err)
}
if !strings.Contains(se.Msg, "byte offset 14") {
t.Errorf("Msg = %q, want it to name byte offset 14", se.Msg)
}
if se.Offset != 14 {
t.Errorf("Offset = %d, want 14", se.Offset)
}
want := "b = \"\xff\xfe\"\n ^"
if got := se.SourceLine(src); got != want {
t.Errorf("SourceLine =\n%q\nwant:\n%q", got, want)
}
}
func TestSourceLineEdgePositions(t *testing.T) {
src := []byte("a = 1\n")
e := &SyntaxError{Line: 1, Msg: "no position"}
if got, want := e.SourceLine(src), "a = 1\n^"; got != want {
t.Errorf("SourceLine(zero offset) =\n%q\nwant:\n%q", got, want)
}
e = &SyntaxError{Line: 2, Offset: 100, Msg: "past the end"}
if got, want := e.SourceLine(src), "\n^"; got != want {
t.Errorf("SourceLine(offset past end) =\n%q\nwant:\n%q", got, want)
}
}