Add test cases for questioning ternaries (#13952)

## Description

Extracts test cases that I added for https://github.com/prettier/prettier/pull/13183 to make it easier to visualize the changes that PR makes, as @vjeux [requested](https://github.com/prettier/prettier/pull/13183#discussion_r990820889).

## Checklist

<!-- Please ensure you’ve done all of these things (if applicable). -->
<!-- You can replace the `[ ]` with `[x]` to mark each task as done. -->

- [x] I’ve added tests to confirm my change works.
- [x] I’ve read the [contributing guidelines](https://github.com/prettier/prettier/blob/main/CONTRIBUTING.md).

<!-- Please DO NOT remove the playground link -->

**✨[Try the playground for this PR](https://prettier.io/playground-redirect)✨**
This commit is contained in:
Alex Rattray authored and GitHub committed 2022-12-07 15:46:40 -05:00
1 parent 26b5273833
commit 28d097bbf5
14 files changed
+2023 -15

No files matched your search

+1
View File
@@ -0,0 +1 @@
18.12.1
File diff suppressed because it is too large. Load diff
+18
View File
@@ -86,6 +86,7 @@ test
comment
comment
comment
A newline will be added after this comment, unfortunately – but it can be removed manually, see next statement.
*/
test
? foo
@@ -95,6 +96,23 @@ test
*/
bar;
// It is at least possible to delete the extra newline that was
// unfortunately added before the second condition above:
test ?
foo :/* comment
comment
comment
comment
*/
test ?
foo :
/* comment
comment
comment
*/
bar;
test
? foo
: /* comment */
@@ -0,0 +1,138 @@
// from https://gist.github.com/rattrayalex/dacbf5838571a47f22d0ae1f8b960268
// Input and output should match (for 2-space indent formatting).
// TypeScript is here: prettier/tests/format/typescript/conditional-types/new-ternary-spec.ts
// EXAMPLES
// mostly taken from https://github.com/prettier/prettier/issues/9561
const message =
i % 3 === 0 && i % 5 === 0 ? "fizzbuzz"
: i % 3 === 0 ? "fizz"
: i % 5 === 0 ? "buzz"
: String(i);
const paymentMessageShort =
state == "success" ? "Payment completed successfully"
: state == "processing" ? "Payment processing"
: state == "invalid_cvc" ? "There was an issue with your CVC number"
: state == "invalid_expiry" ? "Expiry must be sometime in the past."
: "There was an issue with the payment. Please contact support.";
const paymentMessageWithABreak =
state == "success" ? "Payment completed successfully"
: state == "processing" ? "Payment processing"
: state == "invalid_cvc" ?
"There was an issue with your CVC number, and you need to take a prompt action on it."
: state == "invalid_expiry" ? "Expiry must be sometime in the past."
: "There was an issue with the payment. Please contact support.";
const typeofExample =
definition.encode ?
definition.encode(
typeof row[field] !== "undefined" ? row[field]
: typeof definition.default !== "undefined" ? definition.default
: null
)
: typeof row[field] !== "undefined" ? row[field]
: typeof definition.default !== "undefined" ? definition.default
: null
// (the following is semantically equivalent to the above, but written in a more-confusing style – it'd be hard to grok no matter the formatting)
const typeofExampleFlipped =
definition.encode ?
definition.encode(
typeof row[field] === "undefined" ?
typeof definition.default === "undefined" ? null
: definition.default
: row[field]
)
: typeof row[field] === "undefined" ?
typeof definition.default === "undefined" ? null
: definition.default
: row[field];
// JSX Examples:
const typicalLongConsequentWithNullAlternate = (
<div>
{children && !isEmptyChildren(children) ?
<FooComponent
className="a bunch of css classes might go here, wow so many"
foo={foo}
bar={includeBar ? bar : null}
/>
: null}
</div>
);
const reactRouterExampleJSX = (
<div>
{children && !isEmptyChildren(children) ?
children
: props.match ?
component ? React.createElement(component, props)
: render ? render(props)
: null
: null}
</div>
);
const reactRouterExampleNonJSX =
children && !isEmptyChildren(children) ? children
: props.match ?
component ? React.createElement(component, props)
: render ? render(props)
: null
: null;
inJSXExpressionContainer.withLongConditionals.example = (
<div>
{(
isACat() &&
(someReallyLongCondition ||
moreInThisLongCondition)
) ?
someReallyLargeExpression
.toMakeMeowNoise()
.willCauseParens()
: (
someReallyLongCondition ||
moreInThisLongCondition
) ?
bark()
: someReallyLargeExpression
.toMakeMeowNoise()
.willCauseParens()
}
</div>
);
inJSXExpressionContainer.withLoops.orBooleans.example = (
<div>
{items ?
items.map((item) => (
item.display ?
<Item item={item} attr="breaks ternary but not consequent" />
: <Blank />
))
: null}
{showTheStuff && (
foo ?
<Thing thing={foooooooooooooooooooooooooo} bar="bazzzzzz" />
: <OtherThing />
)}
</div>
);
inJSXExpressionContainer.withNullConditional = (
<div>
{isACat() ? null : <Foo />}
{isACat() && (someReallyLongCondition || moreInThisLongCondition) ? null : (
<Foo />
)}
{isACat() && (someReallyLongCondition || moreInThisLongCondition || evenMoreInThisExtraLongConditional) ? null : (
<Foo />
)}
</div>
);
@@ -0,0 +1,189 @@
// from https://gist.github.com/rattrayalex/dacbf5838571a47f22d0ae1f8b960268
// Input and output should match (for 2-space indent formatting).
// TypeScript is here: prettier/tests/format/typescript/conditional-types/new-ternary-spec.ts
// remain on one line if possible:
const short = isLoud() ? makeNoise() : silent();
// next, put everything after the =
const lessShort =
isLoudReallyLoud() ? makeNoiseReallyLoudly.omgSoLoud() : silent();
// next, indent the consequent:
const andIndented = isLoudReallyReallyReallyReallyLoud() ?
makeNoiseReallyReallyReallyReallyReallyLoudly.omgSoLoud()
: silent();
// unless the consequent is short (less than ten characters long):
const shortSoCase = isLoudReallyReallyReallyReallyLoud() ? silent()
: makeNoiseReallyReallyReallyReallyReallyLoudly.omgSoLoud();
// if chained, always break and put after the =
const chainedShort =
isCat() ? meow()
: isDog() ? bark()
: silent();
// when a consequent breaks in a chain:
const chainedWithLongConsequent =
isCat() ?
someReallyLargeExpression
.thatWouldCauseALineBreak()
.willCauseAnIndentButNotParens()
: isDog() ? bark()
: silent();
// nested ternary in consequent always breaks:
const chainedWithTernaryConsequent =
isCat() ?
aNestedCondition ? theResult()
: theAlternate()
: isDog() ? bark()
: silent();
// consequent and terminal alternate break:
const consequentAndTerminalAlternateBreak =
isCat() ?
someReallyLargeExpression
.thatWouldCauseALineBreak()
.willCauseAnIndentButNotParens()
: isDog() ? bark()
: someReallyLargeExpression
.thatWouldCauseALineBreak()
.willCauseAnIndentButNotParens();
// multiline conditions and consequents/alternates:
const multilineConditionsConsequentsAndAlternates =
(
isAnAdorableKittyCat() &&
(someReallyLongCondition || moreInThisLongCondition)
) ?
someReallyLargeExpression
.thatWouldCauseALineBreak()
.willCauseAnIndentButNotParens()
: (
isNotAnAdorableKittyCat() &&
(someReallyLongCondition || moreInThisLongCondition)
) ?
bark()
: shortCondition() ? shortConsequent()
: someReallyLargeExpression
.thatWouldCauseALineBreak()
.willCauseAnIndentButNotParens();
// illustrating case of mostly short conditionals
const mostlyShort =
x === 1 ? "one"
: x === 2 ? "two"
: x === 3 ? "three"
: (
x === 5 &&
y === 7 &&
someOtherThing.thatIsSoLong.thatItBreaksTheTestCondition()
) ?
"four"
: x === 6 ? "six"
: "idk";
// long conditional, short consequent/alternate, not chained - do indent after ?
const longConditional = (
bifornCringerMoshedPerplexSawder === 2 / askTrovenaBeenaDependsRowans &&
glimseGlyphsHazardNoopsTieTie >=
averredBathersBoxroomBuggyNurl().anodyneCondosMalateOverateRetinol()
) ?
"foo"
: "bar";
// long conditional, short consequent/alternate, chained
// (break on short consequents iff in chained ternary and its conditional broke)
const longConditionalChained =
(
bifornCringerMoshedPerplexSawder === 2 / askTrovenaBeenaDependsRowans &&
glimseGlyphsHazardNoopsTieTie >=
averredBathersBoxroomBuggyNurl().anodyneCondosMalateOverateRetinol()
) ?
"foo"
: anotherCondition ? "bar"
: "baz";
// As a function parameter, don't add an extra indent:
definition.encode(
typeof row[field] !== "undefined" ? row[field]
: typeof definition.default !== "undefined" ? definition.default
: null,
typeof row[field] === "undefined" ?
typeof definition.default === "undefined" ? null
: definition.default
: row[field]
);
// In a return, break and over-indent:
const inReturn = () => {
if (short) {
return foo ? 1 : 2;
}
return typeof row[aVeryLongFieldName] !== "undefined" ?
row[aVeryLongFieldName]
: null;
};
// Remove current JSX Mode, and replace it with this algorithm:
// When a ternary's parent is a JSXExpressionContainer which is not in a JSXAttribute,
// force the consequent to break,
// and if the alternate breaks,
// add a newline before the closing curly brace.
// Special case when the consequent is `null`:
// do not add a line before or after it,
// and wrap the alternate in parens.
const someJSX = (
<div>
Typical jsx case:
{showFoo ?
<Foo attribute="such and such stuff here" />
: <Bar short />}
Nested, and with a non-jsx consequent is the same:
{component ?
React.createElement(component, props)
: render ?
<div>{render(props)}</div>
: <div>Nothing is here</div>}
As is a non-jsx consequent:
{showTheJSXElement ?
<div>the stuff</div>
: renderOtherStuff()}
But if the alternate breaks, add a newline before the closing curly brace:
{showTheThing || pleaseShowTheThing ?
<Foo attribute="such and such stuff here" />
: <Bar
attribute="such and such stuff here"
another="more stuff here"
third="and even more, hooray!"
/>
}
When the consequent is `null` and the alternate breaks,
hug it with parens to match boolean behavior:
{!thing ? null : (
<TheThing
thing={thing}
someVeryLongPropertyThatBreaksTheAlternate="hello"
/>
)}
</div>
);
ternaryWithJSXElements.hasNoSpecialCasing =
component ? <div>{React.createElement(component, props)}</div>
: render ? <div>{render(props)}</div>
: <div>Nothing is here</div>;
jsxExpressionContainer.inJSXAttribute.hasNoSpecialCasing = (
<Foo
withJSX={isRed ? <RedColorThing /> : <GreenColorThing />}
withJSXBroken={
isRed || isSomeOtherLongCondition.thatBreaksTheLine() ?
<RedColorThing />
: <GreenColorThing />
}
/>
);
@@ -0,0 +1,150 @@
// concatened string in consequent should be visually distinguishable from alternate
// … or maybe this is okay, because the colon is enough?
const avatar = has_ordered ?
'https://marmelab.com/posters/avatar/longer-word-that-breaks-consequent-' +
numberOfCustomers +
'.jpeg'
: undefined;
// Similarly, in the alternate:
const redirectUrl = pathName ?
pathName
: nextPathName + nextSearch ||
defaultAuthParams.afterLoginUrl.makeThisLongerSoItBreaks;
// And another, more pathological case of the above:
const isEmpty = obj =>
obj instanceof Date ?
false
: obj === '' ||
obj === null ||
obj === undefined ||
obj === somethingThatIsLonger ||
shallowEqual(obj, {});
// Again, this case is a bit hard to distinguish the alternate.
const eventsFromOrders =
orderIds && orders ?
orderIds.map(id => ({
type: 'order',
date: orders[id].date,
data: orders[id],
}))
: [];
// Kinda weird to have dedents to the level of "return" in a function.
function foo() {
return !linkTo ?
false
: typeof linkTo === 'function'
? linkTo(record, reference)
: linkToRecord(rootPath, sourceId, linkTo_as_string);
}
function foo2() {
return React.isValidElement(emptyText)
? React.cloneElement(emptyText)
: emptyText === ''
? ' ' // em space, forces the display of an empty line of normal height
: translate(emptyText, { _: emptyText });
}
// Function call ideally wouldnt break break
const matchingReferencesError = isMatchingReferencesError(
matchingReferences
)
? translate(matchingReferences.error, {
_: matchingReferences.error,
})
: null;
// This one is kinda confusing any way you slice it…
const obj = {
error:
matchingReferencesError &&
(!input.value ||
(input.value &&
selectedReferencesDataStatus === REFERENCES_STATUS_EMPTY))
? translate('ra.input.references.all_missing', {
_: 'ra.input.references.all_missing',
})
: null,
}
// I think we should indent after the inner || on this, and do better wtih the parens around the &&
const obj2 = {
warning:
matchingReferencesError ||
(input.value && selectedReferencesDataStatus !== REFERENCES_STATUS_READY)
? matchingReferencesError ||
translate('ra.input.references.many_missing', {
_: 'ra.input.references.many_missing',
})
: null,
}
// The boolean conditions in the test should look cohesive.
const selectedReferencesDataStatus =
!isEmpty(value) && typeof value === 'string' && !pattern.test(value)
? getMessage(message, { pattern }, value, values)
: undefined
// Would be nice if these two nested ternaries didn't look like a single one.
resolveRedirectTo(
redirectTo,
basePath,
payload
? payload.id || (payload.data ? payload.data.id : null)
: requestPayload
? requestPayload.id
: null,
payload && payload.data
? payload.data
: requestPayload && requestPayload.data
? requestPayload.data
: null
)
const delayedDataProvider = new Proxy(restProvider, {
get: (target, name, self) =>
name === 'then' ? // as we await for the dataProvider, JS calls then on it. We must trap that call or else the dataProvider will be called with the then method
self
: (
(resource, params) =>
new Promise(resolve =>
setTimeout(
() =>
resolve(
restProvider[name](resource, params)
),
500
)
)
),
});
function foo4() {
return !match || match.length < 5 ? line : (
match[1] + match[2] + match[3] + match[4]
)
}
function foo5() {
return !match || match.length < 5 ? foo(line) : (
match[1] + match[2] + match[3] + match[4]
)
}
function foo6() {
return !match || match.length < 5 ? linethatisverylongandbreaksthelinehooray : (
match[1] + match[2] + match[3] + match[4]
)
}
function foo7() {
return !match || match.length < 5 ? linethatisverylongandbreaksthelinehoorayjustabitlonger : (
match[1] + match[2] + match[3] + match[4]
)
}
@@ -179,10 +179,11 @@ fn(
bifornCringerMoshedPerplexSawder,
askTrovenaBeenaDependsRowans,
glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl &&
anodyneCondosMalateOverateRetinol
? annularCooeedSplicesWalksWayWay
: kochabCooieGameOnOboleUnweave
anodyneCondosMalateOverateRetinol
? annularCooeedSplicesWalksWayWay
: kochabCooieGameOnOboleUnweave
);
// TODO(rattrayalex): try to indent consequent/alternate here.
=====================================output=====================================
fn(
@@ -193,6 +194,7 @@ fn(
? annularCooeedSplicesWalksWayWay
: kochabCooieGameOnOboleUnweave
);
// TODO(rattrayalex): try to indent consequent/alternate here.
================================================================================
`;
@@ -209,10 +211,11 @@ fn(
bifornCringerMoshedPerplexSawder,
askTrovenaBeenaDependsRowans,
glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl &&
anodyneCondosMalateOverateRetinol
? annularCooeedSplicesWalksWayWay
: kochabCooieGameOnOboleUnweave
anodyneCondosMalateOverateRetinol
? annularCooeedSplicesWalksWayWay
: kochabCooieGameOnOboleUnweave
);
// TODO(rattrayalex): try to indent consequent/alternate here.
=====================================output=====================================
fn(
@@ -223,6 +226,7 @@ fn(
? annularCooeedSplicesWalksWayWay
: kochabCooieGameOnOboleUnweave
);
// TODO(rattrayalex): try to indent consequent/alternate here.
================================================================================
`;
@@ -238,10 +242,11 @@ fn(
bifornCringerMoshedPerplexSawder,
askTrovenaBeenaDependsRowans,
glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl &&
anodyneCondosMalateOverateRetinol
? annularCooeedSplicesWalksWayWay
: kochabCooieGameOnOboleUnweave
anodyneCondosMalateOverateRetinol
? annularCooeedSplicesWalksWayWay
: kochabCooieGameOnOboleUnweave
);
// TODO(rattrayalex): try to indent consequent/alternate here.
=====================================output=====================================
fn(
@@ -252,6 +257,7 @@ fn(
? annularCooeedSplicesWalksWayWay
: kochabCooieGameOnOboleUnweave
);
// TODO(rattrayalex): try to indent consequent/alternate here.
================================================================================
`;
@@ -266,10 +272,11 @@ fn(
bifornCringerMoshedPerplexSawder,
askTrovenaBeenaDependsRowans,
glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl &&
anodyneCondosMalateOverateRetinol
? annularCooeedSplicesWalksWayWay
: kochabCooieGameOnOboleUnweave
anodyneCondosMalateOverateRetinol
? annularCooeedSplicesWalksWayWay
: kochabCooieGameOnOboleUnweave
);
// TODO(rattrayalex): try to indent consequent/alternate here.
=====================================output=====================================
fn(
@@ -280,6 +287,7 @@ fn(
? annularCooeedSplicesWalksWayWay
: kochabCooieGameOnOboleUnweave
);
// TODO(rattrayalex): try to indent consequent/alternate here.
================================================================================
`;
@@ -1816,6 +1824,7 @@ bifornCringerMoshedPerplexSawder =
kochabCooieGameOnOboleUnweave === Math.PI
? averredBathersBoxroomBuggyNurl
: anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo));
// TODO(rattrayalex): try to fix this case
bifornCringerMoshedPerplexSawder = (
glimseGlyphsHazardNoopsTieTie === 0 &&
@@ -2160,6 +2169,7 @@ bifornCringerMoshedPerplexSawder =
kochabCooieGameOnOboleUnweave === Math.PI
? averredBathersBoxroomBuggyNurl
: anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo);
// TODO(rattrayalex): try to fix this case
bifornCringerMoshedPerplexSawder = (
glimseGlyphsHazardNoopsTieTie === 0 &&
@@ -2468,6 +2478,7 @@ bifornCringerMoshedPerplexSawder =
kochabCooieGameOnOboleUnweave === Math.PI
? averredBathersBoxroomBuggyNurl
: anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo));
// TODO(rattrayalex): try to fix this case
bifornCringerMoshedPerplexSawder = (
glimseGlyphsHazardNoopsTieTie === 0 &&
@@ -2812,6 +2823,7 @@ bifornCringerMoshedPerplexSawder =
kochabCooieGameOnOboleUnweave === Math.PI
? averredBathersBoxroomBuggyNurl
: anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo);
// TODO(rattrayalex): try to fix this case
bifornCringerMoshedPerplexSawder = (
glimseGlyphsHazardNoopsTieTie === 0 &&
@@ -3119,6 +3131,7 @@ bifornCringerMoshedPerplexSawder =
kochabCooieGameOnOboleUnweave === Math.PI
? averredBathersBoxroomBuggyNurl
: anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo));
// TODO(rattrayalex): try to fix this case
bifornCringerMoshedPerplexSawder = (
glimseGlyphsHazardNoopsTieTie === 0 &&
@@ -3463,6 +3476,7 @@ bifornCringerMoshedPerplexSawder =
kochabCooieGameOnOboleUnweave === Math.PI
? averredBathersBoxroomBuggyNurl
: anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo);
// TODO(rattrayalex): try to fix this case
bifornCringerMoshedPerplexSawder = (
glimseGlyphsHazardNoopsTieTie === 0 &&
@@ -3769,6 +3783,7 @@ bifornCringerMoshedPerplexSawder =
kochabCooieGameOnOboleUnweave === Math.PI
? averredBathersBoxroomBuggyNurl
: anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo));
// TODO(rattrayalex): try to fix this case
bifornCringerMoshedPerplexSawder = (
glimseGlyphsHazardNoopsTieTie === 0 &&
@@ -4113,6 +4128,7 @@ bifornCringerMoshedPerplexSawder =
kochabCooieGameOnOboleUnweave === Math.PI
? averredBathersBoxroomBuggyNurl
: anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo);
// TODO(rattrayalex): try to fix this case
bifornCringerMoshedPerplexSawder = (
glimseGlyphsHazardNoopsTieTie === 0 &&
@@ -4315,6 +4331,34 @@ a
? line
: softline
const config = {
onFailure: onFailure !== undefined ? onFailure : (
error => {
notify(
typeof error === 'string' ?
error
: error.message || 'ra.notification.http_error',
'warning',
{
_:
typeof error === 'string' ? error
: error && error.message ? error.message
: undefined,
}
);
refresh();
}
)
}
showNotification(
typeof error === 'string' ? error : error.message || body,
level || 'warning',
{
messageArgs,
undoable: false,
}
)
=====================================output=====================================
let icecream =
what == "cone"
@@ -4413,6 +4457,38 @@ a
? line
: softline;
const config = {
onFailure:
onFailure !== undefined
? onFailure
: (error) => {
notify(
typeof error === "string"
? error
: error.message || "ra.notification.http_error",
"warning",
{
_:
typeof error === "string"
? error
: error && error.message
? error.message
: undefined,
}
);
refresh();
},
};
showNotification(
typeof error === "string" ? error : error.message || body,
level || "warning",
{
messageArgs,
undoable: false,
}
);
================================================================================
`;
@@ -4520,6 +4596,34 @@ a
? line
: softline
const config = {
onFailure: onFailure !== undefined ? onFailure : (
error => {
notify(
typeof error === 'string' ?
error
: error.message || 'ra.notification.http_error',
'warning',
{
_:
typeof error === 'string' ? error
: error && error.message ? error.message
: undefined,
}
);
refresh();
}
)
}
showNotification(
typeof error === 'string' ? error : error.message || body,
level || 'warning',
{
messageArgs,
undoable: false,
}
)
=====================================output=====================================
let icecream =
what == "cone"
@@ -4618,6 +4722,38 @@ a
? line
: softline;
const config = {
onFailure:
onFailure !== undefined
? onFailure
: (error) => {
notify(
typeof error === "string"
? error
: error.message || "ra.notification.http_error",
"warning",
{
_:
typeof error === "string"
? error
: error && error.message
? error.message
: undefined,
}
);
refresh();
},
};
showNotification(
typeof error === "string" ? error : error.message || body,
level || "warning",
{
messageArgs,
undoable: false,
}
);
================================================================================
`;
@@ -4724,6 +4860,34 @@ a
? line
: softline
const config = {
onFailure: onFailure !== undefined ? onFailure : (
error => {
notify(
typeof error === 'string' ?
error
: error.message || 'ra.notification.http_error',
'warning',
{
_:
typeof error === 'string' ? error
: error && error.message ? error.message
: undefined,
}
);
refresh();
}
)
}
showNotification(
typeof error === 'string' ? error : error.message || body,
level || 'warning',
{
messageArgs,
undoable: false,
}
)
=====================================output=====================================
let icecream =
what == "cone"
@@ -4822,6 +4986,38 @@ a
? line
: softline;
const config = {
onFailure:
onFailure !== undefined
? onFailure
: (error) => {
notify(
typeof error === "string"
? error
: error.message || "ra.notification.http_error",
"warning",
{
_:
typeof error === "string"
? error
: error && error.message
? error.message
: undefined,
}
);
refresh();
},
};
showNotification(
typeof error === "string" ? error : error.message || body,
level || "warning",
{
messageArgs,
undoable: false,
}
);
================================================================================
`;
@@ -4927,6 +5123,34 @@ a
? line
: softline
const config = {
onFailure: onFailure !== undefined ? onFailure : (
error => {
notify(
typeof error === 'string' ?
error
: error.message || 'ra.notification.http_error',
'warning',
{
_:
typeof error === 'string' ? error
: error && error.message ? error.message
: undefined,
}
);
refresh();
}
)
}
showNotification(
typeof error === 'string' ? error : error.message || body,
level || 'warning',
{
messageArgs,
undoable: false,
}
)
=====================================output=====================================
let icecream =
what == "cone"
@@ -5025,6 +5249,38 @@ a
? line
: softline;
const config = {
onFailure:
onFailure !== undefined
? onFailure
: (error) => {
notify(
typeof error === "string"
? error
: error.message || "ra.notification.http_error",
"warning",
{
_:
typeof error === "string"
? error
: error && error.message
? error.message
: undefined,
}
);
refresh();
},
};
showNotification(
typeof error === "string" ? error : error.message || body,
level || "warning",
{
messageArgs,
undoable: false,
}
);
================================================================================
`;
+4 -3
View File
@@ -2,7 +2,8 @@ fn(
bifornCringerMoshedPerplexSawder,
askTrovenaBeenaDependsRowans,
glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl &&
anodyneCondosMalateOverateRetinol
? annularCooeedSplicesWalksWayWay
: kochabCooieGameOnOboleUnweave
anodyneCondosMalateOverateRetinol
? annularCooeedSplicesWalksWayWay
: kochabCooieGameOnOboleUnweave
);
// TODO(rattrayalex): try to indent consequent/alternate here.
@@ -199,6 +199,7 @@ bifornCringerMoshedPerplexSawder =
kochabCooieGameOnOboleUnweave === Math.PI
? averredBathersBoxroomBuggyNurl
: anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo));
// TODO(rattrayalex): try to fix this case
bifornCringerMoshedPerplexSawder = (
glimseGlyphsHazardNoopsTieTie === 0 &&
+29
View File
@@ -93,3 +93,32 @@ a
}
? line
: softline
const config = {
onFailure: onFailure !== undefined ? onFailure : (
error => {
notify(
typeof error === 'string' ?
error
: error.message || 'ra.notification.http_error',
'warning',
{
_:
typeof error === 'string' ? error
: error && error.message ? error.message
: undefined,
}
);
refresh();
}
)
}
showNotification(
typeof error === 'string' ? error : error.message || body,
level || 'warning',
{
messageArgs,
undoable: false,
}
)
@@ -1102,6 +1102,13 @@ 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>
{thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo ? "a" : b ? "b" : "c"}
</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" : isPublic ? "affairs" : network ? <span id="c" /> : "dun";
@@ -1243,6 +1250,17 @@ 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>
{thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo
? "a"
: b
? "b"
: "c"}
</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" : isPublic ? "affairs" : network ? <span id="c" /> : "dun";
@@ -1401,6 +1419,13 @@ 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>
{thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo ? "a" : b ? "b" : "c"}
</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" : isPublic ? "affairs" : network ? <span id="c" /> : "dun";
@@ -1542,6 +1567,17 @@ 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>
{thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo
? "a"
: b
? "b"
: "c"}
</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" : isPublic ? "affairs" : network ? <span id='c' /> : "dun";
@@ -1700,6 +1736,13 @@ 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>
{thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo ? "a" : b ? "b" : "c"}
</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" : isPublic ? "affairs" : network ? <span id="c" /> : "dun";
@@ -1841,6 +1884,17 @@ 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>
{thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo
? 'a'
: b
? 'b'
: 'c'}
</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' : isPublic ? 'affairs' : network ? <span id="c" /> : 'dun';
@@ -1999,6 +2053,13 @@ 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>
{thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo ? "a" : b ? "b" : "c"}
</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" : isPublic ? "affairs" : network ? <span id="c" /> : "dun";
@@ -2140,6 +2201,17 @@ 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>
{thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo
? 'a'
: b
? 'b'
: 'c'}
</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' : isPublic ? 'affairs' : network ? <span id='c' /> : 'dun';
@@ -84,6 +84,13 @@ 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>
{thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo ? "a" : b ? "b" : "c"}
</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" : isPublic ? "affairs" : network ? <span id="c" /> : "dun";
@@ -347,3 +347,87 @@ type Foo3 = (
================================================================================
`;
exports[`new-ternary-spec.ts format 1`] = `
====================================options=====================================
parsers: ["typescript"]
printWidth: 80
| printWidth
=====================================input======================================
// TypeScript has the same behavior, including a line break after =, but no parens around "conditional":
type KnownKeys<T> =
{
[K in keyof T]: string extends K ? never
: number extends K ? never
: K;
} extends { [_ in keyof T]: infer U } ?
{} extends U ? never
: U
: never;
type KnownKeysWithLongExtends<T> =
{
[K in keyof T]: string extends K ? never
: number extends K ? never
: K;
} extends {
[_ in keyof T]: SomeReallyLongThingThatBreaksTheLine<infer U>
} ? U
: never;
// TypeScript examples:
type TypeName<T> =
T extends string ? "string"
: T extends number ? "number"
: T extends boolean ? "boolean"
: T extends undefined ? "undefined"
: T extends Function ? "function"
: "object";
type Unpacked<T> =
T extends (infer U)[] ? U
: T extends (...args: any[]) => infer U ?
SomeReallyLongThingThatBreaksTheLine<U>
: T extends Promise<infer U> ? U
: T;
=====================================output=====================================
// TypeScript has the same behavior, including a line break after =, but no parens around "conditional":
type KnownKeys<T> = {
[K in keyof T]: string extends K ? never : number extends K ? never : K;
} extends { [_ in keyof T]: infer U }
? {} extends U
? never
: U
: never;
type KnownKeysWithLongExtends<T> = {
[K in keyof T]: string extends K ? never : number extends K ? never : K;
} extends {
[_ in keyof T]: SomeReallyLongThingThatBreaksTheLine<infer U>;
}
? U
: never;
// TypeScript examples:
type TypeName<T> = T extends string
? "string"
: T extends number
? "number"
: T extends boolean
? "boolean"
: T extends undefined
? "undefined"
: T extends Function
? "function"
: "object";
type Unpacked<T> = T extends (infer U)[]
? U
: T extends (...args: any[]) => infer U
? SomeReallyLongThingThatBreaksTheLine<U>
: T extends Promise<infer U>
? U
: T;
================================================================================
`;
@@ -0,0 +1,36 @@
// TypeScript has the same behavior, including a line break after =, but no parens around "conditional":
type KnownKeys<T> =
{
[K in keyof T]: string extends K ? never
: number extends K ? never
: K;
} extends { [_ in keyof T]: infer U } ?
{} extends U ? never
: U
: never;
type KnownKeysWithLongExtends<T> =
{
[K in keyof T]: string extends K ? never
: number extends K ? never
: K;
} extends {
[_ in keyof T]: SomeReallyLongThingThatBreaksTheLine<infer U>
} ? U
: never;
// TypeScript examples:
type TypeName<T> =
T extends string ? "string"
: T extends number ? "number"
: T extends boolean ? "boolean"
: T extends undefined ? "undefined"
: T extends Function ? "function"
: "object";
type Unpacked<T> =
T extends (infer U)[] ? U
: T extends (...args: any[]) => infer U ?
SomeReallyLongThingThatBreaksTheLine<U>
: T extends Promise<infer U> ? U
: T;