enzyme-adapter-preact-pure
Version:
Enzyme adapter for Preact
150 lines (149 loc) • 6.35 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.EnzymeAdapter = void 0;
const enzyme_1 = __importDefault(require("enzyme"));
const preact_1 = require("preact");
const MountRenderer_js_1 = __importDefault(require("./MountRenderer.js"));
const ShallowRenderer_js_1 = __importDefault(require("./ShallowRenderer.js"));
const StringRenderer_js_1 = __importDefault(require("./StringRenderer.js"));
const compat_js_1 = require("./compat.js");
const preact10_rst_js_1 = require("./preact10-rst.js");
const RootFinder_js_1 = __importDefault(require("./RootFinder.js"));
const util_js_1 = require("./util.js");
exports.EnzymeAdapter = enzyme_1.default.EnzymeAdapter;
class Adapter extends exports.EnzymeAdapter {
constructor(preactAdapterOptions = {}) {
super();
// This function is only called during shallow rendering
this.wrapWithWrappingComponent = (el,
/**
* Tip:
* The use of `wrappingComponent` and `wrappingComponentProps` is discouraged.
* Using those props complicates a potential future migration to a different testing library.
* Instead, wrap a component like this:
* ```
* shallow(<Wrapper><Component/></Wrapper>).dive()
* ```
*/
options = {}) => {
const { wrappingComponent, wrappingComponentProps = {} } = options;
if (!wrappingComponent) {
return { RootFinder: RootFinder_js_1.default, node: el };
}
let elementWithValidChildren;
if (typeof el.props.children === 'string') {
// This prevents an error when `.dive()` is used:
// `TypeError: ShallowWrapper::dive() can only be called on components`.
// ---------------------------------------------------------------------
// VNode before: `{ type: Widget, props: { children: 'test' }, ... }`
// VNode after: `{ type: Widget, props: { children: ['test'] }, ... }`
elementWithValidChildren = (0, preact_1.cloneElement)(el, el.props, (0, compat_js_1.childElements)(el));
}
else {
elementWithValidChildren = el;
}
const wrappedElement = (0, preact_1.h)(wrappingComponent, wrappingComponentProps, (0, preact_1.h)(RootFinder_js_1.default, null, elementWithValidChildren));
return {
RootFinder: RootFinder_js_1.default,
node: wrappedElement,
};
};
this.preactAdapterOptions = preactAdapterOptions;
this.options = {
// Prevent Enzyme's shallow renderer from manually invoking lifecycle
// methods after a render. This manual invocation is needed for React
// but not for the Preact adapter because we re-use the normal rendering
// logic.
lifecycles: {
componentDidUpdate: {
onSetState: false,
},
},
};
// Work around a bug in Enzyme where `ShallowWrapper.getElements` calls
// the `nodeToElement` method with undefined `this`.
this.nodeToElement = this.nodeToElement.bind(this);
if (this.preactAdapterOptions.ShallowRenderer) {
this.isFragment = node => node?.type === preact_1.Fragment;
this.displayNameOfNode = (node) => {
if (!node || !node.type) {
return null;
}
if (this.isFragment?.(node)) {
return 'Fragment';
}
return typeof node.type === 'function'
? node.type.displayName || node.type.name || 'Component'
: node.type;
};
}
}
createRenderer(options) {
switch (options.mode) {
case 'mount':
// The `attachTo` option is only supported for DOM rendering, for
// consistency with React, even though the Preact adapter could easily
// support it for shallow rendering.
return new MountRenderer_js_1.default({
...options,
...this.preactAdapterOptions,
container: options.attachTo,
});
case 'shallow':
if (this.preactAdapterOptions.ShallowRenderer) {
return new this.preactAdapterOptions.ShallowRenderer({
...this.preactAdapterOptions,
});
}
else {
return new ShallowRenderer_js_1.default({ ...this.preactAdapterOptions });
}
case 'string':
return new StringRenderer_js_1.default({ ...this.preactAdapterOptions });
default:
throw new Error(`"${options.mode}" rendering is not supported`);
}
}
nodeToElement(node) {
if (!(0, util_js_1.isRSTNode)(node)) {
return node;
}
const props = { ...node.props };
if (node.key) {
props.key = node.key;
}
if (node.ref) {
props.ref = node.ref;
}
const childElements = node.rendered.map(n => this.nodeToElement(n));
return (0, preact_1.h)(node.type, props, ...childElements);
}
nodeToHostNode(node) {
return (0, util_js_1.nodeToHostNode)(node);
}
isValidElement(el) {
if (el == null || typeof el !== 'object') {
return false;
}
if (typeof el.type !== 'string' &&
typeof el.type !== 'function' &&
el.type !== null) {
return false;
}
if (typeof el.props !== 'object' || el.props == null) {
return false;
}
return true;
}
createElement(type, props, ...children) {
return (0, preact_1.h)(type, props, ...children);
}
elementToNode(el) {
return (0, preact10_rst_js_1.rstNodeFromElement)(el, Boolean(this.preactAdapterOptions.ShallowRenderer) // preserveChildrenProp
);
}
}
exports.default = Adapter;