-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[NO QA][TS migration] Migrate '[Remaining]' test to TypeScript #36867
Changes from 27 commits
33b1400
dbe4d7c
9d10ab7
0bfbaee
cb7e261
8d354d1
4d4628c
6ff1321
6cae028
7b5f839
46506f0
2d930dc
59071f1
3cc250c
b0a88ed
dff82ff
54deb99
093e674
c79782d
0c050cc
f82a45b
f5e2c6a
8deff43
b914a43
ac4284e
d2c5348
599adad
aaad266
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,15 @@ | ||
import {fireEvent} from '@testing-library/react-native'; | ||
import type {RenderResult} from '@testing-library/react-native'; | ||
import React from 'react'; | ||
import type {ComponentType} from 'react'; | ||
import {measurePerformance} from 'reassure'; | ||
import _ from 'underscore'; | ||
import type {WithLocalizeProps} from '@components/withLocalize'; | ||
import type {WithNavigationFocusProps} from '@components/withNavigationFocus'; | ||
import OptionsSelector from '@src/components/OptionsSelector'; | ||
import variables from '@src/styles/variables'; | ||
|
||
jest.mock('../../src/components/withLocalize', () => (Component) => { | ||
function WrappedComponent(props) { | ||
jest.mock('@src/components/withLocalize', () => (Component: ComponentType<WithLocalizeProps>) => { | ||
function WrappedComponent(props: WithLocalizeProps) { | ||
return ( | ||
<Component | ||
// eslint-disable-next-line react/jsx-props-no-spreading | ||
|
@@ -19,8 +22,8 @@ jest.mock('../../src/components/withLocalize', () => (Component) => { | |
return WrappedComponent; | ||
}); | ||
|
||
jest.mock('../../src/components/withNavigationFocus', () => (Component) => { | ||
function WithNavigationFocus(props) { | ||
jest.mock('@src/components/withNavigationFocus', () => (Component: ComponentType<WithNavigationFocusProps>) => { | ||
function WithNavigationFocus(props: WithNavigationFocusProps) { | ||
return ( | ||
<Component | ||
// eslint-disable-next-line react/jsx-props-no-spreading | ||
|
@@ -35,25 +38,27 @@ jest.mock('../../src/components/withNavigationFocus', () => (Component) => { | |
return WithNavigationFocus; | ||
}); | ||
|
||
const generateSections = (sectionConfigs) => | ||
_.map(sectionConfigs, ({numItems, indexOffset, shouldShow = true}) => ({ | ||
data: Array.from({length: numItems}, (_v, i) => ({ | ||
type GenerateSectionsProps = Array<{numberOfItems: number; indexOffset: number; shouldShow?: boolean}>; | ||
|
||
const generateSections = (sections: GenerateSectionsProps) => | ||
sections.map(({numberOfItems, indexOffset, shouldShow = true}) => ({ | ||
data: Array.from({length: numberOfItems}, (v, i) => ({ | ||
text: `Item ${i + indexOffset}`, | ||
keyForList: `item-${i + indexOffset}`, | ||
})), | ||
indexOffset, | ||
shouldShow, | ||
})); | ||
|
||
const singleSectionSConfig = [{numItems: 1000, indexOffset: 0}]; | ||
const singleSectionsConfig = [{numberOfItems: 1000, indexOffset: 0}]; | ||
|
||
const mutlipleSectionsConfig = [ | ||
{numItems: 1000, indexOffset: 0}, | ||
{numItems: 100, indexOffset: 70}, | ||
{numberOfItems: 1000, indexOffset: 0}, | ||
{numberOfItems: 100, indexOffset: 70}, | ||
]; | ||
|
||
// @ts-expect-error TODO: Remove this once OptionsSelector is migrated to TypeScript. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do we have any issue to track this @cead22 ? If not, should we be creating one? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We have this one but it's closed #25125. Maybe we need a new one for src/components/OptionsSelector/index.android.js and src/components/OptionsSelector/index.js |
||
function OptionsSelectorWrapper(args) { | ||
const sections = generateSections(singleSectionSConfig); | ||
const sections = generateSections(singleSectionsConfig); | ||
return ( | ||
<OptionsSelector | ||
value="test" | ||
|
@@ -65,12 +70,12 @@ function OptionsSelectorWrapper(args) { | |
} | ||
HezekielT marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
test('[OptionsSelector] should render text input with interactions', () => { | ||
const scenario = (screen) => { | ||
const scenario = ((screen: RenderResult) => { | ||
const textInput = screen.getByTestId('options-selector-input'); | ||
fireEvent.changeText(textInput, 'test'); | ||
fireEvent.changeText(textInput, 'test2'); | ||
fireEvent.changeText(textInput, 'test3'); | ||
}; | ||
}) as Awaited<(screen: RenderResult) => Promise<void>>; | ||
|
||
measurePerformance(<OptionsSelectorWrapper />, {scenario}); | ||
}); | ||
|
@@ -85,22 +90,22 @@ test('[OptionsSelector] should render multiple sections', () => { | |
}); | ||
|
||
test('[OptionsSelector] should press a list items', () => { | ||
const scenario = (screen) => { | ||
const scenario = ((screen: RenderResult) => { | ||
fireEvent.press(screen.getByText('Item 1')); | ||
fireEvent.press(screen.getByText('Item 5')); | ||
fireEvent.press(screen.getByText('Item 10')); | ||
}; | ||
}) as Awaited<(screen: RenderResult) => Promise<void>>; | ||
|
||
measurePerformance(<OptionsSelectorWrapper />, {scenario}); | ||
}); | ||
|
||
test('[OptionsSelector] should scroll and press few items', () => { | ||
const sections = generateSections(mutlipleSectionsConfig); | ||
|
||
const generateEventData = (numOptions, optionRowHeight) => ({ | ||
const generateEventData = (numberOfOptions: number, optionRowHeight: number) => ({ | ||
nativeEvent: { | ||
contentOffset: { | ||
y: optionRowHeight * numOptions, | ||
y: optionRowHeight * numberOfOptions, | ||
}, | ||
contentSize: { | ||
height: optionRowHeight * 10, | ||
|
@@ -115,7 +120,7 @@ test('[OptionsSelector] should scroll and press few items', () => { | |
|
||
const eventData = generateEventData(100, variables.optionRowHeight); | ||
const eventData2 = generateEventData(200, variables.optionRowHeight); | ||
const scenario = async (screen) => { | ||
const scenario = async (screen: RenderResult) => { | ||
fireEvent.press(screen.getByText('Item 10')); | ||
fireEvent.scroll(screen.getByTestId('options-list'), eventData); | ||
fireEvent.press(await screen.findByText('Item 100')); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't put TODOs in the code. If we have an issue, that's already good enough
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I included the TODO part because of the guidelines
Link
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hayata-suenaga any reason we need TODOs in the code, or are GH issues sufficient? I ask cause we normally don't put TODOs in code (see SO), and this guideline is kinda contradicts that. In any case, @HezekielT don't block on this, and sorry for the confusion
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cead22 We were at a point where every issue was blocked by some other and without
@ts-expect-error
we would be stuck or move very slowly. That's why we decided to allow TODOs in the codebase, the good part is that onceTestHelper
gets migrated here, this line will throw an error so these TODOs will disappear over time (once we migrate blocking files).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks @blazejkustra for the explanation!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the context. I'm still curious, why do we need TODOs when we have GH issues? Don't the GH issues serve as TODOs? Could we link the lines of codes in the issues, instead of linking the issues in the code?