@@ -3,7 +3,7 @@ import React from 'react';
3
3
import { render } from '@testing-library/react' ;
4
4
import { parse } from 'react-docgen' ;
5
5
import PropsRenderer , { columns , getRowKey } from './PropsRenderer' ;
6
- import { unquote , getType , showSpaces , PropDescriptorWithFlow } from './util' ;
6
+ import { unquote , getType , showSpaces , PropDescriptor } from './util' ;
7
7
8
8
const propsToArray = ( props : any ) => Object . keys ( props ) . map ( name => ( { ...props [ name ] , name } ) ) ;
9
9
@@ -16,7 +16,7 @@ const getText = (node: { innerHTML: string }): string =>
16
16
. trim ( ) ;
17
17
18
18
// Test renderers with clean readable snapshot diffs
19
- export default function ColumnsRenderer ( { props } : { props : PropDescriptorWithFlow [ ] } ) {
19
+ export default function ColumnsRenderer ( { props } : { props : PropDescriptor [ ] } ) {
20
20
return (
21
21
< >
22
22
{ props . map ( ( row , rowIdx ) => (
@@ -58,11 +58,12 @@ function renderJs(propTypes: string[], defaultProps: string[] = []) {
58
58
return render ( < ColumnsRenderer props = { propsToArray ( props . props ) } /> ) ;
59
59
}
60
60
61
- function renderFlow ( propsType : string [ ] , defaultProps : string [ ] = [ ] ) {
61
+ function renderFlow ( propsType : string [ ] , defaultProps : string [ ] = [ ] , preparations : string [ ] = [ ] ) {
62
62
const props = parse (
63
63
`
64
64
// @flow
65
65
import * as React from 'react';
66
+ ${ preparations . join ( ';' ) }
66
67
type Props = {
67
68
${ propsType . join ( ',' ) }
68
69
};
@@ -84,6 +85,36 @@ function renderFlow(propsType: string[], defaultProps: string[] = []) {
84
85
return render ( < ColumnsRenderer props = { propsToArray ( props . props ) } /> ) ;
85
86
}
86
87
88
+ function renderTypeScript (
89
+ propsType : string [ ] ,
90
+ defaultProps : string [ ] = [ ] ,
91
+ preparations : string [ ] = [ ]
92
+ ) {
93
+ const props = parse (
94
+ `
95
+ import * as React from 'react';
96
+ ${ preparations . join ( ';' ) }
97
+ type Props = {
98
+ ${ propsType . join ( ';' ) }
99
+ };
100
+ export default class Cmpnt extends React.Component<Props> {
101
+ static defaultProps = {
102
+ ${ defaultProps . join ( ',' ) }
103
+ }
104
+ render() {
105
+ }
106
+ }
107
+ ` ,
108
+ undefined ,
109
+ undefined ,
110
+ { filename : 'Component.tsx' }
111
+ ) ;
112
+ if ( Array . isArray ( props ) ) {
113
+ return render ( < div /> ) ;
114
+ }
115
+ return render ( < ColumnsRenderer props = { propsToArray ( props . props ) } /> ) ;
116
+ }
117
+
87
118
describe ( 'PropsRenderer' , ( ) => {
88
119
test ( 'should render a table' , async ( ) => {
89
120
const { findAllByRole } = render (
@@ -509,94 +540,107 @@ describe('props columns', () => {
509
540
` ) ;
510
541
} ) ;
511
542
512
- test ( 'should render type string' , ( ) => {
513
- const { container } = renderFlow ( [ 'foo: string' ] ) ;
514
-
515
- expect ( getText ( container ) ) . toMatchInlineSnapshot ( `
516
- "Prop name: foo
517
- Type: string
518
- Default: Required
519
- Description:"
520
- ` ) ;
521
- } ) ;
522
-
523
- test ( 'should render optional type string' , ( ) => {
524
- const { container } = renderFlow ( [ 'foo?: string' ] ) ;
525
-
526
- expect ( getText ( container ) ) . toMatchInlineSnapshot ( `
527
- "Prop name: foo
528
- Type: string
529
- Default:
530
- Description:"
531
- ` ) ;
532
- } ) ;
533
-
534
- test ( 'should render type string with a default value' , ( ) => {
535
- const { container } = renderFlow ( [ 'foo?: string' ] , [ 'foo: "bar"' ] ) ;
536
-
537
- expect ( getText ( container ) ) . toMatchInlineSnapshot ( `
538
- "Prop name: foo
539
- Type: string
540
- Default: bar
541
- Description:"
542
- ` ) ;
543
- } ) ;
544
-
545
- test ( 'should render literal type' , ( ) => {
546
- const { container } = renderFlow ( [ 'foo?: "bar"' ] ) ;
547
-
548
- expect ( getText ( container ) ) . toMatchInlineSnapshot ( `
549
- "Prop name: foo
550
- Type: \\"bar\\"
551
- Default:
552
- Description:"
553
- ` ) ;
554
- } ) ;
555
-
556
- test ( 'should render object type with body in tooltip' , ( ) => {
557
- const { getByText } = renderFlow ( [ 'foo: { bar: string }' ] ) ;
558
-
559
- expect ( getByText ( 'object' ) . title ) . toMatchInlineSnapshot ( `"{ bar: string }"` ) ;
560
- } ) ;
561
-
562
- test ( 'should render function type with body in tooltip' , ( ) => {
563
- const { getByText } = renderFlow ( [ 'foo: () => void' ] ) ;
564
-
565
- expect ( getByText ( 'function' ) . title ) . toMatchInlineSnapshot ( `"() => void"` ) ;
566
- } ) ;
567
-
568
- test ( 'should render union type with body in tooltip' , ( ) => {
569
- const { getByText } = renderFlow ( [ 'foo: "bar" | number' ] ) ;
570
-
571
- expect ( getByText ( 'union' ) . title ) . toMatchInlineSnapshot ( `"\\"bar\\" | number"` ) ;
572
- } ) ;
573
-
574
- test ( 'should render enum type when union of literals' , ( ) => {
575
- const { container } = renderFlow ( [ 'foo: "bar" | "baz"' ] ) ;
576
-
577
- expect ( getText ( container ) ) . toMatchInlineSnapshot ( `
578
- "Prop name: foo
579
- Type: enum
580
- Default: Required
581
- Description:"
582
- ` ) ;
583
- } ) ;
584
-
585
- test ( 'should render tuple type with body in tooltip' , ( ) => {
586
- const { getByText } = renderFlow ( [ 'foo: ["bar", number]' ] ) ;
587
-
588
- expect ( getByText ( 'tuple' ) . title ) . toMatchInlineSnapshot ( `"[\\"bar\\", number]"` ) ;
589
- } ) ;
590
-
591
- test ( 'should render custom class type' , ( ) => {
592
- const { container } = renderFlow ( [ 'foo: React.ReactNode' ] ) ;
593
-
594
- expect ( getText ( container ) ) . toMatchInlineSnapshot ( `
595
- "Prop name: foo
596
- Type: React.ReactNode
597
- Default: Required
598
- Description:"
599
- ` ) ;
543
+ describe . each ( [
544
+ [
545
+ 'flowType' ,
546
+ renderFlow ,
547
+ { enum : { declaration : "type MyEnum = 'One' | 'Two'" , expect : { type : 'enum' } } } ,
548
+ ] ,
549
+ [
550
+ 'TypeScript' ,
551
+ renderTypeScript ,
552
+ { enum : { declaration : 'enum MyEnum { One, Two }' , expect : { type : 'MyEnum' } } } ,
553
+ ] ,
554
+ ] ) ( '%s' , ( _ , renderFn , options ) => {
555
+ test ( 'should render type string' , ( ) => {
556
+ const { container } = renderFn ( [ 'foo: string' ] ) ;
557
+
558
+ expect ( getText ( container ) ) . toMatchInlineSnapshot ( `
559
+ "Prop name: foo
560
+ Type: string
561
+ Default: Required
562
+ Description:"
563
+ ` ) ;
564
+ } ) ;
565
+
566
+ test ( 'should render optional type string' , ( ) => {
567
+ const { container } = renderFn ( [ 'foo?: string' ] ) ;
568
+
569
+ expect ( getText ( container ) ) . toMatchInlineSnapshot ( `
570
+ "Prop name: foo
571
+ Type: string
572
+ Default:
573
+ Description:"
574
+ ` ) ;
575
+ } ) ;
576
+
577
+ test ( 'should render type string with a default value' , ( ) => {
578
+ const { container } = renderFn ( [ 'foo?: string' ] , [ 'foo: "bar"' ] ) ;
579
+
580
+ expect ( getText ( container ) ) . toMatchInlineSnapshot ( `
581
+ "Prop name: foo
582
+ Type: string
583
+ Default: bar
584
+ Description:"
585
+ ` ) ;
586
+ } ) ;
587
+
588
+ test ( 'should render object type with body in tooltip' , ( ) => {
589
+ const { getByText } = renderFn ( [ 'foo: { bar: string }' ] ) ;
590
+
591
+ expect ( getByText ( 'object' ) . title ) . toMatchInlineSnapshot ( `"{ bar: string }"` ) ;
592
+ } ) ;
593
+
594
+ test ( 'should render function type with body in tooltip' , ( ) => {
595
+ const { getByText } = renderFn ( [ 'foo: () => void' ] ) ;
596
+
597
+ expect ( getByText ( 'function' ) . title ) . toMatchInlineSnapshot ( `"() => void"` ) ;
598
+ } ) ;
599
+
600
+ test ( 'should render union type with body in tooltip' , ( ) => {
601
+ const { getByText } = renderFn ( [ 'foo: "bar" | number' ] ) ;
602
+
603
+ expect ( getByText ( 'union' ) . title ) . toMatchInlineSnapshot ( `"\\"bar\\" | number"` ) ;
604
+ } ) ;
605
+
606
+ test ( 'should render enum type' , ( ) => {
607
+ const { container } = renderFn ( [ 'foo: MyEnum' ] , [ ] , [ options . enum . declaration ] ) ;
608
+
609
+ expect ( getText ( container ) ) . toMatchInlineSnapshot ( `
610
+ "Prop name: foo
611
+ Type: ${ options . enum . expect . type }
612
+ Default: Required
613
+ Description:"
614
+ ` ) ;
615
+ } ) ;
616
+
617
+ test ( 'should render tuple type with body in tooltip' , ( ) => {
618
+ const { getByText } = renderFn ( [ 'foo: ["bar", number]' ] ) ;
619
+
620
+ expect ( getByText ( 'tuple' ) . title ) . toMatchInlineSnapshot ( `"[\\"bar\\", number]"` ) ;
621
+ } ) ;
622
+
623
+ test ( 'should render custom class type' , ( ) => {
624
+ const { container } = renderFn ( [ 'foo: React.ReactNode' ] ) ;
625
+
626
+ expect ( getText ( container ) ) . toMatchInlineSnapshot ( `
627
+ "Prop name: foo
628
+ Type: React.ReactNode
629
+ Default: Required
630
+ Description:"
631
+ ` ) ;
632
+ } ) ;
633
+
634
+ test ( 'should render unknown when a relevant prop type is not assigned' , ( ) => {
635
+ const { container } = renderFn ( [ ] , [ 'color: "pink"' ] ) ;
636
+
637
+ expect ( getText ( container ) ) . toMatchInlineSnapshot ( `
638
+ "Prop name: color
639
+ Type:
640
+ Default: pink
641
+ Description:"
642
+ ` ) ;
643
+ } ) ;
600
644
} ) ;
601
645
} ) ;
602
646
@@ -618,13 +662,28 @@ describe('unquote', () => {
618
662
} ) ;
619
663
620
664
describe ( 'getType' , ( ) => {
621
- test ( 'should return .type or .flowType property' , ( ) => {
665
+ test ( 'should return not .type but .flowType property' , ( ) => {
622
666
const result = getType ( {
623
667
type : 'foo' ,
624
668
flowType : 'bar' ,
625
669
} as any ) ;
626
670
expect ( result ) . toBe ( 'bar' ) ;
627
671
} ) ;
672
+
673
+ test ( 'should return not .type but .tsType property' , ( ) => {
674
+ const result = getType ( {
675
+ type : 'foo' ,
676
+ tsType : 'bar' ,
677
+ } as any ) ;
678
+ expect ( result ) . toBe ( 'bar' ) ;
679
+ } ) ;
680
+
681
+ test ( 'should return .type property' , ( ) => {
682
+ const result = getType ( {
683
+ type : 'foo' ,
684
+ } as any ) ;
685
+ expect ( result ) . toBe ( 'foo' ) ;
686
+ } ) ;
628
687
} ) ;
629
688
630
689
describe ( 'showSpaces' , ( ) => {
0 commit comments