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+
45import Autocomplete from '../index' ;
56
67const ITEMS = [
@@ -12,111 +13,85 @@ const ITEMS = [
1213 'Revenge of the Sith' ,
1314] as const ;
1415
16+ const suggestionListTestId = 'suggestionListTestId' ;
17+ function TestSuggestionList < T > ( props : FlatListProps < T > ) : ReactElement {
18+ return < FlatList { ...props } testID = { suggestionListTestId } /> ;
19+ }
20+
1521describe ( '<AutocompleteInput />' , ( ) => {
1622 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 ( ) ;
2126 } ) ;
2227
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 } /> ) ;
2630
27- expect ( autocomplete . findAllByType ( FlatList ) ) . toHaveLength ( 0 ) ;
31+ const hiddenSuggestionList = screen . queryByTestId ( suggestionListTestId ) ;
32+ expect ( hiddenSuggestionList ) . not . toBeOnTheScreen ( ) ;
2833
29- testRenderer . update ( < Autocomplete data = { ITEMS } /> ) ;
34+ rerender ( < Autocomplete data = { ITEMS } renderResultList = { TestSuggestionList } /> ) ;
3035
31- const list = autocomplete . findByType ( FlatList ) ;
32- expect ( list . props . data ) . toEqual ( ITEMS ) ;
36+ const suggestionList = screen . getByTestId ( suggestionListTestId ) ;
37+ expect ( suggestionList ) . toBeOnTheScreen ( ) ;
3338
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+ } ) ;
3643 } ) ;
3744
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+ ) ;
4257
43- expect ( autocomplete . findAllByType ( FlatList ) ) . toHaveLength ( 1 ) ;
44- testRenderer . update ( < Autocomplete data = { [ ] } /> ) ;
58+ const suggestionList = screen . getByTestId ( suggestionListTestId ) ;
59+ expect ( suggestionList ) . toBeOnTheScreen ( ) ;
4560
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 ( ) ;
4765 } ) ;
4866
4967 it ( 'should render custom text input' , ( ) => {
50- const text = 'Custom Text Input ' ;
51- const testRenderer = renderer . create (
68+ const customTextInputTestId = 'customTextInput ' ;
69+ render (
5270 < Autocomplete
5371 data = { [ ] }
54- foo = "bar"
55- renderTextInput = { ( props ) => < Text { ...props } > { text } </ Text > }
72+ renderTextInput = { ( props ) => < TextInput { ...props } testID = { customTextInputTestId } /> }
5673 /> ,
5774 ) ;
5875
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 ( ) ;
6478 } ) ;
6579
6680 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" /> ) ;
11082
111- const texts = autocomplete . findAllByType ( Text ) ;
112- expect ( texts ) . toHaveLength ( ITEMS . length ) ;
83+ const input = screen . getByPlaceholderText ( 'Enter search' ) ;
84+ expect ( input ) . toBeOnTheScreen ( ) ;
11385 } ) ;
11486
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+ }
11793
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' ) ;
12196 } ) ;
12297} ) ;
0 commit comments