fix: get rid of CRLF (#5494)

master
Ika 2018-12-08 18:28:29 +08:00 committed by GitHub
parent b878a54e6a
commit 952bc0cc03
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
131 changed files with 2071 additions and 2494 deletions

5
.gitattributes vendored
View File

@ -1,4 +1 @@
# Make sure baseline files have consistent line endings
*.txt text eol=lf
*.snap text eol=lf
*.debug-check text eol=lf
* text=auto eol=lf

View File

@ -1,6 +1,6 @@
trigger:
- master
- releases-*
- release-*
variables:
AST_COMPARE: true
@ -31,6 +31,7 @@ jobs:
vmImage: vs2017-win2016
variables:
node_version: 10
TEST_CRLF: true
steps:
- template: .azure-pipelines/dev.yml

View File

@ -17,13 +17,9 @@ module.exports = {
"jest-snapshot-serializer-ansi"
],
testRegex: "jsfmt\\.spec\\.js$|__tests__/.*\\.js$",
testPathIgnorePatterns: ["tests/new_react", "tests/more_react"]
.concat(isOldNode ? requiresPrettierInternals : [])
.concat(
require("os").EOL == "\n"
? ["tests_integration/__tests__/eol-crlf.js"]
: ["tests_integration/__tests__/eol-lf.js"]
),
testPathIgnorePatterns: ["tests/new_react", "tests/more_react"].concat(
isOldNode ? requiresPrettierInternals : []
),
collectCoverage: ENABLE_COVERAGE,
collectCoverageFrom: ["src/**/*.js", "index.js", "!<rootDir>/node_modules/"],
coveragePathIgnorePatterns: [

View File

@ -71,8 +71,8 @@
"unicode-regex": "2.0.0",
"unified": "6.1.6",
"vnopts": "1.0.2",
"yaml": "1.0.0-rc.8",
"yaml-unist-parser": "1.0.0-rc.4"
"yaml": "1.0.2",
"yaml-unist-parser": "1.0.0"
},
"devDependencies": {
"@babel/cli": "7.1.5",

View File

@ -675,7 +675,19 @@ function isWithinParentArrayProperty(path, propertyName) {
return parent[propertyName][key] === node;
}
function replaceEndOfLineWith(text, replacement) {
const parts = [];
for (const part of text.split("\n")) {
if (parts.length !== 0) {
parts.push(replacement);
}
parts.push(part);
}
return parts;
}
module.exports = {
replaceEndOfLineWith,
getStringWidth,
getMaxContinuousCount,
getPrecedence,

View File

@ -110,11 +110,7 @@ function genericPrint(path, options, print) {
}
case "css-comment": {
if (node.raws.content) {
return (
node.raws.content
// there's a bug in the less parser that trailing `\r`s are included in inline comments
.replace(/^(\/\/[^]+)\r+$/, "$1")
);
return node.raws.content;
}
const text = options.originalText.slice(
options.locStart(node),

View File

@ -265,7 +265,6 @@ function createParser({
allowHtmComponentClosingTags = false
} = {}) {
return {
preprocess: text => text.replace(/\r\n?/g, "\n"),
parse: (text, parsers, options) =>
_parse(text, options, {
recognizeSelfClosing,

View File

@ -34,12 +34,11 @@ const {
isTextLikeNode,
normalizeParts,
preferHardlineAsLeadingSpaces,
replaceDocNewlines,
replaceNewlines,
shouldNotPrintClosingTag,
shouldPreserveContent,
unescapeQuoteEntities
} = require("./utils");
const { replaceEndOfLineWith } = require("../common/util");
const preprocess = require("./preprocess");
const assert = require("assert");
const { insertPragma } = require("./pragma");
@ -147,10 +146,7 @@ function embed(path, print, textToDoc, options) {
hardline,
node.value.trim().length === 0
? ""
: replaceDocNewlines(
textToDoc(node.value, { parser: "yaml" }),
literalline
),
: textToDoc(node.value, { parser: "yaml" }),
"---"
])
);
@ -287,7 +283,7 @@ function genericPrint(path, options, print) {
? node.value.replace(trailingNewlineRegex, "")
: node.value;
return concat([
concat(replaceNewlines(value, literalline)),
concat(replaceEndOfLineWith(value, literalline)),
hasTrailingNewline ? hardline : ""
]);
}
@ -316,7 +312,7 @@ function genericPrint(path, options, print) {
return concat([
printOpeningTagPrefix(node, options),
concat(
replaceNewlines(
replaceEndOfLineWith(
options.originalText.slice(
options.locStart(node),
options.locEnd(node)
@ -341,7 +337,7 @@ function genericPrint(path, options, print) {
"=",
quote,
concat(
replaceNewlines(
replaceEndOfLineWith(
quote === '"'
? value.replace(/"/g, "&quot;")
: value.replace(/'/g, "&apos;"),
@ -354,7 +350,7 @@ function genericPrint(path, options, print) {
}
case "yaml":
case "toml":
return node.raw;
return concat(replaceEndOfLineWith(node.raw, literalline));
default:
throw new Error(`Unexpected node type ${node.type}`);
}
@ -473,7 +469,7 @@ function printChildren(path, options, print) {
return concat(
[].concat(
printOpeningTagPrefix(child, options),
replaceNewlines(
replaceEndOfLineWith(
options.originalText.slice(
options.locStart(child) +
(child.prev &&
@ -497,7 +493,7 @@ function printChildren(path, options, print) {
[].concat(
printOpeningTagPrefix(child, options),
group(printOpeningTag(childPath, options, print)),
replaceNewlines(
replaceEndOfLineWith(
options.originalText.slice(
child.startSourceSpan.end.offset +
(child.firstChild &&
@ -620,7 +616,7 @@ function printOpeningTag(path, options, print) {
const attr = attrPath.getValue();
return hasPrettierIgnoreAttribute(attr)
? concat(
replaceNewlines(
replaceEndOfLineWith(
options.originalText.slice(
options.locStart(attr),
options.locEnd(attr)
@ -894,8 +890,8 @@ function printClosingTagEndMarker(node, options) {
function getTextValueParts(node, value = node.value) {
return node.parent.isWhitespaceSensitive
? node.parent.isIndentationSensitive
? replaceNewlines(value, literalline)
: replaceNewlines(
? replaceEndOfLineWith(value, literalline)
: replaceEndOfLineWith(
dedentString(value.replace(/^\s*?\n|\n\s*?$/g, "")),
hardline
)
@ -1037,7 +1033,7 @@ function printEmbeddedAttributeValue(node, originalTextToDoc, options) {
const parts = [];
value.split(interpolationRegex).forEach((part, index) => {
if (index % 2 === 0) {
parts.push(concat(replaceNewlines(part, literalline)));
parts.push(concat(replaceEndOfLineWith(part, literalline)));
} else {
try {
parts.push(
@ -1056,7 +1052,11 @@ function printEmbeddedAttributeValue(node, originalTextToDoc, options) {
)
);
} catch (e) {
parts.push("{{", concat(replaceNewlines(part, literalline)), "}}");
parts.push(
"{{",
concat(replaceEndOfLineWith(part, literalline)),
"}}"
);
}
}
});

View File

@ -1,10 +1,5 @@
"use strict";
const {
builders: { concat },
utils: { mapDoc }
} = require("../doc");
const {
CSS_DISPLAY_TAGS,
CSS_DISPLAY_DEFAULT,
@ -263,20 +258,6 @@ function isDanglingSpaceSensitiveNode(node) {
);
}
function replaceNewlines(text, replacement) {
return text
.split(/(\n)/g)
.map((data, index) => (index % 2 === 1 ? replacement : data));
}
function replaceDocNewlines(doc, replacement) {
return mapDoc(doc, currentDoc =>
typeof currentDoc === "string" && currentDoc.includes("\n")
? concat(replaceNewlines(currentDoc, replacement))
: currentDoc
);
}
function forceNextEmptyLine(node) {
return (
isFrontMatterNode(node) ||
@ -645,8 +626,6 @@ module.exports = {
normalizeParts,
preferHardlineAsLeadingSpaces,
preferHardlineAsTrailingSpaces,
replaceDocNewlines,
replaceNewlines,
shouldNotPrintClosingTag,
shouldPreserveContent,
unescapeQuoteEntities

View File

@ -2395,7 +2395,10 @@ function printPathNoParens(path, options, print, args) {
"${" +
printDocToString(
doc,
Object.assign({}, options, { printWidth: Infinity })
Object.assign({}, options, {
printWidth: Infinity,
endOfLine: "lf"
})
).formatted +
"}"
);

View File

@ -42,7 +42,7 @@ function embed(path, print, textToDoc, options) {
concat([
"---",
hardline,
node.value.trim()
node.value && node.value.trim()
? replaceNewlinesWithLiterallines(
textToDoc(node.value, { parser: "yaml" })
)

View File

@ -9,7 +9,7 @@ function startWithPragma(text) {
const regex = new RegExp(
[
`<!--\\s*${pragma}\\s*-->`,
`<!--.*\n[\\s\\S]*(^|\n)[^\\S\n]*${pragma}[^\\S\n]*($|\n)[\\s\\S]*\n.*-->`
`<!--.*\r?\n[\\s\\S]*(^|\n)[^\\S\n]*${pragma}[^\\S\n]*($|\n)[\\s\\S]*\n.*-->`
].join("|"),
"m"
);

View File

@ -27,6 +27,7 @@ const {
splitText,
punctuationPattern
} = require("./utils");
const { replaceEndOfLineWith } = require("../common/util");
const TRAILING_HARDLINE_NODES = ["importExport"];
@ -209,7 +210,10 @@ function genericPrint(path, options, print) {
const alignment = " ".repeat(4);
return align(
alignment,
concat([alignment, replaceNewlinesWith(node.value, hardline)])
concat([
alignment,
concat(replaceEndOfLineWith(node.value, hardline))
])
);
}
@ -225,9 +229,11 @@ function genericPrint(path, options, print) {
style,
node.lang || "",
hardline,
replaceNewlinesWith(
getFencedCodeBlockValue(node, options.originalText),
hardline
concat(
replaceEndOfLineWith(
getFencedCodeBlockValue(node, options.originalText),
hardline
)
),
hardline,
style
@ -247,9 +253,11 @@ function genericPrint(path, options, print) {
? node.value.trimRight()
: node.value;
const isHtmlComment = /^<!--[\s\S]*-->$/.test(value);
return replaceNewlinesWith(
value,
isHtmlComment ? hardline : markAsRoot(literalline)
return concat(
replaceEndOfLineWith(
value,
isHtmlComment ? hardline : markAsRoot(literalline)
)
);
}
case "list": {
@ -394,7 +402,7 @@ function genericPrint(path, options, print) {
? concat([" ", markAsRoot(literalline)])
: concat(["\\", hardline]);
case "liquidNode":
return replaceNewlinesWith(node.value, hardline);
return concat(replaceEndOfLineWith(node.value, hardline));
// MDX
case "importExport":
case "jsx":
@ -404,7 +412,10 @@ function genericPrint(path, options, print) {
"$$",
hardline,
node.value
? concat([replaceNewlinesWith(node.value, hardline), hardline])
? concat([
concat(replaceEndOfLineWith(node.value, hardline)),
hardline
])
: "",
"$$"
]);
@ -467,10 +478,6 @@ function getNthListSiblingIndex(node, parentNode) {
);
}
function replaceNewlinesWith(str, doc) {
return join(doc, str.replace(/\r\n?/g, "\n").split("\n"));
}
function getNthSiblingIndex(node, parentNode, condition) {
condition = condition || (() => true);

View File

@ -148,7 +148,7 @@ function getFencedCodeBlockValue(node, originalText) {
const leadingSpaceCount = text.match(/^\s*/)[0].length;
const replaceRegex = new RegExp(`^\\s{0,${leadingSpaceCount}}`);
const lineContents = text.replace(/\r\n?/g, "\n").split("\n");
const lineContents = text.split("\n");
const markerStyle = text[leadingSpaceCount]; // ` or ~
const marker = text

View File

@ -29,11 +29,7 @@ const parser = {
parse,
hasPragma,
locStart: node => node.position.start.offset,
locEnd: node => node.position.end.offset,
// workaround for https://github.com/eemeli/yaml/issues/20
preprocess: text =>
text.indexOf("\r") === -1 ? text : text.replace(/\r\n?/g, "\n")
locEnd: node => node.position.end.offset
};
module.exports = {

View File

@ -38,6 +38,7 @@ const {
markAsRoot,
softline
} = docBuilders;
const { replaceEndOfLineWith } = require("../common/util");
function preprocess(ast) {
return mapNode(ast, defineShortcuts);
@ -104,9 +105,14 @@ function genericPrint(path, options, print) {
])
: "",
hasPrettierIgnore(path)
? options.originalText.slice(
node.position.start.offset,
node.position.end.offset
? concat(
replaceEndOfLineWith(
options.originalText.slice(
node.position.start.offset,
node.position.end.offset
),
literalline
)
)
: group(_print(node, parentNode, path, options, print)),
hasTrailingComment(node) && !isNode(node, ["document", "documentHead"])

View File

@ -1,8 +1,6 @@
"use strict";
function getLast(array) {
return array[array.length - 1];
}
const { getLast } = require("../common/util");
function getAncestorCount(path, filter) {
let counter = 0;

View File

@ -14,6 +14,7 @@ const {
const rangeUtil = require("./range-util");
const privateUtil = require("../common/util");
const {
utils: { mapDoc },
printer: { printDocToString },
debug: { printDocToDebug }
} = require("../doc");
@ -21,6 +22,11 @@ const {
const UTF8BOM = 0xfeff;
const CURSOR = Symbol("cursor");
const PLACEHOLDERS = {
cursorOffset: "<<<PRETTIER_CURSOR>>>",
rangeStart: "<<<PRETTIER_RANGE_START>>>",
rangeEnd: "<<<PRETTIER_RANGE_END>>>"
};
function ensureAllCommentsPrinted(astComments) {
if (!astComments) {
@ -67,8 +73,6 @@ function coreFormat(text, opts, addAlignmentSize) {
const parsed = parser.parse(text, opts);
const ast = parsed.ast;
const originalText = text;
text = parsed.text;
if (opts.cursorOffset >= 0) {
@ -80,11 +84,18 @@ function coreFormat(text, opts, addAlignmentSize) {
const astComments = attachComments(text, ast, opts);
const doc = printAstToDoc(ast, opts, addAlignmentSize);
if (opts.endOfLine === "auto") {
opts.endOfLine = guessEndOfLine(originalText);
}
const result = printDocToString(doc, opts);
const eol = convertEndOfLineToChars(opts.endOfLine);
const result = printDocToString(
opts.endOfLine === "lf"
? doc
: mapDoc(doc, currentDoc =>
typeof currentDoc === "string" && currentDoc.indexOf("\n") !== -1
? currentDoc.replace(/\n/g, eol)
: currentDoc
),
opts
);
ensureAllCommentsPrinted(astComments);
// Remove extra leading indentation as well as the added indentation after last newline
@ -212,8 +223,8 @@ function formatRange(text, opts) {
// Since the range contracts to avoid trailing whitespace,
// we need to remove the newline that was inserted by the `format` call.
const rangeTrimmed = rangeResult.formatted.trimRight();
const formatted =
text.slice(0, rangeStart) + rangeTrimmed + text.slice(rangeEnd);
const rangeLeft = text.slice(0, rangeStart);
const rangeRight = text.slice(rangeEnd);
let cursorOffset = opts.cursorOffset;
if (opts.cursorOffset >= rangeEnd) {
@ -226,6 +237,44 @@ function formatRange(text, opts) {
}
// keep the cursor as it was if it was before the start of the range
let formatted;
if (opts.endOfLine === "lf") {
formatted = rangeLeft + rangeTrimmed + rangeRight;
} else {
const eol = convertEndOfLineToChars(opts.endOfLine);
if (cursorOffset >= 0) {
const parts = [rangeLeft, rangeTrimmed, rangeRight];
let partIndex = 0;
let partOffset = cursorOffset;
while (partIndex < parts.length) {
const part = parts[partIndex];
if (partOffset < part.length) {
parts[partIndex] =
parts[partIndex].slice(0, partOffset) +
PLACEHOLDERS.cursorOffset +
parts[partIndex].slice(partOffset);
break;
}
partIndex++;
partOffset -= part.length;
}
const [newRangeLeft, newRangeTrimmed, newRangeRight] = parts;
formatted = (
newRangeLeft.replace(/\n/g, eol) +
newRangeTrimmed +
newRangeRight.replace(/\n/g, eol)
).replace(PLACEHOLDERS.cursorOffset, (_, index) => {
cursorOffset = index;
return "";
});
} else {
formatted =
rangeLeft.replace(/\n/g, eol) +
rangeTrimmed +
rangeRight.replace(/\n/g, eol);
}
}
return { formatted, cursorOffset };
}
@ -236,23 +285,83 @@ function format(text, opts) {
return { formatted: text };
}
if (opts.rangeStart > 0 || opts.rangeEnd < text.length) {
return formatRange(text, opts);
if (opts.endOfLine === "auto") {
opts.endOfLine = guessEndOfLine(text);
}
const hasCursor = opts.cursorOffset >= 0;
const hasRangeStart = opts.rangeStart > 0;
const hasRangeEnd = opts.rangeEnd < text.length;
// get rid of CR/CRLF parsing
if (text.indexOf("\r") !== -1) {
const offsetKeys = [
hasCursor && "cursorOffset",
hasRangeStart && "rangeStart",
hasRangeEnd && "rangeEnd"
]
.filter(Boolean)
.sort((aKey, bKey) => opts[aKey] - opts[bKey]);
for (let i = offsetKeys.length - 1; i >= 0; i--) {
const key = offsetKeys[i];
text =
text.slice(0, opts[key]) + PLACEHOLDERS[key] + text.slice(opts[key]);
}
text = text.replace(/\r\n?/g, "\n");
for (let i = 0; i < offsetKeys.length; i++) {
const key = offsetKeys[i];
text = text.replace(PLACEHOLDERS[key], (_, index) => {
opts[key] = index;
return "";
});
}
}
const hasUnicodeBOM = text.charCodeAt(0) === UTF8BOM;
if (hasUnicodeBOM) {
text = text.substring(1);
if (hasCursor) {
opts.cursorOffset++;
}
if (hasRangeStart) {
opts.rangeStart++;
}
if (hasRangeEnd) {
opts.rangeEnd++;
}
}
if (opts.insertPragma && opts.printer.insertPragma && !hasPragma) {
text = opts.printer.insertPragma(text);
if (!hasCursor) {
opts.cursorOffset = -1;
}
if (opts.rangeStart < 0) {
opts.rangeStart = 0;
}
if (opts.rangeEnd > text.length) {
opts.rangeEnd = text.length;
}
const result = coreFormat(text, opts);
const result =
hasRangeStart || hasRangeEnd
? formatRange(text, opts)
: coreFormat(
opts.insertPragma && opts.printer.insertPragma && !hasPragma
? opts.printer.insertPragma(text)
: text,
opts
);
if (hasUnicodeBOM) {
result.formatted = String.fromCharCode(UTF8BOM) + result.formatted;
if (hasCursor) {
result.cursorOffset++;
}
}
return result;
}
@ -264,6 +373,9 @@ module.exports = {
parse(text, opts, massage) {
opts = normalizeOptions(opts);
if (text.indexOf("\r") !== -1) {
text = text.replace(/\r\n?/g, "\n");
}
const parsed = parser.parse(text, opts);
if (massage) {
parsed.ast = massageAST(parsed.ast, opts);

View File

@ -1,145 +1,58 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`usingCrlf.js 1`] = `
====================================options=====================================
parsers: ["babylon"]
printWidth: 80
| printWidth
=====================================input======================================
function f() {
console.log("testing line endings");
}
=====================================output=====================================
function f() {
console.log("testing line endings");
}
================================================================================
`;
exports[`usingCrlf.js 2`] = `
exports[`example.js 1`] = `
====================================options=====================================
endOfLine: "cr"
parsers: ["babylon"]
printWidth: 80
| printWidth
=====================================input======================================
function f() {
console.log("testing line endings");
}
function f() {<LF>
console.log("testing line endings");<LF>
}<LF>
=====================================output=====================================
function f() {/*CR*/ console.log("testing line endings");/*CR*/}/*CR*/
function f() {<CR>
console.log("testing line endings");<CR>
}<CR>
================================================================================
`;
exports[`usingCrlf.js 3`] = `
exports[`example.js 2`] = `
====================================options=====================================
endOfLine: "crlf"
parsers: ["babylon"]
printWidth: 80
| printWidth
=====================================input======================================
function f() {
console.log("testing line endings");
}
function f() {<LF>
console.log("testing line endings");<LF>
}<LF>
=====================================output=====================================
function f() {/*CR*/
console.log("testing line endings");/*CR*/
}/*CR*/
function f() {<CRLF>
console.log("testing line endings");<CRLF>
}<CRLF>
================================================================================
`;
exports[`usingCrlf.js 4`] = `
exports[`example.js 3`] = `
====================================options=====================================
endOfLine: "lf"
parsers: ["babylon"]
printWidth: 80
| printWidth
=====================================input======================================
function f() {
console.log("testing line endings");
}
function f() {<LF>
console.log("testing line endings");<LF>
}<LF>
=====================================output=====================================
function f() {
console.log("testing line endings");
}
================================================================================
`;
exports[`usingLf.js 1`] = `
====================================options=====================================
parsers: ["babylon"]
printWidth: 80
| printWidth
=====================================input======================================
function f() {
console.log("testing line endings");
}
=====================================output=====================================
function f() {
console.log("testing line endings");
}
================================================================================
`;
exports[`usingLf.js 2`] = `
====================================options=====================================
endOfLine: "cr"
parsers: ["babylon"]
printWidth: 80
| printWidth
=====================================input======================================
function f() {
console.log("testing line endings");
}
=====================================output=====================================
function f() {/*CR*/ console.log("testing line endings");/*CR*/}/*CR*/
================================================================================
`;
exports[`usingLf.js 3`] = `
====================================options=====================================
endOfLine: "crlf"
parsers: ["babylon"]
printWidth: 80
| printWidth
=====================================input======================================
function f() {
console.log("testing line endings");
}
=====================================output=====================================
function f() {/*CR*/
console.log("testing line endings");/*CR*/
}/*CR*/
================================================================================
`;
exports[`usingLf.js 4`] = `
====================================options=====================================
endOfLine: "lf"
parsers: ["babylon"]
printWidth: 80
| printWidth
=====================================input======================================
function f() {
console.log("testing line endings");
}
=====================================output=====================================
function f() {
console.log("testing line endings");
}
function f() {<LF>
console.log("testing line endings");<LF>
}<LF>
================================================================================
`;

View File

@ -1,4 +1,3 @@
run_spec(__dirname, ["babylon"]);
run_spec(__dirname, ["babylon"], { endOfLine: "cr" });
run_spec(__dirname, ["babylon"], { endOfLine: "crlf" });
run_spec(__dirname, ["babylon"], { endOfLine: "lf" });

View File

@ -1,3 +0,0 @@
function f() {
console.log("testing line endings");
}

View File

@ -1,137 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`usingCrlf.css 1`] = `
====================================options=====================================
parsers: ["css"]
printWidth: 80
| printWidth
=====================================input======================================
.foo {
margin: 42px;
}
=====================================output=====================================
.foo {
margin: 42px;
}
================================================================================
`;
exports[`usingCrlf.css 2`] = `
====================================options=====================================
endOfLine: "cr"
parsers: ["css"]
printWidth: 80
| printWidth
=====================================input======================================
.foo {
margin: 42px;
}
=====================================output=====================================
.foo {/*CR*/ margin: 42px;/*CR*/}/*CR*/
================================================================================
`;
exports[`usingCrlf.css 3`] = `
====================================options=====================================
endOfLine: "crlf"
parsers: ["css"]
printWidth: 80
| printWidth
=====================================input======================================
.foo {
margin: 42px;
}
=====================================output=====================================
.foo {/*CR*/
margin: 42px;/*CR*/
}/*CR*/
================================================================================
`;
exports[`usingCrlf.css 4`] = `
====================================options=====================================
endOfLine: "lf"
parsers: ["css"]
printWidth: 80
| printWidth
=====================================input======================================
.foo {
margin: 42px;
}
=====================================output=====================================
.foo {
margin: 42px;
}
================================================================================
`;
exports[`usingLf.css 1`] = `
====================================options=====================================
parsers: ["css"]
printWidth: 80
| printWidth
=====================================input======================================
.foo {
margin: 42px;
}
=====================================output=====================================
.foo {
margin: 42px;
}
================================================================================
`;
exports[`usingLf.css 2`] = `
====================================options=====================================
endOfLine: "cr"
parsers: ["css"]
printWidth: 80
| printWidth
=====================================input======================================
.foo {
margin: 42px;
}
=====================================output=====================================
.foo {/*CR*/ margin: 42px;/*CR*/}/*CR*/
================================================================================
`;
exports[`usingLf.css 3`] = `
====================================options=====================================
endOfLine: "crlf"
parsers: ["css"]
printWidth: 80
| printWidth
=====================================input======================================
.foo {
margin: 42px;
}
=====================================output=====================================
.foo {/*CR*/
margin: 42px;/*CR*/
}/*CR*/
================================================================================
`;
exports[`usingLf.css 4`] = `
====================================options=====================================
endOfLine: "lf"
parsers: ["css"]
printWidth: 80
| printWidth
=====================================input======================================
.foo {
margin: 42px;
}
=====================================output=====================================
.foo {
margin: 42px;
}
================================================================================
`;

View File

@ -1,4 +0,0 @@
run_spec(__dirname, ["css"]);
run_spec(__dirname, ["css"], { endOfLine: "cr" });
run_spec(__dirname, ["css"], { endOfLine: "crlf" });
run_spec(__dirname, ["css"], { endOfLine: "lf" });

View File

@ -1,3 +0,0 @@
.foo {
margin: 42px;
}

View File

@ -1,3 +0,0 @@
.foo {
margin: 42px;
}

View File

@ -1,137 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`usingCrlf.md 1`] = `
====================================options=====================================
parsers: ["markdown"]
printWidth: 80
| printWidth
=====================================input======================================
# Markdown file
testing line endings
=====================================output=====================================
# Markdown file
testing line endings
================================================================================
`;
exports[`usingCrlf.md 2`] = `
====================================options=====================================
endOfLine: "cr"
parsers: ["markdown"]
printWidth: 80
| printWidth
=====================================input======================================
# Markdown file
testing line endings
=====================================output=====================================
# Markdown file/*CR*//*CR*/testing line endings/*CR*/
================================================================================
`;
exports[`usingCrlf.md 3`] = `
====================================options=====================================
endOfLine: "crlf"
parsers: ["markdown"]
printWidth: 80
| printWidth
=====================================input======================================
# Markdown file
testing line endings
=====================================output=====================================
# Markdown file/*CR*/
/*CR*/
testing line endings/*CR*/
================================================================================
`;
exports[`usingCrlf.md 4`] = `
====================================options=====================================
endOfLine: "lf"
parsers: ["markdown"]
printWidth: 80
| printWidth
=====================================input======================================
# Markdown file
testing line endings
=====================================output=====================================
# Markdown file
testing line endings
================================================================================
`;
exports[`usingLf.md 1`] = `
====================================options=====================================
parsers: ["markdown"]
printWidth: 80
| printWidth
=====================================input======================================
# Markdown file
testing line endings
=====================================output=====================================
# Markdown file
testing line endings
================================================================================
`;
exports[`usingLf.md 2`] = `
====================================options=====================================
endOfLine: "cr"
parsers: ["markdown"]
printWidth: 80
| printWidth
=====================================input======================================
# Markdown file
testing line endings
=====================================output=====================================
# Markdown file/*CR*//*CR*/testing line endings/*CR*/
================================================================================
`;
exports[`usingLf.md 3`] = `
====================================options=====================================
endOfLine: "crlf"
parsers: ["markdown"]
printWidth: 80
| printWidth
=====================================input======================================
# Markdown file
testing line endings
=====================================output=====================================
# Markdown file/*CR*/
/*CR*/
testing line endings/*CR*/
================================================================================
`;
exports[`usingLf.md 4`] = `
====================================options=====================================
endOfLine: "lf"
parsers: ["markdown"]
printWidth: 80
| printWidth
=====================================input======================================
# Markdown file
testing line endings
=====================================output=====================================
# Markdown file
testing line endings
================================================================================
`;

View File

@ -1,4 +0,0 @@
run_spec(__dirname, ["markdown"]);
run_spec(__dirname, ["markdown"], { endOfLine: "cr" });
run_spec(__dirname, ["markdown"], { endOfLine: "crlf" });
run_spec(__dirname, ["markdown"], { endOfLine: "lf" });

View File

@ -1,3 +0,0 @@
# Markdown file
testing line endings

View File

@ -1,3 +0,0 @@
# Markdown file
testing line endings

View File

@ -1,157 +1,163 @@
"use strict";
const fs = require("fs");
const extname = require("path").extname;
const path = require("path");
const raw = require("jest-snapshot-serializer-raw").wrap;
const AST_COMPARE = process.env["AST_COMPARE"];
const TEST_STANDALONE = process.env["TEST_STANDALONE"];
const TEST_CRLF = process.env["TEST_CRLF"];
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");
function run_spec(dirname, parsers, options) {
/* instabul ignore if */
global.run_spec = (dirname, parsers, options) => {
// istanbul ignore next
if (!parsers || !parsers.length) {
throw new Error(`No parsers were specified for ${dirname}`);
}
fs.readdirSync(dirname).forEach(filename => {
// We need to have a skipped test with the same name of the snapshots,
// so Jest doesn't mark them as obsolete.
if (TEST_STANDALONE && parsers.some(skipStandalone)) {
parsers.forEach(parser =>
test.skip(`${filename} - ${parser}-verify`, () => {})
);
fs.readdirSync(dirname).forEach(basename => {
const filename = path.join(dirname, basename);
if (
path.extname(basename) === ".snap" ||
!fs.lstatSync(filename).isFile() ||
basename[0] === "." ||
basename === "jsfmt.spec.js"
) {
return;
}
const path = dirname + "/" + filename;
if (
extname(filename) !== ".snap" &&
fs.lstatSync(path).isFile() &&
filename[0] !== "." &&
filename !== "jsfmt.spec.js"
) {
let rangeStart;
let rangeEnd;
let cursorOffset;
const source = read(path)
.replace(/\r\n/g, "\n")
.replace("<<<PRETTIER_RANGE_START>>>", (match, offset) => {
rangeStart = offset;
return "";
})
.replace("<<<PRETTIER_RANGE_END>>>", (match, offset) => {
rangeEnd = offset;
return "";
});
let rangeStart;
let rangeEnd;
let cursorOffset;
const input = source.replace("<|>", (match, offset) => {
cursorOffset = offset;
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;
return "";
});
const baseOptions = Object.assign(mergeDefaultOptions(options || {}), {
rangeStart,
rangeEnd,
cursorOffset
});
const mainOptions = Object.assign({}, baseOptions, {
parser: parsers[0]
});
const output = prettyprint(input, path, mainOptions);
test(filename, () => {
expect(
raw(
createSnapshot(
source,
output,
Object.assign({}, baseOptions, { parsers })
)
const input = source.replace(CURSOR_PLACEHOLDER, (match, offset) => {
cursorOffset = offset;
return "";
});
const baseOptions = Object.assign({ printWidth: 80 }, options, {
rangeStart,
rangeEnd,
cursorOffset
});
const mainOptions = Object.assign({}, baseOptions, {
parser: parsers[0]
});
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,
Object.assign({}, baseOptions, { parsers })
)
).toMatchSnapshot();
)
).toMatchSnapshot();
});
for (const parser of parsers.slice(1)) {
const verifyOptions = Object.assign({}, baseOptions, { parser });
test(`${basename} - ${parser}-verify`, () => {
const verifyOutput = format(input, filename, verifyOptions);
expect(visualizedOutput).toEqual(visualizeEndOfLine(verifyOutput));
});
parsers.slice(1).forEach(parser => {
const verifyOptions = Object.assign({}, mainOptions, { parser });
test(`${filename} - ${parser}-verify`, () => {
const verifyOutput = prettyprint(input, path, verifyOptions);
expect(output).toEqual(verifyOutput);
});
});
if (AST_COMPARE) {
test(`${path} parse`, () => {
const compareOptions = Object.assign({}, mainOptions);
delete compareOptions.cursorOffset;
const astMassaged = parse(input, compareOptions);
let ppastMassaged = undefined;
expect(() => {
ppastMassaged = parse(
prettyprint(input, path, compareOptions)
// \r has been replaced with /*CR*/ to test presence of CR in jest snapshots;
// reverting this to get the right AST
.replace(/\/\*CR\*\//g, "\r"),
compareOptions
);
}).not.toThrow();
expect(ppastMassaged).toBeDefined();
if (!astMassaged.errors || astMassaged.errors.length === 0) {
expect(astMassaged).toEqual(ppastMassaged);
}
});
}
}
if (AST_COMPARE) {
test(`${filename} parse`, () => {
const parseOptions = Object.assign({}, mainOptions);
delete parseOptions.cursorOffset;
const originalAst = parse(input, parseOptions);
let formattedAst;
expect(() => {
formattedAst = parse(
output.replace(CURSOR_PLACEHOLDER, ""),
parseOptions
);
}).not.toThrow();
expect(originalAst).toEqual(formattedAst);
});
}
});
};
function parse(source, options) {
return prettier.__debug.parse(source, options, /* massage */ true).ast;
}
function format(source, filename, options) {
const result = prettier.formatWithCursor(
source,
Object.assign({ filepath: filename }, options)
);
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;
});
}
global.run_spec = run_spec;
function parse(string, opts) {
return prettier.__debug.parse(string, opts, /* massage */ true).ast;
}
function prettyprint(src, filename, options) {
const result = prettier.formatWithCursor(
src,
Object.assign(
{
filepath: filename
},
options
)
);
if (options.cursorOffset >= 0) {
result.formatted =
result.formatted.slice(0, result.cursorOffset) +
"<|>" +
result.formatted.slice(result.cursorOffset);
}
// \r is trimmed from jest snapshots by default;
// manually replacing this character with /*CR*/ to test its true presence
return result.formatted.replace(/\r/g, "/*CR*/");
}
function read(filename) {
return fs.readFileSync(filename, "utf8");
}
function skipStandalone(/* parser */) {
return false;
}
function mergeDefaultOptions(parserConfig) {
return Object.assign(
{
printWidth: 80
},
parserConfig
);
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)}`);
}
});
}
function createSnapshot(input, output, options) {

View File

@ -1,62 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Has correct default Windows line endings (stderr) 1`] = `""`;
exports[`Has correct default Windows line endings (stdout) 1`] = `
"function f() {
console.log(\\"should have tab width 8\\")
}
function f() {
console.log(\\"should have space width 2\\")
}
function f() {
console.log(\\"should have space width 8\\")
}
function f() {
console.log(
\\"should have space width 2 despite ../.editorconfig specifying 8, because ./.hg is present\\"
)
}
console.log(\\"jest/__best-tests__/file.js should have semi\\");/*CR*/
console.log(\\"jest/Component.js should not have semi\\")/*CR*/
console.log(\\"jest/Component.test.js should have semi\\");/*CR*/
function js() {
console.log(\\"js/file.js should have tab width 8 (1 if CLI)\\");
}
\\"use strict\\";
module.exports = {
endOfLine: \\"lf\\",
tabWidth: 8
};
function noConfigJs() {
console.log(\\"no-config/file.js should have no semicolons\\")
}
function packageJs() {/*CR*/
console.log(\\"package/file.js should have tab width 3\\");/*CR*/
}/*CR*/
function rcJson() {/*CR*/
console.log.apply(null, [/*CR*/
'rc-json/file.js',/*CR*/
'should have trailing comma',/*CR*/
'and single quotes',/*CR*/
]);/*CR*/
}/*CR*/
function rcToml() {/*CR*/
console.log.apply(null, [/*CR*/
'rc-toml/file.js',/*CR*/
'should have trailing comma',/*CR*/
'and single quotes',/*CR*/
]);/*CR*/
}/*CR*/
function rcYaml() {/*CR*/
console.log.apply(null, [/*CR*/
'rc-yaml/file.js',/*CR*/
'should have trailing comma',/*CR*/
'and single quotes',/*CR*/
]);/*CR*/
}/*CR*/
"
`;
exports[`Has correct default Windows line endings (write) 1`] = `Array []`;

View File

@ -1,62 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Has correct default Unix line endings (stderr) 1`] = `""`;
exports[`Has correct default Unix line endings (stdout) 1`] = `
"function f() {
console.log(\\"should have tab width 8\\")
}
function f() {
console.log(\\"should have space width 2\\")
}
function f() {
console.log(\\"should have space width 8\\")
}
function f() {
console.log(
\\"should have space width 2 despite ../.editorconfig specifying 8, because ./.hg is present\\"
)
}
console.log(\\"jest/__best-tests__/file.js should have semi\\");
console.log(\\"jest/Component.js should not have semi\\")
console.log(\\"jest/Component.test.js should have semi\\");
function js() {
console.log(\\"js/file.js should have tab width 8 (1 if CLI)\\");
}
\\"use strict\\";
module.exports = {
endOfLine: \\"lf\\",
tabWidth: 8
};
function noConfigJs() {
console.log(\\"no-config/file.js should have no semicolons\\")
}
function packageJs() {
console.log(\\"package/file.js should have tab width 3\\");
}
function rcJson() {
console.log.apply(null, [
'rc-json/file.js',
'should have trailing comma',
'and single quotes',
]);
}
function rcToml() {
console.log.apply(null, [
'rc-toml/file.js',
'should have trailing comma',
'and single quotes',
]);
}
function rcYaml() {
console.log.apply(null, [
'rc-yaml/file.js',
'should have trailing comma',
'and single quotes',
]);
}
"
`;
exports[`Has correct default Unix line endings (write) 1`] = `Array []`;

View File

@ -1,11 +0,0 @@
"use strict";
const runPrettier = require("../runPrettier");
expect.addSnapshotSerializer(require("../path-serializer"));
describe("Has correct default Windows line endings", () => {
runPrettier("cli/config/", ["**/*.js"]).test({
status: 0
});
});

View File

@ -1,11 +0,0 @@
"use strict";
const runPrettier = require("../runPrettier");
expect.addSnapshotSerializer(require("../path-serializer"));
describe("Has correct default Unix line endings", () => {
runPrettier("cli/config/", ["**/*.js"]).test({
status: 0
});
});

View File

@ -6132,16 +6132,16 @@ yallist@^3.0.0, yallist@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9"
yaml-unist-parser@1.0.0-rc.4:
version "1.0.0-rc.4"
resolved "https://registry.yarnpkg.com/yaml-unist-parser/-/yaml-unist-parser-1.0.0-rc.4.tgz#d8fb9c673d59a4f7d532840b120abd6400237014"
yaml-unist-parser@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/yaml-unist-parser/-/yaml-unist-parser-1.0.0.tgz#060def481d2319a8def3b6a06cb8ae3848b0aed3"
dependencies:
lines-and-columns "^1.1.6"
tslib "^1.9.1"
yaml@1.0.0-rc.8:
version "1.0.0-rc.8"
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.0.0-rc.8.tgz#e5604c52b7b07b16e469bcf875ab0dfe08c50d42"
yaml@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.0.2.tgz#77941a457090e17b8ca65b53322e68a050e090d4"
yargs-parser@^7.0.0:
version "7.0.0"