diff --git a/src/__tests__/__snapshots__/main-test.js.snap b/src/__tests__/__snapshots__/main-test.js.snap index 43068fcae9e..ad3fe175bc7 100644 --- a/src/__tests__/__snapshots__/main-test.js.snap +++ b/src/__tests__/__snapshots__/main-test.js.snap @@ -162,3 +162,11 @@ Object { }, } `; + +exports[`main fixtures processes component "component_7.js" without errors 1`] = ` +Object { + "description": "The is a component to test the document generation", + "displayName": "Component", + "methods": Array [], +} +`; diff --git a/src/__tests__/fixtures/component_7.js b/src/__tests__/fixtures/component_7.js new file mode 100644 index 00000000000..cb18b636852 --- /dev/null +++ b/src/__tests__/fixtures/component_7.js @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +var Component, createReactClass; + +createReactClass = require('create-react-class'); + +/** + * The is a component to test the document generation + */ +Component = createReactClass({ + displayName: 'Component', +}); + +module.exports = Component; diff --git a/src/utils/__tests__/isReactCreateClassCall-test.js b/src/utils/__tests__/isReactCreateClassCall-test.js new file mode 100644 index 00000000000..c4cfd166e1c --- /dev/null +++ b/src/utils/__tests__/isReactCreateClassCall-test.js @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +/*global jest, describe, beforeEach, it, expect*/ + + +jest.disableAutomock(); + +describe('isReactCreateClassCall', () => { + var isReactCreateClassCall; + var utils; + + function parse(src) { + var root = utils.parse(src); + return root.get('body', root.node.body.length - 1, 'expression'); + } + + beforeEach(() => { + isReactCreateClassCall = require('../isReactCreateClassCall').default; + utils = require('../../../tests/utils'); + }); + + describe('built in React.createClass', () => { + it('accepts createClass called on React', () => { + var def = parse(` + var React = require("React"); + React.createClass({ + render() {} + }); + `); + expect(isReactCreateClassCall(def)).toBe(true); + }); + + it('accepts createClass called on aliased React', () => { + var def = parse(` + var other = require("React"); + other.createClass({ + render() {} + }); + `); + expect(isReactCreateClassCall(def)).toBe(true); + }); + + it('ignores other React calls', () => { + var def = parse(` + var React = require("React"); + React.isValidElement({}); + `); + expect(isReactCreateClassCall(def)).toBe(false); + }); + + it('ignores non React calls to createClass', () => { + var def = parse(` + var React = require("bob"); + React.createClass({ + render() {} + }); + `); + expect(isReactCreateClassCall(def)).toBe(false); + }); + }); + + describe('modular in create-react-class', () => { + it('accepts create-react-class', () => { + var def = parse(` + var createReactClass = require("create-react-class"); + createReactClass({ + render() {} + }); + `); + expect(isReactCreateClassCall(def)).toBe(true); + }); + + it('accepts create-react-class calls on another name', () => { + var def = parse(` + var makeClass = require("create-react-class"); + makeClass({ + render() {} + }); + `); + expect(isReactCreateClassCall(def)).toBe(true); + }); + + it('ignores non create-react-class calls to createReactClass', () => { + var def = parse(` + var createReactClass = require("bob"); + createReactClass({ + render() {} + }); + `); + expect(isReactCreateClassCall(def)).toBe(false); + }); + }); +}); diff --git a/src/utils/isReactCreateClassCall.js b/src/utils/isReactCreateClassCall.js index 4583fa446f4..44a15133cff 100644 --- a/src/utils/isReactCreateClassCall.js +++ b/src/utils/isReactCreateClassCall.js @@ -21,7 +21,7 @@ var {types: {namedTypes: types}} = recast; * Returns true if the expression is a function call of the form * `React.createClass(...)`. */ -export default function isReactCreateClassCall(path: NodePath): boolean { +function isReactCreateClassCallBuiltIn(path: NodePath): boolean { if (types.ExpressionStatement.check(path.node)) { path = path.get('expression'); } @@ -32,3 +32,35 @@ export default function isReactCreateClassCall(path: NodePath): boolean { var module = resolveToModule(path.get('callee', 'object')); return Boolean(module && isReactModuleName(module)); } + + +/** + * Returns true if the expression is a function call of the form + * ``` + * import createReactClass from 'create-react-class'; + * createReactClass(...); + * ``` + */ +function isReactCreateClassCallModular(path: NodePath): boolean { + if (types.ExpressionStatement.check(path.node)) { + path = path.get('expression'); + } + + if (!match(path.node, {type: 'CallExpression'})) { + return false; + } + var module = resolveToModule(path); + return Boolean(module && module === 'create-react-class'); +} + +/** + * Returns true if the expression is a function call of the form + * `React.createClass(...)` or + * ``` + * import createReactClass from 'create-react-class'; + * createReactClass(...); + * ``` + */ +export default function isReactCreateClassCall(path: NodePath): boolean { + return isReactCreateClassCallBuiltIn(path) || isReactCreateClassCallModular(path) +}