feat(javascript): support jest-each template string (#4423)
* feat(javascript): support jest-each * test: add trailing newline * fix: there can be no trailing newline * refactor: simplify regex * refactor: Array.from * refactor * fix: print quasis safelymaster
parent
5776c8405a
commit
7e81a613b5
|
@ -30,6 +30,7 @@ const breakParent = docBuilders.breakParent;
|
||||||
const lineSuffixBoundary = docBuilders.lineSuffixBoundary;
|
const lineSuffixBoundary = docBuilders.lineSuffixBoundary;
|
||||||
const addAlignmentToDoc = docBuilders.addAlignmentToDoc;
|
const addAlignmentToDoc = docBuilders.addAlignmentToDoc;
|
||||||
const dedent = docBuilders.dedent;
|
const dedent = docBuilders.dedent;
|
||||||
|
const printDocToString = doc.printer.printDocToString;
|
||||||
|
|
||||||
const docUtils = doc.utils;
|
const docUtils = doc.utils;
|
||||||
const willBreak = docUtils.willBreak;
|
const willBreak = docUtils.willBreak;
|
||||||
|
@ -2054,6 +2055,122 @@ function printPathNoParens(path, options, print, args) {
|
||||||
return join(literalline, n.value.raw.split(/\r?\n/g));
|
return join(literalline, n.value.raw.split(/\r?\n/g));
|
||||||
case "TemplateLiteral": {
|
case "TemplateLiteral": {
|
||||||
const expressions = path.map(print, "expressions");
|
const expressions = path.map(print, "expressions");
|
||||||
|
const parentNode = path.getParentNode();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* describe.each`table`(name, fn)
|
||||||
|
* describe.only.each`table`(name, fn)
|
||||||
|
* describe.skip.each`table`(name, fn)
|
||||||
|
* test.each`table`(name, fn)
|
||||||
|
* test.only.each`table`(name, fn)
|
||||||
|
* test.skip.each`table`(name, fn)
|
||||||
|
*
|
||||||
|
* Ref: https://github.com/facebook/jest/pull/6102
|
||||||
|
*/
|
||||||
|
const jestEachTriggerRegex = /^[xf]?(describe|it|test)$/;
|
||||||
|
if (
|
||||||
|
parentNode.type === "TaggedTemplateExpression" &&
|
||||||
|
parentNode.quasi === n &&
|
||||||
|
parentNode.tag.type === "MemberExpression" &&
|
||||||
|
parentNode.tag.property.type === "Identifier" &&
|
||||||
|
parentNode.tag.property.name === "each" &&
|
||||||
|
((parentNode.tag.object.type === "Identifier" &&
|
||||||
|
jestEachTriggerRegex.test(parentNode.tag.object.name)) ||
|
||||||
|
(parentNode.tag.object.type === "MemberExpression" &&
|
||||||
|
parentNode.tag.object.property.type === "Identifier" &&
|
||||||
|
(parentNode.tag.object.property.name === "only" ||
|
||||||
|
parentNode.tag.object.property.name === "skip") &&
|
||||||
|
parentNode.tag.object.object.type === "Identifier" &&
|
||||||
|
jestEachTriggerRegex.test(parentNode.tag.object.object.name)))
|
||||||
|
) {
|
||||||
|
/**
|
||||||
|
* a | b | expected
|
||||||
|
* ${1} | ${1} | ${2}
|
||||||
|
* ${1} | ${2} | ${3}
|
||||||
|
* ${2} | ${1} | ${3}
|
||||||
|
*/
|
||||||
|
const headerNames = n.quasis[0].value.raw.trim().split(/\s*\|\s*/);
|
||||||
|
if (
|
||||||
|
headerNames.length > 1 ||
|
||||||
|
headerNames.some(headerName => headerName.length !== 0)
|
||||||
|
) {
|
||||||
|
const stringifiedExpressions = expressions.map(
|
||||||
|
doc =>
|
||||||
|
"${" +
|
||||||
|
printDocToString(
|
||||||
|
doc,
|
||||||
|
Object.assign({}, options, { printWidth: Infinity })
|
||||||
|
).formatted +
|
||||||
|
"}"
|
||||||
|
);
|
||||||
|
|
||||||
|
const tableBody = [{ hasLineBreak: false, cells: [] }];
|
||||||
|
for (let i = 1; i < n.quasis.length; i++) {
|
||||||
|
const row = tableBody[tableBody.length - 1];
|
||||||
|
const correspondingExpression = stringifiedExpressions[i - 1];
|
||||||
|
|
||||||
|
row.cells.push(correspondingExpression);
|
||||||
|
if (correspondingExpression.indexOf("\n") !== -1) {
|
||||||
|
row.hasLineBreak = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n.quasis[i].value.raw.indexOf("\n") !== -1) {
|
||||||
|
tableBody.push({ hasLineBreak: false, cells: [] });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const maxColumnCount = tableBody.reduce(
|
||||||
|
(maxColumnCount, row) => Math.max(maxColumnCount, row.cells.length),
|
||||||
|
headerNames.length
|
||||||
|
);
|
||||||
|
|
||||||
|
const maxColumnWidths = Array.from(
|
||||||
|
new Array(maxColumnCount),
|
||||||
|
() => 0
|
||||||
|
);
|
||||||
|
const table = [{ cells: headerNames }].concat(
|
||||||
|
tableBody.filter(row => row.cells.length !== 0)
|
||||||
|
);
|
||||||
|
table.filter(row => !row.hasLineBreak).forEach(row => {
|
||||||
|
row.cells.forEach((cell, index) => {
|
||||||
|
maxColumnWidths[index] = Math.max(
|
||||||
|
maxColumnWidths[index],
|
||||||
|
privateUtil.getStringWidth(cell)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
parts.push(
|
||||||
|
"`",
|
||||||
|
indent(
|
||||||
|
concat([
|
||||||
|
hardline,
|
||||||
|
join(
|
||||||
|
hardline,
|
||||||
|
table.map(row =>
|
||||||
|
join(
|
||||||
|
" | ",
|
||||||
|
row.cells.map(
|
||||||
|
(cell, index) =>
|
||||||
|
row.hasLineBreak
|
||||||
|
? cell
|
||||||
|
: cell +
|
||||||
|
" ".repeat(
|
||||||
|
maxColumnWidths[index] -
|
||||||
|
privateUtil.getStringWidth(cell)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
])
|
||||||
|
),
|
||||||
|
hardline,
|
||||||
|
"`"
|
||||||
|
);
|
||||||
|
return concat(parts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
parts.push("`");
|
parts.push("`");
|
||||||
|
|
||||||
|
|
|
@ -102,6 +102,202 @@ function x() {
|
||||||
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`jest-each.js 1`] = `
|
||||||
|
describe.each\`
|
||||||
|
a|b|expected
|
||||||
|
\${11 } | \${ 1 }|\${222}
|
||||||
|
\${1-1}|\${2+2}|\${ 3333}
|
||||||
|
\${2+1+2}|\${1111}|\${3}
|
||||||
|
\`('$a + $b', ({a, b, expected}) => {
|
||||||
|
test(\`returns \${expected}\`, () => {
|
||||||
|
expect(a + b).toBe(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(\`returned value not be greater than \${expected}\`, () => {
|
||||||
|
expect(a + b).not.toBeGreaterThan(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(\`returned value not be less than \${expected}\`, () => {
|
||||||
|
expect(a + b).not.toBeLessThan(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe.only.each\`
|
||||||
|
a|b|expected
|
||||||
|
\${11 } | \${ 1 }|\${222}|\${'unknown column 1'}|\${'unknown column 2'}
|
||||||
|
\${1-1}|\${2+2}|\${ 3333}
|
||||||
|
\${2+1+2}|\${1111}|\${3} |\${'unknown column xyz'}
|
||||||
|
\`
|
||||||
|
|
||||||
|
describe.only.each\`
|
||||||
|
||
|
||||||
|
\${11 } | \${ 1 }|\${222}|\${'unknown column 1'}|\${'unknown column 2'}
|
||||||
|
\${1-1}|\${2+2}|\${ 3333}
|
||||||
|
\${2+1+2}|\${1111}|\${3} |\${'unknown column xyz'}
|
||||||
|
\`
|
||||||
|
|
||||||
|
describe.each\`a | b | expected
|
||||||
|
\${1} | \${1} | \${2}
|
||||||
|
\${1} | \${2} | \${3}
|
||||||
|
\${2} | \${1} | \${3}\`
|
||||||
|
|
||||||
|
// an example to demo multiline quasi
|
||||||
|
describe.each\`a | b | expected
|
||||||
|
\${11111111111} | \${a().b().c().d()} | \${2}
|
||||||
|
\${1} | \${2} | \${3}
|
||||||
|
\${2} | \${1} | \${3}\`
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
describe.each\`
|
||||||
|
a | b | expected
|
||||||
|
\${11} | \${1} | \${222}
|
||||||
|
\${1 - 1} | \${2 + 2} | \${3333}
|
||||||
|
\${2 + 1 + 2} | \${1111} | \${3}
|
||||||
|
\`("$a + $b", ({ a, b, expected }) => {
|
||||||
|
test(\`returns \${expected}\`, () => {
|
||||||
|
expect(a + b).toBe(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(\`returned value not be greater than \${expected}\`, () => {
|
||||||
|
expect(a + b).not.toBeGreaterThan(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(\`returned value not be less than \${expected}\`, () => {
|
||||||
|
expect(a + b).not.toBeLessThan(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe.only.each\`
|
||||||
|
a | b | expected
|
||||||
|
\${11} | \${1} | \${222} | \${"unknown column 1"} | \${"unknown column 2"}
|
||||||
|
\${1 - 1} | \${2 + 2} | \${3333}
|
||||||
|
\${2 + 1 + 2} | \${1111} | \${3} | \${"unknown column xyz"}
|
||||||
|
\`;
|
||||||
|
|
||||||
|
describe.only.each\`
|
||||||
|
| |
|
||||||
|
\${11} | \${1} | \${222} | \${"unknown column 1"} | \${"unknown column 2"}
|
||||||
|
\${1 - 1} | \${2 + 2} | \${3333}
|
||||||
|
\${2 + 1 + 2} | \${1111} | \${3} | \${"unknown column xyz"}
|
||||||
|
\`;
|
||||||
|
|
||||||
|
describe.each\`
|
||||||
|
a | b | expected
|
||||||
|
\${1} | \${1} | \${2}
|
||||||
|
\${1} | \${2} | \${3}
|
||||||
|
\${2} | \${1} | \${3}
|
||||||
|
\`;
|
||||||
|
|
||||||
|
// an example to demo multiline quasi
|
||||||
|
describe.each\`
|
||||||
|
a | b | expected
|
||||||
|
\${11111111111} | \${a()
|
||||||
|
.b()
|
||||||
|
.c()
|
||||||
|
.d()} | \${2}
|
||||||
|
\${1} | \${2} | \${3}
|
||||||
|
\${2} | \${1} | \${3}
|
||||||
|
\`;
|
||||||
|
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`jest-each.js 2`] = `
|
||||||
|
describe.each\`
|
||||||
|
a|b|expected
|
||||||
|
\${11 } | \${ 1 }|\${222}
|
||||||
|
\${1-1}|\${2+2}|\${ 3333}
|
||||||
|
\${2+1+2}|\${1111}|\${3}
|
||||||
|
\`('$a + $b', ({a, b, expected}) => {
|
||||||
|
test(\`returns \${expected}\`, () => {
|
||||||
|
expect(a + b).toBe(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(\`returned value not be greater than \${expected}\`, () => {
|
||||||
|
expect(a + b).not.toBeGreaterThan(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(\`returned value not be less than \${expected}\`, () => {
|
||||||
|
expect(a + b).not.toBeLessThan(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe.only.each\`
|
||||||
|
a|b|expected
|
||||||
|
\${11 } | \${ 1 }|\${222}|\${'unknown column 1'}|\${'unknown column 2'}
|
||||||
|
\${1-1}|\${2+2}|\${ 3333}
|
||||||
|
\${2+1+2}|\${1111}|\${3} |\${'unknown column xyz'}
|
||||||
|
\`
|
||||||
|
|
||||||
|
describe.only.each\`
|
||||||
|
||
|
||||||
|
\${11 } | \${ 1 }|\${222}|\${'unknown column 1'}|\${'unknown column 2'}
|
||||||
|
\${1-1}|\${2+2}|\${ 3333}
|
||||||
|
\${2+1+2}|\${1111}|\${3} |\${'unknown column xyz'}
|
||||||
|
\`
|
||||||
|
|
||||||
|
describe.each\`a | b | expected
|
||||||
|
\${1} | \${1} | \${2}
|
||||||
|
\${1} | \${2} | \${3}
|
||||||
|
\${2} | \${1} | \${3}\`
|
||||||
|
|
||||||
|
// an example to demo multiline quasi
|
||||||
|
describe.each\`a | b | expected
|
||||||
|
\${11111111111} | \${a().b().c().d()} | \${2}
|
||||||
|
\${1} | \${2} | \${3}
|
||||||
|
\${2} | \${1} | \${3}\`
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
describe.each\`
|
||||||
|
a | b | expected
|
||||||
|
\${11} | \${1} | \${222}
|
||||||
|
\${1 - 1} | \${2 + 2} | \${3333}
|
||||||
|
\${2 + 1 + 2} | \${1111} | \${3}
|
||||||
|
\`("$a + $b", ({ a, b, expected }) => {
|
||||||
|
test(\`returns \${expected}\`, () => {
|
||||||
|
expect(a + b).toBe(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(\`returned value not be greater than \${expected}\`, () => {
|
||||||
|
expect(a + b).not.toBeGreaterThan(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(\`returned value not be less than \${expected}\`, () => {
|
||||||
|
expect(a + b).not.toBeLessThan(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe.only.each\`
|
||||||
|
a | b | expected
|
||||||
|
\${11} | \${1} | \${222} | \${"unknown column 1"} | \${"unknown column 2"}
|
||||||
|
\${1 - 1} | \${2 + 2} | \${3333}
|
||||||
|
\${2 + 1 + 2} | \${1111} | \${3} | \${"unknown column xyz"}
|
||||||
|
\`;
|
||||||
|
|
||||||
|
describe.only.each\`
|
||||||
|
| |
|
||||||
|
\${11} | \${1} | \${222} | \${"unknown column 1"} | \${"unknown column 2"}
|
||||||
|
\${1 - 1} | \${2 + 2} | \${3333}
|
||||||
|
\${2 + 1 + 2} | \${1111} | \${3} | \${"unknown column xyz"}
|
||||||
|
\`;
|
||||||
|
|
||||||
|
describe.each\`
|
||||||
|
a | b | expected
|
||||||
|
\${1} | \${1} | \${2}
|
||||||
|
\${1} | \${2} | \${3}
|
||||||
|
\${2} | \${1} | \${3}
|
||||||
|
\`;
|
||||||
|
|
||||||
|
// an example to demo multiline quasi
|
||||||
|
describe.each\`
|
||||||
|
a | b | expected
|
||||||
|
\${11111111111} | \${a()
|
||||||
|
.b()
|
||||||
|
.c()
|
||||||
|
.d()} | \${2}
|
||||||
|
\${1} | \${2} | \${3}
|
||||||
|
\${2} | \${1} | \${3}
|
||||||
|
\`;
|
||||||
|
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`test_declarations.js 1`] = `
|
exports[`test_declarations.js 1`] = `
|
||||||
// Shouldn't break
|
// Shouldn't break
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
describe.each`
|
||||||
|
a|b|expected
|
||||||
|
${11 } | ${ 1 }|${222}
|
||||||
|
${1-1}|${2+2}|${ 3333}
|
||||||
|
${2+1+2}|${1111}|${3}
|
||||||
|
`('$a + $b', ({a, b, expected}) => {
|
||||||
|
test(`returns ${expected}`, () => {
|
||||||
|
expect(a + b).toBe(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(`returned value not be greater than ${expected}`, () => {
|
||||||
|
expect(a + b).not.toBeGreaterThan(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(`returned value not be less than ${expected}`, () => {
|
||||||
|
expect(a + b).not.toBeLessThan(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe.only.each`
|
||||||
|
a|b|expected
|
||||||
|
${11 } | ${ 1 }|${222}|${'unknown column 1'}|${'unknown column 2'}
|
||||||
|
${1-1}|${2+2}|${ 3333}
|
||||||
|
${2+1+2}|${1111}|${3} |${'unknown column xyz'}
|
||||||
|
`
|
||||||
|
|
||||||
|
describe.only.each`
|
||||||
|
||
|
||||||
|
${11 } | ${ 1 }|${222}|${'unknown column 1'}|${'unknown column 2'}
|
||||||
|
${1-1}|${2+2}|${ 3333}
|
||||||
|
${2+1+2}|${1111}|${3} |${'unknown column xyz'}
|
||||||
|
`
|
||||||
|
|
||||||
|
describe.each`a | b | expected
|
||||||
|
${1} | ${1} | ${2}
|
||||||
|
${1} | ${2} | ${3}
|
||||||
|
${2} | ${1} | ${3}`
|
||||||
|
|
||||||
|
// an example to demo multiline quasi
|
||||||
|
describe.each`a | b | expected
|
||||||
|
${11111111111} | ${a().b().c().d()} | ${2}
|
||||||
|
${1} | ${2} | ${3}
|
||||||
|
${2} | ${1} | ${3}`
|
Loading…
Reference in New Issue