UNPKG

unexpected-htmllike-jsx-adapter

Version:

Adapter for unexpected-htmllike for ReactElements, e.g. JSX and the shallow renderer

195 lines (151 loc) 6.92 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _objectAssign = require('object-assign'); var _objectAssign2 = _interopRequireDefault(_objectAssign); var _getIteratorFn = require('./getIteratorFn'); var _getIteratorFn2 = _interopRequireDefault(_getIteratorFn); var REACT_ELEMENT_TYPE = typeof Symbol === 'function' && Symbol['for'] && Symbol['for']('react.element') || 0xeac7; function isRawType(value) { var type = typeof value; return type === 'string' || type === 'number' || type === 'boolean' || type === 'undefined' || value === null; } var DefaultOptions = { concatTextContent: false }; function convertValueTypeToString(value) { if (typeof value === 'string') { // Common case can be fasttracked return value; } if (value === null || value === undefined) { return ''; } return '' + value; } function concatenateStringChildren(accum, value) { if (isRawType(value) && accum.length && isRawType(accum[accum.length - 1])) { accum[accum.length - 1] = convertValueTypeToString(accum[accum.length - 1]) + convertValueTypeToString(value); return accum; } accum.push(value); return accum; } function isValidChild(child) { var typeofChild = typeof child; return typeofChild === 'string' || typeofChild === 'number' || typeofChild === 'function' && child._expectIt || typeof child === 'object' && child !== null && (child._isReactElement /* React 0.13 */ || child.$$typeof === REACT_ELEMENT_TYPE) /* React 0.14 */; } function flatten(value) { var iteratorFn = (0, _getIteratorFn2['default'])(value); if (!Array.isArray(value) && typeof value !== 'string' && iteratorFn) { var iterator = iteratorFn.call(value); var childrenArray = []; var step = undefined; while (!(step = iterator.next()).done) { childrenArray.push(step.value); } return childrenArray; } if (!Array.isArray(value)) { return [value]; } return value.reduce(function (result, item) { return result.concat(flatten(item)); }, []); } var ReactElementAdapter = (function () { function ReactElementAdapter(options) { _classCallCheck(this, ReactElementAdapter); this._options = (0, _objectAssign2['default'])({}, DefaultOptions, options); } _createClass(ReactElementAdapter, [{ key: 'getName', value: function getName(element) { if (typeof element.type === 'string') { return element.type; } return element.type.displayName || element.type.name || 'no-display-name'; } }, { key: 'getAttributes', value: function getAttributes(element) { var realProps = {}; if (element.props) { for (var key in element.props) { if (key !== 'children') { realProps[key] = element.props[key]; } } } if (this._options.includeKeyProp && element.key) { realProps.key = element.key; } if (this._options.includeRefProp && element.ref) { realProps.ref = element.ref; } return realProps; } }, { key: 'getChildren', value: function getChildren(element) { var children = element.props.children; var childrenArray = []; var iteratorFn; // This is not using React.Children.forEach / map / toArray because it drops invalid children, // which would be fine, but we want to explicitly include the `expect.it()` function as a valid child // to enable inline assertions // This mirrors the React.Children.forEach logic, as seen at // https://github.com/facebook/react/blob/35962a00084382b49d1f9e3bd36612925f360e5b/src/shared/utils/traverseAllChildren.js // with the exception that we remove the nulls // Basically strings & numbers && elements are allowed (elements classed as objects & functions for simplicity) if (Array.isArray(children)) { childrenArray = flatten(children).filter(function (child) { return isValidChild(child); }); } else if (isValidChild(children)) { childrenArray = [children]; } else if (iteratorFn = (0, _getIteratorFn2['default'])(children)) { var iterator = iteratorFn.call(children); var step = undefined; while (!(step = iterator.next()).done) { childrenArray.push(step.value); } } if (this._options.convertToString || this._options.convertMultipleRawToStrings && childrenArray.length > 1) { childrenArray = childrenArray.reduce(function (agg, child) { if (child !== null && child !== undefined && isRawType(child)) { child = convertValueTypeToString(child); } agg.push(child); return agg; }, []); } if (this._options.concatTextContent) { childrenArray = childrenArray.reduce(concatenateStringChildren, []); } return childrenArray; } }, { key: 'setOptions', value: function setOptions(newOptions) { this._options = (0, _objectAssign2['default'])({}, this._options, newOptions); } }, { key: 'getOptions', value: function getOptions() { return this._options; } }]); return ReactElementAdapter; })(); ReactElementAdapter.prototype.classAttributeName = 'className'; exports['default'] = ReactElementAdapter; module.exports = exports['default']; //# sourceMappingURL=ReactElementAdapter.js.map