UNPKG

enzyme-adapter-preact-pure

Version:

Enzyme adapter for Preact

131 lines (130 loc) 5.28 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const preact_1 = require("preact"); const test_utils_1 = require("preact/test-utils"); const compat_js_1 = require("./compat.js"); const debounce_render_hook_js_1 = require("./debounce-render-hook.js"); const event_map_js_1 = require("./event-map.js"); const preact10_internals_js_1 = require("./preact10-internals.js"); const preact10_rst_js_1 = require("./preact10-rst.js"); const util_js_1 = require("./util.js"); function constructEvent(type, init) { const meta = event_map_js_1.eventMap[type]; const defaultInit = meta?.defaultInit ?? {}; return new Event(type, { ...defaultInit, ...init, }); } class MountRenderer { constructor(options = {}) { (0, debounce_render_hook_js_1.installHook)(); this._container = options.container || document.createElement('div'); this._getNode = preact10_rst_js_1.getNode; this._options = options; } render(el, context, callback) { (0, test_utils_1.act)(() => { if (!this._options.wrappingComponent) { (0, compat_js_1.render)(el, this._container); return; } // `this._options.wrappingComponent` is only available during mount-rendering, // even though ShallowRenderer uses an instance of MountRenderer under the hood. // For shallow-rendered components, we need to utilize `wrapWithWrappingComponent`. const wrappedComponent = (0, preact_1.createElement)(this._options.wrappingComponent, this._options.wrappingComponentProps || null, el); (0, compat_js_1.render)(wrappedComponent, this._container); }); if (callback) { callback(); } } unmount() { // A custom tag name is used here to work around // https://github.com/developit/preact/issues/1288. (0, compat_js_1.render)((0, preact_1.h)('unmount-me', {}), this._container); this._container.innerHTML = ''; } getNode() { (0, debounce_render_hook_js_1.flushRenders)(); const container = this._container; if ( // If the root component rendered null then the only indicator that content // has been rendered will be metadata attached to the container. typeof (0, preact10_internals_js_1.getLastVNodeRenderedIntoContainer)(container) === 'undefined') { return null; } return this._getNode(this._container); } simulateError(nodeHierarchy, rootNode, error) { const errNode = nodeHierarchy[0]; const render = () => { // Modify the stack to match where the error is thrown. This makes // debugging easier. error.stack = new Error().stack; throw error; }; (0, util_js_1.withReplacedMethod)(errNode.instance, 'render', render, () => { (0, test_utils_1.act)(() => { errNode.instance.forceUpdate(); }); }); } simulateEvent(node, eventName, args = {}) { let hostNode; if (node.nodeType == 'host') { hostNode = node.instance; } else if (this._options.simulateEventsOnComponents) { const possibleHostNode = (0, util_js_1.nodeToHostNode)(node); if (possibleHostNode == null) { const name = (0, util_js_1.getDisplayName)(node); throw new Error(`Cannot simulate event on "${name}" which is not a DOM element or contains no DOM element children. ` + 'Find a DOM element or Component that contains a DOM element in the output and simulate an event on that.'); } hostNode = possibleHostNode; } else { const name = (0, util_js_1.getDisplayName)(node); throw new Error(`Cannot simulate event on "${name}" which is not a DOM element. ` + 'Find a DOM element in the output and simulate an event on that. ' + 'Or, enable the simulateEventsOnComponents option to enable this feature.'); } // To be more faithful to a real browser, this should use the appropriate // constructor for the event type. This implementation is good enough for // many components though. const { bubbles, composed, cancelable, ...extra } = args; const init = {}; if (typeof bubbles === 'boolean') { init.bubbles = bubbles; } if (typeof composed === 'boolean') { init.composed = composed; } if (typeof cancelable === 'boolean') { init.cancelable = cancelable; } const event = constructEvent(eventName, init); Object.assign(event, extra); (0, test_utils_1.act)(() => { hostNode.dispatchEvent(event); }); } batchedUpdates(fn) { fn(); } container() { return this._container; } wrapInvoke(callback) { let result; (0, test_utils_1.act)(() => { result = callback(); }); return result; } getWrappingComponentRenderer() { return this; } } exports.default = MountRenderer;