Skip to content

fix: resolve value to a proper node instead of an array #278

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 13, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions src/handlers/__tests__/propTypeHandler-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,8 @@ describe('propTypeHandler', () => {

propTypeHandler(documentation, definition);

expect(getPropTypeMock.mock.calls[0][0].node).toEqualASTNode(
fooPath.node,
);
expect(getPropTypeMock.mock.calls[1][0].node).toEqualASTNode(
xyzPath.node,
);
expect(getPropTypeMock.mock.calls[0][0]).toEqualASTNode(fooPath);
expect(getPropTypeMock.mock.calls[1][0]).toEqualASTNode(xyzPath);
});

it('finds definitions via React.PropTypes', () => {
Expand Down
2 changes: 1 addition & 1 deletion src/utils/__tests__/getMemberExpressionRoot-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ import getMemberExpressionRoot from '../getMemberExpressionRoot';
describe('getMemberExpressionRoot', () => {
it('returns the root of a member expression', () => {
const root = getMemberExpressionRoot(expression('foo.bar.baz'));
expect(root.node).toEqualASTNode(expression('foo').node);
expect(root).toEqualASTNode(expression('foo'));
});
});
8 changes: 4 additions & 4 deletions src/utils/__tests__/resolveHOC-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,19 @@ describe('resolveHOC', () => {

it('resolves simple hoc', () => {
const path = parse(['hoc(42);'].join('\n'));
expect(resolveHOC(path).node).toEqualASTNode(builders.literal(42));
expect(resolveHOC(path)).toEqualASTNode(builders.literal(42));
});

it('resolves simple hoc w/ multiple args', () => {
const path = parse(['hoc1(arg1a, arg1b)(42);'].join('\n'));
expect(resolveHOC(path).node).toEqualASTNode(builders.literal(42));
expect(resolveHOC(path)).toEqualASTNode(builders.literal(42));
});

it('resolves nested hocs', () => {
const path = parse(
['hoc2(arg2b, arg2b)(', ' hoc1(arg1a, arg2a)(42)', ');'].join('\n'),
);
expect(resolveHOC(path).node).toEqualASTNode(builders.literal(42));
expect(resolveHOC(path)).toEqualASTNode(builders.literal(42));
});

it('resolves really nested hocs', () => {
Expand All @@ -56,6 +56,6 @@ describe('resolveHOC', () => {
');',
].join('\n'),
);
expect(resolveHOC(path).node).toEqualASTNode(builders.literal(42));
expect(resolveHOC(path)).toEqualASTNode(builders.literal(42));
});
});
16 changes: 8 additions & 8 deletions src/utils/__tests__/resolveObjectKeysToArray-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ describe('resolveObjectKeysToArray', () => {
['var foo = { bar: 1, foo: 2 };', 'Object.keys(foo);'].join('\n'),
);

expect(resolveObjectKeysToArray(path).node).toEqualASTNode(
expect(resolveObjectKeysToArray(path)).toEqualASTNode(
builders.arrayExpression([
builders.literal('bar'),
builders.literal('foo'),
Expand All @@ -40,7 +40,7 @@ describe('resolveObjectKeysToArray', () => {
['var foo = { "bar": 1, 5: 2 };', 'Object.keys(foo);'].join('\n'),
);

expect(resolveObjectKeysToArray(path).node).toEqualASTNode(
expect(resolveObjectKeysToArray(path)).toEqualASTNode(
builders.arrayExpression([
builders.literal('bar'),
builders.literal('5'),
Expand All @@ -53,7 +53,7 @@ describe('resolveObjectKeysToArray', () => {
['var foo = { ["bar"]: 1, [5]: 2};', 'Object.keys(foo);'].join('\n'),
);

expect(resolveObjectKeysToArray(path).node).toEqualASTNode(
expect(resolveObjectKeysToArray(path)).toEqualASTNode(
builders.arrayExpression([
builders.literal('bar'),
builders.literal('5'),
Expand All @@ -70,7 +70,7 @@ describe('resolveObjectKeysToArray', () => {
].join('\n'),
);

expect(resolveObjectKeysToArray(path).node).toEqualASTNode(
expect(resolveObjectKeysToArray(path)).toEqualASTNode(
builders.arrayExpression([
builders.literal('boo'),
builders.literal('foo'),
Expand All @@ -86,7 +86,7 @@ describe('resolveObjectKeysToArray', () => {
),
);

expect(resolveObjectKeysToArray(path).node).toEqualASTNode(
expect(resolveObjectKeysToArray(path)).toEqualASTNode(
builders.arrayExpression([
builders.literal('boo'),
builders.literal('foo'),
Expand All @@ -103,7 +103,7 @@ describe('resolveObjectKeysToArray', () => {
].join('\n'),
);

expect(resolveObjectKeysToArray(path).node).toEqualASTNode(
expect(resolveObjectKeysToArray(path)).toEqualASTNode(
builders.arrayExpression([
builders.literal('boo'),
builders.literal('foo'),
Expand All @@ -121,7 +121,7 @@ describe('resolveObjectKeysToArray', () => {
].join('\n'),
);

expect(resolveObjectKeysToArray(path).node).toEqualASTNode(
expect(resolveObjectKeysToArray(path)).toEqualASTNode(
builders.arrayExpression([
builders.literal('boo'),
builders.literal('foo'),
Expand All @@ -137,7 +137,7 @@ describe('resolveObjectKeysToArray', () => {
),
);

expect(resolveObjectKeysToArray(path).node).toEqualASTNode(
expect(resolveObjectKeysToArray(path)).toEqualASTNode(
builders.arrayExpression([builders.literal('x')]),
);
});
Expand Down
38 changes: 23 additions & 15 deletions src/utils/__tests__/resolveToValue-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ describe('resolveToValue', () => {

it('resolves simple variable declarations', () => {
const path = parse(['var foo = 42;', 'foo;'].join('\n'));
expect(resolveToValue(path).node).toEqualASTNode(builders.literal(42));
expect(resolveToValue(path)).toEqualASTNode(builders.literal(42));
});

it('resolves object destructuring', () => {
const path = parse(['var {foo: {bar: baz}} = bar;', 'baz;'].join('\n'));

// Node should be equal to bar.foo.bar
expect(resolveToValue(path).node).toEqualASTNode(
expect(resolveToValue(path)).toEqualASTNode(
builders.memberExpression(
builders.memberExpression(
builders.identifier('bar'),
Expand All @@ -45,19 +45,19 @@ describe('resolveToValue', () => {
it('handles SpreadElements properly', () => {
const path = parse(['var {foo: {bar}, ...baz} = bar;', 'baz;'].join('\n'));

expect(resolveToValue(path).node).toEqualASTNode(path.node);
expect(resolveToValue(path)).toEqualASTNode(path);
});

it('returns the original path if it cannot be resolved', () => {
const path = parse(['function foo() {}', 'foo()'].join('\n'));

expect(resolveToValue(path).node).toEqualASTNode(path.node);
expect(resolveToValue(path)).toEqualASTNode(path);
});

it('resolves variable declarators to their init value', () => {
const path = utils.parse('var foo = 42;').get('body', 0, 'declarations', 0);

expect(resolveToValue(path).node).toEqualASTNode(builders.literal(42));
expect(resolveToValue(path)).toEqualASTNode(builders.literal(42));
});

it('resolves to class declarations', () => {
Expand All @@ -84,49 +84,57 @@ describe('resolveToValue', () => {
it('resolves to assigned values', () => {
const path = parse(['var foo;', 'foo = 42;', 'foo;'].join('\n'));

expect(resolveToValue(path).node).toEqualASTNode(builders.literal(42));
expect(resolveToValue(path)).toEqualASTNode(builders.literal(42));
});
});

describe('ImportDeclaration', () => {
it('resolves default import references to the import declaration', () => {
const path = parse(['import foo from "Foo"', 'foo;'].join('\n'));
const value = resolveToValue(path);

expect(resolveToValue(path).node.type).toBe('ImportDeclaration');
expect(Array.isArray(value.value)).toBe(false);
expect(value.node.type).toBe('ImportDeclaration');
});

it('resolves named import references to the import declaration', () => {
const path = parse(['import {foo} from "Foo"', 'foo;'].join('\n'));
const value = resolveToValue(path);

expect(resolveToValue(path).node.type).toBe('ImportDeclaration');
expect(Array.isArray(value.value)).toBe(false);
expect(value.node.type).toBe('ImportDeclaration');
});

it('resolves aliased import references to the import declaration', () => {
const path = parse(['import {foo as bar} from "Foo"', 'bar;'].join('\n'));
const value = resolveToValue(path);

expect(resolveToValue(path).node.type).toBe('ImportDeclaration');
expect(Array.isArray(value.value)).toBe(false);
expect(value.node.type).toBe('ImportDeclaration');
});

it('resolves namespace import references to the import declaration', () => {
const path = parse(['import * as bar from "Foo"', 'bar;'].join('\n'));
const value = resolveToValue(path);

expect(resolveToValue(path).node.type).toBe('ImportDeclaration');
expect(Array.isArray(value.value)).toBe(false);
expect(value.node.type).toBe('ImportDeclaration');
});
});

describe('MemberExpression', () => {
it("resolves a MemberExpression to it's init value", () => {
const path = parse(['var foo = { bar: 1 };', 'foo.bar;'].join('\n'));

expect(resolveToValue(path).node).toEqualASTNode(builders.literal(1));
expect(resolveToValue(path)).toEqualASTNode(builders.literal(1));
});

it('resolves a MemberExpression in the scope chain', () => {
const path = parse(
['var foo = 1;', 'var bar = { baz: foo };', 'bar.baz;'].join('\n'),
);

expect(resolveToValue(path).node).toEqualASTNode(builders.literal(1));
expect(resolveToValue(path)).toEqualASTNode(builders.literal(1));
});

it('resolves a nested MemberExpression in the scope chain', () => {
Expand All @@ -138,7 +146,7 @@ describe('resolveToValue', () => {
].join('\n'),
);

expect(resolveToValue(path).node).toEqualASTNode(builders.literal(1));
expect(resolveToValue(path)).toEqualASTNode(builders.literal(1));
});

it('returns the last resolvable MemberExpression', () => {
Expand All @@ -150,7 +158,7 @@ describe('resolveToValue', () => {
].join('\n'),
);

expect(resolveToValue(path).node).toEqualASTNode(
expect(resolveToValue(path)).toEqualASTNode(
builders.memberExpression(
builders.identifier('foo'),
builders.identifier('bar'),
Expand All @@ -163,7 +171,7 @@ describe('resolveToValue', () => {
['var foo = {};', 'foo.bar = 1;', 'foo.bar;'].join('\n'),
);

expect(resolveToValue(path).node).toEqualASTNode(path.node);
expect(resolveToValue(path)).toEqualASTNode(path);
});
});
});
3 changes: 2 additions & 1 deletion src/utils/resolveToValue.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,8 @@ export default function resolveToValue(path: NodePath): NodePath {
types.ImportNamespaceSpecifier.check(node) ||
types.ImportSpecifier.check(node)
) {
return path.parentPath;
// go up two levels as first level is only the array of specifiers
return path.parentPath.parentPath;
} else if (types.AssignmentExpression.check(node)) {
if (node.operator === '=') {
return resolveToValue(path.get('right'));
Expand Down
16 changes: 12 additions & 4 deletions tests/setupTestFramework.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,24 @@ const matchers = {
);
}

// Use value here instead of node, as node has some magic and always returns
// the next Node it finds even if value is an array
const receivedNode = received.value;
let expectedNode = expected;
if (expected instanceof recast.types.NodePath) {
expectedNode = expected.value;
}

return {
pass: recast.types.astNodesAreEquivalent(received, expected),
pass: recast.types.astNodesAreEquivalent(receivedNode, expectedNode),
message: () => {
const diffString = diff(expected, received);
const diffString = diff(expectedNode, receivedNode);

return (
'Expected value to be (using ast-types):\n' +
` ${utils.printExpected(expected)}\n` +
` ${utils.printExpected(expectedNode)}\n` +
'Received:\n' +
` ${utils.printReceived(received)}` +
` ${utils.printReceived(receivedNode)}` +
(diffString ? `\n\nDifference:\n\n${diffString}` : '')
);
},
Expand Down