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 addAlignmentToDoc = docBuilders.addAlignmentToDoc;
|
||||
const dedent = docBuilders.dedent;
|
||||
const printDocToString = doc.printer.printDocToString;
|
||||
|
||||
const docUtils = doc.utils;
|
||||
const willBreak = docUtils.willBreak;
|
||||
|
@ -2054,6 +2055,122 @@ function printPathNoParens(path, options, print, args) {
|
|||
return join(literalline, n.value.raw.split(/\r?\n/g));
|
||||
case "TemplateLiteral": {
|
||||
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("`");
|
||||
|
||||
|
|
|
@ -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`] = `
|
||||
// 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