1
+ /* eslint-disable react/require-default-props */
1
2
/* eslint-disable react/no-array-index-key */
2
- /* eslint-disable react/jsx-filename-extension */
3
3
import '@testing-library/jest-dom' ;
4
4
import React from 'react' ;
5
- import PropTypes from 'prop-types' ;
6
5
import { render , screen } from '@testing-library/react' ;
7
- import { MemoryRouter as Router , Route , useLocation } from 'react-router' ;
8
- import useBreadcrumbs , { getBreadcrumbs , createRoutesFromChildren } from './index.tsx ' ;
6
+ import { MemoryRouter as Router , useLocation } from 'react-router' ;
7
+ import useBreadcrumbs , { getBreadcrumbs , createRoutesFromChildren , BreadcrumbsRoute , Route , Options } from './index' ;
9
8
10
9
// imports to test compiled builds
11
10
import useBreadcrumbsCompiledES , {
12
11
getBreadcrumbs as getBreadcrumbsCompiledES ,
13
12
} from '../dist/es/index' ;
14
13
import useBreadcrumbsCompiledUMD , {
14
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
15
+ // @ts -ignore
15
16
getBreadcrumbs as getBreadcrumbsCompiledUMD ,
16
17
} from '../dist/umd/index' ;
17
18
import useBreadcrumbsCompiledCJS , {
@@ -24,6 +25,10 @@ const components = {
24
25
options,
25
26
routes,
26
27
...forwardedProps
28
+ } : {
29
+ useBreadcrumbs : ( r ?: BreadcrumbsRoute [ ] , o ?: Options ) => [ ]
30
+ options ?: Options
31
+ routes ?: BreadcrumbsRoute [ ]
27
32
} ) => {
28
33
const breadcrumbs = useBreadcrumbsHook ( routes , options ) ;
29
34
const location = useLocation ( ) ;
@@ -34,8 +39,10 @@ const components = {
34
39
< div data-test-id = "forwarded-props" >
35
40
{ forwardedProps
36
41
&& Object . values ( forwardedProps )
37
- . filter ( ( v ) => typeof v === 'string' )
38
- . map ( ( value ) => < span key = { value } > { value } </ span > ) }
42
+ . filter ( ( v : unknown ) => typeof v === 'string' )
43
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
44
+ // @ts -ignore
45
+ . map ( ( value : string ) => < span key = { value } > { value } </ span > ) }
39
46
</ div >
40
47
< div className = "breadcrumbs-container" >
41
48
{ breadcrumbs . map ( ( { breadcrumb, key } , index ) => (
@@ -48,28 +55,44 @@ const components = {
48
55
</ h1 >
49
56
) ;
50
57
} ,
51
- BreadcrumbMatchTest : ( { match } ) => < span > { match . params . number } </ span > ,
52
- BreadcrumbRouteTest : ( { match } ) => < span > { match . route ?. arbitraryProp } </ span > ,
53
- BreadcrumbNavLinkTest : ( { match } ) => < a role = "link" to = { match . pathname } > Link</ a > ,
58
+ BreadcrumbMatchTest : (
59
+ { match } : { match ?: { params ?: { number ?: number } } } ,
60
+ ) => < span > { match ?. params ?. number } </ span > ,
61
+
62
+ BreadcrumbRouteTest : (
63
+ { match } : { match : { route ?: { arbitraryProp : string } } } ,
64
+ ) => < span > { match . route ?. arbitraryProp } </ span > ,
65
+
66
+ BreadcrumbNavLinkTest : (
67
+ { match } : { match : { pathname : string } } ,
68
+ ) => < a href = { match . pathname } > Link</ a > ,
69
+
54
70
BreadcrumbLocationTest : ( {
55
- location : {
56
- state : { isLocationTest } ,
57
- } ,
58
- } ) => < span > { isLocationTest ? 'pass' : 'fail' } </ span > ,
59
- BreadcrumbExtraPropsTest : ( { foo, bar } ) => (
71
+ location,
72
+ } : {
73
+ location ?: {
74
+ state ?: { isLocationTest ?: boolean }
75
+ }
76
+ } ) => < span > { location ?. state ?. isLocationTest ? 'pass' : 'fail' } </ span > ,
77
+
78
+ BreadcrumbExtraPropsTest : ( { foo, bar } : { foo : string , bar : string } ) => (
60
79
< span >
61
80
{ foo }
62
81
{ bar }
63
82
</ span >
64
83
) ,
84
+
65
85
BreadcrumbMemoized : React . memo ( ( ) => < span > Memoized</ span > ) ,
86
+
66
87
// eslint-disable-next-line react/prefer-stateless-function
67
88
BreadcrumbClass : class BreadcrumbClass extends React . PureComponent {
68
89
render ( ) {
69
90
return < span > Class</ span > ;
70
91
}
71
92
} ,
72
- Layout : React . memo ( ( { children } ) => < div > { children } </ div > ) ,
93
+
94
+ // eslint-disable-next-line react/require-default-props
95
+ Layout : React . memo ( ( { children } : { children ?: React . ReactNode } ) => < div > { children } </ div > ) ,
73
96
} ;
74
97
75
98
const getHOC = ( ) => {
@@ -98,13 +121,24 @@ const getMethod = () => {
98
121
}
99
122
} ;
100
123
101
- const renderer = ( { options, pathname, routes, state, props } ) => {
124
+ const renderer = (
125
+ { options, pathname, routes, state, props } :
126
+ {
127
+ options ?: Options
128
+ pathname : string
129
+ routes ?: BreadcrumbsRoute < string > [ ]
130
+ state ?: { isLocationTest : boolean }
131
+ props ?: { [ x : string ] : unknown }
132
+ } ,
133
+ ) => {
102
134
const useBreadcrumbsHook = getHOC ( ) ;
103
135
const { Breadcrumbs } = components ;
104
136
105
137
const wrapper = render (
106
138
< Router initialIndex = { 0 } initialEntries = { [ { pathname, state } ] } >
107
139
< Breadcrumbs
140
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
141
+ // @ts -ignore
108
142
useBreadcrumbs = { useBreadcrumbsHook }
109
143
options = { options }
110
144
routes = { routes }
@@ -118,88 +152,8 @@ const renderer = ({ options, pathname, routes, state, props }) => {
118
152
} ;
119
153
} ;
120
154
121
- const matchShape = {
122
- params : PropTypes . shape ( ) . isRequired ,
123
- pathname : PropTypes . string . isRequired ,
124
- pattern : PropTypes . object . isRequired ,
125
- } ;
126
-
127
- components . Breadcrumbs . propTypes = {
128
- useBreadcrumbs : PropTypes . func . isRequired ,
129
- options : PropTypes . shape ( {
130
- excludePaths : PropTypes . arrayOf ( PropTypes . string ) ,
131
- disableDefaults : PropTypes . bool ,
132
- } ) ,
133
- routes : PropTypes . arrayOf (
134
- PropTypes . oneOfType ( [
135
- PropTypes . shape ( {
136
- path : PropTypes . string ,
137
- breadcrumb : PropTypes . oneOfType ( [
138
- PropTypes . node ,
139
- PropTypes . func ,
140
- PropTypes . object ,
141
- ] ) ,
142
- } ) ,
143
- PropTypes . shape ( {
144
- index : PropTypes . bool ,
145
- breadcrumb : PropTypes . oneOfType ( [
146
- PropTypes . node ,
147
- PropTypes . func ,
148
- PropTypes . object ,
149
- ] ) ,
150
- } ) ,
151
- PropTypes . shape ( {
152
- children : PropTypes . arrayOf ( PropTypes . shape ( ) ) . isRequired ,
153
- breadcrumb : PropTypes . oneOfType ( [
154
- PropTypes . node ,
155
- PropTypes . func ,
156
- PropTypes . object ,
157
- ] ) ,
158
- } ) ,
159
- ] ) ,
160
- ) ,
161
- } ;
162
-
163
- components . Breadcrumbs . defaultProps = {
164
- routes : null ,
165
- options : null ,
166
- } ;
167
-
168
- components . BreadcrumbMatchTest . propTypes = {
169
- match : PropTypes . shape ( matchShape ) . isRequired ,
170
- } ;
171
-
172
- components . BreadcrumbRouteTest . propTypes = {
173
- match : PropTypes . shape ( matchShape ) . isRequired ,
174
- } ;
175
-
176
- components . BreadcrumbNavLinkTest . propTypes = {
177
- match : PropTypes . shape ( matchShape ) . isRequired ,
178
- } ;
179
-
180
- components . BreadcrumbLocationTest . propTypes = {
181
- location : PropTypes . shape ( {
182
- state : PropTypes . shape ( {
183
- isLocationTest : PropTypes . bool . isRequired ,
184
- } ) . isRequired ,
185
- } ) . isRequired ,
186
- } ;
187
-
188
- components . BreadcrumbExtraPropsTest . propTypes = {
189
- foo : PropTypes . string . isRequired ,
190
- bar : PropTypes . string . isRequired ,
191
- } ;
192
-
193
- components . Layout . propTypes = {
194
- children : PropTypes . node ,
195
- } ;
196
-
197
- components . Layout . defaultProps = {
198
- children : null ,
199
- } ;
200
-
201
- const getByTextContent = ( text ) => screen . getByText ( ( content , element ) => {
202
- const hasText = ( ele ) => ele . textContent === text ;
155
+ const getByTextContent = ( text : string ) => screen . getByText ( ( content , element ) => {
156
+ const hasText = ( ele : Element | null ) => ele ?. textContent === text ;
203
157
const elementHasText = hasText ( element ) ;
204
158
const childrenDontHaveText = ( element ?. children ? Array . from ( element . children ) : [ ] )
205
159
. every ( ( child ) => ! hasText ( child ) ) ;
@@ -210,15 +164,16 @@ const getByTextContent = (text) => screen.getByText((content, element) => {
210
164
describe ( 'use-react-router-breadcrumbs' , ( ) => {
211
165
describe ( 'Valid routes' , ( ) => {
212
166
it ( 'Should render breadcrumb components as expected' , ( ) => {
213
- const routes = [
167
+ const { BreadcrumbMatchTest } = components ;
168
+ const routes : BreadcrumbsRoute [ ] = [
214
169
// test home route
215
170
{ path : '/' , breadcrumb : 'Home' } ,
216
171
// test breadcrumb passed as string
217
172
{ path : '/1' , breadcrumb : 'One' } ,
218
173
// test simple breadcrumb component
219
174
{ path : '/1/2' , breadcrumb : ( ) => < span > TWO</ span > } ,
220
175
// test advanced breadcrumb component (user can use `match` however they wish)
221
- { path : '/1/2/:number' , breadcrumb : components . BreadcrumbMatchTest } ,
176
+ { path : '/1/2/:number' , breadcrumb : BreadcrumbMatchTest } ,
222
177
// test NavLink wrapped breadcrumb
223
178
{
224
179
path : '/1/2/:number/4' ,
@@ -232,7 +187,7 @@ describe('use-react-router-breadcrumbs', () => {
232
187
routes,
233
188
} ) ;
234
189
expect ( getByTextContent ( 'Home / One / TWO / 3 / Link / Any' ) ) . toBeTruthy ( ) ;
235
- expect ( screen . getByRole ( 'link' ) ) . toHaveAttribute ( 'to ' , '/1/2/3/4' ) ;
190
+ expect ( screen . getByRole ( 'link' ) ) . toHaveAttribute ( 'href ' , '/1/2/3/4' ) ;
236
191
} ) ;
237
192
} ) ;
238
193
@@ -536,7 +491,6 @@ describe('use-react-router-breadcrumbs', () => {
536
491
it ( 'Should be able to set options without defining a routes array' , ( ) => {
537
492
renderer ( {
538
493
pathname : '/one/two' ,
539
- routes : null ,
540
494
options : { excludePaths : [ '/' , '/one' ] } ,
541
495
} ) ;
542
496
expect ( getByTextContent ( 'Two' ) ) . toBeTruthy ( ) ;
@@ -569,7 +523,7 @@ describe('use-react-router-breadcrumbs', () => {
569
523
renderer ( {
570
524
pathname : '/one/two/three_four' ,
571
525
routes,
572
- options : { defaultFormatter : ( breadcrumb ) => breadcrumb . replace ( / t w o / g, 'changed' ) } ,
526
+ options : { defaultFormatter : ( breadcrumb : string ) => breadcrumb . replace ( / t w o / g, 'changed' ) } ,
573
527
} ) ;
574
528
575
529
expect ( getByTextContent ( 'Home / One / changed / three_four' ) ) . toBeTruthy ( ) ;
0 commit comments