-
Notifications
You must be signed in to change notification settings - Fork 44
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: toBeOnTheScreen() matcher (#125)
- Loading branch information
1 parent
c3dc5ce
commit a97ed16
Showing
8 changed files
with
192 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import * as React from 'react'; | ||
import { View } from 'react-native'; | ||
import { render } from '@testing-library/react-native'; | ||
|
||
jest.mock('@testing-library/react-native', () => ({ | ||
...jest.requireActual('@testing-library/react-native'), | ||
screen: undefined, | ||
})); | ||
|
||
test('toBeOnTheScreen() on null element', () => { | ||
const screen = render(<View testID="test" />); | ||
|
||
const test = screen.getByTestId('test'); | ||
expect(() => expect(test).toBeOnTheScreen()).toThrowErrorMatchingInlineSnapshot(` | ||
"Could not import \`screen\` object from @testing-library/react-native. | ||
Using toBeOnTheScreen() matcher requires @testing-library/react-native v10.1.0 or later to be added to your devDependencies." | ||
`); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import * as React from 'react'; | ||
import { View, Text } from 'react-native'; | ||
import { render, screen } from '@testing-library/react-native'; | ||
|
||
function ShowChildren({ show }: { show: boolean }) { | ||
return show ? ( | ||
<View> | ||
<Text testID="text">Hello</Text> | ||
</View> | ||
) : ( | ||
<View /> | ||
); | ||
} | ||
|
||
test('toBeOnTheScreen() on attached element', () => { | ||
render(<View testID="test" />); | ||
const element = screen.getByTestId('test'); | ||
expect(element).toBeOnTheScreen(); | ||
expect(() => expect(element).not.toBeOnTheScreen()).toThrowErrorMatchingInlineSnapshot(` | ||
"expect(element).not.toBeOnTheScreen() | ||
expected element tree not to contain element but found: | ||
<View | ||
testID="test" | ||
/>" | ||
`); | ||
}); | ||
|
||
test('toBeOnTheScreen() on detached element', () => { | ||
render(<ShowChildren show />); | ||
const element = screen.getByTestId('text'); | ||
|
||
screen.update(<ShowChildren show={false} />); | ||
expect(element).toBeTruthy(); | ||
expect(element).not.toBeOnTheScreen(); | ||
expect(() => expect(element).toBeOnTheScreen()).toThrowErrorMatchingInlineSnapshot(` | ||
"expect(element).toBeOnTheScreen() | ||
element could not be found in the element tree" | ||
`); | ||
}); | ||
|
||
test('toBeOnTheScreen() on null element', () => { | ||
expect(null).not.toBeOnTheScreen(); | ||
expect(() => expect(null).toBeOnTheScreen()).toThrowErrorMatchingInlineSnapshot(` | ||
"expect(element).toBeOnTheScreen() | ||
element could not be found in the element tree" | ||
`); | ||
}); | ||
|
||
test('example test', () => { | ||
render( | ||
<View> | ||
<View testID="child" /> | ||
</View>, | ||
); | ||
|
||
const child = screen.getByTestId('child'); | ||
expect(child).toBeOnTheScreen(); | ||
|
||
screen.update(<View />); | ||
expect(child).not.toBeOnTheScreen(); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import type { ReactTestInstance } from 'react-test-renderer'; | ||
import { matcherHint, RECEIVED_COLOR } from 'jest-matcher-utils'; | ||
import { checkReactElement, printElement } from './utils'; | ||
|
||
export function toBeOnTheScreen(this: jest.MatcherContext, element: ReactTestInstance) { | ||
if (element !== null) { | ||
checkReactElement(element, toBeOnTheScreen, this); | ||
} | ||
|
||
const pass = element === null ? false : getScreen().container === getRootElement(element); | ||
|
||
const errorFound = () => { | ||
return `expected element tree not to contain element but found:\n${printElement(element)}`; | ||
}; | ||
|
||
const errorNotFound = () => { | ||
return `element could not be found in the element tree`; | ||
}; | ||
|
||
return { | ||
pass, | ||
message: () => { | ||
return [ | ||
matcherHint(`${this.isNot ? '.not' : ''}.toBeOnTheScreen`, 'element', ''), | ||
'', | ||
RECEIVED_COLOR(this.isNot ? errorFound() : errorNotFound()), | ||
].join('\n'); | ||
}, | ||
}; | ||
} | ||
|
||
function getRootElement(element: ReactTestInstance) { | ||
let root = element; | ||
while (root.parent) { | ||
root = root.parent; | ||
} | ||
return root; | ||
} | ||
|
||
function getScreen() { | ||
try { | ||
// eslint-disable-next-line import/no-extraneous-dependencies | ||
const { screen } = require('@testing-library/react-native'); | ||
if (!screen) { | ||
throw new Error('screen is undefined'); | ||
} | ||
|
||
return screen; | ||
} catch (error) { | ||
throw new Error( | ||
'Could not import `screen` object from @testing-library/react-native.\n\n' + | ||
'Using toBeOnTheScreen() matcher requires @testing-library/react-native v10.1.0 or later to be added to your devDependencies.', | ||
); | ||
} | ||
} |