Files
languageservices/workflow-parser/src/expressions.test.ts
T
Christopher Schleiden 2a3d63551f Rename folders
2023-02-22 15:52:40 -08:00

203 lines
5.4 KiB
TypeScript

import {StringToken} from "./templates/tokens";
import {isBasicExpression, isString} from "./templates/tokens/type-guards";
import {nullTrace} from "./test-utils/null-trace";
import {parseWorkflow} from "./workflows/workflow-parser";
describe("Workflow Expression Parsing", () => {
it("preserves original expressions when building format", () => {
const result = parseWorkflow(
{
name: "test.yaml",
content: `on: push
run-name: Test \${{ github.event_name }} \${{ github.ref }}
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: echo 'hello'`
},
nullTrace
);
expect(result.context.errors.getErrors()).toHaveLength(0);
const run = result.value!.assertMapping("run")!;
const runNameMapping = run.get(1)!;
expect(runNameMapping?.key?.assertString("run-name key").value).toBe("run-name");
const v = runNameMapping.value!;
expect(v).not.toBeUndefined();
if (!isBasicExpression(v)) {
throw new Error("expected run-name to be a basic expression");
}
expect(v.originalExpressions).toHaveLength(2);
expect(v.originalExpressions!.map(x => x.toDisplayString())).toEqual([
"${{ github.event_name }}",
"${{ github.ref }}"
]);
});
it("preserves original expressions when building format for multi-line strings", () => {
const result = parseWorkflow(
{
name: "test.yaml",
content: `on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: |
echo \${{ github.event_name }}
echo 'hello' \${{github.ref }}`
},
nullTrace
);
expect(result.context.errors.getErrors()).toHaveLength(0);
const run = result.value!.assertMapping("run")!;
const jobsMapping = run.get(1)!;
expect(jobsMapping?.key?.assertString("jobs").value).toBe("jobs");
const job = jobsMapping.value!.assertMapping("jobs")!.get(0)!.value!.assertMapping("job");
const stepRun = job
.get(1)
.value!.assertSequence("steps")
.get(0)
.assertMapping("step")
.get(0)
.value!.assertScalar("step-run");
if (!isBasicExpression(stepRun)) {
throw new Error("expected run-name to be a basic expression");
}
expect(stepRun.originalExpressions).toHaveLength(2);
expect(stepRun.originalExpressions!.map(x => [x.toDisplayString(), x.range, x.expressionRange])).toEqual([
[
"${{ github.event_name }}",
{
start: {line: 7, column: 16},
end: {line: 7, column: 40}
},
{
start: {line: 7, column: 20},
end: {line: 7, column: 37}
}
],
[
"${{ github.ref }}",
{
start: {line: 8, column: 24},
end: {line: 8, column: 40}
},
{
start: {line: 8, column: 27},
end: {line: 8, column: 37}
}
]
]);
});
it("return errors and string token with preserved expressions for (multiple) expression errors", () => {
const result = parseWorkflow(
{
name: "test.yaml",
content: `on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: |
echo \${{ abc }}
echo 'hello' \${{ gith }}`
},
nullTrace
);
expect(result.context.errors.getErrors()).toHaveLength(2);
const run = result.value!.assertMapping("run")!;
const jobsMapping = run.get(1)!;
expect(jobsMapping?.key?.assertString("jobs").value).toBe("jobs");
const job = jobsMapping.value!.assertMapping("jobs")!.get(0)!.value!.assertMapping("job");
const stepRun = job
.get(1)
.value!.assertSequence("steps")
.get(0)
.assertMapping("step")
.get(0)
.value!.assertScalar("step-run");
expect(isString(stepRun)).toBe(true);
expect((stepRun as StringToken).value).toContain("${{");
});
it("reports all errors for multi-line expressions at the correct locations", () => {
const result = parseWorkflow(
{
name: "test.yaml",
content: `on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: |
echo \${{ fromJSON2('test') }}
echo 'hello' \${{ toJSON2(inputs.test) }}`
},
nullTrace
);
expect(result.context.errors.getErrors()).toEqual([
{
prefix: "test.yaml (Line: 6, Col: 14)",
range: {
start: {line: 7, column: 16},
end: {line: 7, column: 40}
},
rawMessage: "Unrecognized function: 'fromJSON2'"
},
{
prefix: "test.yaml (Line: 6, Col: 14)",
range: {
start: {line: 8, column: 24},
end: {line: 8, column: 51}
},
rawMessage: "Unrecognized function: 'toJSON2'"
}
]);
});
it("parses isExpression strings into expression tokens", () => {
const result = parseWorkflow(
{
name: "test.yaml",
content: `on: push
jobs:
build:
runs-on: ubuntu-latest
if: github.event_name == 'push'
steps:
- run: echo 'hello'`
},
nullTrace
);
expect(result.context.errors.getErrors()).toHaveLength(0);
const workflowRoot = result.value!.assertMapping("root")!;
const jobs = workflowRoot.get(1).value.assertMapping("jobs");
const build = jobs.get(0).value.assertMapping("job");
const ifToken = build.get(1).value;
expect(ifToken.toString()).toEqual("${{ github.event_name == 'push' }}");
if (!isBasicExpression(ifToken)) {
throw new Error("expected if to be a basic expression");
}
});
});