From 0fa34b2c634ebda8dea8b18ea41fba95cf84cc6c Mon Sep 17 00:00:00 2001 From: Suchipi Date: Sun, 14 Oct 2018 09:45:37 -0600 Subject: [PATCH] Print nested ternaries differently (#5039) --- src/language-js/printer-estree.js | 120 +-- .../__snapshots__/jsfmt.spec.js.snap | 716 +++++++++++++++++- tests/ternaries/indent.js | 2 +- tests/ternaries/nested.js | 84 ++ .../__snapshots__/jsfmt.spec.js.snap | 8 +- .../__snapshots__/jsfmt.spec.js.snap | 18 + .../conditonal-types.ts | 8 + 7 files changed, 877 insertions(+), 79 deletions(-) diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index 068df10ea..8a099067c 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -194,31 +194,37 @@ function hasJsxIgnoreComment(path) { ); } -// The following is the shared logic for -// ternary operators, namely ConditionalExpression -// and TSConditionalType -function formatTernaryOperator(path, options, print, operatorOptions) { - const n = path.getValue(); +/** + * The following is the shared logic for + * ternary operators, namely ConditionalExpression + * and TSConditionalType + * @typedef {Object} OperatorOptions + * @property {() => Array} beforeParts - Parts to print before the `?`. + * @property {(breakClosingParen: boolean) => Array} afterParts - Parts to print after the conditional expression. + * @property {boolean} shouldCheckJsx - Whether to check for and print in JSX mode. + * @property {string} conditionalNodeType - The type of the conditional expression node, ie "ConditionalExpression" or "TSConditionalType". + * @property {string} consequentNodePropertyName - The property at which the consequent node can be found on the main node, eg "consequent". + * @property {string} alternateNodePropertyName - The property at which the alternate node can be found on the main node, eg "alternate". + * @property {string} testNodePropertyName - The property at which the test node can be found on the main node, eg "test". + * @property {boolean} breakNested - Whether to break all nested ternaries when one breaks. + * @param {FastPath} path - The path to the ConditionalExpression/TSConditionalType node. + * @param {Options} options - Prettier options + * @param {Function} print - Print function to call recursively + * @param {OperatorOptions} operatorOptions + * @returns Doc + */ +function printTernaryOperator(path, options, print, operatorOptions) { + const node = path.getValue(); + const testNode = node[operatorOptions.testNodePropertyName]; + const consequentNode = node[operatorOptions.consequentNodePropertyName]; + const alternateNode = node[operatorOptions.alternateNodePropertyName]; const parts = []; - const operatorOpts = Object.assign( - { - beforeParts: () => [""], - afterParts: () => [""], - shouldCheckJsx: true, - operatorName: "ConditionalExpression", - consequentNode: "consequent", - alternateNode: "alternate", - testNode: "test", - breakNested: true - }, - operatorOptions || {} - ); // We print a ConditionalExpression in either "JSX mode" or "normal mode". // See tests/jsx/conditional-expression.js for more info. let jsxMode = false; const parent = path.getParentNode(); - let forceNoIndent = parent.type === operatorOpts.operatorName; + let forceNoIndent = parent.type === operatorOptions.conditionalNodeType; // Find the outermost non-ConditionalExpression parent, and the outermost // ConditionalExpression parent. We'll use these to determine if we should @@ -227,18 +233,22 @@ function formatTernaryOperator(path, options, print, operatorOptions) { let previousParent; let i = 0; do { - previousParent = currentParent || n; + previousParent = currentParent || node; currentParent = path.getParentNode(i); i++; - } while (currentParent && currentParent.type === operatorOpts.operatorName); + } while ( + currentParent && + currentParent.type === operatorOptions.conditionalNodeType + ); const firstNonConditionalParent = currentParent || parent; const lastConditionalParent = previousParent; if ( - (operatorOpts.shouldCheckJsx && isJSXNode(n[operatorOpts.testNode])) || - isJSXNode(n[operatorOpts.consequentNode]) || - isJSXNode(n[operatorOpts.alternateNode]) || - conditionalExpressionChainContainsJSX(lastConditionalParent) + operatorOptions.shouldCheckJsx && + (isJSXNode(testNode) || + isJSXNode(consequentNode) || + isJSXNode(alternateNode) || + conditionalExpressionChainContainsJSX(lastConditionalParent)) ) { jsxMode = true; forceNoIndent = true; @@ -263,37 +273,40 @@ function formatTernaryOperator(path, options, print, operatorOptions) { parts.push( " ? ", - isNull(n[operatorOpts.consequentNode]) - ? path.call(print, operatorOpts.consequentNode) - : wrap(path.call(print, operatorOpts.consequentNode)), + isNull(consequentNode) + ? path.call(print, operatorOptions.consequentNodePropertyName) + : wrap(path.call(print, operatorOptions.consequentNodePropertyName)), " : ", - n[operatorOpts.alternateNode].type === operatorOpts.operatorName || - isNull(n[operatorOpts.alternateNode]) - ? path.call(print, operatorOpts.alternateNode) - : wrap(path.call(print, operatorOpts.alternateNode)) + alternateNode.type === operatorOptions.conditionalNodeType || + isNull(alternateNode) + ? path.call(print, operatorOptions.alternateNodePropertyName) + : wrap(path.call(print, operatorOptions.alternateNodePropertyName)) ); } else { // normal mode const part = concat([ line, "? ", - n[operatorOpts.consequentNode].type === operatorOpts.operatorName + consequentNode.type === operatorOptions.conditionalNodeType ? ifBreak("", "(") : "", - align(2, path.call(print, operatorOpts.consequentNode)), - n[operatorOpts.consequentNode].type === operatorOpts.operatorName + align(2, path.call(print, operatorOptions.consequentNodePropertyName)), + consequentNode.type === operatorOptions.conditionalNodeType ? ifBreak("", ")") : "", line, ": ", - align(2, path.call(print, operatorOpts.alternateNode)) + alternateNode.type === operatorOptions.conditionalNodeType + ? path.call(print, operatorOptions.alternateNodePropertyName) + : align(2, path.call(print, operatorOptions.alternateNodePropertyName)) ]); parts.push( - parent.type === operatorOpts.operatorName - ? options.useTabs + parent.type !== operatorOptions.conditionalNodeType || + parent[operatorOptions.alternateNodePropertyName] === node + ? part + : options.useTabs ? dedent(indent(part)) : align(Math.max(0, options.tabWidth - 2), part) - : part ); } @@ -301,11 +314,11 @@ function formatTernaryOperator(path, options, print, operatorOptions) { // break if any of them break. That means we should only group around the // outer-most ConditionalExpression. const maybeGroup = doc => - operatorOpts.breakNested + operatorOptions.breakNested ? parent === firstNonConditionalParent ? group(doc) : doc - : group(doc); // Always group in normal mode. + : group(doc); // Break the closing paren to keep the chain right after it: // (a @@ -321,9 +334,9 @@ function formatTernaryOperator(path, options, print, operatorOptions) { return maybeGroup( concat( [].concat( - operatorOpts.beforeParts(), + operatorOptions.beforeParts(), forceNoIndent ? concat(parts) : indent(concat(parts)), - operatorOpts.afterParts(breakClosingParen) + operatorOptions.afterParts(breakClosingParen) ) ) ); @@ -1493,9 +1506,15 @@ function printPathNoParens(path, options, print, args) { return concat(parts); case "ConditionalExpression": - return formatTernaryOperator(path, options, print, { + return printTernaryOperator(path, options, print, { beforeParts: () => [path.call(print, "test")], - afterParts: breakClosingParen => [breakClosingParen ? softline : ""] + afterParts: breakClosingParen => [breakClosingParen ? softline : ""], + shouldCheckJsx: true, + conditionalNodeType: "ConditionalExpression", + consequentNodePropertyName: "consequent", + alternateNodePropertyName: "alternate", + testNodePropertyName: "test", + breakNested: true }); case "VariableDeclaration": { const printed = path.map(childPath => { @@ -3244,7 +3263,7 @@ function printPathNoParens(path, options, print, args) { return concat(["#", path.call(print, "id")]); case "TSConditionalType": - return formatTernaryOperator(path, options, print, { + return printTernaryOperator(path, options, print, { beforeParts: () => [ path.call(print, "checkType"), " ", @@ -3252,11 +3271,12 @@ function printPathNoParens(path, options, print, args) { " ", path.call(print, "extendsType") ], + afterParts: () => [], shouldCheckJsx: false, - operatorName: "TSConditionalType", - consequentNode: "trueType", - alternateNode: "falseType", - testNode: "checkType", + conditionalNodeType: "TSConditionalType", + consequentNodePropertyName: "trueType", + alternateNodePropertyName: "falseType", + testNodePropertyName: "checkType", breakNested: false }); diff --git a/tests/ternaries/__snapshots__/jsfmt.spec.js.snap b/tests/ternaries/__snapshots__/jsfmt.spec.js.snap index e215d0863..5f2cb1bdf 100644 --- a/tests/ternaries/__snapshots__/jsfmt.spec.js.snap +++ b/tests/ternaries/__snapshots__/jsfmt.spec.js.snap @@ -382,7 +382,7 @@ a ); } : function() { - + } ]; } @@ -392,10 +392,10 @@ a aaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb : ccccccccccccccc - ? ddddddddddddddd - : eeeeeeeeeeeeeee - ? fffffffffffffff - : gggggggggggggggg; + ? ddddddddddddddd + : eeeeeeeeeeeeeee + ? fffffffffffffff + : gggggggggggggggg; aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -704,7 +704,7 @@ a ); } : function() { - + } ]; } @@ -714,10 +714,10 @@ a aaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb : ccccccccccccccc - ? ddddddddddddddd - : eeeeeeeeeeeeeee - ? fffffffffffffff - : gggggggggggggggg; + ? ddddddddddddddd + : eeeeeeeeeeeeeee + ? fffffffffffffff + : gggggggggggggggg; aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -1026,7 +1026,7 @@ a ); } : function() { - + } ]; } @@ -1036,10 +1036,10 @@ a aaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb : ccccccccccccccc - ? ddddddddddddddd - : eeeeeeeeeeeeeee - ? fffffffffffffff - : gggggggggggggggg; + ? ddddddddddddddd + : eeeeeeeeeeeeeee + ? fffffffffffffff + : gggggggggggggggg; aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -1348,7 +1348,7 @@ a ); } : function() { - + } ]; } @@ -1358,10 +1358,10 @@ a aaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb : ccccccccccccccc - ? ddddddddddddddd - : eeeeeeeeeeeeeee - ? fffffffffffffff - : gggggggggggggggg; + ? ddddddddddddddd + : eeeeeeeeeeeeeee + ? fffffffffffffff + : gggggggggggggggg; aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -1516,48 +1516,716 @@ exports[`nested.js - flow-verify 1`] = ` let icecream = what == "cone" ? p => !!p ? \`here's your \${p} cone\` : \`just the empty cone for you\` : p => \`here's your \${p} \${what}\`; -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +const value = condition1 +? value1 +: condition2 + ? value2 + : condition3 + ? value3 + : value4; + + +const StorybookLoader = ({ match }) => ( + match.params.storyId === "button" + ? + : match.params.storyId === "color" + ? + : match.params.storyId === "typography" + ? + : match.params.storyId === "loading" + ? + : match.params.storyId === "deal-list" + ? + : ( + + {'Missing story book'} + + + + + ) +) + +const message = + i % 3 === 0 && i % 5 === 0 ? + 'fizzbuzz' + : i % 3 === 0 ? + 'fizz' + : i % 5 === 0 ? + 'buzz' + : + String(i) + +const paymentMessage = 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 paymentMessage = state == 'success' + ? 1 //'Payment completed successfully' + +: state == 'processing' + ? 2 //'Payment processing' + +: state == 'invalid_cvc' + ? 3 //'There was an issue with your CVC number' + +: true //state == 'invalid_expiry' + ? 4 //'Expiry must be sometime in the past.' + + : 5 // 'There was an issue with the payment. Please contact support.' + +const foo =
+ {medals[0].record ? ( + i18n('Record') + ) : medals[0].unique ? ( + i18n('Unique') + ) : medals[0].type === 0 ? ( + i18n('Silver') + ) : medals[0].type === 1 ? ( + i18n('Gold') + ) : medals[0].type === 2 ? ( + i18n('Platinum') + ) : ( + i18n('Theme') + )} +
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ let icecream = what == "cone" ? p => (!!p ? \`here's your \${p} cone\` : \`just the empty cone for you\`) : p => \`here's your \${p} \${what}\`; +const value = condition1 + ? value1 + : condition2 + ? value2 + : condition3 + ? value3 + : value4; + +const StorybookLoader = ({ match }) => + match.params.storyId === "button" ? ( + + ) : match.params.storyId === "color" ? ( + + ) : match.params.storyId === "typography" ? ( + + ) : match.params.storyId === "loading" ? ( + + ) : match.params.storyId === "deal-list" ? ( + + ) : ( + + {"Missing story book"} + + + + + ); + +const message = + i % 3 === 0 && i % 5 === 0 + ? "fizzbuzz" + : i % 3 === 0 + ? "fizz" + : i % 5 === 0 + ? "buzz" + : String(i); + +const paymentMessage = + 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 paymentMessage = + state == "success" + ? 1 //'Payment completed successfully' + : state == "processing" + ? 2 //'Payment processing' + : state == "invalid_cvc" + ? 3 //'There was an issue with your CVC number' + : true //state == 'invalid_expiry' + ? 4 //'Expiry must be sometime in the past.' + : 5; // 'There was an issue with the payment. Please contact support.' + +const foo = ( +
+ {medals[0].record + ? i18n("Record") + : medals[0].unique + ? i18n("Unique") + : medals[0].type === 0 + ? i18n("Silver") + : medals[0].type === 1 + ? i18n("Gold") + : medals[0].type === 2 + ? i18n("Platinum") + : i18n("Theme")} +
+); + `; exports[`nested.js - flow-verify 2`] = ` let icecream = what == "cone" ? p => !!p ? \`here's your \${p} cone\` : \`just the empty cone for you\` : p => \`here's your \${p} \${what}\`; -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +const value = condition1 +? value1 +: condition2 + ? value2 + : condition3 + ? value3 + : value4; + + +const StorybookLoader = ({ match }) => ( + match.params.storyId === "button" + ? + : match.params.storyId === "color" + ? + : match.params.storyId === "typography" + ? + : match.params.storyId === "loading" + ? + : match.params.storyId === "deal-list" + ? + : ( + + {'Missing story book'} + + + + + ) +) + +const message = + i % 3 === 0 && i % 5 === 0 ? + 'fizzbuzz' + : i % 3 === 0 ? + 'fizz' + : i % 5 === 0 ? + 'buzz' + : + String(i) + +const paymentMessage = 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 paymentMessage = state == 'success' + ? 1 //'Payment completed successfully' + +: state == 'processing' + ? 2 //'Payment processing' + +: state == 'invalid_cvc' + ? 3 //'There was an issue with your CVC number' + +: true //state == 'invalid_expiry' + ? 4 //'Expiry must be sometime in the past.' + + : 5 // 'There was an issue with the payment. Please contact support.' + +const foo =
+ {medals[0].record ? ( + i18n('Record') + ) : medals[0].unique ? ( + i18n('Unique') + ) : medals[0].type === 0 ? ( + i18n('Silver') + ) : medals[0].type === 1 ? ( + i18n('Gold') + ) : medals[0].type === 2 ? ( + i18n('Platinum') + ) : ( + i18n('Theme') + )} +
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ let icecream = what == "cone" ? p => (!!p ? \`here's your \${p} cone\` : \`just the empty cone for you\`) : p => \`here's your \${p} \${what}\`; +const value = condition1 + ? value1 + : condition2 + ? value2 + : condition3 + ? value3 + : value4; + +const StorybookLoader = ({ match }) => + match.params.storyId === "button" ? ( + + ) : match.params.storyId === "color" ? ( + + ) : match.params.storyId === "typography" ? ( + + ) : match.params.storyId === "loading" ? ( + + ) : match.params.storyId === "deal-list" ? ( + + ) : ( + + {"Missing story book"} + + + + + ); + +const message = + i % 3 === 0 && i % 5 === 0 + ? "fizzbuzz" + : i % 3 === 0 + ? "fizz" + : i % 5 === 0 + ? "buzz" + : String(i); + +const paymentMessage = + 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 paymentMessage = + state == "success" + ? 1 //'Payment completed successfully' + : state == "processing" + ? 2 //'Payment processing' + : state == "invalid_cvc" + ? 3 //'There was an issue with your CVC number' + : true //state == 'invalid_expiry' + ? 4 //'Expiry must be sometime in the past.' + : 5; // 'There was an issue with the payment. Please contact support.' + +const foo = ( +
+ {medals[0].record + ? i18n("Record") + : medals[0].unique + ? i18n("Unique") + : medals[0].type === 0 + ? i18n("Silver") + : medals[0].type === 1 + ? i18n("Gold") + : medals[0].type === 2 + ? i18n("Platinum") + : i18n("Theme")} +
+); + `; exports[`nested.js - flow-verify 3`] = ` let icecream = what == "cone" ? p => !!p ? \`here's your \${p} cone\` : \`just the empty cone for you\` : p => \`here's your \${p} \${what}\`; -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +const value = condition1 +? value1 +: condition2 + ? value2 + : condition3 + ? value3 + : value4; + + +const StorybookLoader = ({ match }) => ( + match.params.storyId === "button" + ? + : match.params.storyId === "color" + ? + : match.params.storyId === "typography" + ? + : match.params.storyId === "loading" + ? + : match.params.storyId === "deal-list" + ? + : ( + + {'Missing story book'} + + + + + ) +) + +const message = + i % 3 === 0 && i % 5 === 0 ? + 'fizzbuzz' + : i % 3 === 0 ? + 'fizz' + : i % 5 === 0 ? + 'buzz' + : + String(i) + +const paymentMessage = 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 paymentMessage = state == 'success' + ? 1 //'Payment completed successfully' + +: state == 'processing' + ? 2 //'Payment processing' + +: state == 'invalid_cvc' + ? 3 //'There was an issue with your CVC number' + +: true //state == 'invalid_expiry' + ? 4 //'Expiry must be sometime in the past.' + + : 5 // 'There was an issue with the payment. Please contact support.' + +const foo =
+ {medals[0].record ? ( + i18n('Record') + ) : medals[0].unique ? ( + i18n('Unique') + ) : medals[0].type === 0 ? ( + i18n('Silver') + ) : medals[0].type === 1 ? ( + i18n('Gold') + ) : medals[0].type === 2 ? ( + i18n('Platinum') + ) : ( + i18n('Theme') + )} +
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ let icecream = what == "cone" ? p => (!!p ? \`here's your \${p} cone\` : \`just the empty cone for you\`) : p => \`here's your \${p} \${what}\`; +const value = condition1 + ? value1 + : condition2 + ? value2 + : condition3 + ? value3 + : value4; + +const StorybookLoader = ({ match }) => + match.params.storyId === "button" ? ( + + ) : match.params.storyId === "color" ? ( + + ) : match.params.storyId === "typography" ? ( + + ) : match.params.storyId === "loading" ? ( + + ) : match.params.storyId === "deal-list" ? ( + + ) : ( + + {"Missing story book"} + + + + + ); + +const message = + i % 3 === 0 && i % 5 === 0 + ? "fizzbuzz" + : i % 3 === 0 + ? "fizz" + : i % 5 === 0 + ? "buzz" + : String(i); + +const paymentMessage = + 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 paymentMessage = + state == "success" + ? 1 //'Payment completed successfully' + : state == "processing" + ? 2 //'Payment processing' + : state == "invalid_cvc" + ? 3 //'There was an issue with your CVC number' + : true //state == 'invalid_expiry' + ? 4 //'Expiry must be sometime in the past.' + : 5; // 'There was an issue with the payment. Please contact support.' + +const foo = ( +
+ {medals[0].record + ? i18n("Record") + : medals[0].unique + ? i18n("Unique") + : medals[0].type === 0 + ? i18n("Silver") + : medals[0].type === 1 + ? i18n("Gold") + : medals[0].type === 2 + ? i18n("Platinum") + : i18n("Theme")} +
+); + `; exports[`nested.js - flow-verify 4`] = ` let icecream = what == "cone" ? p => !!p ? \`here's your \${p} cone\` : \`just the empty cone for you\` : p => \`here's your \${p} \${what}\`; -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +const value = condition1 +? value1 +: condition2 + ? value2 + : condition3 + ? value3 + : value4; + + +const StorybookLoader = ({ match }) => ( + match.params.storyId === "button" + ? + : match.params.storyId === "color" + ? + : match.params.storyId === "typography" + ? + : match.params.storyId === "loading" + ? + : match.params.storyId === "deal-list" + ? + : ( + + {'Missing story book'} + + + + + ) +) + +const message = + i % 3 === 0 && i % 5 === 0 ? + 'fizzbuzz' + : i % 3 === 0 ? + 'fizz' + : i % 5 === 0 ? + 'buzz' + : + String(i) + +const paymentMessage = 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 paymentMessage = state == 'success' + ? 1 //'Payment completed successfully' + +: state == 'processing' + ? 2 //'Payment processing' + +: state == 'invalid_cvc' + ? 3 //'There was an issue with your CVC number' + +: true //state == 'invalid_expiry' + ? 4 //'Expiry must be sometime in the past.' + + : 5 // 'There was an issue with the payment. Please contact support.' + +const foo =
+ {medals[0].record ? ( + i18n('Record') + ) : medals[0].unique ? ( + i18n('Unique') + ) : medals[0].type === 0 ? ( + i18n('Silver') + ) : medals[0].type === 1 ? ( + i18n('Gold') + ) : medals[0].type === 2 ? ( + i18n('Platinum') + ) : ( + i18n('Theme') + )} +
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ let icecream = what == "cone" ? p => (!!p ? \`here's your \${p} cone\` : \`just the empty cone for you\`) : p => \`here's your \${p} \${what}\`; +const value = condition1 + ? value1 + : condition2 + ? value2 + : condition3 + ? value3 + : value4; + +const StorybookLoader = ({ match }) => + match.params.storyId === "button" ? ( + + ) : match.params.storyId === "color" ? ( + + ) : match.params.storyId === "typography" ? ( + + ) : match.params.storyId === "loading" ? ( + + ) : match.params.storyId === "deal-list" ? ( + + ) : ( + + {"Missing story book"} + + + + + ); + +const message = + i % 3 === 0 && i % 5 === 0 + ? "fizzbuzz" + : i % 3 === 0 + ? "fizz" + : i % 5 === 0 + ? "buzz" + : String(i); + +const paymentMessage = + 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 paymentMessage = + state == "success" + ? 1 //'Payment completed successfully' + : state == "processing" + ? 2 //'Payment processing' + : state == "invalid_cvc" + ? 3 //'There was an issue with your CVC number' + : true //state == 'invalid_expiry' + ? 4 //'Expiry must be sometime in the past.' + : 5; // 'There was an issue with the payment. Please contact support.' + +const foo = ( +
+ {medals[0].record + ? i18n("Record") + : medals[0].unique + ? i18n("Unique") + : medals[0].type === 0 + ? i18n("Silver") + : medals[0].type === 1 + ? i18n("Gold") + : medals[0].type === 2 + ? i18n("Platinum") + : i18n("Theme")} +
+); + `; exports[`parenthesis.js - flow-verify 1`] = ` diff --git a/tests/ternaries/indent.js b/tests/ternaries/indent.js index e2ace47af..80f625eb7 100644 --- a/tests/ternaries/indent.js +++ b/tests/ternaries/indent.js @@ -159,7 +159,7 @@ a ); } : function() { - + } ]; } diff --git a/tests/ternaries/nested.js b/tests/ternaries/nested.js index a00fda82c..df6d12c2e 100644 --- a/tests/ternaries/nested.js +++ b/tests/ternaries/nested.js @@ -1,3 +1,87 @@ let icecream = what == "cone" ? p => !!p ? `here's your ${p} cone` : `just the empty cone for you` : p => `here's your ${p} ${what}`; + +const value = condition1 +? value1 +: condition2 + ? value2 + : condition3 + ? value3 + : value4; + + +const StorybookLoader = ({ match }) => ( + match.params.storyId === "button" + ? + : match.params.storyId === "color" + ? + : match.params.storyId === "typography" + ? + : match.params.storyId === "loading" + ? + : match.params.storyId === "deal-list" + ? + : ( + + {'Missing story book'} + + + + + ) +) + +const message = + i % 3 === 0 && i % 5 === 0 ? + 'fizzbuzz' + : i % 3 === 0 ? + 'fizz' + : i % 5 === 0 ? + 'buzz' + : + String(i) + +const paymentMessage = 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 paymentMessage = state == 'success' + ? 1 //'Payment completed successfully' + +: state == 'processing' + ? 2 //'Payment processing' + +: state == 'invalid_cvc' + ? 3 //'There was an issue with your CVC number' + +: true //state == 'invalid_expiry' + ? 4 //'Expiry must be sometime in the past.' + + : 5 // 'There was an issue with the payment. Please contact support.' + +const foo =
+ {medals[0].record ? ( + i18n('Record') + ) : medals[0].unique ? ( + i18n('Unique') + ) : medals[0].type === 0 ? ( + i18n('Silver') + ) : medals[0].type === 1 ? ( + i18n('Gold') + ) : medals[0].type === 2 ? ( + i18n('Platinum') + ) : ( + i18n('Theme') + )} +
\ No newline at end of file diff --git a/tests/throw_expressions/__snapshots__/jsfmt.spec.js.snap b/tests/throw_expressions/__snapshots__/jsfmt.spec.js.snap index 1bf8bdce3..12e80c2c5 100644 --- a/tests/throw_expressions/__snapshots__/jsfmt.spec.js.snap +++ b/tests/throw_expressions/__snapshots__/jsfmt.spec.js.snap @@ -30,10 +30,10 @@ function getEncoder(encoding) { encoding === "utf8" ? new UTF8Encoder() : encoding === "utf16le" - ? new UTF16Encoder(false) - : encoding === "utf16be" - ? new UTF16Encoder(true) - : throw new Error("Unsupported encoding"); + ? new UTF16Encoder(false) + : encoding === "utf16be" + ? new UTF16Encoder(true) + : throw new Error("Unsupported encoding"); } class Product { diff --git a/tests/typescript_conditional_types/__snapshots__/jsfmt.spec.js.snap b/tests/typescript_conditional_types/__snapshots__/jsfmt.spec.js.snap index 65e2efd47..3048eb774 100644 --- a/tests/typescript_conditional_types/__snapshots__/jsfmt.spec.js.snap +++ b/tests/typescript_conditional_types/__snapshots__/jsfmt.spec.js.snap @@ -10,6 +10,14 @@ interface DeepReadonlyArray extends ReadonlyArray> {} type DeepReadonlyObject = { readonly [P in NonFunctionPropertyNames]: DeepReadonly; }; + +type TypeName = + T extends string ? "string" : + T extends number ? "number" : + T extends boolean ? "boolean" : + T extends undefined ? "undefined" : + T extends Function ? "function" : + "object"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ export type DeepReadonly = T extends any[] ? DeepReadonlyArray @@ -25,6 +33,16 @@ type DeepReadonlyObject = { readonly [P in NonFunctionPropertyNames]: DeepReadonly }; +type TypeName = T extends string + ? "string" + : T extends number + ? "number" + : T extends boolean + ? "boolean" + : T extends undefined + ? "undefined" + : T extends Function ? "function" : "object"; + `; exports[`infer-type.ts - typescript-verify 1`] = ` diff --git a/tests/typescript_conditional_types/conditonal-types.ts b/tests/typescript_conditional_types/conditonal-types.ts index af1847f7e..f1cfd069b 100644 --- a/tests/typescript_conditional_types/conditonal-types.ts +++ b/tests/typescript_conditional_types/conditonal-types.ts @@ -7,3 +7,11 @@ interface DeepReadonlyArray extends ReadonlyArray> {} type DeepReadonlyObject = { readonly [P in NonFunctionPropertyNames]: DeepReadonly; }; + +type TypeName = + T extends string ? "string" : + T extends number ? "number" : + T extends boolean ? "boolean" : + T extends undefined ? "undefined" : + T extends Function ? "function" : + "object";