package app import ( "strings" "testing" "glint/internal/grammar" "glint/internal/theme" ) // TestApplyGrammarDiagsRendersUnderline checks the app buckets a diagnostic batch // by line and the editor renders it as a green undercurl. FlexokiDark's Grammar // green is #879A39 -> the underline-color SGR carries its RGB (135,154,57). func TestApplyGrammarDiagsRendersUnderline(t *testing.T) { a := newApp() a.setSize(100, 24) a.editor.SetTheme(theme.FlexokiDark()) a.editor.SetContent([]byte("This is a a test")) a.editor.SetGrammar(true) a.applyGrammarDiags([]grammar.Diag{{Line: 0, StartCol: 8, EndCol: 11, Message: "repeat"}}) const greenSGR = "58:2::135:154:57" // undercurl color for #879A39 if !strings.Contains(a.editor.View(), greenSGR) { t.Error("expected a green grammar undercurl (SGR " + greenSGR + ") in the rendered view") } } // TestGrammarEndToEnd drives the whole pipeline against the real harper: Init // starts the subprocess and opens the buffer, the listener command blocks for the // first diagnostic batch, and applying it renders a green undercurl. Skipped // without harper on PATH or under -short. func TestGrammarEndToEnd(t *testing.T) { if testing.Short() { t.Skip("skipping live harper test under -short") } if !grammar.Available() { t.Skip("harper-ls not on PATH") } a := newApp() a.setSize(100, 24) a.editor.SetTheme(theme.FlexokiDark()) a.editor.SetContent([]byte("This is a a test.\n")) listen := a.Init() // starts harper, opens the buffer, returns the listener cmd defer a.Close() if a.grammar == nil { t.Fatal("Init did not start a harper client") } msg := listen() // blocks until harper publishes diagnostics diag, ok := msg.(grammarDiagMsg) if !ok { t.Fatalf("listener returned %T, want grammarDiagMsg", msg) } a.applyGrammarDiags(diag.diags) const greenSGR = "58:2::135:154:57" // #879A39 undercurl if !strings.Contains(a.editor.View(), greenSGR) { t.Error("no green grammar undercurl after live harper round-trip") } } // TestGrammarNilClientNoOps confirms the debounce/flush path is inert without a // running harper client, so plain app tests never touch a subprocess. func TestGrammarNilClientNoOps(t *testing.T) { a := newApp() if a.grammar != nil { t.Fatal("newApp should not start a harper client") } if cmd := a.grammarChanged(); cmd != nil { t.Error("grammarChanged should return nil without a client") } a.grammarFlush(a.grammarGen) // must not panic a.grammarOpen() // must not panic }