✅ 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.
This commit is contained in:
tmu committed 2026-09-18 23:44:51 +00:00
1 parent 935e82d205
commit 8615723c64
1 file changed
+57 -1
+57 -1
View File
@@ -344,12 +344,14 @@ interface LabelsProbe {
readonly name: string; readonly name: string;
readonly factory: "getMatcher" | "getMatcherW"; readonly factory: "getMatcher" | "getMatcherW";
readonly body: string; readonly body: string;
readonly tail?: string;
} }
const labelsFor = ({ const labelsFor = ({
name, name,
factory, factory,
body, body,
tail = "",
}: LabelsProbe): Promise<readonly string[]> => { }: LabelsProbe): Promise<readonly string[]> => {
const session = new LspSession(REPO_ROOT); const session = new LspSession(REPO_ROOT);
const target: CompletionTarget = { const target: CompletionTarget = {
@@ -358,7 +360,7 @@ const labelsFor = ({
`import { ${factory} } from "./index.ts";`, `import { ${factory} } from "./index.ts";`,
`const m = ${factory}<${UNIVERSE}>()({`, `const m = ${factory}<${UNIVERSE}>()({`,
body, body,
"});", `}${tail});`,
"", "",
].join("\n"), ].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`", () => { test("autocomplete: `getMatcherW` offers the same popup as `getMatcher`", () => {
// Arrange // Arrange
const name = "getMatcherW_fresh"; const name = "getMatcherW_fresh";
@@ -418,3 +456,21 @@ test("autocomplete: `getMatcherW` offers the same popup as `getMatcher`", () =>
assert.deepEqual([...result], ["a", "b", "c"]); 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?"]);
});
});