From 8615723c64a8b1ed15e33734723b0782117e5ba0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Fri, 18 Sep 2026 23:44:51 +0000 Subject: [PATCH] :white_check_mark: Cover fallback autocompletes When a fallback argument is present, the second overload supplies the contextual type, so the handler map popup offers optional keys (`a? b? c?`) and handled keys stay optional (`b? c?`). The exhaustive one-argument popup is unchanged. Covered for both factories. --- src/primitive.test.ts | 58 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/src/primitive.test.ts b/src/primitive.test.ts index b9d10ae..6b1c9f8 100644 --- a/src/primitive.test.ts +++ b/src/primitive.test.ts @@ -344,12 +344,14 @@ interface LabelsProbe { readonly name: string; readonly factory: "getMatcher" | "getMatcherW"; readonly body: string; + readonly tail?: string; } const labelsFor = ({ name, factory, body, + tail = "", }: LabelsProbe): Promise => { const session = new LspSession(REPO_ROOT); const target: CompletionTarget = { @@ -358,7 +360,7 @@ const labelsFor = ({ `import { ${factory} } from "./index.ts";`, `const m = ${factory}<${UNIVERSE}>()({`, body, - "});", + `}${tail});`, "", ].join("\n"), }; @@ -402,6 +404,42 @@ test("autocomplete: handled keys drop out of the popup", () => { }); }); +test("autocomplete: a fallback makes the remaining keys optional", () => { + // Arrange + const name = "getMatcher_with_fallback"; + + // Act + const labels = labelsFor({ + name, + factory: "getMatcher", + body: " /*COMPLETE*/", + tail: ", () => 0", + }); + + // Assert + return labels.then((result) => { + assert.deepEqual([...result], ["a?", "b?", "c?"]); + }); +}); + +test("autocomplete: with a fallback, handled keys stay optional", () => { + // Arrange + const name = "getMatcher_with_fallback_after_key"; + + // Act + const labels = labelsFor({ + name, + factory: "getMatcher", + body: " a: () => 1,\n /*COMPLETE*/", + tail: ", () => 0", + }); + + // Assert + return labels.then((result) => { + assert.deepEqual([...result], ["b?", "c?"]); + }); +}); + test("autocomplete: `getMatcherW` offers the same popup as `getMatcher`", () => { // Arrange const name = "getMatcherW_fresh"; @@ -418,3 +456,21 @@ test("autocomplete: `getMatcherW` offers the same popup as `getMatcher`", () => assert.deepEqual([...result], ["a", "b", "c"]); }); }); + +test("autocomplete: `getMatcherW` also offers optional keys with a fallback", () => { + // Arrange + const name = "getMatcherW_with_fallback"; + + // Act + const labels = labelsFor({ + name, + factory: "getMatcherW", + body: " /*COMPLETE*/", + tail: ", () => 0", + }); + + // Assert + return labels.then((result) => { + assert.deepEqual([...result], ["a?", "b?", "c?"]); + }); +});