Files
languageservices/actions-expressions/src/completion.test.ts
T

159 lines
4.6 KiB
TypeScript
Raw Normal View History

2023-01-09 19:02:19 -05:00
import {complete, CompletionItem, trimTokenVector} from "./completion";
2023-01-11 10:59:06 -08:00
import {DescriptionDictionary} from "./completion/descriptionDictionary";
2023-01-09 19:02:19 -05:00
import {BooleanData} from "./data/boolean";
import {Dictionary} from "./data/dictionary";
import {StringData} from "./data/string";
import {FunctionInfo} from "./funcs/info";
import {Lexer, TokenType} from "./lexer";
const testContext = new Dictionary(
{
key: "env",
value: new Dictionary(
{
key: "FOO",
2023-01-09 19:02:19 -05:00
value: new StringData("")
},
{
key: "BAR_TEST",
2023-01-09 19:02:19 -05:00
value: new StringData("")
}
2023-01-09 19:02:19 -05:00
)
},
2023-01-10 17:44:48 -08:00
{
key: "github",
value: new DescriptionDictionary({
key: "actor",
value: new StringData(""),
description: "The name of the person or app that initiated the workflow. For example, octocat."
})
},
{
key: "secrets",
value: new Dictionary({
key: "AWS_TOKEN",
2023-01-09 19:02:19 -05:00
value: new BooleanData(true)
})
},
{
key: "hashFiles(1,255)",
2023-01-09 19:02:19 -05:00
value: new Dictionary()
}
);
const testFunctions: FunctionInfo[] = [];
const testComplete = (input: string): CompletionItem[] => {
const pos = input.indexOf("|");
input = input.replace("|", "");
2023-01-09 19:02:19 -05:00
const results = complete(input.slice(0, pos >= 0 ? pos : input.length), testContext, testFunctions);
return results;
};
function completionItems(...labels: string[]): CompletionItem[] {
2023-01-09 19:02:19 -05:00
return labels.map(label => ({label, function: false}));
}
describe("auto-complete", () => {
describe("top-level", () => {
it("includes built-in functions", () => {
const expected: CompletionItem = {
label: "toJson",
description:
"`toJSON(value)`\n\nReturns a pretty-print JSON representation of `value`. You can use this function to debug the information provided in contexts.",
2023-01-09 19:02:19 -05:00
function: true
};
expect(testComplete("to")).toContainEqual(expected);
expect(testComplete("toJs")).toContainEqual(expected);
expect(testComplete("1 == toJS")).toContainEqual(expected);
expect(testComplete("toJS| == 1")).toContainEqual(expected);
});
it("removes parentheses from passed in function context", () => {
expect(testComplete("|")).toContainEqual({
label: "hashFiles",
2023-01-09 19:02:19 -05:00
function: true
});
});
});
2023-01-10 16:05:50 -08:00
describe("in multi-line expressions", () => {
it("includes built-in functions", () => {
expect(testComplete("1 == (\nto").map(x => x.label)).toContainEqual("toJson");
});
});
describe("for contexts", () => {
it("provides suggestions for env", () => {
const expected = completionItems("BAR_TEST", "FOO");
expect(testComplete("env.X")).toEqual(expected);
expect(testComplete("1 == env.F")).toEqual(expected);
expect(testComplete("env.")).toEqual(expected);
expect(testComplete("env.FOO")).toEqual(expected);
});
2023-01-10 17:44:48 -08:00
it("includes descriptions", () => {
expect(testComplete("github.")).toContainEqual<CompletionItem>({
label: "actor",
function: false,
description: "The name of the person or app that initiated the workflow. For example, octocat."
});
});
it("provides suggestions for secrets", () => {
const expected = completionItems("AWS_TOKEN");
expect(testComplete("secrets.A")).toEqual(expected);
expect(testComplete("1 == secrets.F")).toEqual(expected);
expect(testComplete("toJSON(secrets.")).toEqual(expected);
});
it("provides suggestions for contexts in function call", () => {
2023-01-09 19:02:19 -05:00
expect(testComplete("toJSON(env.|)")).toEqual(completionItems("BAR_TEST", "FOO"));
});
});
});
describe("trimTokenVector", () => {
test.each<{
input: string;
expected: TokenType[];
}>([
{
input: "env.",
2023-01-09 19:02:19 -05:00
expected: [TokenType.IDENTIFIER, TokenType.DOT, TokenType.EOF]
},
{
input: "github.act",
2023-01-09 19:02:19 -05:00
expected: [TokenType.IDENTIFIER, TokenType.DOT, TokenType.IDENTIFIER, TokenType.EOF]
},
{
input: "1 == github.act",
2023-01-09 19:02:19 -05:00
expected: [TokenType.IDENTIFIER, TokenType.DOT, TokenType.IDENTIFIER, TokenType.EOF]
},
{
input: "github.mona == github.act",
2023-01-09 19:02:19 -05:00
expected: [TokenType.IDENTIFIER, TokenType.DOT, TokenType.IDENTIFIER, TokenType.EOF]
},
{
input: "github['test'].",
expected: [
TokenType.IDENTIFIER,
TokenType.LEFT_BRACKET,
TokenType.STRING,
TokenType.RIGHT_BRACKET,
TokenType.DOT,
2023-01-09 19:02:19 -05:00
TokenType.EOF
]
}
])("$input", ({input, expected}) => {
const l = new Lexer(input);
const lr = l.lex();
const tv = trimTokenVector(lr.tokens);
2023-01-09 19:02:19 -05:00
expect(tv.map(x => x.type)).toEqual(expected);
});
});