@@ -4,7 +4,7 @@ import { AsyncView } from '../AsyncView'
44
55type Data = {
66 greeting : string
7- }
7+ } | null
88
99type Error = {
1010 message : string
@@ -15,36 +15,76 @@ const Loading: React.FC = () => {
1515}
1616
1717const Success : React . FC < { data : Data } > = ( { data } ) => {
18- return < > { data . greeting } </ >
18+ return < > { data ? .greeting } </ >
1919}
2020
2121const Error : React . FC < { error : Error } > = ( { error } ) => {
2222 return < > { error . message } </ >
2323}
2424
25- function renderAsyncView ( data ?: Data , error ?: Error ) : RenderResult {
25+ type RenderAsyncViewProps = {
26+ isLoading : boolean
27+ error ?: Error
28+ data ?: Data
29+ allowMissingData ?: boolean
30+ }
31+
32+ function renderAsyncView ( {
33+ isLoading,
34+ data,
35+ error,
36+ allowMissingData = false ,
37+ } : RenderAsyncViewProps ) : RenderResult {
2638 return render (
27- < AsyncView < Data , Error >
39+ < AsyncView
40+ isLoading = { isLoading }
2841 data = { data }
2942 error = { error }
43+ allowMissingData = { allowMissingData }
3044 renderLoading = { < Loading /> }
31- renderSuccess = { ( data ) => < Success data = { data } /> }
45+ renderSuccess = { ( data : unknown ) => < Success data = { data as Data } /> }
3246 renderError = { ( error ) => < Error error = { error } /> }
3347 /> ,
3448 )
3549}
3650
3751test ( 'should render loading if asyncState is loading for the first time' , function ( ) {
38- const { getByText } = renderAsyncView ( )
52+ const { getByText } = renderAsyncView ( { isLoading : true } )
3953 expect ( getByText ( / l o a d i n g / i) ) . toBeInTheDocument ( )
4054} )
4155
4256test ( 'should render success if asyncState is successful' , function ( ) {
43- const { getByText } = renderAsyncView ( { greeting : 'Hello' } )
57+ const { getByText } = renderAsyncView ( {
58+ isLoading : false ,
59+ data : { greeting : 'Hello' } ,
60+ } )
4461 expect ( getByText ( / h e l l o / i) ) . toBeInTheDocument ( )
4562} )
4663
64+ test . each ( [ null , undefined ] ) (
65+ 'should throw asyncState is successful but data is missing' ,
66+ function ( value ) {
67+ expect ( renderAsyncView ( { isLoading : false , data : value } ) ) . toThrow ( )
68+ } ,
69+ )
70+
71+ test . each ( [ null , undefined ] ) (
72+ 'should render success if asyncState is successful but data is missing but allowed' ,
73+ function ( value ) {
74+ expect (
75+ renderAsyncView ( {
76+ isLoading : false ,
77+ data : value ,
78+ allowMissingData : true ,
79+ } ) ,
80+ ) . not . toThrow ( )
81+ } ,
82+ )
83+
4784test ( 'should render error if asyncState is error' , function ( ) {
48- const { getByText } = renderAsyncView ( undefined , { message : 'Error' } )
85+ const { getByText } = renderAsyncView ( {
86+ isLoading : false ,
87+ error : { message : 'Error' } ,
88+ } )
4989 expect ( getByText ( / e r r o r / i) ) . toBeInTheDocument ( )
5090} )
0 commit comments