diff options
| author | Paul Buetow <paul@buetow.org> | 2025-09-04 16:29:57 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2025-09-04 16:29:57 +0300 |
| commit | d99bdf981dbee7e038e4a8e262504c1a15047c38 (patch) | |
| tree | eb866c854c2c8b10bbacf53e38fdd9c7fe66d66f /internal | |
| parent | 2a6ff853c20e6c1c780c69affdadacda2db202b6 (diff) | |
tests: add more table-driven cases and negative provider tests; update report
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/llm/copilot_http_test.go | 19 | ||||
| -rw-r--r-- | internal/lsp/build_prompts_table_test.go | 16 | ||||
| -rw-r--r-- | internal/lsp/compute_textedit_table_test.go | 33 |
3 files changed, 68 insertions, 0 deletions
diff --git a/internal/llm/copilot_http_test.go b/internal/llm/copilot_http_test.go index 30144d1..2e46d68 100644 --- a/internal/llm/copilot_http_test.go +++ b/internal/llm/copilot_http_test.go @@ -108,6 +108,25 @@ func TestCopilot_Chat_MultiChoice_And_ErrorBody(t *testing.T) { } } +func TestCopilot_Chat_DecodeError_StatusOK(t *testing.T) { + // Chat returns 200 but invalid JSON; expect decode error + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, "{invalid") + })) + defer srv.Close() + c := newCopilot(srv.URL, "gpt-4o-mini", "KEY", f64p(0.1)).(copilotClient) + tr := rtFunc2(func(r *http.Request) (*http.Response, error) { + if r.URL.Host == "api.github.com" && r.URL.Path == "/copilot_internal/v2/token" { + rw := httptest.NewRecorder(); _ = json.NewEncoder(rw).Encode(map[string]string{"token":"tok"}); res := rw.Result(); res.StatusCode = 200; return res, nil + } + return http.DefaultTransport.RoundTrip(r) + }) + c.httpClient = &http.Client{Transport: tr, Timeout: 5 * time.Second} + if _, err := c.Chat(context.Background(), []Message{{Role:"user", Content:"hi"}}); err == nil { + t.Fatalf("expected decode error for invalid body") + } +} + func TestCopilot_CodeCompletion_MalformedAndEmpty(t *testing.T) { c := newCopilot("https://api.githubcopilot.com", "gpt-4o-mini", "API", f64p(0.1)).(copilotClient) tr := rtFunc2(func(r *http.Request) (*http.Response, error) { diff --git a/internal/lsp/build_prompts_table_test.go b/internal/lsp/build_prompts_table_test.go new file mode 100644 index 0000000..b0092e2 --- /dev/null +++ b/internal/lsp/build_prompts_table_test.go @@ -0,0 +1,16 @@ +package lsp + +import "testing" + +func TestBuildPrompts_Table(t *testing.T) { + p := CompletionParams{TextDocument: TextDocumentIdentifier{URI: "file:///x.go"}, Position: Position{Line:5, Character:7}} + cases := []struct{ name string; inParams bool }{ + {"generic", false}, + {"in_params", true}, + } + for _, c := range cases { + sys, user := buildPrompts(c.inParams, p, "above", "current", "below", "func ctx") + if sys == "" || user == "" { t.Fatalf("%s: prompts empty", c.name) } + } +} + diff --git a/internal/lsp/compute_textedit_table_test.go b/internal/lsp/compute_textedit_table_test.go new file mode 100644 index 0000000..d82e91d --- /dev/null +++ b/internal/lsp/compute_textedit_table_test.go @@ -0,0 +1,33 @@ +package lsp + +import "testing" + +func TestComputeTextEditAndFilter_Table(t *testing.T) { + cases := []struct{ + name string + inParams bool + current string + pos Position + cleaned string + }{ + {"ident_replace", false, "ab cd", Position{Line:1, Character:4}, "X"}, + {"params_inside", true, "func add(a int, b string)", Position{Line:0, Character:15}, "c bool"}, + {"params_at_close", true, "func add(a int)", Position{Line:0, Character:len("func add(a int)")}, "b string"}, + } + for _, c := range cases { + te, filter := computeTextEditAndFilter(c.cleaned, c.inParams, c.current, CompletionParams{Position: c.pos}) + if te == nil { + t.Fatalf("%s: expected edit", c.name) + } + if c.inParams && te.Range.Start.Character == 0 { + t.Fatalf("%s: expected param range (non-zero start)", c.name) + } + if filter == "" && c.current != "" { + // For ident_replace, filter may be non-empty; for params, it can be empty when replacing entire segment + } + if te.NewText != c.cleaned { + t.Fatalf("%s: newText got %q want %q", c.name, te.NewText, c.cleaned) + } + } +} + |
