Skip to content

Commit e02a1c1

Browse files
authored
Adds integrity check of formatter as a CI/CD step (#416)
1 parent e09ec06 commit e02a1c1

File tree

4 files changed

+12020
-0
lines changed

4 files changed

+12020
-0
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
on:
2+
push:
3+
branches:
4+
- main
5+
paths:
6+
- 'packages/language-support/src/formatting/**'
7+
8+
pull_request:
9+
branches:
10+
- main
11+
paths:
12+
- 'packages/language-support/src/formatting/**'
13+
14+
jobs:
15+
formatting-integrity-check:
16+
name: Formatter integrity check
17+
runs-on: ubuntu-latest
18+
steps:
19+
- uses: actions/checkout@v4
20+
21+
- name: Setup antlr4
22+
uses: ./.github/actions/setup-antlr4
23+
24+
- name: Install dependencies with frozen lock file and generate parser
25+
run: npm ci
26+
27+
- name: Build Project
28+
run: npm run build
29+
30+
- name: Run formatting check
31+
run: npm run test:formattingIntegrity

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"watch": "turbowatch ./turbowatch.ts",
2222
"test": "turbo run test",
2323
"test:e2e": "turbo run test:e2e",
24+
"test:formattingIntegrity": "ts-node ./packages/language-support/src/tests/formatting/verification/verificationCheck.ts",
2425
"dev-codemirror": "turbo run @neo4j-cypher/react-codemirror-playground#dev",
2526
"lint": "eslint . --ext .ts",
2627
"lint-fix": "eslint . --fix --ext .ts",

packages/language-support/src/tests/formatting/verification/sample_queries.json

Lines changed: 11935 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import * as fs from 'fs';
2+
import * as path from 'path';
3+
import { formatQuery } from '../../../formatting/formatting';
4+
import { standardizeQuery } from '../../../formatting/standardizer';
5+
6+
function throwError(message: string, query: string, formatted: string): never {
7+
throw new Error(`${message},
8+
--------- QUERY BEFORE START ------------
9+
${query}
10+
--------- QUERY BEFORE END ----------
11+
12+
--------- QUERY FORMATTED START ------------
13+
${formatted}
14+
--------- QUERY FORMATTED END ----------
15+
`);
16+
}
17+
18+
function verifyFormatting(query: string): void {
19+
const formatted = formatQuery(query);
20+
const queryStandardized = standardizeQuery(query);
21+
const formattedStandardized = standardizeQuery(formatted);
22+
const originalNonWhitespaceCount = query.replace(/\s/g, '').length;
23+
const formattedNonWhitespaceCount = formatted.replace(/\s/g, '').length;
24+
25+
// Non-whitespace character count check
26+
if (originalNonWhitespaceCount !== formattedNonWhitespaceCount) {
27+
throwError('Non-whitespace character count mismatch', query, formatted);
28+
}
29+
30+
// AST integrity check
31+
if (formattedStandardized !== queryStandardized) {
32+
throwError(
33+
'Standardized query does not match standardized formatted query',
34+
query,
35+
formatted,
36+
);
37+
}
38+
39+
// Idempotency check
40+
const formattedTwice = formatQuery(formatted);
41+
if (formattedTwice !== formatted) {
42+
throwError('Formatting is not idempotent', query, formatted);
43+
}
44+
}
45+
46+
function verifyFormattingOfSampleQueries() {
47+
const filePath = path.join(__dirname, 'sample_queries.json');
48+
const fileContent = fs.readFileSync(filePath, 'utf-8');
49+
const queries: string[] = JSON.parse(fileContent) as string[];
50+
queries.forEach((query) => verifyFormatting(query));
51+
}
52+
53+
verifyFormattingOfSampleQueries();

0 commit comments

Comments
 (0)