UNPKG

enzyme-adapter-preact-pure

Version:

Enzyme adapter for Preact

142 lines (141 loc) 4.44 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.withShallowRendering = exports.shallowRenderVNodeTree = exports.isShallowRendered = exports.getRealType = void 0; const preact_1 = require("preact"); const compat_js_1 = require("./compat.js"); /** * Map of component function to replacement stub function used when shallow * rendering. */ const shallowRenderComponents = new Map(); /** * Global flag indicating whether shallow rendering is active. */ let shallowRenderActive = false; let shallowRenderHookInstalled = false; function getDisplayName(type) { return type.displayName || type.name; } /** * Return the real component type of a component instance created by * shallow rendering. */ function getRealType(component) { const c = component; const ctor = c.constructor; if (ctor.originalType) { return ctor.originalType; } else { return null; } } exports.getRealType = getRealType; /** * Return true if a value is something that can be returned from a render * function. */ function isRenderable(value) { return (value === null || Array.isArray(value) || typeof value == 'number' || typeof value === 'string' || (typeof value === 'object' && value.type !== undefined)); } /** * Create a dummy component to replace an existing component in rendered output. * * The dummy renders nothing but has the same display name as the original. * This is used to implement shallow rendering by replacing the real component * during shallow renders. */ function makeShallowRenderComponent(type) { function ShallowRenderStub({ children }) { // Preact can render fragments, so we can return the children directly. // // There is an exception for `children` values which are not directly // renderable but need to be processed by the component being stubbed. // For example, a function used as part of the "render prop" pattern // (https://reactjs.org/docs/render-props.html). return isRenderable(children) ? children : null; } ShallowRenderStub.originalType = type; ShallowRenderStub.displayName = getDisplayName(type); return ShallowRenderStub; } /** * Preact `options.vnode` hook that causes a component not to be rendered when * shallow rendering is enabled. */ function shallowRenderVNode(vnode) { if (typeof vnode.type === 'string' || vnode.type == null || (typeof preact_1.Fragment !== 'undefined' && vnode.type === preact_1.Fragment)) { return; } let stub = shallowRenderComponents.get(vnode.type); if (!stub) { stub = makeShallowRenderComponent(vnode.type); shallowRenderComponents.set(vnode.type, stub); } vnode.type = stub; } function installShallowRenderHook() { if (shallowRenderHookInstalled) { return; } const prevHook = preact_1.options.vnode; preact_1.options.vnode = vnode => { if (shallowRenderActive) { shallowRenderVNode(vnode); } if (prevHook) { prevHook(vnode); } }; shallowRenderHookInstalled = true; } function isVNode(obj) { return Object(obj) === obj && typeof obj.type !== 'undefined'; } /** * Return true if a VNode has been modified to shallow-render. */ function isShallowRendered(vnode) { if (vnode.type == null || typeof vnode.type === 'string') { return false; } const type = vnode.type; return typeof type.originalType === 'function'; } exports.isShallowRendered = isShallowRendered; /** * Convert components in a VNode tree to shallow-render. */ function shallowRenderVNodeTree(vnode) { shallowRenderVNode(vnode); (0, compat_js_1.childElements)(vnode).forEach(c => { if (isVNode(c)) { shallowRenderVNodeTree(c); } }); } exports.shallowRenderVNodeTree = shallowRenderVNodeTree; /** * Invoke `fn` with shallow rendering enabled in Preact. * * During the execution of `fn`, any function or class component elements * created by Preact's `h` function will be modified to only render a placeholder * instead of the real component. */ function withShallowRendering(fn) { installShallowRenderHook(); try { shallowRenderActive = true; fn(); } finally { shallowRenderActive = false; } } exports.withShallowRendering = withShallowRendering;