✅ 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:
1 parent
935e82d205
commit
8615723c64
1 file changed
+57
-1
+57
-1
@@ -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?"]);
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in new issue
Block a user