1
- import React from 'react' ;
2
- import renderer from 'react-test-renderer' ;
3
- import { FlatList , Text , TextInput , View } from 'react-native' ;
1
+ import React , { type ReactElement } from 'react' ;
2
+ import { render , screen , within } from '@testing-library/react-native' ;
3
+ import { FlatList , TextInput , type FlatListProps } from 'react-native' ;
4
+
4
5
import Autocomplete from '../index' ;
5
6
6
7
const ITEMS = [
@@ -12,111 +13,85 @@ const ITEMS = [
12
13
'Revenge of the Sith' ,
13
14
] as const ;
14
15
16
+ const suggestionListTestId = 'suggestionListTestId' ;
17
+ function TestSuggestionList < T > ( props : FlatListProps < T > ) : ReactElement {
18
+ return < FlatList { ...props } testID = { suggestionListTestId } /> ;
19
+ }
20
+
15
21
describe ( '<AutocompleteInput />' , ( ) => {
16
22
it ( 'should hide suggestion list on initial render' , ( ) => {
17
- const r = renderer . create ( < Autocomplete data = { [ ] } /> ) ;
18
- const autocomplete = r . root ;
19
-
20
- expect ( autocomplete . findAllByType ( FlatList ) ) . toHaveLength ( 0 ) ;
23
+ render ( < Autocomplete data = { [ ] } renderResultList = { TestSuggestionList } /> ) ;
24
+ const suggestionList = screen . queryByTestId ( suggestionListTestId ) ;
25
+ expect ( suggestionList ) . not . toBeOnTheScreen ( ) ;
21
26
} ) ;
22
27
23
- it ( 'should show suggestion list when data gets updated with length > 0' , ( ) => {
24
- const testRenderer = renderer . create ( < Autocomplete data = { [ ] } /> ) ;
25
- const autocomplete = testRenderer . root ;
28
+ it ( 'should show suggestion list with suggestions when data gets updated with length > 0' , ( ) => {
29
+ const { rerender } = render ( < Autocomplete data = { [ ] } renderResultList = { TestSuggestionList } /> ) ;
26
30
27
- expect ( autocomplete . findAllByType ( FlatList ) ) . toHaveLength ( 0 ) ;
31
+ const hiddenSuggestionList = screen . queryByTestId ( suggestionListTestId ) ;
32
+ expect ( hiddenSuggestionList ) . not . toBeOnTheScreen ( ) ;
28
33
29
- testRenderer . update ( < Autocomplete data = { ITEMS } /> ) ;
34
+ rerender ( < Autocomplete data = { ITEMS } renderResultList = { TestSuggestionList } /> ) ;
30
35
31
- const list = autocomplete . findByType ( FlatList ) ;
32
- expect ( list . props . data ) . toEqual ( ITEMS ) ;
36
+ const suggestionList = screen . getByTestId ( suggestionListTestId ) ;
37
+ expect ( suggestionList ) . toBeOnTheScreen ( ) ;
33
38
34
- const texts = list . findAllByType ( Text ) ;
35
- expect ( texts ) . toHaveLength ( ITEMS . length ) ;
39
+ const suggestions = within ( suggestionList ) . getAllByRole ( 'text' ) ;
40
+ suggestions . forEach ( ( suggestion , index ) => {
41
+ expect ( suggestion ) . toHaveTextContent ( ITEMS [ index ] ) ;
42
+ } ) ;
36
43
} ) ;
37
44
38
- it ( 'should hide suggestion list when data gets updates with length < 1' , ( ) => {
39
- const props = { data : ITEMS } ;
40
- const testRenderer = renderer . create ( < Autocomplete { ...props } /> ) ;
41
- const autocomplete = testRenderer . root ;
45
+ it ( 'should apply default render list function' , ( ) => {
46
+ render ( < Autocomplete data = { ITEMS } renderResultList = { undefined } /> ) ;
47
+ const suggestions = screen . getAllByRole ( 'text' ) ;
48
+ suggestions . forEach ( ( suggestion , index ) => {
49
+ expect ( suggestion ) . toHaveTextContent ( ITEMS [ index ] ) ;
50
+ } ) ;
51
+ } ) ;
52
+
53
+ it ( 'should hide suggestion list when data gets updated with length < 1' , ( ) => {
54
+ const { rerender } = render (
55
+ < Autocomplete data = { ITEMS } renderResultList = { TestSuggestionList } /> ,
56
+ ) ;
42
57
43
- expect ( autocomplete . findAllByType ( FlatList ) ) . toHaveLength ( 1 ) ;
44
- testRenderer . update ( < Autocomplete data = { [ ] } /> ) ;
58
+ const suggestionList = screen . getByTestId ( suggestionListTestId ) ;
59
+ expect ( suggestionList ) . toBeOnTheScreen ( ) ;
45
60
46
- expect ( autocomplete . findAllByType ( FlatList ) ) . toHaveLength ( 0 ) ;
61
+ rerender ( < Autocomplete data = { [ ] } renderResultList = { TestSuggestionList } /> ) ;
62
+
63
+ const hiddenSuggestionList = screen . queryByTestId ( suggestionListTestId ) ;
64
+ expect ( hiddenSuggestionList ) . not . toBeOnTheScreen ( ) ;
47
65
} ) ;
48
66
49
67
it ( 'should render custom text input' , ( ) => {
50
- const text = 'Custom Text Input ' ;
51
- const testRenderer = renderer . create (
68
+ const customTextInputTestId = 'customTextInput ' ;
69
+ render (
52
70
< Autocomplete
53
71
data = { [ ] }
54
- foo = "bar"
55
- renderTextInput = { ( props ) => < Text { ...props } > { text } </ Text > }
72
+ renderTextInput = { ( props ) => < TextInput { ...props } testID = { customTextInputTestId } /> }
56
73
/> ,
57
74
) ;
58
75
59
- const autocomplete = testRenderer . root ;
60
- const customTextInput = autocomplete . findByType ( Text ) ;
61
-
62
- expect ( ( customTextInput . children [ 0 ] as { children : unknown [ ] } ) . children ) . toEqual ( [ text ] ) ;
63
- expect ( autocomplete . findAllByType ( TextInput ) ) . toHaveLength ( 0 ) ;
76
+ const textInput = screen . getByTestId ( customTextInputTestId ) ;
77
+ expect ( textInput ) . toBeOnTheScreen ( ) ;
64
78
} ) ;
65
79
66
80
it ( 'should render default <TextInput /> if no custom one is supplied' , ( ) => {
67
- const props = { foo : 'bar' } ;
68
- const testRenderer = renderer . create ( < Autocomplete data = { [ ] } { ...props } /> ) ;
69
- const autocomplete = testRenderer . root ;
70
- const textInput = autocomplete . findByType ( TextInput ) ;
71
-
72
- expect ( textInput . props ) . toEqual ( expect . objectContaining ( props ) ) ;
73
- } ) ;
74
-
75
- it ( 'should render default <FlatList /> if no custom one is supplied' , ( ) => {
76
- const testRenderer = renderer . create ( < Autocomplete data = { ITEMS } /> ) ;
77
- const autocomplete = testRenderer . root ;
78
- const list = autocomplete . findByType ( FlatList ) ;
79
-
80
- expect ( list . props . data ) . toEqual ( ITEMS ) ;
81
- } ) ;
82
-
83
- it ( 'should only pass props in flatListProps to <FlatList />' , ( ) => {
84
- // Using keyExtractor isn't important for the test, but prevents a warning
85
- const keyExtractor = ( _ , index ) => `key-${ index } ` ;
86
- const flatListProps = { foo : 'bar' , keyExtractor } ;
87
- const otherProps = { baz : 'qux' } ;
88
- const testRenderer = renderer . create (
89
- < Autocomplete data = { ITEMS } flatListProps = { flatListProps } { ...otherProps } /> ,
90
- ) ;
91
- const autocomplete = testRenderer . root ;
92
- const list = autocomplete . findByType ( FlatList ) ;
93
-
94
- expect ( list . props ) . toEqual ( expect . objectContaining ( flatListProps ) ) ;
95
- expect ( list . props ) . toEqual ( expect . not . objectContaining ( otherProps ) ) ;
96
- } ) ;
97
-
98
- it ( 'should render a custom result list' , ( ) => {
99
- const testRenderer = renderer . create (
100
- < Autocomplete
101
- data = { ITEMS }
102
- renderResultList = { ( { data, style } ) => (
103
- < View style = { style } > { data ?. map ( ( item , index ) => < Text key = { index } > { item } </ Text > ) } </ View >
104
- ) }
105
- /> ,
106
- ) ;
107
-
108
- const autocomplete = testRenderer . root ;
109
- expect ( autocomplete . findAllByType ( FlatList ) ) . toHaveLength ( 0 ) ;
81
+ render ( < Autocomplete data = { [ ] } placeholder = "Enter search" /> ) ;
110
82
111
- const texts = autocomplete . findAllByType ( Text ) ;
112
- expect ( texts ) . toHaveLength ( ITEMS . length ) ;
83
+ const input = screen . getByPlaceholderText ( 'Enter search' ) ;
84
+ expect ( input ) . toBeOnTheScreen ( ) ;
113
85
} ) ;
114
86
115
- it ( 'should forward the ref to the input' , ( ) => {
116
- const inputRef = React . createRef ( ) ;
87
+ it ( 'should forward the ref to the text input' , async ( ) => {
88
+ let ref : React . RefObject < TextInput > ;
89
+ function TestForwardRefComponent ( ) {
90
+ ref = React . useRef < TextInput > ( null ) ;
91
+ return < Autocomplete data = { ITEMS } placeholder = "TestText" ref = { ref } /> ;
92
+ }
117
93
118
- renderer . create ( < Autocomplete data = { ITEMS } ref = { inputRef } /> ) ;
119
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
120
- expect ( ( inputRef . current as any ) . _reactInternals . elementType . displayName ) . toBe ( 'TextInput' ) ;
94
+ render ( < TestForwardRefComponent /> ) ;
95
+ expect ( ref ! . current ?. constructor . name ) . toBe ( 'TextInput' ) ;
121
96
} ) ;
122
97
} ) ;
0 commit comments