Merge branch 'master' into refactor/cli

master
ikatyang 2017-09-14 12:49:07 +08:00
commit b2a8f3ffce
46 changed files with 987 additions and 303 deletions

View File

@ -274,6 +274,17 @@ you can pass `--no-config` instead.
Path to a file containing patterns that describe files to ignore. By default, prettier looks for `./.prettierignore`.
#### `--require-pragma`
Require a special comment, called a pragma, to be present in the file's first docblock comment in order for prettier to format it.
```js
/**
* @prettier
*/
```
Valid pragmas are `@prettier` and `@format`.
#### `--list-different`
Another useful flag is `--list-different` (or `-l`) which prints the filenames of files that are different from Prettier formatting. If there are differences the script errors out, which is useful in a CI scenario.
@ -288,7 +299,7 @@ Do not look for a configuration file. The default settings will be used.
#### `--config-precedence`
Defines how config file should be evaluated in combination of CLI options.
Defines how config file should be evaluated in combination of CLI options.
**cli-override (default)**
@ -659,6 +670,30 @@ Default | CLI Override | API Override
--------|--------------|-------------
None | `--stdin-filepath <string>` | `filepath: "<string>"`
### Require pragma
Prettier can restrict itself to only format files that contain a special comment, called a pragma, at the top of the file. This is very useful
when gradually transitioning large, unformatted codebases to prettier.
For example, a file with the following as its first comment will be formatted when `--require-pragma` is supplied:
```js
/**
* @prettier
*/
```
or
```js
/**
* @format
*/
```
Default | CLI Override | API Override
--------|--------------|-------------
`false` | `--require-pragma` | `requirePragma`
## Configuration File
Prettier uses [cosmiconfig](https://github.com/davidtheclark/cosmiconfig) for configuration file support.

View File

@ -133,3 +133,26 @@ Default | CLI Override | API Override
--------|--------------|-------------
None | `--stdin-filepath <string>` | `filepath: "<string>"`
## Require pragma
Prettier can restrict itself to only format files that contain a special comment, called a pragma, at the top of the file. This is very useful
when gradually transitioning large, unformatted codebases to prettier.
For example, a file with the following as its first comment will be formatted when `--require-pragma` is supplied:
```js
/**
* @prettier
*/
```
or
```js
/**
* @format
*/
```
Default | CLI Override | API Override
--------|--------------|-------------
`false` | `--require-pragma` | `requirePragma`

View File

@ -6,7 +6,7 @@ Go to *File | Settings | Tools | External Tools* for Windows and Linux or *WebSt
* **Program** set `prettier`
> If on the other hand you have `prettier` installed locally, replace the **Program** with `./node_modules/.bin/prettier` (on OS X and Linux) or `.\node_modules\.bin\prettier.cmd` (on Windows).
> If on the other hand you have `prettier` installed locally, replace the **Program** with `$ProjectFileDir$/node_modules/.bin/prettier` (on OS X and Linux) or `$ProjectFileDir$\node_modules\.bin\prettier.cmd` (on Windows).
* **Parameters** set `--write [other opts] $FilePathRelativeToProjectRoot$`
* **Working directory** set `$ProjectFileDir$`
@ -16,7 +16,7 @@ Go to *File | Settings | Tools | External Tools* for Windows and Linux or *WebSt
### Process directories
* Clone the External tool created above and name it `Prettier Directories`
* **Parameters** set `--write [other opts] $FileDirRelativeToProjectRoot$/**/(*.js|*.jsx)`
* **Parameters** set `--write [other opts] $FileDirRelativeToProjectRoot$/**/{*.js,*.jsx}`
## Usage

View File

@ -10,6 +10,7 @@ const normalizeOptions = require("./src/options").normalize;
const parser = require("./src/parser");
const printDocToDebug = require("./src/doc-debug").printDocToDebug;
const config = require("./src/resolve-config");
const docblock = require("jest-docblock");
function guessLineEnding(text) {
const index = text.indexOf("\n");
@ -30,6 +31,11 @@ function attachComments(text, ast, opts) {
return astComments;
}
function hasPragma(text) {
const pragmas = Object.keys(docblock.parse(docblock.extract(text)));
return pragmas.indexOf("prettier") !== -1 || pragmas.indexOf("format") !== -1;
}
function ensureAllCommentsPrinted(astComments) {
if (!astComments) {
return;
@ -56,6 +62,10 @@ function ensureAllCommentsPrinted(astComments) {
}
function formatWithCursor(text, opts, addAlignmentSize) {
if (opts.requirePragma && !hasPragma(text)) {
return { formatted: text };
}
text = stripBom(text);
addAlignmentSize = addAlignmentSize || 0;

View File

@ -23,6 +23,7 @@
"globby": "^6.1.0",
"graphql": "0.10.1",
"ignore": "^3.3.3",
"jest-docblock": "^21.0.2",
"jest-validate": "20.0.3",
"minimatch": "3.0.4",
"minimist": "1.2.0",

View File

@ -98,6 +98,14 @@ shell.sed(
"dist/bin/prettier.js"
);
shell.echo("Update ISSUE_TEMPLATE.md");
shell.sed(
"-i",
/(Prettier Version.+?)\d+\.\d+\.\d+/,
`$1${pkg.version}`,
".github/ISSUE_TEMPLATE.md"
);
shell.echo("Create prettier-version.js");
pipe(`prettierVersion = "${pkg.version}";\n`).to(`${docs}/prettier-version.js`);

View File

@ -4,9 +4,9 @@ function cleanAST(ast) {
return JSON.stringify(massageAST(ast), null, 2);
}
function massageAST(ast) {
function massageAST(ast, parent) {
if (Array.isArray(ast)) {
return ast.map(e => massageAST(e)).filter(e => e);
return ast.map(e => massageAST(e, parent)).filter(e => e);
}
if (ast && typeof ast === "object") {
// We remove extra `;` and add them when needed
@ -29,7 +29,7 @@ function massageAST(ast) {
const newObj = {};
for (const key in ast) {
if (typeof ast[key] !== "function") {
newObj[key] = massageAST(ast[key]);
newObj[key] = massageAST(ast[key], ast);
}
}
@ -219,6 +219,7 @@ function massageAST(ast) {
quasis.forEach(q => delete q.value);
}
// styled-components and graphql
if (
ast.type === "TaggedTemplateExpression" &&
@ -231,6 +232,13 @@ function massageAST(ast) {
) {
newObj.quasi.quasis.forEach(quasi => delete quasi.value);
}
if (
ast.type === "TemplateLiteral" &&
parent.type === "CallExpression" &&
parent.callee.name === "graphql"
) {
newObj.quasis.forEach(quasi => delete quasi.value);
}
return newObj;
}

View File

@ -200,6 +200,14 @@ const detailedOptions = normalizeDetailedOptions({
Defaults to 0.
`)
},
"require-pragma": {
type: "boolean",
forwardToApi: true,
description: dedent(`
Require either '@prettier' or '@format' to be present in the file's first docblock comment
in order for it to be formatted.
`)
},
semi: {
type: "boolean",
category: CATEGORY_FORMAT,

View File

@ -226,7 +226,14 @@ function eachFilename(argv, patterns, callback) {
}
try {
const filePaths = globby.sync(patterns, { dot: true });
const filePaths = globby
.sync(patterns, { dot: true })
.map(
filePath =>
path.isAbsolute(filePath)
? path.relative(process.cwd(), filePath)
: filePath
);
if (filePaths.length === 0) {
console.error(`No matching files. Patterns tried: ${patterns.join(" ")}`);
process.exitCode = 2;

View File

@ -466,12 +466,12 @@ function handleIfStatementComments(
}
// We unfortunately have no way using the AST or location of nodes to know
// if the comment is positioned before or after the condition parenthesis:
// if the comment is positioned before the condition parenthesis:
// if (a /* comment */) {}
// if (a) /* comment */ {}
// The only workaround I found is to look at the next character to see if
// it is a ).
if (getNextNonSpaceNonCommentCharacter(text, comment) === ")") {
const nextCharacter = getNextNonSpaceNonCommentCharacter(text, comment);
if (nextCharacter === ")") {
addTrailingComment(precedingNode, comment);
return true;
}
@ -486,6 +486,16 @@ function handleIfStatementComments(
return true;
}
// For comments positioned after the condition parenthesis in an if statement
// before the consequent with or without brackets on, such as
// if (a) /* comment */ {} or if (a) /* comment */ true,
// we look at the next character to see if it is a { or if the following node
// is the consequent for the if statement
if (nextCharacter === "{" || enclosingNode.consequent === followingNode) {
addLeadingComment(followingNode, comment);
return true;
}
return false;
}

View File

@ -68,14 +68,17 @@ function fromBabylonFlowOrTypeScript(path) {
*/
if (
parentParent &&
parentParent.type === "TaggedTemplateExpression" &&
parent.quasis.length === 1 &&
((parentParent.tag.type === "MemberExpression" &&
parentParent.tag.object.name === "graphql" &&
parentParent.tag.property.name === "experimental") ||
(parentParent.tag.type === "Identifier" &&
(parentParent.tag.name === "gql" ||
parentParent.tag.name === "graphql")))
((parentParent.type === "TaggedTemplateExpression" &&
parent.quasis.length === 1 &&
((parentParent.tag.type === "MemberExpression" &&
parentParent.tag.object.name === "graphql" &&
parentParent.tag.property.name === "experimental") ||
(parentParent.tag.type === "Identifier" &&
(parentParent.tag.name === "gql" ||
parentParent.tag.name === "graphql")))) ||
(parentParent.type === "CallExpression" &&
parentParent.callee.type === "Identifier" &&
parentParent.callee.name === "graphql"))
) {
return {
options: { parser: "graphql" },

View File

@ -15,6 +15,7 @@ const defaults = {
bracketSpacing: true,
jsxBracketSameLine: false,
parser: "babylon",
requirePragma: false,
semi: true
};

View File

@ -338,32 +338,51 @@ function genericPrintNoParens(path, options, print, args) {
);
}
// Avoid indenting sub-expressions in assignment/return/etc statements.
if (
parent.type === "AssignmentExpression" ||
parent.type === "VariableDeclarator" ||
shouldInlineLogicalExpression(n) ||
// Avoid indenting sub-expressions in some cases where the first sub-expression is already
// idented accordingly. We should ident sub-expressions where the first case isn't idented.
const shouldNotIdent =
parent.type === "ReturnStatement" ||
(parent.type === "JSXExpressionContainer" &&
parentParent.type === "JSXAttribute") ||
(n === parent.body && parent.type === "ArrowFunctionExpression") ||
(n !== parent.body && parent.type === "ForStatement") ||
(parent.type === "ConditionalExpression" &&
parentParent.type !== "ReturnStatement");
const shouldIdentIfInlining =
parent.type === "AssignmentExpression" ||
parent.type === "VariableDeclarator" ||
parent.type === "ObjectProperty" ||
parent.type === "Property" ||
parent.type === "ConditionalExpression"
parent.type === "Property";
const logicalSubExpression = n.left.type === "LogicalExpression";
if (
shouldNotIdent ||
(shouldInlineLogicalExpression(n) && !logicalSubExpression) ||
(!shouldInlineLogicalExpression(n) && shouldIdentIfInlining)
) {
return group(concat(parts));
}
const rest = concat(parts.slice(1));
// Break the closing paren to keep the chain right after it:
// (a &&
// b &&
// c
// ).call()
const breakClosingParen =
parent.type === "MemberExpression" && !parent.computed;
return group(
concat([
// Don't include the initial expression in the indentation
// level. The first item is guaranteed to be the first
// left-most expression.
parts.length > 0 ? parts[0] : "",
indent(rest)
indent(rest),
breakClosingParen ? softline : ""
])
);
}
@ -1244,8 +1263,6 @@ function genericPrintNoParens(path, options, print, args) {
n.test.type === "JSXElement" ||
n.consequent.type === "JSXElement" ||
n.alternate.type === "JSXElement" ||
parent.type === "JSXExpressionContainer" ||
firstNonConditionalParent.type === "JSXExpressionContainer" ||
conditionalExpressionChainContainsJSX(lastConditionalParent)
) {
jsxMode = true;
@ -1263,20 +1280,19 @@ function genericPrintNoParens(path, options, print, args) {
]);
// The only things we don't wrap are:
// * Nested conditional expressions
// * Nested conditional expressions in alternates
// * null
const shouldNotWrap = node =>
node.type === "ConditionalExpression" ||
const isNull = node =>
node.type === "NullLiteral" ||
(node.type === "Literal" && node.value === null);
parts.push(
" ? ",
shouldNotWrap(n.consequent)
isNull(n.consequent)
? path.call(print, "consequent")
: wrap(path.call(print, "consequent")),
" : ",
shouldNotWrap(n.alternate)
n.alternate.type === "ConditionalExpression" || isNull(n.alternate)
? path.call(print, "alternate")
: wrap(path.call(print, "alternate"))
);
@ -1302,10 +1318,19 @@ function genericPrintNoParens(path, options, print, args) {
? parent === firstNonConditionalParent ? group(doc) : doc
: group(doc); // Always group in normal mode.
// Break the closing paren to keep the chain right after it:
// (a
// ? b
// : c
// ).call()
const breakClosingParen =
!jsxMode && parent.type === "MemberExpression" && !parent.computed;
return maybeGroup(
concat([
path.call(print, "test"),
forceNoIndent ? concat(parts) : indent(concat(parts))
forceNoIndent ? concat(parts) : indent(concat(parts)),
breakClosingParen ? softline : ""
])
);
}
@ -3694,12 +3719,7 @@ function printMemberChain(path, options, print) {
// If we only have a single `.`, we shouldn't do anything fancy and just
// render everything concatenated together.
if (
groups.length <= cutoff &&
!hasComment &&
// (a || b).map() should be break before .map() instead of ||
groups[0][0].node.type !== "LogicalExpression"
) {
if (groups.length <= cutoff && !hasComment) {
return group(oneLine);
}

View File

@ -6,6 +6,14 @@ function f() {
entity => entity && entity.isInstallAvailable() && !entity.isQueue() && entity.isDisabled()
)
}
function f() {
const appEntitys = getAppEntitys(loadObject).map(
entity => entity && entity.isInstallAvailable() && !entity.isQueue() && entity.isDisabled() && {
id: entity.id
}
)
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function f() {
const appEntitys = getAppEntitys(loadObject).filter(
@ -17,6 +25,18 @@ function f() {
);
}
function f() {
const appEntitys = getAppEntitys(loadObject).map(
entity =>
entity &&
entity.isInstallAvailable() &&
!entity.isQueue() &&
entity.isDisabled() && {
id: entity.id
}
);
}
`;
exports[`bitwise-flags.js 1`] = `
@ -134,12 +154,42 @@ prevState = prevState || {
selectedCatalog: null,
};
prevState = prevState ||
defaultState || {
catalogs: [],
loadState: LOADED,
opened: false,
searchQuery: '',
selectedCatalog: null,
};
this.steps = steps || [
{
name: 'mock-module',
path: '/nux/mock-module',
},
];
const create = () => {
const result = doSomething();
return (
shouldReturn &&
result.ok && {
status: "ok",
createdAt: result.createdAt,
updatedAt: result.updatedAt
}
);
}
const obj = {
state: shouldHaveState &&
stateIsOK && {
loadState: LOADED,
opened: false
},
loaded: true
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
prevState = prevState || {
catalogs: [],
@ -149,6 +199,15 @@ prevState = prevState || {
selectedCatalog: null
};
prevState = prevState ||
defaultState || {
catalogs: [],
loadState: LOADED,
opened: false,
searchQuery: "",
selectedCatalog: null
};
this.steps = steps || [
{
name: "mock-module",
@ -156,6 +215,27 @@ this.steps = steps || [
}
];
const create = () => {
const result = doSomething();
return (
shouldReturn &&
result.ok && {
status: "ok",
createdAt: result.createdAt,
updatedAt: result.updatedAt
}
);
};
const obj = {
state: shouldHaveState &&
stateIsOK && {
loadState: LOADED,
opened: false
},
loaded: true
};
`;
exports[`jsx_parent.js 1`] = `
@ -172,6 +252,21 @@ exports[`jsx_parent.js 1`] = `
diffUpdateMessageInput != null &&
this.state.isUpdateMessageEmpty}
</div>;
<div
style={
!isJellyfishEnabled &&
diffUpdateMessageInput && {
fontSize: 14,
color: '#fff'
}
}
/>;
<div>
{!isJellyfishEnabled &&
diffUpdateMessageInput != null && <div><span>Text</span></div>}
</div>;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<div
src={
@ -187,6 +282,25 @@ exports[`jsx_parent.js 1`] = `
this.state.isUpdateMessageEmpty}
</div>;
<div
style={
!isJellyfishEnabled &&
diffUpdateMessageInput && {
fontSize: 14,
color: "#fff"
}
}
/>;
<div>
{!isJellyfishEnabled &&
diffUpdateMessageInput != null && (
<div>
<span>Text</span>
</div>
)}
</div>;
`;
exports[`math.js 1`] = `
@ -238,6 +352,46 @@ x & (y >> z);
`;
exports[`return.js 1`] = `
function foo() {
return this.hasPlugin("dynamicImports") && this.lookahead().type === tt.parenLeft.right;
}
function foo() {
return this.hasPlugin("dynamicImports") && this.lookahead().type === tt.parenLeft.right
? true
: false;
}
function foo() {
return this.calculate().compute().first.numberOfThings > this.calculate().compute().last.numberOfThings
? true
: false;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function foo() {
return (
this.hasPlugin("dynamicImports") &&
this.lookahead().type === tt.parenLeft.right
);
}
function foo() {
return this.hasPlugin("dynamicImports") &&
this.lookahead().type === tt.parenLeft.right
? true
: false;
}
function foo() {
return this.calculate().compute().first.numberOfThings >
this.calculate().compute().last.numberOfThings
? true
: false;
}
`;
exports[`short-right.js 1`] = `
this._cumulativeHeights &&
Math.abs(

View File

@ -3,3 +3,11 @@ function f() {
entity => entity && entity.isInstallAvailable() && !entity.isQueue() && entity.isDisabled()
)
}
function f() {
const appEntitys = getAppEntitys(loadObject).map(
entity => entity && entity.isInstallAvailable() && !entity.isQueue() && entity.isDisabled() && {
id: entity.id
}
)
}

View File

@ -6,9 +6,39 @@ prevState = prevState || {
selectedCatalog: null,
};
prevState = prevState ||
defaultState || {
catalogs: [],
loadState: LOADED,
opened: false,
searchQuery: '',
selectedCatalog: null,
};
this.steps = steps || [
{
name: 'mock-module',
path: '/nux/mock-module',
},
];
const create = () => {
const result = doSomething();
return (
shouldReturn &&
result.ok && {
status: "ok",
createdAt: result.createdAt,
updatedAt: result.updatedAt
}
);
}
const obj = {
state: shouldHaveState &&
stateIsOK && {
loadState: LOADED,
opened: false
},
loaded: true
}

View File

@ -11,3 +11,18 @@
diffUpdateMessageInput != null &&
this.state.isUpdateMessageEmpty}
</div>;
<div
style={
!isJellyfishEnabled &&
diffUpdateMessageInput && {
fontSize: 14,
color: '#fff'
}
}
/>;
<div>
{!isJellyfishEnabled &&
diffUpdateMessageInput != null && <div><span>Text</span></div>}
</div>;

View File

@ -0,0 +1,15 @@
function foo() {
return this.hasPlugin("dynamicImports") && this.lookahead().type === tt.parenLeft.right;
}
function foo() {
return this.hasPlugin("dynamicImports") && this.lookahead().type === tt.parenLeft.right
? true
: false;
}
function foo() {
return this.calculate().compute().first.numberOfThings > this.calculate().compute().last.numberOfThings
? true
: false;
}

View File

@ -328,10 +328,45 @@ else if (4) {
else {
}
if (1)
{}
if (5) // comment
true
if (6) // comment
{true}
else if (7) // comment
true
else // comment
{}
{true}
if (8) // comment
// comment
{true}
else if (9) // comment
// comment
true
else // comment
// comment
{true}
if (10) /* comment */ // comment
{true}
else if (11) /* comment */
true
else if (12) // comment /* comment */ // comment
true
else if (13) /* comment */ /* comment */ // comment
true
else /* comment */
{true}
if (14) // comment
/* comment */
// comment
{true}
else if (15) // comment
/* comment */
/* comment */ // comment
true
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if (1) {
// comment
@ -352,11 +387,63 @@ else if (4) {
// comment
}
if (1) {
} else {
if (5)
// comment
true;
if (6) {
// comment
true;
} else if (7)
// comment
true;
else {
// comment
true;
}
if (8) {
// comment
// comment
true;
} else if (9)
// comment
// comment
true;
else {
// comment
// comment
true;
}
if (10) {
/* comment */ // comment
true;
} else if (11)
/* comment */
true;
else if (12)
// comment /* comment */ // comment
true;
else if (13)
/* comment */ /* comment */ // comment
true;
else {
/* comment */
true;
}
if (14) {
// comment
/* comment */
// comment
true;
} else if (15)
// comment
/* comment */
/* comment */ // comment
true;
`;
exports[`issues.js 1`] = `

View File

@ -20,7 +20,42 @@ else if (4) {
else {
}
if (1)
{}
if (5) // comment
true
if (6) // comment
{true}
else if (7) // comment
true
else // comment
{}
{true}
if (8) // comment
// comment
{true}
else if (9) // comment
// comment
true
else // comment
// comment
{true}
if (10) /* comment */ // comment
{true}
else if (11) /* comment */
true
else if (12) // comment /* comment */ // comment
true
else if (13) /* comment */ /* comment */ // comment
true
else /* comment */
{true}
if (14) // comment
/* comment */
// comment
{true}
else if (15) // comment
/* comment */
/* comment */ // comment
true

View File

@ -54,6 +54,24 @@ async function f() {
}
}
async function f() {
if (untrackedChoice === 0) /* Cancel */
null;
else if (untrackedChoice === 1) /* Add */
shouldAmend = true;
else if (untrackedChoice === 2) /* Allow Untracked */
allowUntracked = true;
}
async function f() {
if (untrackedChoice === 0) /* Cancel */ // Cancel
null;
else if (untrackedChoice === 1) /* Add */ // Add
shouldAmend = true;
else if (untrackedChoice === 2) /* Allow Untracked */ // Allow Untracked
allowUntracked = true;
}
async function f() {
if (untrackedChoice === 0)
/* Cancel */ {
@ -92,6 +110,30 @@ async function f() {
}
}
async function f() {
if (untrackedChoice === 0)
/* Cancel */
null;
else if (untrackedChoice === 1)
/* Add */
shouldAmend = true;
else if (untrackedChoice === 2)
/* Allow Untracked */
allowUntracked = true;
}
async function f() {
if (untrackedChoice === 0)
/* Cancel */ // Cancel
null;
else if (untrackedChoice === 1)
/* Add */ // Add
shouldAmend = true;
else if (untrackedChoice === 2)
/* Allow Untracked */ // Allow Untracked
allowUntracked = true;
}
async function f() {
if (untrackedChoice === 0) {
/* Cancel */ return null;

View File

@ -9,6 +9,24 @@ async function f() {
}
}
async function f() {
if (untrackedChoice === 0) /* Cancel */
null;
else if (untrackedChoice === 1) /* Add */
shouldAmend = true;
else if (untrackedChoice === 2) /* Allow Untracked */
allowUntracked = true;
}
async function f() {
if (untrackedChoice === 0) /* Cancel */ // Cancel
null;
else if (untrackedChoice === 1) /* Add */ // Add
shouldAmend = true;
else if (untrackedChoice === 2) /* Allow Untracked */ // Allow Untracked
allowUntracked = true;
}
async function f() {
if (untrackedChoice === 0)
/* Cancel */ {

View File

@ -20,86 +20,20 @@ exports[`conditional-expression.js 1`] = `
//
// test ? consequent : alternate;
//
// We print a conditional expression in JSX mode if any of the following are
// true:
// * Its parent is a JSXExpressionContainer
// * Its test, consequent, or alternate are JSXElements
// * It is in a chain with other ConditionalExpressions, and the outermost
// one's parent is a JSXExpressionContainer
// * It is in a chain with other ConditionalExpressions, and any of the
// tests, consequents, or alternates of any of the ConditionalExpressions in
// the chain are JSXElements.
// We only print a conditional expression in JSX mode if its test,
// consequent, or alternate are JSXElements.
// Otherwise, we print in normal mode.
// This ConditionalExpression does not meet any of the other criteria for
// printing in JSX mode, so it prints in normal mode. The line does not break.
// This ConditionalExpression has no JSXElements so it prints in normal mode.
// The line does not break.
normalModeNonBreaking ? "a" : "b";
// This ConditionalExpression does not meet any of the criteria to print in JSX
// mode, so it prints in normal mode. Its consequent is very long, so it breaks
// out to multiple lines.
// This ConditionalExpression has no JSXElements so it prints in normal mode.
// Its consequent is very long, so it breaks out to multiple lines.
normalModeBreaking
? johnJacobJingleHeimerSchmidtHisNameIsMyNameTooWheneverWeGoOutThePeopleAlwaysShoutThereGoesJohnJacobJingleHeimerSchmidtYaDaDaDaDaDaDa
: "c";
// This ConditionalExpression prints in JSX mode because its parent is a
// JSXExpressionContainer. The line does not break, so it does not contain
// parens.
<div>
{a ? "b" : "c"}
</div>;
// This ConditionalExpression prints in JSX mode because its parent is a
// JSXExpressionContainer. Because the consequent is long enough to break the
// line, both its consequent and alternate break out and are wrapped in parens.
<div>
{a ? (
johnJacobJingleHeimerSchmidtHisNameIsMyNameTooWheneverWeGoOutThePeopleAlwaysShoutThereGoesJohnJacobJingleHeimerSchmidtYaDaDaDaDaDaDa
) : (
"c"
)}
</div>;
// This ConditionalExpression prints in JSX mode because its parent is a
// JSXExpressionContainer. The consequent is long enough to break the line, but
// because the alternate is null, only the consequent is wrapped in parens.
<div>
{a ? (
johnJacobJingleHeimerSchmidtHisNameIsMyNameTooWheneverWeGoOutThePeopleAlwaysShoutThereGoesJohnJacobJingleHeimerSchmidtYaDaDaDaDaDaDa
) : null}
</div>;
// This ConditionalExpression prints in JSX mode because its parent is a
// JSXExpressionContainer. Because the alternate is long enough to break the
// line, both its consequent and alternate break out and are wrapped in parens.
<div>
{a ? (
"b"
) : (
johnJacobJingleHeimerSchmidtHisNameIsMyNameTooWheneverWeGoOutThePeopleAlwaysShoutThereGoesJohnJacobJingleHeimerSchmidtYaDaDaDaDaDaDa
)}
</div>;
// This ConditionalExpression prints in JSX mode because its parent is a
// JSXExpressionContainer. The alternate is long enough to break the line, but
// because the consequent is null, only the alternate is wrapped in parens.
<div>
{a ? null : (
johnJacobJingleHeimerSchmidtHisNameIsMyNameTooWheneverWeGoOutThePeopleAlwaysShoutThereGoesJohnJacobJingleHeimerSchmidtYaDaDaDaDaDaDa
)}
</div>;
// This ConditionalExpression prints in JSX mode because its parent is a
// JSXExpressionContainer. Because the test is long enough to break the
// line, both its consequent and alternate break out and are wrapped in parens.
<div>
{johnJacobJingleHeimerSchmidtHisNameIsMyNameTooWheneverWeGoOutThePeopleAlwaysShoutThereGoesJohnJacobJingleHeimerSchmidtYaDaDaDaDaDaDa ? (
"b"
) : (
"c"
)}
</div>;
// This ConditionalExpression prints in JSX mode because its test is a
// JSXElement. It is non-breaking.
// Note: I have never, ever seen someone use a JSXElement as the test in a
@ -153,19 +87,6 @@ jsxModeFromElementBreaking ? (
{a ? "a" : b ? "b" : "c"}
</div>;
// This chain of ConditionalExpressions prints in JSX mode because the parent of
// the outermost ConditionalExpression is a JSXExpressionContainer. It is
// breaking.
<div>
{a ? (
"a"
) : b ? (
"b"
) : (
thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo
)}
</div>;
// This chain of ConditionalExpressions prints in JSX mode because there is a
// JSX element somewhere in the chain. It is non-breaking.
cable ? "satellite" : public ? "affairs" : network ? <span id="c" /> : "dunno";
@ -197,6 +118,20 @@ cable ? (
) : affairs ? (
"network"
) : "dunno";
// This chain of ConditionalExpressions prints in JSX mode because there is a
// JSX element somewhere in the chain. It is breaking; notice the consequents
// and alternates in the entire chain get wrapped in parens.
<div>
{properties.length > 1 ||
(properties.length === 1 && properties[0].apps.size > 1) ? (
draggingApp == null || newPropertyName == null ? (
<MigrationPropertyListItem />
) : (
<MigrationPropertyListItem apps={Immutable.List()} />
)
) : null}
</div>;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// There are two ways to print ConditionalExpressions: "normal mode" and
// "JSX mode". This is normal mode (when breaking):
@ -217,84 +152,20 @@ cable ? (
//
// test ? consequent : alternate;
//
// We print a conditional expression in JSX mode if any of the following are
// true:
// * Its parent is a JSXExpressionContainer
// * Its test, consequent, or alternate are JSXElements
// * It is in a chain with other ConditionalExpressions, and the outermost
// one's parent is a JSXExpressionContainer
// * It is in a chain with other ConditionalExpressions, and any of the
// tests, consequents, or alternates of any of the ConditionalExpressions in
// the chain are JSXElements.
// We only print a conditional expression in JSX mode if its test,
// consequent, or alternate are JSXElements.
// Otherwise, we print in normal mode.
// This ConditionalExpression does not meet any of the other criteria for
// printing in JSX mode, so it prints in normal mode. The line does not break.
// This ConditionalExpression has no JSXElements so it prints in normal mode.
// The line does not break.
normalModeNonBreaking ? "a" : "b";
// This ConditionalExpression does not meet any of the criteria to print in JSX
// mode, so it prints in normal mode. Its consequent is very long, so it breaks
// out to multiple lines.
// This ConditionalExpression has no JSXElements so it prints in normal mode.
// Its consequent is very long, so it breaks out to multiple lines.
normalModeBreaking
? johnJacobJingleHeimerSchmidtHisNameIsMyNameTooWheneverWeGoOutThePeopleAlwaysShoutThereGoesJohnJacobJingleHeimerSchmidtYaDaDaDaDaDaDa
: "c";
// This ConditionalExpression prints in JSX mode because its parent is a
// JSXExpressionContainer. The line does not break, so it does not contain
// parens.
<div>{a ? "b" : "c"}</div>;
// This ConditionalExpression prints in JSX mode because its parent is a
// JSXExpressionContainer. Because the consequent is long enough to break the
// line, both its consequent and alternate break out and are wrapped in parens.
<div>
{a ? (
johnJacobJingleHeimerSchmidtHisNameIsMyNameTooWheneverWeGoOutThePeopleAlwaysShoutThereGoesJohnJacobJingleHeimerSchmidtYaDaDaDaDaDaDa
) : (
"c"
)}
</div>;
// This ConditionalExpression prints in JSX mode because its parent is a
// JSXExpressionContainer. The consequent is long enough to break the line, but
// because the alternate is null, only the consequent is wrapped in parens.
<div>
{a ? (
johnJacobJingleHeimerSchmidtHisNameIsMyNameTooWheneverWeGoOutThePeopleAlwaysShoutThereGoesJohnJacobJingleHeimerSchmidtYaDaDaDaDaDaDa
) : null}
</div>;
// This ConditionalExpression prints in JSX mode because its parent is a
// JSXExpressionContainer. Because the alternate is long enough to break the
// line, both its consequent and alternate break out and are wrapped in parens.
<div>
{a ? (
"b"
) : (
johnJacobJingleHeimerSchmidtHisNameIsMyNameTooWheneverWeGoOutThePeopleAlwaysShoutThereGoesJohnJacobJingleHeimerSchmidtYaDaDaDaDaDaDa
)}
</div>;
// This ConditionalExpression prints in JSX mode because its parent is a
// JSXExpressionContainer. The alternate is long enough to break the line, but
// because the consequent is null, only the alternate is wrapped in parens.
<div>
{a ? null : (
johnJacobJingleHeimerSchmidtHisNameIsMyNameTooWheneverWeGoOutThePeopleAlwaysShoutThereGoesJohnJacobJingleHeimerSchmidtYaDaDaDaDaDaDa
)}
</div>;
// This ConditionalExpression prints in JSX mode because its parent is a
// JSXExpressionContainer. Because the test is long enough to break the
// line, both its consequent and alternate break out and are wrapped in parens.
<div>
{johnJacobJingleHeimerSchmidtHisNameIsMyNameTooWheneverWeGoOutThePeopleAlwaysShoutThereGoesJohnJacobJingleHeimerSchmidtYaDaDaDaDaDaDa ? (
"b"
) : (
"c"
)}
</div>;
// This ConditionalExpression prints in JSX mode because its test is a
// JSXElement. It is non-breaking.
// Note: I have never, ever seen someone use a JSXElement as the test in a
@ -352,19 +223,6 @@ jsxModeFromElementBreaking ? (
// non-breaking.
<div>{a ? "a" : b ? "b" : "c"}</div>;
// This chain of ConditionalExpressions prints in JSX mode because the parent of
// the outermost ConditionalExpression is a JSXExpressionContainer. It is
// breaking.
<div>
{a ? (
"a"
) : b ? (
"b"
) : (
thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo
)}
</div>;
// This chain of ConditionalExpressions prints in JSX mode because there is a
// JSX element somewhere in the chain. It is non-breaking.
cable ? "satellite" : public ? "affairs" : network ? <span id="c" /> : "dunno";
@ -405,6 +263,20 @@ cable ? (
"dunno"
);
// This chain of ConditionalExpressions prints in JSX mode because there is a
// JSX element somewhere in the chain. It is breaking; notice the consequents
// and alternates in the entire chain get wrapped in parens.
<div>
{properties.length > 1 ||
(properties.length === 1 && properties[0].apps.size > 1) ? (
draggingApp == null || newPropertyName == null ? (
<MigrationPropertyListItem />
) : (
<MigrationPropertyListItem apps={Immutable.List()} />
)
) : null}
</div>;
`;
exports[`expression.js 1`] = `
@ -656,6 +528,14 @@ exports[`logical-expression.js 1`] = `
{a && <span></span>}
</div>;
<div>
{a && <span>make this text just so long enough to break this to the next line</span>}
</div>;
<div>
{a && b && <span>make this text just so long enough to break this to the next line</span>}
</div>;
<div>
{a && <span>
<div>
@ -672,6 +552,23 @@ exports[`logical-expression.js 1`] = `
<div>{a && <span />}</div>;
<div>
{a && (
<span>
make this text just so long enough to break this to the next line
</span>
)}
</div>;
<div>
{a &&
b && (
<span>
make this text just so long enough to break this to the next line
</span>
)}
</div>;
<div>
{a && (
<span>

View File

@ -17,86 +17,20 @@
//
// test ? consequent : alternate;
//
// We print a conditional expression in JSX mode if any of the following are
// true:
// * Its parent is a JSXExpressionContainer
// * Its test, consequent, or alternate are JSXElements
// * It is in a chain with other ConditionalExpressions, and the outermost
// one's parent is a JSXExpressionContainer
// * It is in a chain with other ConditionalExpressions, and any of the
// tests, consequents, or alternates of any of the ConditionalExpressions in
// the chain are JSXElements.
// We only print a conditional expression in JSX mode if its test,
// consequent, or alternate are JSXElements.
// Otherwise, we print in normal mode.
// This ConditionalExpression does not meet any of the other criteria for
// printing in JSX mode, so it prints in normal mode. The line does not break.
// This ConditionalExpression has no JSXElements so it prints in normal mode.
// The line does not break.
normalModeNonBreaking ? "a" : "b";
// This ConditionalExpression does not meet any of the criteria to print in JSX
// mode, so it prints in normal mode. Its consequent is very long, so it breaks
// out to multiple lines.
// This ConditionalExpression has no JSXElements so it prints in normal mode.
// Its consequent is very long, so it breaks out to multiple lines.
normalModeBreaking
? johnJacobJingleHeimerSchmidtHisNameIsMyNameTooWheneverWeGoOutThePeopleAlwaysShoutThereGoesJohnJacobJingleHeimerSchmidtYaDaDaDaDaDaDa
: "c";
// This ConditionalExpression prints in JSX mode because its parent is a
// JSXExpressionContainer. The line does not break, so it does not contain
// parens.
<div>
{a ? "b" : "c"}
</div>;
// This ConditionalExpression prints in JSX mode because its parent is a
// JSXExpressionContainer. Because the consequent is long enough to break the
// line, both its consequent and alternate break out and are wrapped in parens.
<div>
{a ? (
johnJacobJingleHeimerSchmidtHisNameIsMyNameTooWheneverWeGoOutThePeopleAlwaysShoutThereGoesJohnJacobJingleHeimerSchmidtYaDaDaDaDaDaDa
) : (
"c"
)}
</div>;
// This ConditionalExpression prints in JSX mode because its parent is a
// JSXExpressionContainer. The consequent is long enough to break the line, but
// because the alternate is null, only the consequent is wrapped in parens.
<div>
{a ? (
johnJacobJingleHeimerSchmidtHisNameIsMyNameTooWheneverWeGoOutThePeopleAlwaysShoutThereGoesJohnJacobJingleHeimerSchmidtYaDaDaDaDaDaDa
) : null}
</div>;
// This ConditionalExpression prints in JSX mode because its parent is a
// JSXExpressionContainer. Because the alternate is long enough to break the
// line, both its consequent and alternate break out and are wrapped in parens.
<div>
{a ? (
"b"
) : (
johnJacobJingleHeimerSchmidtHisNameIsMyNameTooWheneverWeGoOutThePeopleAlwaysShoutThereGoesJohnJacobJingleHeimerSchmidtYaDaDaDaDaDaDa
)}
</div>;
// This ConditionalExpression prints in JSX mode because its parent is a
// JSXExpressionContainer. The alternate is long enough to break the line, but
// because the consequent is null, only the alternate is wrapped in parens.
<div>
{a ? null : (
johnJacobJingleHeimerSchmidtHisNameIsMyNameTooWheneverWeGoOutThePeopleAlwaysShoutThereGoesJohnJacobJingleHeimerSchmidtYaDaDaDaDaDaDa
)}
</div>;
// This ConditionalExpression prints in JSX mode because its parent is a
// JSXExpressionContainer. Because the test is long enough to break the
// line, both its consequent and alternate break out and are wrapped in parens.
<div>
{johnJacobJingleHeimerSchmidtHisNameIsMyNameTooWheneverWeGoOutThePeopleAlwaysShoutThereGoesJohnJacobJingleHeimerSchmidtYaDaDaDaDaDaDa ? (
"b"
) : (
"c"
)}
</div>;
// This ConditionalExpression prints in JSX mode because its test is a
// JSXElement. It is non-breaking.
// Note: I have never, ever seen someone use a JSXElement as the test in a
@ -150,19 +84,6 @@ jsxModeFromElementBreaking ? (
{a ? "a" : b ? "b" : "c"}
</div>;
// This chain of ConditionalExpressions prints in JSX mode because the parent of
// the outermost ConditionalExpression is a JSXExpressionContainer. It is
// breaking.
<div>
{a ? (
"a"
) : b ? (
"b"
) : (
thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo
)}
</div>;
// This chain of ConditionalExpressions prints in JSX mode because there is a
// JSX element somewhere in the chain. It is non-breaking.
cable ? "satellite" : public ? "affairs" : network ? <span id="c" /> : "dunno";
@ -194,3 +115,17 @@ cable ? (
) : affairs ? (
"network"
) : "dunno";
// This chain of ConditionalExpressions prints in JSX mode because there is a
// JSX element somewhere in the chain. It is breaking; notice the consequents
// and alternates in the entire chain get wrapped in parens.
<div>
{properties.length > 1 ||
(properties.length === 1 && properties[0].apps.size > 1) ? (
draggingApp == null || newPropertyName == null ? (
<MigrationPropertyListItem />
) : (
<MigrationPropertyListItem apps={Immutable.List()} />
)
) : null}
</div>;

View File

@ -14,6 +14,14 @@
{a && <span></span>}
</div>;
<div>
{a && <span>make this text just so long enough to break this to the next line</span>}
</div>;
<div>
{a && b && <span>make this text just so long enough to break this to the next line</span>}
</div>;
<div>
{a && <span>
<div>

View File

@ -1,5 +1,18 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`conditional.js 1`] = `
(valid
? helper.responseBody(this.currentUser)
: helper.responseBody(this.defaultUser))
.prop;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(valid
? helper.responseBody(this.currentUser)
: helper.responseBody(this.defaultUser)
).prop;
`;
exports[`expand.js 1`] = `
const veryVeryVeryVeryVeryVeryVeryLong = doc.expandedStates[doc.expandedStates.length - 1];
const small = doc.expandedStates[doc.expandedStates.length - 1];
@ -53,3 +66,17 @@ const promises = [
];
`;
exports[`logical.js 1`] = `
(veryLongVeryLongVeryLong || e).prop;
(veryLongVeryLongVeryLong || anotherVeryLongVeryLongVeryLong || veryVeryVeryLongError).prop;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(veryLongVeryLongVeryLong || e).prop;
(veryLongVeryLongVeryLong ||
anotherVeryLongVeryLongVeryLong ||
veryVeryVeryLongError
).prop;
`;

View File

@ -0,0 +1,4 @@
(valid
? helper.responseBody(this.currentUser)
: helper.responseBody(this.defaultUser))
.prop;

3
tests/member/logical.js Normal file
View File

@ -0,0 +1,3 @@
(veryLongVeryLongVeryLong || e).prop;
(veryLongVeryLongVeryLong || anotherVeryLongVeryLongVeryLong || veryVeryVeryLongError).prop;

View File

@ -416,6 +416,67 @@ exports[`computed-merge.js 1`] = `
`;
exports[`conditional.js 1`] = `
(a ? b : c).d();
(a ? b : c).d().e();
(a ? b : c).d().e().f();
(valid
? helper.responseBody(this.currentUser)
: helper.responseBody(this.defaultUser))
.map();
(valid
? helper.responseBody(this.currentUser)
: helper.responseBody(this.defaultUser))
.map().filter();
(valid
? helper.responseBody(this.currentUser)
: helper.responseBody(defaultUser))
.map();
object[valid
? helper.responseBody(this.currentUser)
: helper.responseBody(defaultUser)]
.map();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(a ? b : c).d();
(a ? b : c).d().e();
(a ? b : c)
.d()
.e()
.f();
(valid
? helper.responseBody(this.currentUser)
: helper.responseBody(this.defaultUser)
).map();
(valid
? helper.responseBody(this.currentUser)
: helper.responseBody(this.defaultUser)
)
.map()
.filter();
(valid
? helper.responseBody(this.currentUser)
: helper.responseBody(defaultUser)
).map();
object[
valid
? helper.responseBody(this.currentUser)
: helper.responseBody(defaultUser)
].map();
`;
exports[`first_long.js 1`] = `
export default function theFunction(action$, store) {
return action$.ofType(THE_ACTION).switchMap(action => Observable
@ -511,9 +572,35 @@ Object.keys(
exports[`logical.js 1`] = `
(veryLongVeryLongVeryLong || e).map(tickets =>
TicketRecord.createFromSomeLongString());
(veryLongVeryLongVeryLong || e).map(tickets =>
TicketRecord.createFromSomeLongString()).filter(obj => !!obj);
(veryLongVeryLongVeryLong || anotherVeryLongVeryLongVeryLong || veryVeryVeryLongError).map(tickets =>
TicketRecord.createFromSomeLongString());
(veryLongVeryLongVeryLong || anotherVeryLongVeryLongVeryLong || veryVeryVeryLongError).map(tickets =>
TicketRecord.createFromSomeLongString()).filter(obj => !!obj);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(veryLongVeryLongVeryLong || e).map(tickets =>
TicketRecord.createFromSomeLongString()
);
(veryLongVeryLongVeryLong || e)
.map(tickets => TicketRecord.createFromSomeLongString());
.map(tickets => TicketRecord.createFromSomeLongString())
.filter(obj => !!obj);
(veryLongVeryLongVeryLong ||
anotherVeryLongVeryLongVeryLong ||
veryVeryVeryLongError
).map(tickets => TicketRecord.createFromSomeLongString());
(veryLongVeryLongVeryLong ||
anotherVeryLongVeryLongVeryLong ||
veryVeryVeryLongError
)
.map(tickets => TicketRecord.createFromSomeLongString())
.filter(obj => !!obj);
`;

View File

@ -0,0 +1,25 @@
(a ? b : c).d();
(a ? b : c).d().e();
(a ? b : c).d().e().f();
(valid
? helper.responseBody(this.currentUser)
: helper.responseBody(this.defaultUser))
.map();
(valid
? helper.responseBody(this.currentUser)
: helper.responseBody(this.defaultUser))
.map().filter();
(valid
? helper.responseBody(this.currentUser)
: helper.responseBody(defaultUser))
.map();
object[valid
? helper.responseBody(this.currentUser)
: helper.responseBody(defaultUser)]
.map();

View File

@ -1,2 +1,11 @@
(veryLongVeryLongVeryLong || e).map(tickets =>
TicketRecord.createFromSomeLongString());
(veryLongVeryLongVeryLong || e).map(tickets =>
TicketRecord.createFromSomeLongString()).filter(obj => !!obj);
(veryLongVeryLongVeryLong || anotherVeryLongVeryLongVeryLong || veryVeryVeryLongError).map(tickets =>
TicketRecord.createFromSomeLongString());
(veryLongVeryLongVeryLong || anotherVeryLongVeryLongVeryLong || veryVeryVeryLongError).map(tickets =>
TicketRecord.createFromSomeLongString()).filter(obj => !!obj);

View File

@ -1,5 +1,28 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`graphql.js 1`] = `
graphql(schema, \`
mutation MarkReadNotificationMutation(
$input
: MarkReadNotificationData!
)
{ markReadNotification(data: $input ) { notification {seenState} } }\`)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
graphql(
schema,
\`
mutation MarkReadNotificationMutation($input: MarkReadNotificationData!) {
markReadNotification(data: $input) {
notification {
seenState
}
}
}
\`
);
`;
exports[`graphql-tag.js 1`] = `
import gql from "graphql-tag";

View File

@ -0,0 +1,6 @@
graphql(schema, `
mutation MarkReadNotificationMutation(
$input
: MarkReadNotificationData!
)
{ markReadNotification(data: $input ) { notification {seenState} } }`)

View File

@ -0,0 +1,59 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`module-with-pragma.js 1`] = `
/**
* @flow
* @format
*/
function foo(bar)
{
return bar +
3 +
4;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* @flow
* @format
*/
function foo(bar) {
return bar + 3 + 4;
}
`;
exports[`module-without-pragma.js 1`] = `
/**
* @flow
*/
function foo(bar)
{
return bar +
3 +
4;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* @flow
*/
function foo(bar)
{
return bar +
3 +
4;
}
`;

View File

@ -0,0 +1 @@
run_spec(__dirname, { requirePragma: true });

View File

@ -0,0 +1,14 @@
/**
* @flow
* @format
*/
function foo(bar)
{
return bar +
3 +
4;
}

View File

@ -0,0 +1,13 @@
/**
* @flow
*/
function foo(bar)
{
return bar +
3 +
4;
}

View File

@ -59,6 +59,8 @@ Other options:
--no-color Do not colorize error messages.
--help or -h Show help.
--require-pragma Require either '@prettier' or '@format' to be present in the file's first docblock comment
in order for it to be formatted.
--stdin Force reading input from stdin.
--stdin-filepath <path> Path to the file to pretend that stdin comes from.
--version or -v Print Prettier version.
@ -126,6 +128,8 @@ Other options:
--no-color Do not colorize error messages.
--help or -h Show help.
--require-pragma Require either '@prettier' or '@format' to be present in the file's first docblock comment
in order for it to be formatted.
--stdin Force reading input from stdin.
--stdin-filepath <path> Path to the file to pretend that stdin comes from.
--version or -v Print Prettier version.

View File

@ -0,0 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`support absolute filename 1`] = `
"regular-module.js
"
`;

View File

@ -0,0 +1,16 @@
"use strict";
const path = require("path");
const runPrettier = require("../runPrettier");
test("support absolute filename", () => {
const result = runPrettier("cli/ignore-absolute-path", [
path.resolve(__dirname, "../cli/ignore-absolute-path/ignored/module.js"),
path.resolve(__dirname, "../cli/ignore-absolute-path/depth1/ignored/*.js"),
path.resolve(__dirname, "../cli/ignore-absolute-path/regular-module.js"),
"-l"
]);
expect(result.stdout).toMatchSnapshot();
expect(result.status).toEqual(1);
});

View File

@ -0,0 +1,2 @@
/ignored/
depth1/ignored/

View File

@ -0,0 +1 @@
'use strict';

View File

@ -0,0 +1 @@
'use strict';

View File

@ -0,0 +1 @@
'use strict';

View File

@ -4,5 +4,5 @@ module.exports = {
test: value =>
typeof value === "string" && value.indexOf(process.cwd()) !== -1,
print: (value, serializer) =>
serializer(value.replace(process.cwd(), "<cwd>"))
serializer(value.replace(process.cwd(), "<cwd>").replace(/\\/g, "/"))
};

View File

@ -2258,6 +2258,10 @@ jest-docblock@^20.0.1, jest-docblock@^20.0.3:
version "20.0.3"
resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-20.0.3.tgz#17bea984342cc33d83c50fbe1545ea0efaa44712"
jest-docblock@^21.0.2:
version "21.0.2"
resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-21.0.2.tgz#66f69ddb440799fc32f91d0ac3d8d35e99e2032f"
jest-environment-jsdom@^20.0.3:
version "20.0.3"
resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-20.0.3.tgz#048a8ac12ee225f7190417713834bb999787de99"