Skip to content

Commit

Permalink
chore: add parseExpect() util function
Browse files Browse the repository at this point in the history
  • Loading branch information
macklinu committed Apr 1, 2018
1 parent 03a7cda commit dd4aea6
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 1 deletion.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
"eslint-plugin-eslint-plugin": "^1.4.0",
"eslint-plugin-node": "^6.0.0",
"eslint-plugin-prettier": "^2.3.1",
"espree": "^3.5.4",
"estraverse": "^4.2.0",
"husky": "^0.14.3",
"jest": "^22.0.4",
"jest-runner-eslint": "^0.4.0",
Expand Down
114 changes: 114 additions & 0 deletions rules/__tests__/parse-expect.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
'use strict';

const espree = require('espree');
const estraverse = require('estraverse');
const parseExpect = require('../parse-expect');

const CASES = {
notExpect(parsed) {
expect(parsed).toBeNull();
},
'expect()'(parsed) {
expect(parsed).toMatchObject({
arguments: [],
properties: [],
matcher: undefined,
matcherArguments: [],
});
},
'expect().toBe'(parsed) {
expect(parsed).toMatchObject({
arguments: [],
properties: [Identifier('toBe')],
matcher: undefined,
matcherArguments: [],
});
},
'expect().toBe()'(parsed) {
expect(parsed).toMatchObject({
arguments: [],
properties: [],
matcher: Identifier('toBe'),
matcherArguments: [],
});
},
'expect(Promise.resolve(2)).not.resolves.toEqual(3)'(parsed) {
expect(parsed).toMatchObject({
arguments: [
CallExpression(Identifier('Promise'), Identifier('resolve'), [
Literal(2),
]),
],
properties: [Identifier('not'), Identifier('resolves')],
matcher: Identifier('toEqual'),
matcherArguments: [Literal(3)],
});
},
'expect().a.b.c.d.e.f()'(parsed) {
expect(parsed).toMatchObject({
arguments: [],
properties: [
Identifier('a'),
Identifier('b'),
Identifier('c'),
Identifier('d'),
Identifier('e'),
],
matcher: Identifier('f'),
matcherArguments: [],
});
},
};

Object.keys(CASES).forEach(code => {
test(code, () => {
const assertion = CASES[code];
const node = findExpect(code);
assertion(parseExpect(node));
});
});

function findExpect(code) {
let callExpression = null;

const ast = espree.parse(code);
estraverse.traverse(ast, {
enter(node, parent) {
node.parent = parent;
if (
!callExpression &&
node.type === 'CallExpression' &&
node.callee.name === 'expect'
) {
callExpression = node;
}
},
});

return callExpression;
}

function Identifier(name) {
return {
type: 'Identifier',
name,
};
}

function Literal(value) {
return {
type: 'Literal',
value,
};
}

function CallExpression(object, property, args) {
return {
type: 'CallExpression',
callee: {
object,
property,
},
arguments: args || [],
};
}
35 changes: 35 additions & 0 deletions rules/parse-expect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
'use strict';

module.exports = function parseExpect(node) {
if (node && node.type === 'CallExpression' && node.callee.name === 'expect') {
const properties = [];
let matcherArguments = [];
let matcher = undefined;
let parent = node.parent;
while (parent) {
if (parent.type === 'MemberExpression') {
const grandParentType = parent.parent && parent.parent.type;
switch (grandParentType) {
case 'CallExpression': {
matcher = parent.property;
matcherArguments = matcherArguments.concat(parent.parent.arguments);
break;
}
case 'MemberExpression':
case 'ExpressionStatement': {
properties.push(parent.property);
break;
}
}
}
parent = parent.parent;
}
return {
arguments: node.arguments,
properties,
matcher,
matcherArguments,
};
}
return null;
};
2 changes: 1 addition & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1873,7 +1873,7 @@ eslint@^4.10.0, eslint@^4.5.0:
table "4.0.2"
text-table "~0.2.0"

espree@^3.5.2:
espree@^3.5.2, espree@^3.5.4:
version "3.5.4"
resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7"
dependencies:
Expand Down

0 comments on commit dd4aea6

Please sign in to comment.