11import faker from 'faker'
22import _ from 'lodash'
33import React from 'react'
4+ import ReactIs from 'react-is'
45import ReactDOMServer from 'react-dom/server'
56import * as semanticUIReact from 'semantic-ui-react'
67
78import { componentInfoContext } from 'docs/src/utils'
8- import { assertBodyContains , consoleUtil , sandbox , syntheticEvent } from 'test/utils'
9- import helpers from './commonHelpers'
9+ import {
10+ assertBodyContains ,
11+ consoleUtil ,
12+ getComponentName ,
13+ getComponentProps ,
14+ sandbox ,
15+ syntheticEvent ,
16+ } from 'test/utils'
1017import hasValidTypings from './hasValidTypings'
1118
1219/**
@@ -20,7 +27,7 @@ import hasValidTypings from './hasValidTypings'
2027 * @param {boolean } [options.rendersPortal=false] Does this component render a Portal powered component?
2128 * @param {Object } [options.requiredProps={}] Props required to render Component without errors or warnings.
2229 */
23- export default ( Component , options = { } ) => {
30+ export default function isConformant ( Component , options = { } ) {
2431 const {
2532 eventTargets = { } ,
2633 nestingLevel = 0 ,
@@ -29,25 +36,26 @@ export default (Component, options = {}) => {
2936 rendersFragmentByDefault = false ,
3037 rendersPortal = false ,
3138 } = options
32- const { throwError } = helpers ( 'isConformant' , Component )
39+ const constructorName = getComponentName ( Component )
3340
34- const componentType = typeof Component
35-
36- // make sure components are properly exported
37- if ( componentType !== 'function' ) {
38- throwError ( `Components should export a class or function, got: ${ componentType } .` )
39- }
40-
41- // tests depend on Component constructor names, enforce them
42- const constructorName = Component . prototype . constructor . name
43- if ( ! constructorName ) {
44- throwError (
45- [
46- 'Component is not a named function. This should help identify it:\n\n' ,
47- `${ ReactDOMServer . renderToStaticMarkup ( < Component /> ) } ` ,
48- ] . join ( '' ) ,
41+ it ( 'a valid component should be exported' , ( ) => {
42+ expect ( ReactIs . isValidElementType ( Component ) ) . to . equal (
43+ true ,
44+ `Components should export a class or function, got: ${ typeof Component } .` ,
4945 )
50- }
46+ } )
47+
48+ it ( 'a component should be a function/class or "displayName" should be defined' , ( ) => {
49+ if ( ! constructorName ) {
50+ throw new Error (
51+ [
52+ 'Component is not a named function and does not have a "displayName".' ,
53+ 'This should help identify it:\n\n' ,
54+ `${ ReactDOMServer . renderToStaticMarkup ( < Component { ...requiredProps } /> ) } ` ,
55+ ] . join ( '' ) ,
56+ )
57+ }
58+ } )
5159
5260 const info = componentInfoContext . byDisplayName [ constructorName ]
5361
@@ -192,20 +200,22 @@ export default (Component, options = {}) => {
192200 }
193201
194202 describe ( 'handles props' , ( ) => {
203+ const componentProps = getComponentProps ( Component )
204+
195205 it ( 'defines handled props in Component.handledProps' , ( ) => {
196- Component . should . have . any . keys ( 'handledProps' )
197- Component . handledProps . should . be . an ( 'array' )
206+ componentProps . should . have . any . keys ( 'handledProps' )
207+ componentProps . handledProps . should . be . an ( 'array' )
198208 } )
199209
200210 it ( 'Component.handledProps includes all handled props' , ( ) => {
201211 const computedProps = _ . union (
202- Component . autoControlledProps ,
203- _ . keys ( Component . defaultProps ) ,
204- _ . keys ( Component . propTypes ) ,
212+ componentProps . autoControlledProps ,
213+ _ . keys ( componentProps . defaultProps ) ,
214+ _ . keys ( componentProps . propTypes ) ,
205215 )
206216 const expectedProps = _ . uniq ( computedProps ) . sort ( )
207217
208- Component . handledProps . should . to . deep . equal (
218+ componentProps . handledProps . should . to . deep . equal (
209219 expectedProps ,
210220 'It seems that not all props were defined in Component.handledProps, you need to check that they are equal ' +
211221 'to the union of Component.autoControlledProps and keys of Component.defaultProps and Component.propTypes' ,
@@ -376,6 +386,7 @@ export default (Component, options = {}) => {
376386 } )
377387 } )
378388 }
389+
379390 // ----------------------------------------
380391 // Test typings
381392 // ----------------------------------------
0 commit comments