c1ad4d14df
* Use property descriptions for completion items * Add test for type description fallback
218 lines
5.9 KiB
TypeScript
218 lines
5.9 KiB
TypeScript
import {TextDocument} from "vscode-languageserver-textdocument";
|
|
import {hover} from "./hover";
|
|
|
|
describe("hover action files", () => {
|
|
function createActionDocument(
|
|
content: string,
|
|
uri = "file:///test/action.yml"
|
|
): [TextDocument, {line: number; character: number}] {
|
|
// Parse cursor position and remove the | character
|
|
const cursorIndex = content.indexOf("|");
|
|
if (cursorIndex === -1) {
|
|
throw new Error("No cursor (|) found in content");
|
|
}
|
|
const newContent = content.substring(0, cursorIndex) + content.substring(cursorIndex + 1);
|
|
const doc = TextDocument.create(uri, "yaml", 1, newContent);
|
|
const position = doc.positionAt(cursorIndex);
|
|
return [doc, position];
|
|
}
|
|
|
|
describe("top-level keys", () => {
|
|
it("shows description for name key", async () => {
|
|
const [doc, position] = createActionDocument(`na|me: My Action
|
|
description: Test
|
|
runs:
|
|
using: node20
|
|
main: index.js`);
|
|
const result = await hover(doc, position);
|
|
|
|
expect(result).not.toBeNull();
|
|
expect(result?.contents).toContain("name");
|
|
});
|
|
|
|
it("shows description for description key", async () => {
|
|
const [doc, position] = createActionDocument(`name: My Action
|
|
descrip|tion: Test
|
|
runs:
|
|
using: node20
|
|
main: index.js`);
|
|
const result = await hover(doc, position);
|
|
|
|
expect(result).not.toBeNull();
|
|
expect(result?.contents).toContain("description");
|
|
});
|
|
|
|
it("shows description for runs key", async () => {
|
|
const [doc, position] = createActionDocument(`name: My Action
|
|
description: Test
|
|
ru|ns:
|
|
using: node20
|
|
main: index.js`);
|
|
const result = await hover(doc, position);
|
|
|
|
expect(result).not.toBeNull();
|
|
expect(result?.contents).toContain("runs");
|
|
});
|
|
|
|
it("shows description for author key", async () => {
|
|
const [doc, position] = createActionDocument(`name: My Action
|
|
description: Test
|
|
au|thor: Me
|
|
runs:
|
|
using: node20
|
|
main: index.js`);
|
|
const result = await hover(doc, position);
|
|
|
|
expect(result).not.toBeNull();
|
|
expect(result?.contents).toContain("author");
|
|
expect(result?.contents).toContain("Documentation");
|
|
});
|
|
});
|
|
|
|
describe("runs properties", () => {
|
|
it("shows description for using key", async () => {
|
|
const [doc, position] = createActionDocument(`name: My Action
|
|
description: Test
|
|
runs:
|
|
us|ing: node20
|
|
main: index.js`);
|
|
const result = await hover(doc, position);
|
|
|
|
expect(result).not.toBeNull();
|
|
expect(result?.contents).toContain("runtime");
|
|
});
|
|
|
|
it("shows description for main key", async () => {
|
|
const [doc, position] = createActionDocument(`name: My Action
|
|
description: Test
|
|
runs:
|
|
using: node20
|
|
ma|in: index.js`);
|
|
const result = await hover(doc, position);
|
|
|
|
expect(result).not.toBeNull();
|
|
expect(result?.contents).toContain("main");
|
|
});
|
|
});
|
|
|
|
describe("inputs", () => {
|
|
it("shows description for inputs section", async () => {
|
|
const [doc, position] = createActionDocument(`name: My Action
|
|
description: Test
|
|
inp|uts:
|
|
my-input:
|
|
description: A test input
|
|
runs:
|
|
using: node20
|
|
main: index.js`);
|
|
const result = await hover(doc, position);
|
|
|
|
expect(result).not.toBeNull();
|
|
expect(result?.contents).toContain("input");
|
|
});
|
|
|
|
it("shows description for required key", async () => {
|
|
const [doc, position] = createActionDocument(`name: My Action
|
|
description: Test
|
|
inputs:
|
|
my-input:
|
|
description: A test input
|
|
requ|ired: true
|
|
runs:
|
|
using: node20
|
|
main: index.js`);
|
|
const result = await hover(doc, position);
|
|
|
|
expect(result).not.toBeNull();
|
|
expect(result?.contents).toContain("required");
|
|
});
|
|
|
|
it("shows allowed context for default value", async () => {
|
|
const [doc, position] = createActionDocument(`name: My Action
|
|
description: Test
|
|
inputs:
|
|
my-input:
|
|
description: A test input
|
|
def|ault: foo
|
|
runs:
|
|
using: node20
|
|
main: index.js`);
|
|
const result = await hover(doc, position);
|
|
|
|
expect(result).not.toBeNull();
|
|
// Input defaults can use expressions with github, strategy, matrix, job, runner contexts
|
|
expect(result?.contents).toContain("github");
|
|
});
|
|
});
|
|
|
|
describe("branding", () => {
|
|
it("shows description for branding section", async () => {
|
|
const [doc, position] = createActionDocument(`name: My Action
|
|
description: Test
|
|
runs:
|
|
using: node20
|
|
main: index.js
|
|
brand|ing:
|
|
icon: activity
|
|
color: blue`);
|
|
const result = await hover(doc, position);
|
|
|
|
expect(result).not.toBeNull();
|
|
expect(result?.contents).toContain("brand");
|
|
expect(result?.contents).toContain("Documentation");
|
|
});
|
|
|
|
it("shows description for icon key", async () => {
|
|
const [doc, position] = createActionDocument(`name: My Action
|
|
description: Test
|
|
runs:
|
|
using: node20
|
|
main: index.js
|
|
branding:
|
|
ic|on: activity
|
|
color: blue`);
|
|
const result = await hover(doc, position);
|
|
|
|
expect(result).not.toBeNull();
|
|
expect(result?.contents).toContain("icon");
|
|
});
|
|
});
|
|
|
|
describe("document type routing", () => {
|
|
it("routes action.yml to action hover", async () => {
|
|
const [doc, position] = createActionDocument(
|
|
`na|me: My Action
|
|
description: Test
|
|
runs:
|
|
using: node20
|
|
main: index.js`,
|
|
"file:///my-repo/action.yml"
|
|
);
|
|
const result = await hover(doc, position);
|
|
|
|
expect(result).not.toBeNull();
|
|
});
|
|
|
|
it("does not route workflow files to action hover", async () => {
|
|
const doc = TextDocument.create(
|
|
"file:///repo/.github/workflows/ci.yml",
|
|
"yaml",
|
|
1,
|
|
`name: CI
|
|
on: push
|
|
jobs:
|
|
build:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- run: echo hello`
|
|
);
|
|
// Hovering over 'name' in a workflow file should give workflow-specific info
|
|
const result = await hover(doc, {line: 0, character: 2});
|
|
|
|
// The workflow hover might not have description for workflow name,
|
|
// but it should not crash
|
|
expect(result === null || result.contents !== undefined).toBe(true);
|
|
});
|
|
});
|
|
});
|