Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/vitest-dev/vitest. Next generation testing framework powered by Vite. vitest.dev
test testing-tools vite
Something went wrong. Try again.
3.4 kB · 137 lines
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138/** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */
import type { Config, NewPlugin, Printer, Refs } from '../types'import * as ReactIs19 from 'react-is'// @ts-expect-error no typeimport * as ReactIs18 from 'react-is-18'import { printChildren, printElement, printElementAsLeaf, printProps } from './lib/markup'
const reactIsMethods = [ 'isAsyncMode', 'isConcurrentMode', 'isContextConsumer', 'isContextProvider', 'isElement', 'isForwardRef', 'isFragment', 'isLazy', 'isMemo', 'isPortal', 'isProfiler', 'isStrictMode', 'isSuspense', 'isSuspenseList', 'isValidElementType',] as const
const ReactIs: typeof ReactIs18 = Object.fromEntries( reactIsMethods.map((m) => [m, (v: any) => ReactIs18[m](v) || (ReactIs19 as any)[m](v)]),) as any
// Given element.props.children, or subtree during recursive traversal,// return flattened array of children.function getChildren(arg: unknown, children: Array<unknown> = []) { if (Array.isArray(arg)) { for (const item of arg) { getChildren(item, children) } } else if (arg != null && arg !== false && arg !== '') { children.push(arg) } return children}
function getType(element: any) { const type = element.type if (typeof type === 'string') { return type } if (typeof type === 'function') { return type.displayName || type.name || 'Unknown' }
if (ReactIs.isFragment(element)) { return 'React.Fragment' } if (ReactIs.isSuspense(element)) { return 'React.Suspense' } if (typeof type === 'object' && type !== null) { if (ReactIs.isContextProvider(element)) { return 'Context.Provider' }
if (ReactIs.isContextConsumer(element)) { return 'Context.Consumer' }
if (ReactIs.isForwardRef(element)) { if (type.displayName) { return type.displayName }
const functionName = type.render.displayName || type.render.name || ''
return functionName === '' ? 'ForwardRef' : `ForwardRef(${functionName})` }
if (ReactIs.isMemo(element)) { const functionName = type.displayName || type.type.displayName || type.type.name || ''
return functionName === '' ? 'Memo' : `Memo(${functionName})` } } return 'UNDEFINED'}
function getPropKeys(element: any) { const { props } = element
return Object.keys(props) .filter((key) => key !== 'children' && props[key] !== undefined) .sort()}
const serialize: NewPlugin['serialize'] = ( element: any, config: Config, indentation: string, depth: number, refs: Refs, printer: Printer,) => ++depth > config.maxDepth ? printElementAsLeaf(getType(element), config) : printElement( getType(element), printProps( getPropKeys(element), element.props, config, indentation + config.indent, depth, refs, printer, ), printChildren( getChildren(element.props.children), config, indentation + config.indent, depth, refs, printer, ), config, indentation, )
const test: NewPlugin['test'] = (val: unknown) => val != null && ReactIs.isElement(val)
const plugin: NewPlugin = { serialize, test }
export default plugin