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
JavaScript
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
;