Refactor test (#8940)
This commit is contained in:
1 parent
07fbf265fa
commit
69d26582e7
2 files changed
+175
-140
No files matched your search
+173
-140
@@ -50,6 +50,34 @@ const unstableTests = new Map(
|
||||
})
|
||||
);
|
||||
|
||||
const isUnstable = (filename, options) => {
|
||||
const testFunction = unstableTests.get(filename);
|
||||
|
||||
if (!testFunction) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return testFunction(options);
|
||||
};
|
||||
|
||||
const shouldThrowOnVerify = (filename, options) => {
|
||||
if (options.parser !== "babel-ts") {
|
||||
return false;
|
||||
}
|
||||
|
||||
const { disableBabelTS } = options;
|
||||
|
||||
if (disableBabelTS === true) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Array.isArray(disableBabelTS) && disableBabelTS.includes(filename)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
const isTestDirectory = (dirname, name) =>
|
||||
dirname.startsWith(path.join(__dirname, "../tests", name));
|
||||
|
||||
@@ -113,182 +141,156 @@ global.run_spec = (fixtures, parsers, options) => {
|
||||
}
|
||||
|
||||
const stringifiedOptions = stringifyOptionsForTitle(options);
|
||||
const [parser, ...verifyParsers] = parsers;
|
||||
|
||||
if (parsers.includes("typescript") && !parsers.includes("babel-ts")) {
|
||||
verifyParsers.push("babel-ts");
|
||||
}
|
||||
|
||||
for (const { name, filename, code, output } of [...files, ...snippets]) {
|
||||
describe(`${name}${
|
||||
stringifiedOptions ? ` - ${stringifiedOptions}` : ""
|
||||
}`, () => {
|
||||
let rangeStart;
|
||||
let rangeEnd;
|
||||
let cursorOffset;
|
||||
|
||||
const source = (TEST_CRLF ? code.replace(/\n/g, "\r\n") : code)
|
||||
.replace(RANGE_START_PLACEHOLDER, (match, offset) => {
|
||||
rangeStart = offset;
|
||||
return "";
|
||||
})
|
||||
.replace(RANGE_END_PLACEHOLDER, (match, offset) => {
|
||||
rangeEnd = offset;
|
||||
return "";
|
||||
});
|
||||
|
||||
const input = source.replace(CURSOR_PLACEHOLDER, (match, offset) => {
|
||||
cursorOffset = offset;
|
||||
return "";
|
||||
});
|
||||
|
||||
const baseOptions = {
|
||||
const formatOptions = {
|
||||
printWidth: 80,
|
||||
...options,
|
||||
rangeStart,
|
||||
rangeEnd,
|
||||
cursorOffset,
|
||||
filepath: filename,
|
||||
parser,
|
||||
};
|
||||
const mainOptions = {
|
||||
...baseOptions,
|
||||
...(IS_PARSER_INFERENCE_TESTS
|
||||
? { filepath: filename }
|
||||
: { parser: parsers[0] }),
|
||||
};
|
||||
|
||||
const hasEndOfLine = "endOfLine" in mainOptions;
|
||||
|
||||
if (IS_ERROR_TESTS) {
|
||||
test("error test", () => {
|
||||
expect(() => {
|
||||
format(input, filename, mainOptions);
|
||||
format(code, formatOptions);
|
||||
}).toThrowErrorMatchingSnapshot();
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const formattedWithCursor = format(input, filename, mainOptions);
|
||||
const formatted = formattedWithCursor.replace(CURSOR_PLACEHOLDER, "");
|
||||
const visualizedOutput = visualizeEndOfLine(formattedWithCursor);
|
||||
const eolReplacedCode = TEST_CRLF ? code.replace(/\n/g, "\r\n") : code;
|
||||
const firstFormat = format(eolReplacedCode, formatOptions);
|
||||
|
||||
test("format", () => {
|
||||
expect(visualizedOutput).toEqual(
|
||||
visualizeEndOfLine(consistentEndOfLine(formattedWithCursor))
|
||||
// Make sure output has consistent EOL
|
||||
expect(firstFormat.eolVisualizedOutput).toEqual(
|
||||
visualizeEndOfLine(consistentEndOfLine(firstFormat.outputWithCursor))
|
||||
);
|
||||
|
||||
if (typeof output === "string") {
|
||||
expect(formatted).toEqual(output);
|
||||
} else {
|
||||
let codeForSnapshot = hasEndOfLine
|
||||
? code
|
||||
.replace(RANGE_START_PLACEHOLDER, "")
|
||||
.replace(RANGE_END_PLACEHOLDER, "")
|
||||
: source;
|
||||
let codeOffset = 0;
|
||||
let resultForSnapshot = formattedWithCursor;
|
||||
|
||||
if (
|
||||
typeof baseOptions.rangeStart === "number" ||
|
||||
typeof baseOptions.rangeEnd === "number"
|
||||
) {
|
||||
if (TEST_CRLF && hasEndOfLine) {
|
||||
codeForSnapshot = codeForSnapshot.replace(/\n/g, "\r\n");
|
||||
}
|
||||
codeForSnapshot = visualizeRange(codeForSnapshot, baseOptions);
|
||||
codeOffset = codeForSnapshot.match(/^>?\s+1 \| /)[0].length;
|
||||
}
|
||||
|
||||
// When `TEST_CRLF` and `endOfLine: "auto"`, the eol is always `\r\n`,
|
||||
// Replace it with guess result from original input
|
||||
let resultNote = "";
|
||||
if (mainOptions.endOfLine === "auto") {
|
||||
const {
|
||||
guessEndOfLine,
|
||||
convertEndOfLineToChars,
|
||||
} = require("../src/common/end-of-line");
|
||||
const originalAutoResult = convertEndOfLineToChars(
|
||||
guessEndOfLine(code)
|
||||
);
|
||||
if (originalAutoResult !== "\r\n") {
|
||||
resultNote +=
|
||||
"** The EOL of output might not real when `TEST_CRLF` **";
|
||||
|
||||
if (TEST_CRLF) {
|
||||
resultForSnapshot = resultForSnapshot.replace(
|
||||
/\r\n?/g,
|
||||
originalAutoResult
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasEndOfLine) {
|
||||
codeForSnapshot = visualizeEndOfLine(codeForSnapshot);
|
||||
resultForSnapshot = visualizeEndOfLine(resultForSnapshot);
|
||||
}
|
||||
|
||||
if (resultNote) {
|
||||
resultForSnapshot = `${resultNote}\n${resultForSnapshot}`;
|
||||
}
|
||||
|
||||
expect(
|
||||
createSnapshot(
|
||||
codeForSnapshot,
|
||||
resultForSnapshot,
|
||||
composeOptionsForSnapshot(baseOptions, parsers),
|
||||
{ codeOffset }
|
||||
)
|
||||
).toMatchSnapshot();
|
||||
expect(firstFormat.output).toEqual(output);
|
||||
return;
|
||||
}
|
||||
|
||||
const hasEndOfLine = "endOfLine" in formatOptions;
|
||||
let codeForSnapshot = hasEndOfLine
|
||||
? code
|
||||
.replace(RANGE_START_PLACEHOLDER, "")
|
||||
.replace(RANGE_END_PLACEHOLDER, "")
|
||||
: firstFormat.inputWithCursor;
|
||||
let codeOffset = 0;
|
||||
let resultForSnapshot = firstFormat.outputWithCursor;
|
||||
const { rangeStart, rangeEnd } = firstFormat.options;
|
||||
|
||||
if (typeof rangeStart === "number" || typeof rangeEnd === "number") {
|
||||
if (TEST_CRLF && hasEndOfLine) {
|
||||
codeForSnapshot = codeForSnapshot.replace(/\n/g, "\r\n");
|
||||
}
|
||||
codeForSnapshot = visualizeRange(codeForSnapshot, {
|
||||
rangeStart,
|
||||
rangeEnd,
|
||||
});
|
||||
codeOffset = codeForSnapshot.match(/^>?\s+1 \| /)[0].length;
|
||||
}
|
||||
|
||||
// When `TEST_CRLF` and `endOfLine: "auto"`, the eol is always `\r\n`,
|
||||
// Replace it with guess result from original input
|
||||
let resultNote = "";
|
||||
if (formatOptions.endOfLine === "auto") {
|
||||
const {
|
||||
guessEndOfLine,
|
||||
convertEndOfLineToChars,
|
||||
} = require("../src/common/end-of-line");
|
||||
const originalAutoResult = convertEndOfLineToChars(
|
||||
guessEndOfLine(code)
|
||||
);
|
||||
if (originalAutoResult !== "\r\n") {
|
||||
resultNote +=
|
||||
"** The EOL of output might not real when `TEST_CRLF` **";
|
||||
|
||||
if (TEST_CRLF) {
|
||||
resultForSnapshot = resultForSnapshot.replace(
|
||||
/\r\n?/g,
|
||||
originalAutoResult
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasEndOfLine) {
|
||||
codeForSnapshot = visualizeEndOfLine(codeForSnapshot);
|
||||
resultForSnapshot = visualizeEndOfLine(resultForSnapshot);
|
||||
}
|
||||
|
||||
if (resultNote) {
|
||||
resultForSnapshot = `${resultNote}\n${resultForSnapshot}`;
|
||||
}
|
||||
|
||||
expect(
|
||||
createSnapshot(
|
||||
codeForSnapshot,
|
||||
resultForSnapshot,
|
||||
composeOptionsForSnapshot(firstFormat.options, parsers),
|
||||
{ codeOffset }
|
||||
)
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
const parsersToVerify = parsers.slice(1);
|
||||
if (parsers.includes("typescript") && !parsers.includes("babel-ts")) {
|
||||
parsersToVerify.push("babel-ts");
|
||||
}
|
||||
|
||||
for (const parser of parsersToVerify) {
|
||||
const verifyOptions = { ...baseOptions, parser };
|
||||
for (const parser of verifyParsers) {
|
||||
const verifyOptions = { ...firstFormat.options, parser };
|
||||
const verifyFormat = () => format(firstFormat.input, verifyOptions);
|
||||
|
||||
test(`verify (${parser})`, () => {
|
||||
if (
|
||||
parser === "babel-ts" &&
|
||||
options &&
|
||||
(options.disableBabelTS === true ||
|
||||
(Array.isArray(options.disableBabelTS) &&
|
||||
options.disableBabelTS.includes(name)))
|
||||
) {
|
||||
expect(() => {
|
||||
format(input, filename, verifyOptions);
|
||||
}).toThrow(TEST_STANDALONE ? undefined : SyntaxError);
|
||||
} else {
|
||||
const verifyOutput = format(input, filename, verifyOptions);
|
||||
expect(visualizeEndOfLine(verifyOutput)).toEqual(visualizedOutput);
|
||||
if (shouldThrowOnVerify(name, verifyOptions)) {
|
||||
expect(verifyFormat).toThrow(
|
||||
TEST_STANDALONE ? undefined : SyntaxError
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const { eolVisualizedOutput: verifyOutput } = verifyFormat();
|
||||
const { eolVisualizedOutput: firstOutput } = firstFormat;
|
||||
expect(verifyOutput).toEqual(firstOutput);
|
||||
});
|
||||
}
|
||||
|
||||
const isUnstable = unstableTests.get(filename);
|
||||
const isUnstableTest = isUnstable && isUnstable(options || {});
|
||||
const isUnstableTest = isUnstable(filename, formatOptions);
|
||||
if (
|
||||
DEEP_COMPARE &&
|
||||
(formatted !== input || isUnstableTest) &&
|
||||
typeof rangeStart === "undefined" &&
|
||||
typeof rangeEnd === "undefined" &&
|
||||
typeof cursorOffset === "undefined" &&
|
||||
!TEST_CRLF
|
||||
(firstFormat.changed || isUnstableTest) &&
|
||||
// No range and cursor
|
||||
firstFormat.input === eolReplacedCode
|
||||
) {
|
||||
test("second format", () => {
|
||||
const secondOutput = format(formatted, filename, mainOptions);
|
||||
const { eolVisualizedOutput: firstOutput, output } = firstFormat;
|
||||
const { eolVisualizedOutput: secondOutput } = format(
|
||||
output,
|
||||
formatOptions
|
||||
);
|
||||
if (isUnstableTest) {
|
||||
// To keep eye on failed tests, this assert never supposed to pass,
|
||||
// if it fails, just remove the file from `unstableTests`
|
||||
expect(secondOutput).not.toEqual(formatted);
|
||||
expect(secondOutput).not.toEqual(firstOutput);
|
||||
} else {
|
||||
expect(secondOutput).toEqual(formatted);
|
||||
expect(secondOutput).toEqual(firstOutput);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (AST_COMPARE && formatted !== input) {
|
||||
if (AST_COMPARE && firstFormat.changed) {
|
||||
test("compare AST", () => {
|
||||
const { cursorOffset, ...parseOptions } = mainOptions;
|
||||
const originalAst = parse(input, parseOptions);
|
||||
const formattedAst = parse(formatted, parseOptions);
|
||||
const { input, output } = firstFormat;
|
||||
const originalAst = parse(input, formatOptions);
|
||||
const formattedAst = parse(output, formatOptions);
|
||||
expect(formattedAst).toEqual(originalAst);
|
||||
});
|
||||
}
|
||||
@@ -300,15 +302,46 @@ function parse(source, options) {
|
||||
return prettier.__debug.parse(source, options, /* massage */ true).ast;
|
||||
}
|
||||
|
||||
function format(source, filename, options) {
|
||||
const result = prettier.formatWithCursor(source, {
|
||||
filepath: filename,
|
||||
function format(text, options) {
|
||||
options = {
|
||||
...options,
|
||||
};
|
||||
|
||||
const inputWithCursor = text
|
||||
.replace(RANGE_START_PLACEHOLDER, (match, offset) => {
|
||||
options.rangeStart = offset;
|
||||
return "";
|
||||
})
|
||||
.replace(RANGE_END_PLACEHOLDER, (match, offset) => {
|
||||
options.rangeEnd = offset;
|
||||
return "";
|
||||
});
|
||||
|
||||
const input = inputWithCursor.replace(CURSOR_PLACEHOLDER, (match, offset) => {
|
||||
options.cursorOffset = offset;
|
||||
return "";
|
||||
});
|
||||
|
||||
return options.cursorOffset >= 0
|
||||
? result.formatted.slice(0, result.cursorOffset) +
|
||||
const result = prettier.formatWithCursor(input, options);
|
||||
const output = result.formatted;
|
||||
|
||||
const outputWithCursor =
|
||||
options.cursorOffset >= 0
|
||||
? output.slice(0, result.cursorOffset) +
|
||||
CURSOR_PLACEHOLDER +
|
||||
result.formatted.slice(result.cursorOffset)
|
||||
: result.formatted;
|
||||
output.slice(result.cursorOffset)
|
||||
: output;
|
||||
const eolVisualizedOutput = visualizeEndOfLine(outputWithCursor);
|
||||
|
||||
const changed = outputWithCursor !== inputWithCursor;
|
||||
|
||||
return {
|
||||
changed,
|
||||
options,
|
||||
input,
|
||||
inputWithCursor,
|
||||
output,
|
||||
outputWithCursor,
|
||||
eolVisualizedOutput,
|
||||
};
|
||||
}
|
||||
@@ -7,6 +7,8 @@ function composeOptionsForSnapshot(baseOptions, parsers) {
|
||||
cursorOffset,
|
||||
disableBabelTS,
|
||||
plugins,
|
||||
filepath,
|
||||
parser,
|
||||
|
||||
...snapshotOptions
|
||||
} = baseOptions;
|
||||
|
||||
Reference in new issue
Block a user