Files
test-repo/tests_config/run_spec.js
T

233 lines
6.1 KiB
JavaScript
Raw Normal View History

2017-01-10 12:18:22 -05:00
"use strict";
2017-04-12 13:41:51 -07:00
const fs = require("fs");
2018-12-08 18:28:29 +08:00
const path = require("path");
const raw = require("jest-snapshot-serializer-raw").wrap;
2016-12-23 19:31:38 +00:00
2020-01-14 23:30:18 +08:00
const { AST_COMPARE, TEST_STANDALONE, TEST_CRLF } = process.env;
2018-12-08 18:28:29 +08:00
const CURSOR_PLACEHOLDER = "<|>";
const RANGE_START_PLACEHOLDER = "<<<PRETTIER_RANGE_START>>>";
const RANGE_END_PLACEHOLDER = "<<<PRETTIER_RANGE_END>>>";
const prettier = !TEST_STANDALONE
? require("prettier/local")
: require("prettier/standalone");
2018-12-08 18:28:29 +08:00
global.run_spec = (dirname, parsers, options) => {
// istanbul ignore next
if (!parsers || !parsers.length) {
throw new Error(`No parsers were specified for ${dirname}`);
}
const files = fs.readdirSync(dirname, { withFileTypes: true });
for (const file of files) {
const basename = file.name;
2018-12-08 18:28:29 +08:00
const filename = path.join(dirname, basename);
if (
path.extname(basename) === ".snap" ||
!file.isFile() ||
2018-12-08 18:28:29 +08:00
basename[0] === "." ||
basename === "jsfmt.spec.js"
) {
continue;
}
2018-12-08 18:28:29 +08:00
let rangeStart;
let rangeEnd;
let cursorOffset;
2016-12-23 19:31:38 +00:00
2018-12-08 18:28:29 +08:00
const text = fs.readFileSync(filename, "utf8");
const source = (TEST_CRLF ? text.replace(/\n/g, "\r\n") : text)
.replace(RANGE_START_PLACEHOLDER, (match, offset) => {
rangeStart = offset;
return "";
})
.replace(RANGE_END_PLACEHOLDER, (match, offset) => {
rangeEnd = offset;
2018-05-01 13:42:59 +01:00
return "";
});
2018-12-08 18:28:29 +08:00
const input = source.replace(CURSOR_PLACEHOLDER, (match, offset) => {
cursorOffset = offset;
return "";
});
2020-01-19 07:23:17 +08:00
const baseOptions = {
printWidth: 80,
...options,
2018-12-08 18:28:29 +08:00
rangeStart,
rangeEnd,
cursorOffset
2020-01-19 07:23:17 +08:00
};
const mainOptions = { ...baseOptions, parser: parsers[0] };
2018-12-08 18:28:29 +08:00
const hasEndOfLine = "endOfLine" in mainOptions;
const output = format(input, filename, mainOptions);
const visualizedOutput = visualizeEndOfLine(output);
test(basename, () => {
expect(visualizedOutput).toEqual(
visualizeEndOfLine(consistentEndOfLine(output))
);
expect(
raw(
createSnapshot(
hasEndOfLine
? visualizeEndOfLine(
text
.replace(RANGE_START_PLACEHOLDER, "")
.replace(RANGE_END_PLACEHOLDER, "")
)
: source,
hasEndOfLine ? visualizedOutput : output,
2020-01-19 07:23:17 +08:00
{ ...baseOptions, parsers }
2018-11-25 16:21:14 +08:00
)
2018-12-08 18:28:29 +08:00
)
).toMatchSnapshot();
});
const parsersToVerify = parsers.slice(1);
if (
parsers.includes("typescript") &&
!parsers.includes("babel-ts") &&
!(
options &&
(options.disableBabelTS === true ||
(Array.isArray(options.disableBabelTS) &&
options.disableBabelTS.includes(basename)))
)
) {
parsersToVerify.push("babel-ts");
}
for (const parser of parsersToVerify) {
2020-01-19 07:23:17 +08:00
const verifyOptions = { ...baseOptions, parser };
2018-12-08 18:28:29 +08:00
test(`${basename} - ${parser}-verify`, () => {
const verifyOutput = format(input, filename, verifyOptions);
expect(visualizeEndOfLine(verifyOutput)).toEqual(visualizedOutput);
});
2016-12-23 19:31:38 +00:00
}
2018-12-08 18:28:29 +08:00
if (AST_COMPARE) {
test(`${filename} parse`, () => {
2020-01-19 07:23:17 +08:00
const parseOptions = { ...mainOptions };
2018-12-08 18:28:29 +08:00
delete parseOptions.cursorOffset;
const originalAst = parse(input, parseOptions);
let formattedAst;
expect(() => {
formattedAst = parse(
output.replace(CURSOR_PLACEHOLDER, ""),
parseOptions
);
}).not.toThrow();
expect(originalAst).toEqual(formattedAst);
});
}
}
2018-12-08 18:28:29 +08:00
};
function parse(source, options) {
return prettier.__debug.parse(source, options, /* massage */ true).ast;
}
function format(source, filename, options) {
2020-01-19 07:23:17 +08:00
const result = prettier.formatWithCursor(source, {
filepath: filename,
...options
});
2018-12-08 18:28:29 +08:00
return options.cursorOffset >= 0
? result.formatted.slice(0, result.cursorOffset) +
CURSOR_PLACEHOLDER +
result.formatted.slice(result.cursorOffset)
: result.formatted;
}
function consistentEndOfLine(text) {
let firstEndOfLine;
return text.replace(/\r\n?|\n/g, endOfLine => {
if (!firstEndOfLine) {
firstEndOfLine = endOfLine;
}
return firstEndOfLine;
2016-12-23 19:31:38 +00:00
});
}
2018-12-08 18:28:29 +08:00
function visualizeEndOfLine(text) {
return text.replace(/\r\n?|\n/g, endOfLine => {
switch (endOfLine) {
case "\n":
return "<LF>\n";
case "\r\n":
return "<CRLF>\n";
case "\r":
return "<CR>\n";
default:
throw new Error(`Unexpected end of line ${JSON.stringify(endOfLine)}`);
}
});
}
2018-11-25 16:21:14 +08:00
function createSnapshot(input, output, options) {
const separatorWidth = 80;
const printWidthIndicator =
options.printWidth > 0 && Number.isFinite(options.printWidth)
? " ".repeat(options.printWidth) + "| printWidth"
: [];
return []
.concat(
printSeparator(separatorWidth, "options"),
printOptions(
omit(
options,
k =>
k === "rangeStart" ||
k === "rangeEnd" ||
k === "cursorOffset" ||
k === "disableBabelTS"
2018-11-25 16:21:14 +08:00
)
),
printWidthIndicator,
printSeparator(separatorWidth, "input"),
input,
printSeparator(separatorWidth, "output"),
output,
printSeparator(separatorWidth)
)
.join("\n");
}
function printSeparator(width, description) {
description = description || "";
const leftLength = Math.floor((width - description.length) / 2);
const rightLength = width - leftLength - description.length;
return "=".repeat(leftLength) + description + "=".repeat(rightLength);
}
function printOptions(options) {
const keys = Object.keys(options).sort();
return keys.map(key => `${key}: ${stringify(options[key])}`).join("\n");
function stringify(value) {
return value === Infinity
? "Infinity"
: Array.isArray(value)
? `[${value.map(v => JSON.stringify(v)).join(", ")}]`
: JSON.stringify(value);
}
}
function omit(obj, fn) {
return Object.keys(obj).reduce((reduced, key) => {
const value = obj[key];
if (!fn(key, value)) {
reduced[key] = value;
}
return reduced;
}, {});
}