162 lines
5.0 KiB
TypeScript
162 lines
5.0 KiB
TypeScript
import { expect, gotoSilverBulletPage, mod, test } from "./fixtures.ts";
|
|
|
|
test.use({
|
|
spaceFiles: {
|
|
"LuaCompletion.md": `# Lua completion
|
|
|
|
\`\`\`space-lua
|
|
lua.parseB
|
|
string.gs
|
|
editor.setT
|
|
editor.getT
|
|
system.invokeF
|
|
jumpdemo.target()
|
|
\`\`\`
|
|
`,
|
|
"LuaDefinitions.md": `#meta
|
|
|
|
\`\`\`space-lua
|
|
jumpdemo = {}
|
|
|
|
function jumpdemo.target()
|
|
return "definition"
|
|
end
|
|
\`\`\`
|
|
`,
|
|
},
|
|
});
|
|
|
|
test("Lua API completion shows signatures and documentation", async ({
|
|
sbServer,
|
|
page,
|
|
}) => {
|
|
await gotoSilverBulletPage(page, sbServer, "LuaCompletion");
|
|
|
|
const startCompletionAt = async (prefix: string) => {
|
|
await page.evaluate(async (prefix) => {
|
|
const client = (globalThis as any).client;
|
|
const view = client.editorView;
|
|
const text = view.state.doc.toString();
|
|
const cursor = text.indexOf(prefix) + prefix.length;
|
|
view.dispatch({ selection: { anchor: cursor } });
|
|
view.focus();
|
|
await client.clientSystem.localSyscall("editor.startCompletion", []);
|
|
}, prefix);
|
|
};
|
|
|
|
await startCompletionAt("lua.parseB");
|
|
|
|
const luaOption = page.locator(".cm-tooltip-autocomplete li", {
|
|
hasText: "parseBlock(code)",
|
|
});
|
|
await expect(luaOption).toBeVisible();
|
|
await expect(luaOption.locator(".cm-completionDetail")).toHaveText(
|
|
"Parses a Space Lua chunk and returns its AST. Blocks retain comments in source order with their exact text, kind, and source range.",
|
|
);
|
|
|
|
const documentation = page.locator(
|
|
".cm-completionInfo .sb-completion-documentation",
|
|
);
|
|
await expect(documentation).toBeVisible();
|
|
await expect(documentation.locator(":scope > h3")).toBeHidden();
|
|
await expect(documentation).toContainText("lua.parseBlock(code)");
|
|
await expect(documentation).toContainText(
|
|
"Parses a Space Lua chunk and returns its AST.",
|
|
);
|
|
await expect(documentation).toContainText("Parameters:");
|
|
await expect(documentation).toContainText("code");
|
|
await expect(documentation).toContainText("Lua code to parse.");
|
|
await luaOption.click({ force: true });
|
|
|
|
const appliedCompletion = await page.evaluate(() => {
|
|
const view = (globalThis as any).client.editorView;
|
|
const selection = view.state.selection.main;
|
|
const line = view.state.doc.lineAt(selection.head);
|
|
return {
|
|
line: line.text,
|
|
cursorOffset: selection.head - line.from,
|
|
selectionEmpty: selection.empty,
|
|
};
|
|
});
|
|
expect(appliedCompletion).toEqual({
|
|
line: "lua.parseBlock()",
|
|
cursorOffset: "lua.parseBlock(".length,
|
|
selectionEmpty: true,
|
|
});
|
|
|
|
await page.keyboard.press("Escape");
|
|
await startCompletionAt("string.gs");
|
|
|
|
const builtinOption = page.locator(".cm-tooltip-autocomplete li", {
|
|
hasText: "gsub(s, pattern, replacement, n?)",
|
|
});
|
|
await expect(builtinOption).toBeVisible();
|
|
await expect(builtinOption.locator(".cm-completionDetail")).toHaveText(
|
|
"Replaces Lua-pattern matches using a string, table, or function replacement.",
|
|
);
|
|
|
|
await page.keyboard.press("Escape");
|
|
await startCompletionAt("editor.setT");
|
|
|
|
const syscallWithParameters = page.locator(".cm-tooltip-autocomplete li", {
|
|
hasText: "setText(newText, shouldIsolateHistory?)",
|
|
});
|
|
await expect(syscallWithParameters).toBeVisible();
|
|
await expect(
|
|
syscallWithParameters.locator(".cm-completionDetail"),
|
|
).toHaveText(
|
|
"Updates the editor text with a minimal diff while preserving the cursor when possible.",
|
|
);
|
|
|
|
await page.keyboard.press("Escape");
|
|
await startCompletionAt("editor.getT");
|
|
|
|
const syscallWithoutParameters = page.locator(".cm-tooltip-autocomplete li", {
|
|
hasText: "getText()",
|
|
});
|
|
await expect(syscallWithoutParameters).toBeVisible();
|
|
await expect(
|
|
syscallWithoutParameters.locator(".cm-completionDetail"),
|
|
).toHaveText("Returns the full text of the currently open page or document.");
|
|
|
|
await page.keyboard.press("Escape");
|
|
await startCompletionAt("system.invokeF");
|
|
|
|
const signatureFallback = page.locator(".cm-tooltip-autocomplete li", {
|
|
hasText: "invokeFunction(name, ...)",
|
|
});
|
|
await expect(signatureFallback).toBeVisible();
|
|
await expect(signatureFallback.locator(".cm-completionDetail")).toHaveText(
|
|
"Invokes a loaded plug function by its plug-qualified name.",
|
|
);
|
|
});
|
|
|
|
test("modifier-click navigates to Lua function definitions", async ({
|
|
sbServer,
|
|
page,
|
|
}) => {
|
|
await gotoSilverBulletPage(page, sbServer, "LuaCompletion");
|
|
|
|
const coordinates = await page.evaluate(() => {
|
|
const view = (globalThis as any).client.editorView;
|
|
const text = view.state.doc.toString();
|
|
const symbol = "jumpdemo.target";
|
|
const position = text.indexOf(symbol) + "jumpdemo.".length + 2;
|
|
const coordinates = view.coordsAtPos(position);
|
|
if (!coordinates) throw new Error("Could not resolve symbol coordinates");
|
|
return {
|
|
x: coordinates.left + 2,
|
|
y: (coordinates.top + coordinates.bottom) / 2,
|
|
};
|
|
});
|
|
|
|
await page.keyboard.down(mod);
|
|
await page.mouse.click(coordinates.x, coordinates.y);
|
|
await page.keyboard.up(mod);
|
|
|
|
await expect(page.locator("#sb-current-page input.sb-input")).toHaveValue(
|
|
"LuaDefinitions",
|
|
);
|
|
await page.waitForURL(/\/LuaDefinitions$/);
|
|
});
|