Gim/internal/syntax/treesitter_behavior_test.go
Hayden Hargreaves be13f8838d
All checks were successful
Run Test Suite / test (push) Successful in 31s
fix: remove the styles package, fixed tests
However, the colorscheme functions and tests do not work anymore, they
need to be rebuilt.
2026-04-07 22:43:00 -07:00

243 lines
5.7 KiB
Go

package syntax
import (
"fmt"
"strings"
"testing"
"git.gophernest.net/azpect/TextEditor/internal/core"
"git.gophernest.net/azpect/TextEditor/internal/theme/themes"
"github.com/charmbracelet/lipgloss"
)
func TestTreeSitterEngineHighlightsGoKeywordAndString(t *testing.T) {
b := core.NewBufferBuilder().
WithFilename("sample.go").
WithFiletype("go").
WithLines([]string{
"package main",
"func main() {",
" s := \"hi\"",
"}",
}).
Build()
buf := &b
engine := NewTreeSitterEngine(themes.NewDefaultTheme())
engine.PrepareBuffer(buf)
base := engine.editorTheme.Line
line0 := buf.Line(0)
map0 := engine.LineStyleMap(buf, 0)
if len(map0) != len([]rune(line0)) {
t.Fatalf("line 0 style map length mismatch")
}
if len(map0) == 0 || styleEquivalent(map0[0], base) {
t.Fatalf("expected 'package' keyword to be highlighted")
}
line2 := buf.Line(2)
stringStart := strings.Index(line2, "\"hi\"")
if stringStart < 0 {
t.Fatalf("test setup failed: string literal not found")
}
map2 := engine.LineStyleMap(buf, 2)
if styleEquivalent(map2[stringStart+1], base) {
t.Fatalf("expected string contents to be highlighted")
}
}
func TestTreeSitterEngineHighlightsMultilineRawString(t *testing.T) {
b := core.NewBufferBuilder().
WithFilename("sample.go").
WithFiletype("go").
WithLines([]string{
"package main",
"func main() {",
" s := `hello",
"world`",
" println(s)",
"}",
}).
Build()
buf := &b
engine := NewTreeSitterEngine(themes.NewDefaultTheme())
engine.PrepareBuffer(buf)
base := engine.editorTheme.Line
map3 := engine.LineStyleMap(buf, 3)
if len(map3) == 0 {
t.Fatalf("expected style map on multiline raw string line")
}
if styleEquivalent(map3[0], base) {
t.Fatalf("expected multiline raw string line to be highlighted")
}
}
func TestTreeSitterEngineApplyEditUpdatesStyleCategory(t *testing.T) {
b := core.NewBufferBuilder().
WithFilename("sample.go").
WithFiletype("go").
WithLines([]string{
"package main",
"func main() {",
" x := 123",
"}",
}).
Build()
buf := &b
engine := NewTreeSitterEngine(themes.NewDefaultTheme())
engine.PrepareBuffer(buf)
oldLine := buf.Line(2)
oldIdx := strings.Index(oldLine, "123")
if oldIdx < 0 {
t.Fatalf("test setup failed: number not found")
}
oldMap := engine.LineStyleMap(buf, 2)
oldStyle := oldMap[oldIdx]
var edit *core.BufferEdit
buf.OnChange = func(change core.BufferChange) {
edit = change.Edit
}
buf.SetLine(2, " x := \"abc\"")
if edit == nil {
t.Fatalf("expected edit metadata from SetLine")
}
engine.ApplyEdit(buf, edit)
engine.PrepareBuffer(buf)
newLine := buf.Line(2)
newIdx := strings.Index(newLine, "abc")
if newIdx < 0 {
t.Fatalf("test setup failed: string not found")
}
newMap := engine.LineStyleMap(buf, 2)
newStyle := newMap[newIdx]
if styleEquivalent(newStyle, engine.editorTheme.Line) {
t.Fatalf("expected updated string to be highlighted")
}
if styleEquivalent(oldStyle, newStyle) {
t.Fatalf("expected style category to change from number to string")
}
}
func TestTreeSitterEngineApplyEditLineCountChangeForcesFullDirty(t *testing.T) {
b := core.NewBufferBuilder().
WithFilename("sample.go").
WithFiletype("go").
WithLines([]string{"package main", "func main() {}"}).
Build()
buf := &b
engine := NewTreeSitterEngine(themes.NewDefaultTheme())
engine.PrepareBuffer(buf)
bc := engine.getCache(buf)
var edit *core.BufferEdit
buf.OnChange = func(change core.BufferChange) {
edit = change.Edit
}
buf.InsertLine(1, "var x = 1")
if edit == nil {
t.Fatalf("expected edit metadata from InsertLine")
}
engine.ApplyEdit(buf, edit)
if !bc.dirtyAll {
t.Fatalf("expected line count change to set dirtyAll")
}
engine.PrepareBuffer(buf)
if !bc.built {
t.Fatalf("expected cache rebuilt after prepare")
}
if bc.count != buf.LineCount() {
t.Fatalf("expected cache line count to match buffer")
}
if bc.dirtyAll {
t.Fatalf("expected dirtyAll to clear after rebuild")
}
}
func TestTreeSitterEngineUnsupportedBufferFallsBackToDefaultStyles(t *testing.T) {
b := core.NewBufferBuilder().
WithFilename("notes.txt").
WithFiletype("txt").
WithLines([]string{"just text", "with no language"}).
Build()
buf := &b
engine := NewTreeSitterEngine(themes.NewDefaultTheme())
engine.PrepareBuffer(buf)
base := engine.editorTheme.Line
line := buf.Line(0)
m := engine.LineStyleMap(buf, 0)
if len(m) != len([]rune(line)) {
t.Fatalf("style map length mismatch on fallback buffer")
}
for i := range m {
if !styleEquivalent(m[i], base) {
t.Fatalf("expected default style for unsupported filetype at rune %d", i)
}
}
}
func TestTreeSitterEngineLastLineEditDoesNotPanicAndRebuilds(t *testing.T) {
b := core.NewBufferBuilder().
WithFilename("sample.go").
WithFiletype("go").
WithLines([]string{"package main", "func main() {", " return", "}"}).
Build()
buf := &b
engine := NewTreeSitterEngine(themes.NewDefaultTheme())
engine.PrepareBuffer(buf)
bc := engine.getCache(buf)
var edit *core.BufferEdit
buf.OnChange = func(change core.BufferChange) {
edit = change.Edit
}
buf.SetLine(3, "// end")
if edit == nil {
t.Fatalf("expected edit metadata for last line change")
}
engine.ApplyEdit(buf, edit)
engine.PrepareBuffer(buf)
if !bc.built {
t.Fatalf("expected cache built after last-line edit")
}
if len(bc.dirty) != 0 {
t.Fatalf("expected dirty ranges cleared after rebuild")
}
}
func styleEquivalent(a, b lipgloss.Style) bool {
return styleSignature(a) == styleSignature(b)
}
func styleSignature(s lipgloss.Style) string {
return fmt.Sprintf(
"fg=%v,bg=%v,bold=%v,italic=%v,underline=%v,reverse=%v",
s.GetForeground(),
s.GetBackground(),
s.GetBold(),
s.GetItalic(),
s.GetUnderline(),
s.GetReverse(),
)
}