Skip to content

Commit 3223373

Browse files
committed
Validate expression block-scalar chomping
1 parent 7f8bba4 commit 3223373

12 files changed

+2919
-10
lines changed
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import {registerLogger} from "./log";
2+
import {createDocument} from "./test-utils/document";
3+
import {TestLogger} from "./test-utils/logger";
4+
import {clearCache} from "./utils/workflow-cache";
5+
import {validate} from "./validate";
6+
7+
registerLogger(new TestLogger());
8+
9+
beforeEach(() => {
10+
clearCache();
11+
});
12+
13+
describe("block scalar chomping - allowed cases", () => {
14+
it("does NOT warn for step.run with clip chomping (exception)", async () => {
15+
const input = `
16+
on: push
17+
jobs:
18+
build:
19+
runs-on: ubuntu-latest
20+
steps:
21+
- run: |
22+
echo \${{ github.event_name }}
23+
`;
24+
const result = await validate(createDocument("wf.yaml", input));
25+
26+
expect(result.filter(d => d.code === "expression-block-scalar-chomping")).toEqual([]);
27+
});
28+
29+
it("does not warn for inline expression", async () => {
30+
const input = `
31+
on: push
32+
jobs:
33+
build:
34+
if: \${{ github.event_name == 'push' }}
35+
runs-on: ubuntu-latest
36+
steps:
37+
- run: echo hi
38+
`;
39+
const result = await validate(createDocument("wf.yaml", input));
40+
41+
expect(result.filter(d => d.code === "expression-block-scalar-chomping")).toEqual([]);
42+
});
43+
44+
it("does not warn for quoted string", async () => {
45+
const input = `
46+
on: push
47+
jobs:
48+
build:
49+
if: "\${{ github.event_name == 'push' }}"
50+
runs-on: ubuntu-latest
51+
steps:
52+
- run: echo hi
53+
`;
54+
const result = await validate(createDocument("wf.yaml", input));
55+
56+
expect(result.filter(d => d.code === "expression-block-scalar-chomping")).toEqual([]);
57+
});
58+
});
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
import {DiagnosticSeverity} from "vscode-languageserver-types";
2+
import {registerLogger} from "./log";
3+
import {createDocument} from "./test-utils/document";
4+
import {TestLogger} from "./test-utils/logger";
5+
import {clearCache} from "./utils/workflow-cache";
6+
import {validate} from "./validate";
7+
8+
registerLogger(new TestLogger());
9+
10+
beforeEach(() => {
11+
clearCache();
12+
});
13+
14+
describe("block scalar chomping - boolean fields", () => {
15+
describe("job continue-on-error", () => {
16+
it("errors with clip chomping", async () => {
17+
const input = `
18+
on: push
19+
jobs:
20+
build:
21+
runs-on: ubuntu-latest
22+
continue-on-error: |
23+
\${{ matrix.experimental }}
24+
steps:
25+
- run: echo hi
26+
`;
27+
const result = await validate(createDocument("wf.yaml", input));
28+
29+
expect(result).toContainEqual(
30+
expect.objectContaining({
31+
message:
32+
"Block scalar adds trailing newline which breaks boolean evaluation. Use '|-' to strip trailing newlines.",
33+
code: "expression-block-scalar-chomping",
34+
severity: DiagnosticSeverity.Error
35+
})
36+
);
37+
});
38+
39+
it("errors with keep chomping", async () => {
40+
const input = `
41+
on: push
42+
jobs:
43+
build:
44+
runs-on: ubuntu-latest
45+
continue-on-error: |+
46+
\${{ matrix.experimental }}
47+
steps:
48+
- run: echo hi
49+
`;
50+
const result = await validate(createDocument("wf.yaml", input));
51+
52+
expect(result).toContainEqual(
53+
expect.objectContaining({
54+
message:
55+
"Block scalar adds trailing newline which breaks boolean evaluation. Use '|-' to strip trailing newlines.",
56+
code: "expression-block-scalar-chomping",
57+
severity: DiagnosticSeverity.Error
58+
})
59+
);
60+
});
61+
62+
it("does not error with strip chomping", async () => {
63+
const input = `
64+
on: push
65+
jobs:
66+
build:
67+
runs-on: ubuntu-latest
68+
continue-on-error: |-
69+
\${{ matrix.experimental }}
70+
steps:
71+
- run: echo hi
72+
`;
73+
const result = await validate(createDocument("wf.yaml", input));
74+
75+
expect(result.filter(d => d.code === "expression-block-scalar-chomping")).toEqual([]);
76+
});
77+
});
78+
79+
describe("step continue-on-error", () => {
80+
it("errors with clip chomping", async () => {
81+
const input = `
82+
on: push
83+
jobs:
84+
build:
85+
runs-on: ubuntu-latest
86+
steps:
87+
- run: echo hi
88+
continue-on-error: |
89+
\${{ matrix.experimental }}
90+
`;
91+
const result = await validate(createDocument("wf.yaml", input));
92+
93+
expect(result).toContainEqual(
94+
expect.objectContaining({
95+
message:
96+
"Block scalar adds trailing newline which breaks boolean evaluation. Use '|-' to strip trailing newlines.",
97+
code: "expression-block-scalar-chomping",
98+
severity: DiagnosticSeverity.Error
99+
})
100+
);
101+
});
102+
103+
it("errors with keep chomping", async () => {
104+
const input = `
105+
on: push
106+
jobs:
107+
build:
108+
runs-on: ubuntu-latest
109+
steps:
110+
- run: echo hi
111+
continue-on-error: |+
112+
\${{ matrix.experimental }}
113+
`;
114+
const result = await validate(createDocument("wf.yaml", input));
115+
116+
expect(result).toContainEqual(
117+
expect.objectContaining({
118+
message:
119+
"Block scalar adds trailing newline which breaks boolean evaluation. Use '|-' to strip trailing newlines.",
120+
code: "expression-block-scalar-chomping",
121+
severity: DiagnosticSeverity.Error
122+
})
123+
);
124+
});
125+
126+
it("does not error with strip chomping", async () => {
127+
const input = `
128+
on: push
129+
jobs:
130+
build:
131+
runs-on: ubuntu-latest
132+
steps:
133+
- run: echo hi
134+
continue-on-error: |-
135+
\${{ matrix.experimental }}
136+
`;
137+
const result = await validate(createDocument("wf.yaml", input));
138+
139+
expect(result.filter(d => d.code === "expression-block-scalar-chomping")).toEqual([]);
140+
});
141+
});
142+
});
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
import {DiagnosticSeverity} from "vscode-languageserver-types";
2+
import {registerLogger} from "./log";
3+
import {createDocument} from "./test-utils/document";
4+
import {TestLogger} from "./test-utils/logger";
5+
import {clearCache} from "./utils/workflow-cache";
6+
import {validate} from "./validate";
7+
8+
registerLogger(new TestLogger());
9+
10+
beforeEach(() => {
11+
clearCache();
12+
});
13+
14+
describe("block scalar chomping - if fields", () => {
15+
describe("job-if", () => {
16+
it("errors with clip chomping", async () => {
17+
const input = `
18+
on: push
19+
jobs:
20+
build:
21+
if: |
22+
\${{ github.event_name == 'push' }}
23+
runs-on: ubuntu-latest
24+
steps:
25+
- run: echo hi
26+
`;
27+
const result = await validate(createDocument("wf.yaml", input));
28+
29+
expect(result).toContainEqual(
30+
expect.objectContaining({
31+
message:
32+
"Block scalar adds trailing newline which breaks boolean evaluation. Use '|-' to strip trailing newlines.",
33+
code: "expression-block-scalar-chomping",
34+
severity: DiagnosticSeverity.Error
35+
})
36+
);
37+
});
38+
39+
it("errors with keep chomping", async () => {
40+
const input = `
41+
on: push
42+
jobs:
43+
build:
44+
if: |+
45+
\${{ github.event_name == 'push' }}
46+
runs-on: ubuntu-latest
47+
steps:
48+
- run: echo hi
49+
`;
50+
const result = await validate(createDocument("wf.yaml", input));
51+
52+
expect(result).toContainEqual(
53+
expect.objectContaining({
54+
message:
55+
"Block scalar adds trailing newline which breaks boolean evaluation. Use '|-' to strip trailing newlines.",
56+
code: "expression-block-scalar-chomping",
57+
severity: DiagnosticSeverity.Error
58+
})
59+
);
60+
});
61+
62+
it("does not error with strip chomping", async () => {
63+
const input = `
64+
on: push
65+
jobs:
66+
build:
67+
if: |-
68+
\${{ github.event_name == 'push' }}
69+
runs-on: ubuntu-latest
70+
steps:
71+
- run: echo hi
72+
`;
73+
const result = await validate(createDocument("wf.yaml", input));
74+
75+
expect(result.filter(d => d.code === "expression-block-scalar-chomping")).toEqual([]);
76+
});
77+
78+
it("errors without ${{ }} (isExpression)", async () => {
79+
const input = `
80+
on: push
81+
jobs:
82+
build:
83+
if: |
84+
github.event_name == 'push'
85+
runs-on: ubuntu-latest
86+
steps:
87+
- run: echo hi
88+
`;
89+
const result = await validate(createDocument("wf.yaml", input));
90+
91+
expect(result).toContainEqual(
92+
expect.objectContaining({
93+
message:
94+
"Block scalar adds trailing newline which breaks boolean evaluation. Use '|-' to strip trailing newlines.",
95+
code: "expression-block-scalar-chomping",
96+
severity: DiagnosticSeverity.Error
97+
})
98+
);
99+
});
100+
101+
it("uses > indicator in error message for folded scalars", async () => {
102+
const input = `
103+
on: push
104+
jobs:
105+
build:
106+
if: >
107+
\${{ github.event_name == 'push' }}
108+
runs-on: ubuntu-latest
109+
steps:
110+
- run: echo hi
111+
`;
112+
const result = await validate(createDocument("wf.yaml", input));
113+
114+
expect(result).toContainEqual(
115+
expect.objectContaining({
116+
message:
117+
"Block scalar adds trailing newline which breaks boolean evaluation. Use '>-' to strip trailing newlines.",
118+
code: "expression-block-scalar-chomping",
119+
severity: DiagnosticSeverity.Error
120+
})
121+
);
122+
});
123+
});
124+
125+
describe("step-if", () => {
126+
it("errors with clip chomping", async () => {
127+
const input = `
128+
on: push
129+
jobs:
130+
build:
131+
runs-on: ubuntu-latest
132+
steps:
133+
- if: |
134+
\${{ github.event_name == 'push' }}
135+
run: echo hi
136+
`;
137+
const result = await validate(createDocument("wf.yaml", input));
138+
139+
expect(result).toContainEqual(
140+
expect.objectContaining({
141+
message:
142+
"Block scalar adds trailing newline which breaks boolean evaluation. Use '|-' to strip trailing newlines.",
143+
code: "expression-block-scalar-chomping",
144+
severity: DiagnosticSeverity.Error
145+
})
146+
);
147+
});
148+
149+
it("errors with keep chomping", async () => {
150+
const input = `
151+
on: push
152+
jobs:
153+
build:
154+
runs-on: ubuntu-latest
155+
steps:
156+
- if: |+
157+
\${{ github.event_name == 'push' }}
158+
run: echo hi
159+
`;
160+
const result = await validate(createDocument("wf.yaml", input));
161+
162+
expect(result).toContainEqual(
163+
expect.objectContaining({
164+
message:
165+
"Block scalar adds trailing newline which breaks boolean evaluation. Use '|-' to strip trailing newlines.",
166+
code: "expression-block-scalar-chomping",
167+
severity: DiagnosticSeverity.Error
168+
})
169+
);
170+
});
171+
172+
it("does not error with strip chomping", async () => {
173+
const input = `
174+
on: push
175+
jobs:
176+
build:
177+
runs-on: ubuntu-latest
178+
steps:
179+
- if: |-
180+
\${{ github.event_name == 'push' }}
181+
run: echo hi
182+
`;
183+
const result = await validate(createDocument("wf.yaml", input));
184+
185+
expect(result.filter(d => d.code === "expression-block-scalar-chomping")).toEqual([]);
186+
});
187+
});
188+
});

0 commit comments

Comments
 (0)