Inline AngularJS tests that use `inject` (#4495)

* Inline AngularJS tests that use `inject`

See https://docs.angularjs.org/guide/unit-testing#using-beforeall- for a code example.

* More meaningful function name, minor refactoring

* Linting

* Minor regexp improvement

* address review comments
master
Georgii Dolzhykov 2018-05-17 18:09:20 +03:00 committed by Lucas Duailibe
parent a8b0e55205
commit c6e8177282
3 changed files with 164 additions and 19 deletions

View File

@ -3643,7 +3643,7 @@ function printFunctionParams(path, print, options, expandArg, printTypeParams) {
const parent = path.getParentNode();
// don't break in specs, eg; `it("should maintain parens around done even when long", (done) => {})`
if (parent.type === "CallExpression" && isTestCall(parent)) {
if (isTestCall(parent)) {
return concat([typeParams, "(", join(", ", printed), ")"]);
}
@ -3984,10 +3984,7 @@ function printTypeParameters(path, options, print, paramsKey) {
const grandparent = path.getNode(2);
const isParameterInTestCall =
grandparent != null &&
grandparent.type === "CallExpression" &&
isTestCall(grandparent);
const isParameterInTestCall = grandparent != null && isTestCall(grandparent);
const shouldInline =
isParameterInTestCall ||
@ -5580,25 +5577,22 @@ function isObjectType(n) {
return n.type === "ObjectTypeAnnotation" || n.type === "TSTypeLiteral";
}
const unitTestRe = /^(skip|[fx]?(it|describe|test))$/;
// eg; `describe("some string", (done) => {})`
function isTestCall(n, parent) {
const unitTestRe = /^(skip|(f|x)?(it|describe|test))$/;
if (n.type !== "CallExpression") {
return false;
}
if (n.arguments.length === 1) {
if (
n.callee.type === "Identifier" &&
n.callee.name === "async" &&
parent &&
parent.type === "CallExpression" &&
isTestCall(parent)
) {
if (isAngularTestWrapper(n) && parent && isTestCall(parent)) {
return isFunctionOrArrowExpression(n.arguments[0].type);
}
if (isUnitTestSetUp(n)) {
return (
isFunctionOrArrowExpression(n.arguments[0].type) ||
isIdentiferAsync(n.arguments[0])
isAngularTestWrapper(n.arguments[0])
);
}
} else if (n.arguments.length === 2) {
@ -5610,7 +5604,7 @@ function isTestCall(n, parent) {
return (
(isFunctionOrArrowExpression(n.arguments[1].type) &&
n.arguments[1].params.length <= 1) ||
isIdentiferAsync(n.arguments[1])
isAngularTestWrapper(n.arguments[1])
);
}
}
@ -5618,7 +5612,6 @@ function isTestCall(n, parent) {
}
function isSkipOrOnlyBlock(node) {
const unitTestRe = /^(skip|(f|x)?(it|describe|test))$/;
return (
node.callee.type === "MemberExpression" &&
node.callee.object.type === "Identifier" &&
@ -5633,11 +5626,13 @@ function isTemplateLiteral(node) {
return node.type === "TemplateLiteral";
}
function isIdentiferAsync(node) {
// `inject` is used in AngularJS 1.x, `async` in Angular 2+
// example: https://docs.angularjs.org/guide/unit-testing#using-beforeall-
function isAngularTestWrapper(node) {
return (
node.type === "CallExpression" &&
node.callee.type === "Identifier" &&
node.callee.name === "async"
(node.callee.name === "async" || node.callee.name === "inject")
);
}

View File

@ -102,6 +102,130 @@ function x() {
`;
exports[`angularjs_inject.js 1`] = `
beforeEach(inject(($fooService, $barService) => {
// code
}));
afterAll(inject(($fooService, $barService) => {
console.log('Hello');
}));
it('should create the app', inject(($fooService, $barService) => {
//code
}));
it("does something really long and complicated so I have to write a very long name for the test", inject(() => {
// code
}));
it("does something really long and complicated so I have to write a very long name for the test", inject(($fooServiceLongName, $barServiceLongName) => {
// code
}));
/*
* isTestCall(parent) should only be called when parent exists
* and parent.type is CallExpression. This test makes sure that
* no errors are thrown when calling isTestCall(parent)
*/
function x() { inject(() => {}) }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
beforeEach(inject(($fooService, $barService) => {
// code
}));
afterAll(inject(($fooService, $barService) => {
console.log("Hello");
}));
it("should create the app", inject(($fooService, $barService) => {
//code
}));
it("does something really long and complicated so I have to write a very long name for the test", inject(() => {
// code
}));
it("does something really long and complicated so I have to write a very long name for the test", inject((
$fooServiceLongName,
$barServiceLongName
) => {
// code
}));
/*
* isTestCall(parent) should only be called when parent exists
* and parent.type is CallExpression. This test makes sure that
* no errors are thrown when calling isTestCall(parent)
*/
function x() {
inject(() => {});
}
`;
exports[`angularjs_inject.js 2`] = `
beforeEach(inject(($fooService, $barService) => {
// code
}));
afterAll(inject(($fooService, $barService) => {
console.log('Hello');
}));
it('should create the app', inject(($fooService, $barService) => {
//code
}));
it("does something really long and complicated so I have to write a very long name for the test", inject(() => {
// code
}));
it("does something really long and complicated so I have to write a very long name for the test", inject(($fooServiceLongName, $barServiceLongName) => {
// code
}));
/*
* isTestCall(parent) should only be called when parent exists
* and parent.type is CallExpression. This test makes sure that
* no errors are thrown when calling isTestCall(parent)
*/
function x() { inject(() => {}) }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
beforeEach(inject(($fooService, $barService) => {
// code
}));
afterAll(inject(($fooService, $barService) => {
console.log("Hello");
}));
it("should create the app", inject(($fooService, $barService) => {
//code
}));
it("does something really long and complicated so I have to write a very long name for the test", inject(() => {
// code
}));
it("does something really long and complicated so I have to write a very long name for the test", inject((
$fooServiceLongName,
$barServiceLongName
) => {
// code
}));
/*
* isTestCall(parent) should only be called when parent exists
* and parent.type is CallExpression. This test makes sure that
* no errors are thrown when calling isTestCall(parent)
*/
function x() {
inject(() => {});
}
`;
exports[`jest-each.js 1`] = `
describe.each\`
a|b|expected

View File

@ -0,0 +1,26 @@
beforeEach(inject(($fooService, $barService) => {
// code
}));
afterAll(inject(($fooService, $barService) => {
console.log('Hello');
}));
it('should create the app', inject(($fooService, $barService) => {
//code
}));
it("does something really long and complicated so I have to write a very long name for the test", inject(() => {
// code
}));
it("does something really long and complicated so I have to write a very long name for the test", inject(($fooServiceLongName, $barServiceLongName) => {
// code
}));
/*
* isTestCall(parent) should only be called when parent exists
* and parent.type is CallExpression. This test makes sure that
* no errors are thrown when calling isTestCall(parent)
*/
function x() { inject(() => {}) }