diff options
| author | Paul Buetow <paul@buetow.org> | 2025-08-18 09:28:48 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2025-08-18 09:28:48 +0300 |
| commit | 96ace6c7019a914e21b25fa94ddfc4ee9239c2fb (patch) | |
| tree | 30550bcab30c91e917a4d8b3feccda829a364437 /internal/lsp/codeaction_test.go | |
| parent | 6d29ac7e4b2604b5c7df50f33f8ef2357709faf2 (diff) | |
refactor(lsp,llm,hexailsp,appconfig): split long funcs; add tests
- Extract helpers to keep funcs <=50 lines; no behavior changes
- Add tests for prompt removal, code actions, and LLM request builders
- Table-drive TestInParamList; run gofmt
Diffstat (limited to 'internal/lsp/codeaction_test.go')
| -rw-r--r-- | internal/lsp/codeaction_test.go | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/internal/lsp/codeaction_test.go b/internal/lsp/codeaction_test.go new file mode 100644 index 0000000..e9abbb8 --- /dev/null +++ b/internal/lsp/codeaction_test.go @@ -0,0 +1,63 @@ +package lsp + +import ( + "context" + "encoding/json" + "testing" + "hexai/internal/llm" +) + +type fakeLLM struct{ resp string; err error } + +func (f fakeLLM) Chat(_ context.Context, _ []llm.Message, _ ...llm.RequestOption) (string, error) { + return f.resp, f.err +} +func (f fakeLLM) Name() string { return "fake" } +func (f fakeLLM) DefaultModel() string { return "fake-model" } + +func TestBuildRewriteCodeAction_ReturnsEdit(t *testing.T) { + s := newTestServer() + s.llmClient = fakeLLM{resp: "REWRITTEN"} + p := CodeActionParams{TextDocument: TextDocumentIdentifier{URI: "file:///t.go"}, Range: Range{Start: Position{Line: 1, Character: 2}, End: Position{Line: 3, Character: 4}}} + sel := ";rewrite;\nold code" + ca := s.buildRewriteCodeAction(p, sel) + if ca == nil { t.Fatalf("expected code action") } + if ca.Edit == nil || len(ca.Edit.Changes) == 0 { t.Fatalf("expected workspace edit with changes") } + edits := ca.Edit.Changes[p.TextDocument.URI] + if len(edits) != 1 { t.Fatalf("expected 1 edit, got %d", len(edits)) } + if edits[0].Range != p.Range { t.Fatalf("edit range mismatch: got %+v want %+v", edits[0].Range, p.Range) } + if edits[0].NewText == "" { t.Fatalf("expected non-empty replacement text") } +} + +func TestBuildRewriteCodeAction_NoInstruction(t *testing.T) { + s := newTestServer() + s.llmClient = fakeLLM{resp: "IGNORED"} + p := CodeActionParams{TextDocument: TextDocumentIdentifier{URI: "file:///t.go"}, Range: Range{}} + sel := "no instruction here" + if ca := s.buildRewriteCodeAction(p, sel); ca != nil { t.Fatalf("expected nil action when no instruction present") } +} + +func TestBuildDiagnosticsCodeAction_ReturnsEdit(t *testing.T) { + s := newTestServer() + s.llmClient = fakeLLM{resp: "FIXED"} + p := CodeActionParams{TextDocument: TextDocumentIdentifier{URI: "file:///t.go"}, Range: Range{Start: Position{Line: 10}, End: Position{Line: 12, Character: 5}}} + ctx := CodeActionContext{Diagnostics: []Diagnostic{ + {Range: Range{Start: Position{Line: 11}, End: Position{Line: 11, Character: 10}}, Message: "inside"}, + {Range: Range{Start: Position{Line: 2}, End: Position{Line: 3}}, Message: "outside"}, + }} + raw, _ := json.Marshal(ctx) + p.Context = json.RawMessage(raw) + sel := "some selected code" + ca := s.buildDiagnosticsCodeAction(p, sel) + if ca == nil { t.Fatalf("expected diagnostics code action") } + if ca.Edit == nil || len(ca.Edit.Changes) == 0 { t.Fatalf("expected workspace edit") } +} + +func TestBuildDiagnosticsCodeAction_NoDiagnostics(t *testing.T) { + s := newTestServer() + s.llmClient = fakeLLM{resp: "FIXED"} + p := CodeActionParams{TextDocument: TextDocumentIdentifier{URI: "file:///t.go"}, Range: Range{}} + // empty context + p.Context = json.RawMessage(nil) + if ca := s.buildDiagnosticsCodeAction(p, "sel"); ca != nil { t.Fatalf("expected nil action when no diagnostics") } +} |
