summaryrefslogtreecommitdiff
path: root/internal/lsp/completion_prefix_strip_test.go
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2025-09-06 10:25:36 +0300
committerPaul Buetow <paul@buetow.org>2025-09-06 10:25:36 +0300
commit5be9532cfa630f4aacd8d879c3e4f5cc316da0fa (patch)
tree0a901680fccd1e2703ffdbd9284ccff932be1d67 /internal/lsp/completion_prefix_strip_test.go
parent70f1d0e78c57dfa5beae779b3d392b6e6fa44c14 (diff)
feat(lsp): configurable inline/chat triggers; switch inline markers to >text>/>>text>; update docs and example config; tests updated to new triggers and raise LSP coverage to >=85%; chore: remove semicolon legacy; chore(mage): auto-refresh coverage daily if docs/coverage.out is older than 24h
Diffstat (limited to 'internal/lsp/completion_prefix_strip_test.go')
-rw-r--r--internal/lsp/completion_prefix_strip_test.go102
1 files changed, 51 insertions, 51 deletions
diff --git a/internal/lsp/completion_prefix_strip_test.go b/internal/lsp/completion_prefix_strip_test.go
index 99a08d6..e8e70f5 100644
--- a/internal/lsp/completion_prefix_strip_test.go
+++ b/internal/lsp/completion_prefix_strip_test.go
@@ -55,30 +55,30 @@ func TestTryLLMCompletion_ManualInvokeAfterWhitespace_Allows(t *testing.T) {
}
}
-func TestTryLLMCompletion_InlineSemicolonPromptAlwaysTriggers(t *testing.T) {
- s := &Server{maxTokens: 32, triggerChars: []string{".", ":", "/", "_"}, compCache: make(map[string]string)}
- s.llmClient = fakeLLM{resp: "replacement"}
- line := "prefix ;do something; suffix"
- // No trigger char immediately before cursor; place cursor at end
- p := CompletionParams{Position: Position{Line: 0, Character: len(line)}, TextDocument: TextDocumentIdentifier{URI: "file://inline.go"}}
- items, ok := s.tryLLMCompletion(p, "", line, "", "", "", false, "")
- if !ok || len(items) == 0 {
- t.Fatalf("expected completion to trigger on inline ;text; prompt")
- }
+func TestTryLLMCompletion_InlinePromptAlwaysTriggers(t *testing.T) {
+ s := &Server{maxTokens: 32, triggerChars: []string{".", ":", "/", "_"}, compCache: make(map[string]string)}
+ s.llmClient = fakeLLM{resp: "replacement"}
+ line := "prefix >do something> suffix"
+ // No trigger char immediately before cursor; place cursor at end
+ p := CompletionParams{Position: Position{Line: 0, Character: len(line)}, TextDocument: TextDocumentIdentifier{URI: "file://inline.go"}}
+ items, ok := s.tryLLMCompletion(p, "", line, "", "", "", false, "")
+ if !ok || len(items) == 0 {
+ t.Fatalf("expected completion to trigger on inline >text> prompt")
+ }
}
-func TestTryLLMCompletion_DoubleSemicolonEmpty_DoesNotAutoTrigger(t *testing.T) {
+func TestTryLLMCompletion_DoubleOpenEmpty_DoesNotAutoTrigger(t *testing.T) {
s := &Server{maxTokens: 32, triggerChars: []string{".", ":", "/", "_"}, compCache: make(map[string]string)}
fake := &countingLLM{}
s.llmClient = fake
- line := ";; " // empty content after ';;' should not force-trigger
+ line := ">> " // empty content after double-open should not force-trigger
p := CompletionParams{Position: Position{Line: 0, Character: len(line)}, TextDocument: TextDocumentIdentifier{URI: "file://empty-inline.go"}}
items, ok := s.tryLLMCompletion(p, "", line, "", "", "", false, "")
if !ok {
t.Fatalf("expected ok=true for non-trigger path")
}
if len(items) != 0 {
- t.Fatalf("expected no items when inline ';;' is empty")
+ t.Fatalf("expected no items when inline double-open is empty")
}
if fake.calls != 0 {
t.Fatalf("LLM should not be called; calls=%d", fake.calls)
@@ -86,63 +86,63 @@ func TestTryLLMCompletion_DoubleSemicolonEmpty_DoesNotAutoTrigger(t *testing.T)
}
func TestHasDoubleSemicolonTrigger_Variants(t *testing.T) {
- if hasDoubleSemicolonTrigger(";;") {
- t.Fatalf("bare ';;' should not trigger")
- }
- if hasDoubleSemicolonTrigger(";; ;") {
- t.Fatalf("';;' followed by space should not trigger")
- }
- if hasDoubleSemicolonTrigger(";;;") {
- t.Fatalf("';;;' should not trigger (no content)")
- }
- if !hasDoubleSemicolonTrigger(";;x;") {
- t.Fatalf("expected trigger for ';;x;' pattern")
- }
+ if hasDoubleOpenTrigger(">>") {
+ t.Fatalf("bare double-open should not trigger")
+ }
+ if hasDoubleOpenTrigger(">> ") {
+ t.Fatalf("double-open followed by space should not trigger")
+ }
+ if hasDoubleOpenTrigger(">>>") {
+ t.Fatalf("';;;' should not trigger (no content)")
+ }
+ if !hasDoubleOpenTrigger(">>x>") {
+ t.Fatalf("expected trigger for ';;x;' pattern")
+ }
}
-func TestBareDoubleSemicolonPreventsAutoTriggerEvenWithOtherTriggers(t *testing.T) {
- s := &Server{maxTokens: 32, triggerChars: []string{".", ":", "/", "_"}, compCache: make(map[string]string)}
- fake := &countingLLM{}
- s.llmClient = fake
- // Place a '.' earlier but also include bare ';;' at end; should not auto-trigger
- line := "obj. call ;;"
+func TestBareDoubleOpenPreventsAutoTriggerEvenWithOtherTriggers(t *testing.T) {
+ s := &Server{maxTokens: 32, triggerChars: []string{".", ":", "/", "_"}, compCache: make(map[string]string)}
+ fake := &countingLLM{}
+ s.llmClient = fake
+ // Place a '.' earlier but also include bare double-open at end; should not auto-trigger
+ line := "obj. call >>"
p := CompletionParams{Position: Position{Line: 0, Character: len(line)}, TextDocument: TextDocumentIdentifier{URI: "file://bare-ds.go"}}
items, ok := s.tryLLMCompletion(p, "", line, "", "", "", false, "")
if !ok {
t.Fatalf("expected ok=true (handled), but not auto-triggering")
}
- if len(items) != 0 {
- t.Fatalf("expected no items due to bare ';;'")
- }
+ if len(items) != 0 {
+ t.Fatalf("expected no items due to bare double-open")
+ }
if fake.calls != 0 {
t.Fatalf("LLM should not be called; calls=%d", fake.calls)
}
}
-func TestBareDoubleSemicolonOnNextLine_PreventsAutoTrigger(t *testing.T) {
- s := &Server{maxTokens: 32, triggerChars: []string{".", ":", "/", "_"}, compCache: make(map[string]string)}
- fake := &countingLLM{}
- s.llmClient = fake
- current := "expression := flag.String(\"expression\", \"\", \"Expression to evaluate\")"
- below := ";;"
+func TestBareDoubleOpenOnNextLine_PreventsAutoTrigger(t *testing.T) {
+ s := &Server{maxTokens: 32, triggerChars: []string{".", ":", "/", "_"}, compCache: make(map[string]string)}
+ fake := &countingLLM{}
+ s.llmClient = fake
+ current := "expression := flag.String(\"expression\", \"\", \"Expression to evaluate\")"
+ below := ">>"
p := CompletionParams{Position: Position{Line: 0, Character: len(current)}, TextDocument: TextDocumentIdentifier{URI: "file://nextline.go"}}
items, ok := s.tryLLMCompletion(p, "", current, below, "", "", false, "")
if !ok {
t.Fatalf("expected ok=true handled")
}
- if len(items) != 0 {
- t.Fatalf("expected no items due to bare ';;' on next line")
- }
+ if len(items) != 0 {
+ t.Fatalf("expected no items due to bare double-open on next line")
+ }
if fake.calls != 0 {
t.Fatalf("LLM should not be called; calls=%d", fake.calls)
}
}
-func TestBareDoubleSemicolonPreventsManualInvoke(t *testing.T) {
- s := &Server{maxTokens: 32, triggerChars: []string{".", ":", "/", "_"}, compCache: make(map[string]string)}
- fake := &countingLLM{}
- s.llmClient = fake
- line := ";;"
+func TestBareDoubleOpenPreventsManualInvoke(t *testing.T) {
+ s := &Server{maxTokens: 32, triggerChars: []string{".", ":", "/", "_"}, compCache: make(map[string]string)}
+ fake := &countingLLM{}
+ s.llmClient = fake
+ line := ">>"
p := CompletionParams{Position: Position{Line: 0, Character: len(line)}, TextDocument: TextDocumentIdentifier{URI: "file://bare-ds-manual.go"}}
// Simulate manual invoke
p.Context = json.RawMessage([]byte(`{"triggerKind":1}`))
@@ -150,9 +150,9 @@ func TestBareDoubleSemicolonPreventsManualInvoke(t *testing.T) {
if !ok {
t.Fatalf("expected ok=true (handled)")
}
- if len(items) != 0 {
- t.Fatalf("expected no items for bare ';;' even with manual invoke")
- }
+ if len(items) != 0 {
+ t.Fatalf("expected no items for bare double-open even with manual invoke")
+ }
if fake.calls != 0 {
t.Fatalf("LLM should not be called; calls=%d", fake.calls)
}