diff options
| author | Paul Buetow <paul@buetow.org> | 2025-09-06 13:19:01 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2025-09-06 13:19:01 +0300 |
| commit | 04f290dbeeee8a6fcbc70fed253a968336bcb2ab (patch) | |
| tree | 3ee23a4ac4bcc5b43b43697cfb0e905735fc6331 /internal/lsp | |
| parent | 5e966f50111adf6e2cb2683fe588f6fe033fa931 (diff) | |
more tests
Diffstat (limited to 'internal/lsp')
| -rw-r--r-- | internal/lsp/codeaction_gotest_int_test.go | 26 | ||||
| -rw-r--r-- | internal/lsp/coverage_add_test.go | 103 |
2 files changed, 129 insertions, 0 deletions
diff --git a/internal/lsp/codeaction_gotest_int_test.go b/internal/lsp/codeaction_gotest_int_test.go new file mode 100644 index 0000000..6bb1c45 --- /dev/null +++ b/internal/lsp/codeaction_gotest_int_test.go @@ -0,0 +1,26 @@ +package lsp + +import ( + "os" + "path/filepath" + "testing" +) + +func TestResolveGoTest_CreatesTestFile(t *testing.T) { + dir := t.TempDir() + src := filepath.Join(dir, "x.go") + if err := os.WriteFile(src, []byte("package x\n\nfunc Sum(a,b int) int { return a+b }\n"), 0o644); err != nil { + t.Fatalf("write: %v", err) + } + s := &Server{} // minimal server with nil llmClient to trigger stub + uri := "file://" + src + we, jumpURI, jumpRange, ok := s.resolveGoTest(uri, Position{Line: 2}) + if !ok || jumpURI == "" || jumpRange.Start.Line < 0 { + t.Fatalf("resolveGoTest failed: ok=%v uri=%q range=%v", ok, jumpURI, jumpRange) + } + // Expect documentChanges to include a create and an edit + if len(we.DocumentChanges) == 0 && len(we.Changes) == 0 { + t.Fatalf("expected edits to create or append test file: %+v", we) + } +} + diff --git a/internal/lsp/coverage_add_test.go b/internal/lsp/coverage_add_test.go new file mode 100644 index 0000000..f4b0f00 --- /dev/null +++ b/internal/lsp/coverage_add_test.go @@ -0,0 +1,103 @@ +package lsp + +import ( + "encoding/json" + "testing" +) + +func TestInParamListAndComputeWordStart(t *testing.T) { + line := "func add(a int, b int) int { return a + b }" + if !inParamList(line, 15) { // inside params + t.Fatalf("expected inParamList true") + } + if inParamList("not a func", 3) { + t.Fatalf("expected inParamList false") + } + if n := computeWordStart("helloWorld", 10); n != 0 { + t.Fatalf("computeWordStart wrong: %d", n) + } +} + +func TestStripInlineAndLabel(t *testing.T) { + if got := stripInlineCodeSpan("`abc`def"); got != "abc" { + t.Fatalf("stripInlineCodeSpan: %q", got) + } + if lbl := labelForCompletion("First line\nSecond", "fir"); lbl != "First line" { + t.Fatalf("labelForCompletion: %q", lbl) + } + if lbl := labelForCompletion("Other", "zzz"); lbl != "zzz" { + t.Fatalf("label fallback: %q", lbl) + } +} + +func TestRangeComparators(t *testing.T) { + a := Range{Start: Position{Line: 1, Character: 5}, End: Position{Line: 3, Character: 0}} + b := Range{Start: Position{Line: 2, Character: 0}, End: Position{Line: 4, Character: 0}} + if !rangesOverlap(a, b) { + t.Fatalf("expected overlap") + } + if !lessPos(Position{Line: 1, Character: 0}, Position{Line: 1, Character: 1}) { + t.Fatalf("lessPos") + } + if !greaterPos(Position{Line: 2, Character: 0}, Position{Line: 1, Character: 10}) { + t.Fatalf("greaterPos") + } + if !isIdentChar('A') || isIdentChar('-') { + t.Fatalf("isIdentChar") + } +} + +func TestFindGoFunctionAtLine_NoBody(t *testing.T) { + lines := []string{"func X(a int)", "// comment"} + start, end := findGoFunctionAtLine(lines, 0) + if start != 0 || end != 0 { + t.Fatalf("expected single-line prototype, got %d,%d", start, end) + } +} + +func TestLineHasInlinePrompt(t *testing.T) { + if !lineHasInlinePrompt(">do>") { + t.Fatalf("expected inline prompt") + } +} + +func TestDiagnosticsInRange_Overlap(t *testing.T) { + s := &Server{} + ctx := CodeActionContext{Diagnostics: []Diagnostic{{ + Range: Range{Start: Position{Line: 10, Character: 0}, End: Position{Line: 12, Character: 0}}, + Message: "x", + }}} + raw, _ := json.Marshal(ctx) + sel := Range{Start: Position{Line: 11, Character: 0}, End: Position{Line: 11, Character: 1}} + out := s.diagnosticsInRange(raw, sel) + if len(out) != 1 { + t.Fatalf("expected 1 diag overlap, got %d", len(out)) + } + // no diagnostics + var empty json.RawMessage + if o2 := s.diagnosticsInRange(empty, sel); len(o2) != 0 { + t.Fatalf("expected 0 with empty ctx") + } +} + +func TestIndentHelpersAndPromptRemoval(t *testing.T) { + if ind := leadingIndent("\t ab"); ind == "" { + t.Fatalf("expected indent") + } + if out := applyIndent(" ", "x\ny"); out != " x\n y" { + t.Fatalf("applyIndent: %q", out) + } + // double-open trigger removes whole line + edits := promptRemovalEditsForLine(">>ask>", 3) + if len(edits) != 1 || edits[0].Range.Start.Line != 3 { + t.Fatalf("unexpected edits: %#v", edits) + } + // temporarily switch to semicolon tags and test collection + oldOpen, oldClose := inlineOpenChar, inlineCloseChar + inlineOpenChar, inlineCloseChar = ';', ';' + t.Cleanup(func() { inlineOpenChar, inlineCloseChar = oldOpen, oldClose }) + edits2 := collectSemicolonMarkers("pre;do;post", 1) + if len(edits2) != 1 { + t.Fatalf("expected one semicolon edit, got %#v", edits2) + } +} |
