Skip to content

Commit 3e1b20d

Browse files
authored
Tests refactor (#1497)
* delegating test description completely to run test. * moving test format into it's own file * passing the testCase to each test, standardising the functions signature
1 parent e1b7439 commit 3e1b20d

10 files changed

Lines changed: 157 additions & 170 deletions

tests/config/run-format-test.js

Lines changed: 2 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,12 @@ import path from "node:path";
22
import url from "node:url";
33
import { FORMAT_SCRIPT_FILENAME } from "./constants.js";
44
import { getFixtures } from "./get-fixtures.js";
5+
import { testFixture } from "./run-test.js";
56
import { stringifyOptionsForTitle } from "./utils/stringify-options-for-title.js";
67
import {
78
isErrorTest as isErrorTestDirectory,
89
normalizeDirectory,
910
} from "./utilities.js";
10-
import { format } from "./run-prettier.js";
11-
import { replacePlaceholders } from "./replace-placeholders.js";
12-
import { runTest } from "./run-test.js";
13-
import { shouldThrowOnFormat } from "./utilities.js";
1411

1512
function runFormatTest(rawFixtures, explicitParsers, rawOptions) {
1613
const { importMeta, snippets = [] } = rawFixtures.importMeta
@@ -50,70 +47,8 @@ function runFormatTest(rawFixtures, explicitParsers, rawOptions) {
5047
};
5148

5249
for (const fixture of getFixtures(context)) {
53-
const { name, context, filepath } = fixture;
54-
const { stringifiedOptions, parsers } = context;
55-
56-
const title = `${name}${
57-
stringifiedOptions ? ` - ${stringifiedOptions}` : ""
58-
}`;
59-
60-
describe(title, () => {
61-
const testCases = parsers.map((parser) => getTestCase(fixture, parser));
62-
63-
for (const testCase of testCases) {
64-
const testTitle =
65-
testCase.expectFail ||
66-
testCase.formatOptions.parser !== testCase.parser
67-
? `[${testCase.parser}] format`
68-
: "format";
69-
70-
test(testTitle, async () => {
71-
await runTest({
72-
parsers,
73-
name,
74-
filename: filepath,
75-
code: testCase.code,
76-
output: testCase.expectedOutput,
77-
parser: testCase.parser,
78-
mainParserFormatResult: await testCase.runFormat(),
79-
mainParserFormatOptions: testCase.formatOptions,
80-
});
81-
});
82-
}
83-
});
50+
testFixture(fixture);
8451
}
8552
}
8653

87-
function getTestCase(fixture, parser) {
88-
const { code: originalText, context, filepath } = fixture;
89-
90-
const { text: code, options: formatOptions } = replacePlaceholders(
91-
originalText,
92-
{
93-
printWidth: 80,
94-
...context.options,
95-
filepath,
96-
parser,
97-
},
98-
);
99-
100-
const expectFail = shouldThrowOnFormat(fixture, formatOptions);
101-
102-
let promise;
103-
104-
return {
105-
context,
106-
parser,
107-
filepath,
108-
originalText,
109-
code,
110-
formatOptions,
111-
expectFail,
112-
expectedOutput: fixture.output,
113-
isEmpty: code.trim() === "",
114-
runFormat: () =>
115-
promise === undefined ? (promise = format(code, formatOptions)) : promise,
116-
};
117-
}
118-
11954
export default runFormatTest;

tests/config/run-test.js

Lines changed: 66 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,88 @@
11
import { FULL_TEST } from "./constants.js";
2+
import { replacePlaceholders } from "./replace-placeholders.js";
23
import { format } from "./run-prettier.js";
3-
import consistentEndOfLine from "./utils/consistent-end-of-line.js";
4-
import createSnapshot from "./utils/create-snapshot.js";
5-
import visualizeEndOfLine from "./utils/visualize-end-of-line.js";
64
import * as testAstCompare from "./test-ast-compare.js";
75
import * as testBom from "./test-bom.js";
86
import * as testEndOfLine from "./test-end-of-line.js";
7+
import * as testFormat from "./test-format.js";
98
import * as testSecondFormat from "./test-second-format.js";
109
import * as testBytecodeCompare from "./test-bytecode-compare.js";
1110
import * as testAntlrFormat from "./test-antlr-format.js";
1211
import * as testVariantCoverage from "./test-variant-coverage.js";
1312
import { shouldThrowOnFormat } from "./utilities.js";
1413

15-
async function runTest({
16-
parsers,
17-
name,
18-
filename,
19-
code,
20-
output,
21-
parser,
22-
mainParserFormatResult,
23-
mainParserFormatOptions,
24-
}) {
25-
let formatOptions = mainParserFormatOptions;
26-
let formatResult = mainParserFormatResult;
14+
async function testFixture(fixture) {
15+
const { name, context } = fixture;
16+
const { stringifiedOptions, parsers } = context;
2717

28-
// Verify parsers or error tests
29-
if (
30-
mainParserFormatResult.error ||
31-
mainParserFormatOptions.parser !== parser
32-
) {
33-
formatOptions = { ...mainParserFormatResult.options, parser };
34-
const runFormat = () => format(code, formatOptions);
18+
const title = `${name}${
19+
stringifiedOptions ? ` - ${stringifiedOptions}` : ""
20+
}`;
3521

36-
if (shouldThrowOnFormat(name, formatOptions)) {
37-
await expect(runFormat()).rejects.toThrowErrorMatchingSnapshot();
38-
return;
22+
describe(title, () => {
23+
const testCases = parsers.map((parser) => getTestCase(fixture, parser));
24+
25+
for (const testCase of testCases) {
26+
const testTitle =
27+
testCase.expectFail || testCase.formatOptions.parser !== testCase.parser
28+
? `[${testCase.parser}] format`
29+
: "format";
30+
31+
test(testTitle, async () => {
32+
await testFormat.run(testCase);
33+
34+
if (!FULL_TEST) {
35+
return;
36+
}
37+
await Promise.all(
38+
[
39+
testAntlrFormat.run,
40+
testVariantCoverage.run,
41+
testSecondFormat.run,
42+
testAstCompare.run,
43+
testBom.run,
44+
testBytecodeCompare.run,
45+
]
46+
.map((test) => test(testCase))
47+
.join(
48+
["\r\n", "\r"].map((eol) => testEndOfLine.run(testCase, eol)),
49+
),
50+
);
51+
});
3952
}
53+
});
54+
}
4055

41-
// Verify parsers format result should be the same as main parser
42-
output = mainParserFormatResult.outputWithCursor;
43-
formatResult = await runFormat();
44-
}
56+
function getTestCase(fixture, parser) {
57+
const { code: originalText, context, filepath } = fixture;
4558

46-
// Make sure output has consistent EOL
47-
expect(formatResult.eolVisualizedOutput).toEqual(
48-
visualizeEndOfLine(consistentEndOfLine(formatResult.outputWithCursor)),
59+
const { text: code, options: formatOptions } = replacePlaceholders(
60+
originalText,
61+
{
62+
printWidth: 80,
63+
...context.options,
64+
filepath,
65+
parser,
66+
},
4967
);
5068

51-
// The result is assert to equals to `output`
52-
if (typeof output === "string") {
53-
expect(formatResult.eolVisualizedOutput).toEqual(
54-
visualizeEndOfLine(output),
55-
);
56-
return;
57-
}
69+
const expectFail = shouldThrowOnFormat(fixture, formatOptions);
5870

59-
// All parsers have the same result, only snapshot the result from main parser
60-
expect(
61-
createSnapshot(formatResult, { parsers, formatOptions }),
62-
).toMatchSnapshot();
71+
let promise;
6372

64-
if (!FULL_TEST) {
65-
return;
66-
}
67-
await Promise.all(
68-
[
69-
testAntlrFormat.run,
70-
testVariantCoverage.run,
71-
testSecondFormat.run,
72-
testAstCompare.run,
73-
testBom.run,
74-
testBytecodeCompare.run,
75-
]
76-
.map((run) => run(code, formatResult, filename, formatOptions))
77-
.join(
78-
["\r\n", "\r"].map((eol) =>
79-
testEndOfLine.run(code, formatResult, filename, formatOptions, eol),
80-
),
81-
),
82-
);
73+
return {
74+
context,
75+
parser,
76+
filepath,
77+
originalText,
78+
code,
79+
formatOptions,
80+
expectFail,
81+
expectedOutput: fixture.output,
82+
isEmpty: code.trim() === "",
83+
runFormat: () =>
84+
promise === undefined ? (promise = format(code, formatOptions)) : promise,
85+
};
8386
}
8487

85-
export { runTest };
88+
export { testFixture };

tests/config/test-antlr-format.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,19 @@ import getPrettier from "./get-prettier.js";
33
import getCreateParser from "./get-create-parser.js";
44
import getPlugins from "./get-plugins.js";
55

6-
async function testAntlrFormat(source, formatResult, filename, formatOptions) {
6+
async function testAntlrFormat(testCase) {
7+
const { code, filepath, formatOptions } = testCase;
8+
const formatResult = await testCase.runFormat();
9+
710
if (
811
formatOptions.parser === "slang" &&
9-
!failedTests.isAntlrMismatch(filename, formatOptions)
12+
!failedTests.isAntlrMismatch(filepath, formatOptions)
1013
) {
1114
// Compare with ANTLR's format
1215
const createParser = await getCreateParser();
13-
const { parser } = createParser(source, formatOptions);
16+
const { parser } = createParser(code, formatOptions);
1417
const prettier = await getPrettier();
15-
const { formatted: antlrOutput } = await prettier.formatWithCursor(source, {
18+
const { formatted: antlrOutput } = await prettier.formatWithCursor(code, {
1619
...formatOptions,
1720
// Since Slang forces us to decide on a compiler version, we need to do the
1821
// same for ANTLR unless it was already given as an option.

tests/config/test-ast-compare.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import * as failedTests from "./failed-format-tests.js";
22
import { parse } from "./run-prettier.js";
33

4-
async function testAstCompare(source, formatResult, filename, formatOptions) {
5-
const isAstUnstableTest = failedTests.isAstUnstable(filename, formatOptions);
4+
async function testAstCompare(testCase) {
5+
const { code, filepath, formatOptions } = testCase;
6+
const formatResult = await testCase.runFormat();
7+
8+
const isAstUnstableTest = failedTests.isAstUnstable(filepath, formatOptions);
69
// Some parsers skip parsing empty files
7-
if (formatResult.changed && source.trim()) {
10+
if (formatResult.changed && code.trim()) {
811
const [originalAst, formattedAst] = await Promise.all(
912
[formatResult.input, formatResult.output].map((code) =>
1013
parse(code, formatResult.options),

tests/config/test-bom.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import { BOM } from "./constants.js";
22
import { format } from "./run-prettier.js";
33

4-
async function testBom(source, formatResult, _filename, formatOptions) {
5-
if (source.charAt(0) !== BOM) {
4+
async function testBom(testCase) {
5+
const { code, formatOptions } = testCase;
6+
const formatResult = await testCase.runFormat();
7+
8+
if (code.charAt(0) !== BOM) {
69
const { eolVisualizedOutput: output } = await format(
7-
BOM + source,
10+
BOM + code,
811
formatOptions,
912
);
1013
const expected = BOM + formatResult.eolVisualizedOutput;

tests/config/test-bytecode-compare.js

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,13 @@ import path from "node:path";
22
import createEsmUtils from "esm-utils";
33
import compileContract from "./utils/compile-contract.js";
44

5-
async function testBytecodeCompare(
6-
_source,
7-
formatResult,
8-
filename,
9-
formatOptions,
10-
) {
11-
if (shouldCompareBytecode(filename, formatOptions)) {
12-
const output = compileContract(filename, formatResult.output);
13-
const expected = compileContract(filename, formatResult.input);
5+
async function testBytecodeCompare(testCase) {
6+
const { filepath, formatOptions } = testCase;
7+
const formatResult = await testCase.runFormat();
8+
9+
if (shouldCompareBytecode(filepath, formatOptions)) {
10+
const output = compileContract(filepath, formatResult.output);
11+
const expected = compileContract(filepath, formatResult.input);
1412
expect(output).toEqual(expected);
1513
}
1614
}
@@ -41,8 +39,8 @@ const testsWithAstChanges = new Map(
4139
}),
4240
);
4341

44-
const shouldCompareBytecode = (filename, options) => {
45-
const testFunction = testsWithAstChanges.get(filename);
42+
const shouldCompareBytecode = (filepath, options) => {
43+
const testFunction = testsWithAstChanges.get(filepath);
4644

4745
if (!testFunction) {
4846
return false;

tests/config/test-end-of-line.js

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
import { format } from "./run-prettier.js";
22
import visualizeEndOfLine from "./utils/visualize-end-of-line.js";
33

4-
async function testEndOfLine(
5-
source,
6-
formatResult,
7-
_filename,
8-
formatOptions,
9-
eol,
10-
) {
11-
if (!shouldSkipEolTest(source, formatResult.options)) {
4+
async function testEndOfLine(testCase, eol) {
5+
const { code, formatOptions } = testCase;
6+
const formatResult = await testCase.runFormat();
7+
8+
if (!shouldSkipEolTest(code, formatResult.options)) {
129
const { eolVisualizedOutput: output } = await format(
13-
source.replace(/\n/gu, eol),
10+
code.replace(/\n/gu, eol),
1411
formatOptions,
1512
);
1613
// Only if `endOfLine: "auto"` the result will be different

0 commit comments

Comments
 (0)