diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index 512bf092..efefa677 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -1082,6 +1082,62 @@ sometimes{{nogaps}}areimportant {{name}} is your name ``` +#### JavaScript: Break arrays of arrays/objects if each element has more than one element/property ([#6694] by [@sosukesuzuki]) + + +```js +// Input +test.each([ + { a: "1", b: 1 }, + { a: "2", b: 2 }, + { a: "3", b: 3 } +])("test", ({ a, b }) => { + expect(Number(a)).toBe(b); +}); +[[0, 1, 2], [0, 1, 2]]; +new Map([ + [A, B], + [C, D], + [E, F], + [G, H], + [I, J], + [K, L], + [M, N] +]); + +// Output (Prettier stable) +test.each([{ a: "1", b: 1 }, { a: "2", b: 2 }, { a: "3", b: 3 }])( + "test", + ({ a, b }) => { + expect(Number(a)).toBe(b); + } +); +[[0, 1, 2], [0, 1, 2]] +new Map([[A, B], [C, D], [E, F], [G, H], [I, J], [K, L], [M, N]]); + +// Output (Prettier master) +test.each([ + { a: "1", b: 1 }, + { a: "2", b: 2 }, + { a: "3", b: 3 } +])("test", ({ a, b }) => { + expect(Number(a)).toBe(b); +}); +[ + [0, 1, 2], + [0, 1, 2] +]; +new Map([ + [A, B], + [C, D], + [E, F], + [G, H], + [I, J], + [K, L], + [M, N] +]); +``` + [#5682]: https://github.com/prettier/prettier/pull/5682 [#5910]: https://github.com/prettier/prettier/pull/5910 [#6033]: https://github.com/prettier/prettier/pull/6033 @@ -1121,6 +1177,7 @@ sometimes{{nogaps}}areimportant [#6646]: https://github.com/prettier/prettier/pull/6646 [#6666]: https://github.com/prettier/prettier/pull/6666 [#6673]: https://github.com/prettier/prettier/pull/6673 +[#6694]: https://github.com/prettier/prettier/pull/6694 [@brainkim]: https://github.com/brainkim [@duailibe]: https://github.com/duailibe [@gavinjoyce]: https://github.com/gavinjoyce diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index 0298477e..0696c55c 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -1514,6 +1514,28 @@ function printPathNoParens(path, options, print, args) { const needsForcedTrailingComma = canHaveTrailingComma && lastElem === null; + const shouldBreak = + n.elements.length > 1 && + n.elements.every((element, i, elements) => { + const elementType = element && element.type; + if ( + elementType !== "ArrayExpression" && + elementType !== "ObjectExpression" + ) { + return false; + } + + const nextElement = elements[i + 1]; + if (nextElement && elementType !== nextElement.type) { + return false; + } + + const itemsKey = + elementType === "ArrayExpression" ? "elements" : "properties"; + + return element[itemsKey] && element[itemsKey].length > 1; + }); + parts.push( group( concat([ @@ -1539,7 +1561,8 @@ function printPathNoParens(path, options, print, args) { ), softline, "]" - ]) + ]), + { shouldBreak } ) ); } diff --git a/tests/arrays/__snapshots__/jsfmt.spec.js.snap b/tests/arrays/__snapshots__/jsfmt.spec.js.snap index 7fb3665b..235a17c3 100644 --- a/tests/arrays/__snapshots__/jsfmt.spec.js.snap +++ b/tests/arrays/__snapshots__/jsfmt.spec.js.snap @@ -38,6 +38,116 @@ printWidth: 80 ================================================================================ `; +exports[`nested.js 1`] = ` +====================================options===================================== +parsers: ["flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +[[]]; +[[], []]; +[[], [], []]; +[[], [0], []]; +[[], [0], [0]]; +[[], [0, 1], [0]]; +[[], [0, 1], [0, 1]]; +[[0]]; +[[0], []]; +[[0], [], []]; +[[0], [0], []]; +[[0], [0], [0]]; +[[0], [0, 1], [0]]; +[[0], [0, 1], [0, 1]]; +[[0, 1]]; +[[0, 1], []]; +[[0, 1], [], []]; +[[0, 1], [0], []]; +[[0, 1], [0], [0]]; +[[0, 1], [0, 1], [0]]; +[[0, 1], [0, 1], [0, 1]]; +[[], [1, 2, 3]]; +[[1], [1]]; +[[1, 2], [1, 2, 3]]; +[[1, 0], [1, 0]]; +[{}]; +[{}, {}]; +[{}, {}, {}]; +[{}, { a }]; +[{}, { a, b }]; +[{}, { a, b, c }]; +[{ a }]; +[{ a }, { a }]; +[{ a }, { a }, { a }]; +[{ a }, { a, b }]; +[{ a }, { a, b, c}]; +[{ a, b }]; +[{ a, b }, { a }]; +[{ a, b }, { a }, { a }]; +[{ a, b }, { a, b }]; +[{ a, b }, { a, b, c }]; + +=====================================output===================================== +[[]]; +[[], []]; +[[], [], []]; +[[], [0], []]; +[[], [0], [0]]; +[[], [0, 1], [0]]; +[[], [0, 1], [0, 1]]; +[[0]]; +[[0], []]; +[[0], [], []]; +[[0], [0], []]; +[[0], [0], [0]]; +[[0], [0, 1], [0]]; +[[0], [0, 1], [0, 1]]; +[[0, 1]]; +[[0, 1], []]; +[[0, 1], [], []]; +[[0, 1], [0], []]; +[[0, 1], [0], [0]]; +[[0, 1], [0, 1], [0]]; +[ + [0, 1], + [0, 1], + [0, 1] +]; +[[], [1, 2, 3]]; +[[1], [1]]; +[ + [1, 2], + [1, 2, 3] +]; +[ + [1, 0], + [1, 0] +]; +[{}]; +[{}, {}]; +[{}, {}, {}]; +[{}, { a }]; +[{}, { a, b }]; +[{}, { a, b, c }]; +[{ a }]; +[{ a }, { a }]; +[{ a }, { a }, { a }]; +[{ a }, { a, b }]; +[{ a }, { a, b, c }]; +[{ a, b }]; +[{ a, b }, { a }]; +[{ a, b }, { a }, { a }]; +[ + { a, b }, + { a, b } +]; +[ + { a, b }, + { a, b, c } +]; + +================================================================================ +`; + exports[`preserve_empty_lines.js 1`] = ` ====================================options===================================== parsers: ["flow", "typescript"] diff --git a/tests/arrays/nested.js b/tests/arrays/nested.js new file mode 100644 index 00000000..32db0a5e --- /dev/null +++ b/tests/arrays/nested.js @@ -0,0 +1,41 @@ +[[]]; +[[], []]; +[[], [], []]; +[[], [0], []]; +[[], [0], [0]]; +[[], [0, 1], [0]]; +[[], [0, 1], [0, 1]]; +[[0]]; +[[0], []]; +[[0], [], []]; +[[0], [0], []]; +[[0], [0], [0]]; +[[0], [0, 1], [0]]; +[[0], [0, 1], [0, 1]]; +[[0, 1]]; +[[0, 1], []]; +[[0, 1], [], []]; +[[0, 1], [0], []]; +[[0, 1], [0], [0]]; +[[0, 1], [0, 1], [0]]; +[[0, 1], [0, 1], [0, 1]]; +[[], [1, 2, 3]]; +[[1], [1]]; +[[1, 2], [1, 2, 3]]; +[[1, 0], [1, 0]]; +[{}]; +[{}, {}]; +[{}, {}, {}]; +[{}, { a }]; +[{}, { a, b }]; +[{}, { a, b, c }]; +[{ a }]; +[{ a }, { a }]; +[{ a }, { a }, { a }]; +[{ a }, { a, b }]; +[{ a }, { a, b, c}]; +[{ a, b }]; +[{ a, b }, { a }]; +[{ a, b }, { a }, { a }]; +[{ a, b }, { a, b }]; +[{ a, b }, { a, b, c }]; diff --git a/tests/flow/annot/__snapshots__/jsfmt.spec.js.snap b/tests/flow/annot/__snapshots__/jsfmt.spec.js.snap index 096fcfc9..2e12dbe0 100644 --- a/tests/flow/annot/__snapshots__/jsfmt.spec.js.snap +++ b/tests/flow/annot/__snapshots__/jsfmt.spec.js.snap @@ -88,7 +88,10 @@ var arr: Array = [1, 2, "..."]; // array sugar var array: number[] = [1, 2, "..."]; -var matrix: number[][] = [[1, 2], [3, 4]]; +var matrix: number[][] = [ + [1, 2], + [3, 4] +]; var matrix_parens: number[][] = matrix; var nullable_array: ?(number[]) = null; @@ -96,7 +99,10 @@ var nullable_array_parens: ?(number[]) = nullable_array; var array_of_nullable: (?number)[] = [null, 3]; -var array_of_tuple: [number, string][] = [[0, "foo"], [1, "bar"]]; +var array_of_tuple: [number, string][] = [ + [0, "foo"], + [1, "bar"] +]; var array_of_tuple_parens: [number, string][] = array_of_tuple; type ObjType = { "bar-foo": string, "foo-bar": number }; diff --git a/tests/flow/arraylib/__snapshots__/jsfmt.spec.js.snap b/tests/flow/arraylib/__snapshots__/jsfmt.spec.js.snap index 2bcae6ab..616a5cba 100644 --- a/tests/flow/arraylib/__snapshots__/jsfmt.spec.js.snap +++ b/tests/flow/arraylib/__snapshots__/jsfmt.spec.js.snap @@ -108,7 +108,11 @@ function reduce_test() { return a + b; }); - var flattened = [[0, 1], [2, 3], [4, 5]].reduce(function(a, b) { + var flattened = [ + [0, 1], + [2, 3], + [4, 5] + ].reduce(function(a, b) { return a.concat(b); }); diff --git a/tests/test_declarations/__snapshots__/jsfmt.spec.js.snap b/tests/test_declarations/__snapshots__/jsfmt.spec.js.snap index ebdf1fe3..2c99cc49 100644 --- a/tests/test_declarations/__snapshots__/jsfmt.spec.js.snap +++ b/tests/test_declarations/__snapshots__/jsfmt.spec.js.snap @@ -481,6 +481,25 @@ describe.each\`a | b | expected \${1} | \${2} | \${3} \${2} | \${1} | \${3}\` +describe.each([1, 2, 3])("test", a => { + expect(a).toBe(a); +}); + +test.only.each([[1, 1, 2], [1, 2, 3], [2, 1, 3]])( + ".add(%i, %i)", (a, b, expected) => { + expect(a + b).toBe(expected); + } +); + +test.each([ + { a: "1", b: 1 }, + { a: "2", b: 2 }, + { a: "3", b: 3 }, +])("test", ({ a, b }) => { + expect(Number(a)).toBe(b); + } +); + =====================================output===================================== describe.each\` a | b | expected @@ -533,6 +552,26 @@ describe.each\` \${2} | \${1} | \${3} \`; +describe.each([1, 2, 3])("test", a => { + expect(a).toBe(a); +}); + +test.only.each([ + [1, 1, 2], + [1, 2, 3], + [2, 1, 3] +])(".add(%i, %i)", (a, b, expected) => { + expect(a + b).toBe(expected); +}); + +test.each([ + { a: "1", b: 1 }, + { a: "2", b: 2 }, + { a: "3", b: 3 } +])("test", ({ a, b }) => { + expect(Number(a)).toBe(b); +}); + ================================================================================ `; @@ -587,6 +626,25 @@ describe.each\`a | b | expected \${1} | \${2} | \${3} \${2} | \${1} | \${3}\` +describe.each([1, 2, 3])("test", a => { + expect(a).toBe(a); +}); + +test.only.each([[1, 1, 2], [1, 2, 3], [2, 1, 3]])( + ".add(%i, %i)", (a, b, expected) => { + expect(a + b).toBe(expected); + } +); + +test.each([ + { a: "1", b: 1 }, + { a: "2", b: 2 }, + { a: "3", b: 3 }, +])("test", ({ a, b }) => { + expect(Number(a)).toBe(b); + } +); + =====================================output===================================== describe.each\` a | b | expected @@ -639,6 +697,26 @@ describe.each\` \${2} | \${1} | \${3} \`; +describe.each([1, 2, 3])("test", (a) => { + expect(a).toBe(a); +}); + +test.only.each([ + [1, 1, 2], + [1, 2, 3], + [2, 1, 3] +])(".add(%i, %i)", (a, b, expected) => { + expect(a + b).toBe(expected); +}); + +test.each([ + { a: "1", b: 1 }, + { a: "2", b: 2 }, + { a: "3", b: 3 } +])("test", ({ a, b }) => { + expect(Number(a)).toBe(b); +}); + ================================================================================ `; diff --git a/tests/test_declarations/jest-each.js b/tests/test_declarations/jest-each.js index 53933973..8bcdf7fb 100644 --- a/tests/test_declarations/jest-each.js +++ b/tests/test_declarations/jest-each.js @@ -41,3 +41,22 @@ describe.each`a | b | expected ${11111111111} | ${a().b().c().d()} | ${2} ${1} | ${2} | ${3} ${2} | ${1} | ${3}` + +describe.each([1, 2, 3])("test", a => { + expect(a).toBe(a); +}); + +test.only.each([[1, 1, 2], [1, 2, 3], [2, 1, 3]])( + ".add(%i, %i)", (a, b, expected) => { + expect(a + b).toBe(expected); + } +); + +test.each([ + { a: "1", b: 1 }, + { a: "2", b: 2 }, + { a: "3", b: 3 }, +])("test", ({ a, b }) => { + expect(Number(a)).toBe(b); + } +);