package core import "testing" func TestComputeBufferEditReplaceLine(t *testing.T) { oldSource := "abc\ndef" newSource := "abc\nxyz" edit, ok := computeBufferEdit(oldSource, newSource) if !ok { t.Fatalf("expected edit to be detected") } if edit.StartPoint.Row != 1 || edit.StartPoint.Column != 0 { t.Fatalf("unexpected start point: %+v", edit.StartPoint) } if edit.OldEndPoint.Row != 1 || edit.OldEndPoint.Column != 3 { t.Fatalf("unexpected old end point: %+v", edit.OldEndPoint) } if edit.NewEndPoint.Row != 1 || edit.NewEndPoint.Column != 3 { t.Fatalf("unexpected new end point: %+v", edit.NewEndPoint) } } func TestComputeBufferEditInsertAtEnd(t *testing.T) { oldSource := "a\nb" newSource := "a\nbb" edit, ok := computeBufferEdit(oldSource, newSource) if !ok { t.Fatalf("expected edit to be detected") } if edit.StartByte != 3 || edit.OldEndByte != 3 || edit.NewEndByte != 4 { t.Fatalf("unexpected byte offsets: %+v", edit) } if edit.StartPoint.Row != 1 || edit.StartPoint.Column != 1 { t.Fatalf("unexpected start point: %+v", edit.StartPoint) } } func TestByteOffsetToPoint(t *testing.T) { src := []byte("ab\ncd\nef") p := byteOffsetToPoint(src, 0) if p.Row != 0 || p.Column != 0 { t.Fatalf("offset 0 mismatch: %+v", p) } p = byteOffsetToPoint(src, 4) // right after 'c' if p.Row != 1 || p.Column != 1 { t.Fatalf("offset 4 mismatch: %+v", p) } p = byteOffsetToPoint(src, len(src)) if p.Row != 2 || p.Column != 2 { t.Fatalf("end offset mismatch: %+v", p) } } func TestUndoRedoEmitBufferChange(t *testing.T) { b := NewBufferBuilder().WithFiletype("go").WithLines([]string{"one", "two"}).Build() buf := &b win := NewWindowBuilder().WithBuffer(buf).Build() w := &win buf.UndoStack.BeginBlock(Position{Line: 0, Col: 0}) buf.SetLine(0, "ONE") buf.UndoStack.EndBlock(Position{Line: 0, Col: 3}) changes := []BufferChange{} buf.OnChange = func(change BufferChange) { changes = append(changes, change) } if !buf.Undo(w) { t.Fatalf("expected undo to succeed") } if len(changes) != 1 { t.Fatalf("expected one change notification on undo, got %d", len(changes)) } if changes[0].Edit == nil { t.Fatalf("expected undo change to include edit metadata") } if got := buf.Line(0); got != "one" { t.Fatalf("undo did not restore content, got %q", got) } changes = nil if !buf.Redo(w) { t.Fatalf("expected redo to succeed") } if len(changes) != 1 { t.Fatalf("expected one change notification on redo, got %d", len(changes)) } if changes[0].Edit == nil { t.Fatalf("expected redo change to include edit metadata") } if got := buf.Line(0); got != "ONE" { t.Fatalf("redo did not reapply content, got %q", got) } }