Extract tests by queries (#666)

* test: extract byText related tests

* test: extract byDisplayValue related tests

* test: extract byPlaceholderTest related tests

* test: delete unused code in byText test

* test: delete unused code in byTest tests

* test: delete unused code in byDisplayValue tests

* test: delete unused code in byPlaceholderText tests

* test: replace class components with function components
This commit is contained in:
MattAgn
2021-05-17 16:30:57 +02:00
committed by GitHub
parent e716cc4197
commit ffda1de9f9
7 changed files with 401 additions and 372 deletions
+102
View File
@@ -0,0 +1,102 @@
// @flow
import * as React from 'react';
import { View, TextInput } from 'react-native';
import { render } from '..';
const PLACEHOLDER_FRESHNESS = 'Add custom freshness';
const PLACEHOLDER_CHEF = 'Who inspected freshness?';
const INPUT_FRESHNESS = 'Custom Freshie';
const INPUT_CHEF = 'I inspected freshie';
const DEFAULT_INPUT_CHEF = 'What did you inspect?';
const DEFAULT_INPUT_CUSTOMER = 'What banana?';
const Banana = () => (
<View>
<TextInput
testID="bananaCustomFreshness"
placeholder={PLACEHOLDER_FRESHNESS}
value={INPUT_FRESHNESS}
/>
<TextInput
testID="bananaChef"
placeholder={PLACEHOLDER_CHEF}
value={INPUT_CHEF}
defaultValue={DEFAULT_INPUT_CHEF}
/>
<TextInput defaultValue={DEFAULT_INPUT_CUSTOMER} />
<TextInput defaultValue={'hello'} value="" />
</View>
);
test('getByDisplayValue, queryByDisplayValue', () => {
const { getByDisplayValue, queryByDisplayValue } = render(<Banana />);
const input = getByDisplayValue(/custom/i);
expect(input.props.value).toBe(INPUT_FRESHNESS);
const sameInput = getByDisplayValue(INPUT_FRESHNESS);
expect(sameInput.props.value).toBe(INPUT_FRESHNESS);
expect(() => getByDisplayValue('no value')).toThrow(
'Unable to find an element with displayValue: no value'
);
expect(queryByDisplayValue(/custom/i)).toBe(input);
expect(queryByDisplayValue('no value')).toBeNull();
expect(() => queryByDisplayValue(/fresh/i)).toThrow(
'Found multiple elements with display value: /fresh/i'
);
});
test('getByDisplayValue, queryByDisplayValue get element by default value only when value is undefined', () => {
const { getByDisplayValue, queryByDisplayValue } = render(<Banana />);
expect(() => getByDisplayValue(DEFAULT_INPUT_CHEF)).toThrow();
expect(queryByDisplayValue(DEFAULT_INPUT_CHEF)).toBeNull();
expect(() => getByDisplayValue('hello')).toThrow();
expect(queryByDisplayValue('hello')).toBeNull();
expect(getByDisplayValue(DEFAULT_INPUT_CUSTOMER)).toBeTruthy();
expect(queryByDisplayValue(DEFAULT_INPUT_CUSTOMER)).toBeTruthy();
});
test('getAllByDisplayValue, queryAllByDisplayValue', () => {
const { getAllByDisplayValue, queryAllByDisplayValue } = render(<Banana />);
const inputs = getAllByDisplayValue(/fresh/i);
expect(inputs).toHaveLength(2);
expect(() => getAllByDisplayValue('no value')).toThrow(
'Unable to find an element with displayValue: no value'
);
expect(queryAllByDisplayValue(/fresh/i)).toEqual(inputs);
expect(queryAllByDisplayValue('no value')).toHaveLength(0);
});
test('findBy queries work asynchronously', async () => {
const options = { timeout: 10 }; // Short timeout so that this test runs quickly
const { rerender, findByDisplayValue, findAllByDisplayValue } = render(
<View />
);
await expect(
findByDisplayValue('Display Value', options)
).rejects.toBeTruthy();
await expect(
findAllByDisplayValue('Display Value', options)
).rejects.toBeTruthy();
setTimeout(
() =>
rerender(
<View>
<TextInput value="Display Value" />
</View>
),
20
);
await expect(findByDisplayValue('Display Value')).resolves.toBeTruthy();
await expect(findAllByDisplayValue('Display Value')).resolves.toHaveLength(1);
}, 20000);
+61
View File
@@ -0,0 +1,61 @@
// @flow
import * as React from 'react';
import { View, TextInput } from 'react-native';
import { render } from '..';
const PLACEHOLDER_FRESHNESS = 'Add custom freshness';
const PLACEHOLDER_CHEF = 'Who inspected freshness?';
const INPUT_FRESHNESS = 'Custom Freshie';
const INPUT_CHEF = 'I inspected freshie';
const DEFAULT_INPUT_CHEF = 'What did you inspect?';
const Banana = () => (
<View>
<TextInput
testID="bananaCustomFreshness"
placeholder={PLACEHOLDER_FRESHNESS}
value={INPUT_FRESHNESS}
/>
<TextInput
testID="bananaChef"
placeholder={PLACEHOLDER_CHEF}
value={INPUT_CHEF}
defaultValue={DEFAULT_INPUT_CHEF}
/>
</View>
);
test('getByPlaceholderText, queryByPlaceholderText', () => {
const { getByPlaceholderText, queryByPlaceholderText } = render(<Banana />);
const input = getByPlaceholderText(/custom/i);
expect(input.props.placeholder).toBe(PLACEHOLDER_FRESHNESS);
const sameInput = getByPlaceholderText(PLACEHOLDER_FRESHNESS);
expect(sameInput.props.placeholder).toBe(PLACEHOLDER_FRESHNESS);
expect(() => getByPlaceholderText('no placeholder')).toThrow(
'Unable to find an element with placeholder: no placeholder'
);
expect(queryByPlaceholderText(/add/i)).toBe(input);
expect(queryByPlaceholderText('no placeholder')).toBeNull();
expect(() => queryByPlaceholderText(/fresh/)).toThrow(
'Found multiple elements with placeholder: /fresh/ '
);
});
test('getAllByPlaceholderText, queryAllByPlaceholderText', () => {
const { getAllByPlaceholderText, queryAllByPlaceholderText } = render(
<Banana />
);
const inputs = getAllByPlaceholderText(/fresh/i);
expect(inputs).toHaveLength(2);
expect(() => getAllByPlaceholderText('no placeholder')).toThrow(
'Unable to find an element with placeholder: no placeholder'
);
expect(queryAllByPlaceholderText(/fresh/i)).toEqual(inputs);
expect(queryAllByPlaceholderText('no placeholder')).toHaveLength(0);
});
+20 -65
View File
@@ -1,6 +1,6 @@
// @flow
import React from 'react';
import { View, Text, TextInput, TouchableOpacity, Button } from 'react-native';
import { View, Text, TextInput, Button } from 'react-native';
import { render } from '..';
const PLACEHOLDER_FRESHNESS = 'Add custom freshness';
@@ -8,71 +8,26 @@ const PLACEHOLDER_CHEF = 'Who inspected freshness?';
const INPUT_FRESHNESS = 'Custom Freshie';
const INPUT_CHEF = 'I inspected freshie';
class MyButton extends React.Component<any> {
render() {
return (
<TouchableOpacity onPress={this.props.onPress}>
<Text>{this.props.children}</Text>
</TouchableOpacity>
);
}
}
const Banana = () => (
<View>
<Text>Is the banana fresh?</Text>
<Text testID="bananaFresh">not fresh</Text>
<TextInput
testID="bananaCustomFreshness"
placeholder={PLACEHOLDER_FRESHNESS}
value={INPUT_FRESHNESS}
/>
<TextInput
testID="bananaChef"
placeholder={PLACEHOLDER_CHEF}
value={INPUT_CHEF}
/>
<Text testID="duplicateText">First Text</Text>
<Text testID="duplicateText">Second Text</Text>
</View>
);
class Banana extends React.Component<any, any> {
state = {
fresh: false,
};
componentDidUpdate() {
if (this.props.onUpdate) {
this.props.onUpdate();
}
}
componentWillUnmount() {
if (this.props.onUnmount) {
this.props.onUnmount();
}
}
changeFresh = () => {
this.setState((state) => ({
fresh: !state.fresh,
}));
};
render() {
const test = 0;
return (
<View>
<Text>Is the banana fresh?</Text>
<Text testID="bananaFresh">
{this.state.fresh ? 'fresh' : 'not fresh'}
</Text>
<TextInput
testID="bananaCustomFreshness"
placeholder={PLACEHOLDER_FRESHNESS}
value={INPUT_FRESHNESS}
/>
<TextInput
testID="bananaChef"
placeholder={PLACEHOLDER_CHEF}
value={INPUT_CHEF}
/>
<MyButton onPress={this.changeFresh} type="primary">
Change freshness!
</MyButton>
<Text testID="duplicateText">First Text</Text>
<Text testID="duplicateText">Second Text</Text>
<Text>{test}</Text>
</View>
);
}
}
const MyComponent = () => {
return <Text>My Component</Text>;
};
const MyComponent = () => <Text>My Component</Text>;
test('getByTestId returns only native elements', () => {
const { getByTestId, getAllByTestId } = render(
+218
View File
@@ -0,0 +1,218 @@
// @flow
import * as React from 'react';
import { View, Text, TouchableOpacity, Image } from 'react-native';
import { render } from '..';
const MyButton = ({ children, onPress }) => (
<TouchableOpacity onPress={onPress}>
<Text>{children}</Text>
</TouchableOpacity>
);
const Banana = () => {
const test = 0;
return (
<View>
<Text>Is the banana fresh?</Text>
<Text testID="bananaFresh">not fresh</Text>
<MyButton onPress={jest.fn()} type="primary">
Change freshness!
</MyButton>
<Text testID="duplicateText">First Text</Text>
<Text testID="duplicateText">Second Text</Text>
<Text>{test}</Text>
</View>
);
};
test('getByText, queryByText', () => {
const { getByText, queryByText } = render(<Banana />);
const button = getByText(/change/i);
expect(button.props.children).toBe('Change freshness!');
const sameButton = getByText('not fresh');
expect(sameButton.props.children).toBe('not fresh');
expect(() => getByText('InExistent')).toThrow(
'Unable to find an element with text: InExistent'
);
const zeroText = getByText('0');
expect(queryByText(/change/i)).toBe(button);
expect(queryByText('InExistent')).toBeNull();
expect(() => queryByText(/fresh/)).toThrow(
'Found multiple elements with text: /fresh/'
);
expect(queryByText('0')).toBe(zeroText);
});
test('getByText, queryByText with children as Array', () => {
const BananaCounter = ({ numBananas }) => (
<Text>There are {numBananas} bananas in the bunch</Text>
);
const BananaStore = () => (
<View>
<BananaCounter numBananas={3} />
<BananaCounter numBananas={6} />
<BananaCounter numBananas={5} />
</View>
);
const { getByText } = render(<BananaStore />);
const threeBananaBunch = getByText('There are 3 bananas in the bunch');
expect(threeBananaBunch.props.children).toEqual([
'There are ',
3,
' bananas in the bunch',
]);
});
test('getAllByText, queryAllByText', () => {
const { getAllByText, queryAllByText } = render(<Banana />);
const buttons = getAllByText(/fresh/i);
expect(buttons).toHaveLength(3);
expect(() => getAllByText('InExistent')).toThrow(
'Unable to find an element with text: InExistent'
);
expect(queryAllByText(/fresh/i)).toEqual(buttons);
expect(queryAllByText('InExistent')).toHaveLength(0);
});
test('findByText queries work asynchronously', async () => {
const options = { timeout: 10 }; // Short timeout so that this test runs quickly
const { rerender, findByText, findAllByText } = render(<View />);
await expect(findByText('Some Text', options)).rejects.toBeTruthy();
await expect(findAllByText('Some Text', options)).rejects.toBeTruthy();
setTimeout(
() =>
rerender(
<View>
<Text>Some Text</Text>
</View>
),
20
);
await expect(findByText('Some Text')).resolves.toBeTruthy();
await expect(findAllByText('Some Text')).resolves.toHaveLength(1);
}, 20000);
test('queryByText nested <Image> in <Text> at start', () => {
expect(
render(
<Text>
<Image source={{}} />
Hello
</Text>
).queryByText('Hello')
).toBeTruthy();
});
test('queryByText nested <Image> in <Text> at end', () => {
expect(
render(
<Text>
Hello
<Image source={{}} />
</Text>
).queryByText('Hello')
).toBeTruthy();
});
test('queryByText nested <Image> in <Text> in middle', () => {
expect(
render(
<Text>
Hello
<Image source={{}} />
World
</Text>
).queryByText('HelloWorld')
).toBeTruthy();
});
test('queryByText not found', () => {
expect(
render(
<Text>
Hello
<Image source={{}} />
</Text>
).queryByText('SomethingElse')
).toBeFalsy();
});
test('queryByText nested text across multiple <Text> in <Text>', () => {
const { queryByText } = render(
<Text nativeID="1">
Hello{' '}
<Text nativeID="2">
World
<Text>!{true}</Text>
</Text>
</Text>
);
expect(queryByText('Hello World!')?.props.nativeID).toBe('1');
});
test('queryByText with nested Text components return the closest Text', () => {
const NestedTexts = () => (
<Text nativeID="1">
<Text nativeID="2">My text</Text>
</Text>
);
const { queryByText } = render(<NestedTexts />);
expect(queryByText('My text')?.props.nativeID).toBe('2');
});
test('queryByText with nested Text components each with text return the lowest one', () => {
const NestedTexts = () => (
<Text nativeID="1">
bob
<Text nativeID="2">My text</Text>
</Text>
);
const { queryByText } = render(<NestedTexts />);
expect(queryByText('My text')?.props.nativeID).toBe('2');
});
test('queryByText nested <CustomText> in <Text>', () => {
const CustomText = ({ children }) => {
return <Text>{children}</Text>;
};
expect(
render(
<Text>
Hello <CustomText>World!</CustomText>
</Text>
).queryByText('Hello World!')
).toBeTruthy();
});
test('queryByText nested deep <CustomText> in <Text>', () => {
const CustomText = ({ children }) => {
return <Text>{children}</Text>;
};
expect(
render(
<Text>
<CustomText>Hello</CustomText> <CustomText>World!</CustomText>
</Text>
).queryByText('Hello World!')
).toBeTruthy();
});
-52
View File
@@ -1,52 +0,0 @@
// @flow
import * as React from 'react';
import { View, Text, TextInput } from 'react-native';
import { render } from '..';
test('findBy queries work asynchronously', async () => {
const options = { timeout: 10 }; // Short timeout so that this test runs quickly
const {
rerender,
findByText,
findAllByText,
findByPlaceholderText,
findAllByPlaceholderText,
findByDisplayValue,
findAllByDisplayValue,
} = render(<View />);
await expect(findByText('Some Text', options)).rejects.toBeTruthy();
await expect(findAllByText('Some Text', options)).rejects.toBeTruthy();
await expect(
findByPlaceholderText('Placeholder Text', options)
).rejects.toBeTruthy();
await expect(
findAllByPlaceholderText('Placeholder Text', options)
).rejects.toBeTruthy();
await expect(
findByDisplayValue('Display Value', options)
).rejects.toBeTruthy();
await expect(
findAllByDisplayValue('Display Value', options)
).rejects.toBeTruthy();
setTimeout(
() =>
rerender(
<View testID="aTestId">
<Text>Some Text</Text>
<TextInput placeholder="Placeholder Text" />
<TextInput value="Display Value" />
</View>
),
20
);
await expect(findByText('Some Text')).resolves.toBeTruthy();
await expect(findAllByText('Some Text')).resolves.toHaveLength(1);
await expect(findByPlaceholderText('Placeholder Text')).resolves.toBeTruthy();
await expect(
findAllByPlaceholderText('Placeholder Text')
).resolves.toHaveLength(1);
await expect(findByDisplayValue('Display Value')).resolves.toBeTruthy();
await expect(findAllByDisplayValue('Display Value')).resolves.toHaveLength(1);
}, 20000);
-116
View File
@@ -1,116 +0,0 @@
// @flow
import * as React from 'react';
import { Text, Image } from 'react-native';
import { render } from '..';
test('queryByText nested <Image> in <Text> at start', () => {
expect(
render(
<Text>
<Image source={{}} />
Hello
</Text>
).queryByText('Hello')
).toBeTruthy();
});
test('queryByText nested <Image> in <Text> at end', () => {
expect(
render(
<Text>
Hello
<Image source={{}} />
</Text>
).queryByText('Hello')
).toBeTruthy();
});
test('queryByText nested <Image> in <Text> in middle', () => {
expect(
render(
<Text>
Hello
<Image source={{}} />
World
</Text>
).queryByText('HelloWorld')
).toBeTruthy();
});
test('queryByText not found', () => {
expect(
render(
<Text>
Hello
<Image source={{}} />
</Text>
).queryByText('SomethingElse')
).toBeFalsy();
});
test('queryByText nested text across multiple <Text> in <Text>', () => {
const { queryByText } = render(
<Text nativeID="1">
Hello{' '}
<Text nativeID="2">
World
<Text>!{true}</Text>
</Text>
</Text>
);
expect(queryByText('Hello World!')?.props.nativeID).toBe('1');
});
test('queryByText with nested Text components return the closest Text', () => {
const NestedTexts = () => (
<Text nativeID="1">
<Text nativeID="2">My text</Text>
</Text>
);
const { queryByText } = render(<NestedTexts />);
expect(queryByText('My text')?.props.nativeID).toBe('2');
});
test('queryByText with nested Text components each with text return the lowest one', () => {
const NestedTexts = () => (
<Text nativeID="1">
bob
<Text nativeID="2">My text</Text>
</Text>
);
const { queryByText } = render(<NestedTexts />);
expect(queryByText('My text')?.props.nativeID).toBe('2');
});
test('queryByText nested <CustomText> in <Text>', () => {
const CustomText = ({ children }) => {
return <Text>{children}</Text>;
};
expect(
render(
<Text>
Hello <CustomText>World!</CustomText>
</Text>
).queryByText('Hello World!')
).toBeTruthy();
});
test('queryByText nested deep <CustomText> in <Text>', () => {
const CustomText = ({ children }) => {
return <Text>{children}</Text>;
};
expect(
render(
<Text>
<CustomText>Hello</CustomText> <CustomText>World!</CustomText>
</Text>
).queryByText('Hello World!')
).toBeTruthy();
});
-139
View File
@@ -98,145 +98,6 @@ test('UNSAFE_getAllByType, UNSAFE_queryAllByType', () => {
expect(UNSAFE_queryAllByType(InExistent)).toHaveLength(0);
});
test('getByText, queryByText', () => {
const { getByText, queryByText } = render(<Banana />);
const button = getByText(/change/i);
expect(button.props.children).toBe('Change freshness!');
const sameButton = getByText('not fresh');
expect(sameButton.props.children).toBe('not fresh');
expect(() => getByText('InExistent')).toThrow(
'Unable to find an element with text: InExistent'
);
const zeroText = getByText('0');
expect(queryByText(/change/i)).toBe(button);
expect(queryByText('InExistent')).toBeNull();
expect(() => queryByText(/fresh/)).toThrow(
'Found multiple elements with text: /fresh/'
);
expect(queryByText('0')).toBe(zeroText);
});
test('getByText, queryByText with children as Array', () => {
const BananaCounter = ({ numBananas }) => (
<Text>There are {numBananas} bananas in the bunch</Text>
);
const BananaStore = () => (
<View>
<BananaCounter numBananas={3} />
<BananaCounter numBananas={6} />
<BananaCounter numBananas={5} />
</View>
);
const { getByText } = render(<BananaStore />);
const threeBananaBunch = getByText('There are 3 bananas in the bunch');
expect(threeBananaBunch.props.children).toEqual([
'There are ',
3,
' bananas in the bunch',
]);
});
test('getAllByText, queryAllByText', () => {
const { getAllByText, queryAllByText } = render(<Banana />);
const buttons = getAllByText(/fresh/i);
expect(buttons).toHaveLength(3);
expect(() => getAllByText('InExistent')).toThrow(
'Unable to find an element with text: InExistent'
);
expect(queryAllByText(/fresh/i)).toEqual(buttons);
expect(queryAllByText('InExistent')).toHaveLength(0);
});
test('getByPlaceholderText, queryByPlaceholderText', () => {
const { getByPlaceholderText, queryByPlaceholderText } = render(<Banana />);
const input = getByPlaceholderText(/custom/i);
expect(input.props.placeholder).toBe(PLACEHOLDER_FRESHNESS);
const sameInput = getByPlaceholderText(PLACEHOLDER_FRESHNESS);
expect(sameInput.props.placeholder).toBe(PLACEHOLDER_FRESHNESS);
expect(() => getByPlaceholderText('no placeholder')).toThrow(
'Unable to find an element with placeholder: no placeholder'
);
expect(queryByPlaceholderText(/add/i)).toBe(input);
expect(queryByPlaceholderText('no placeholder')).toBeNull();
expect(() => queryByPlaceholderText(/fresh/)).toThrow(
'Found multiple elements with placeholder: /fresh/ '
);
});
test('getAllByPlaceholderText, queryAllByPlaceholderText', () => {
const { getAllByPlaceholderText, queryAllByPlaceholderText } = render(
<Banana />
);
const inputs = getAllByPlaceholderText(/fresh/i);
expect(inputs).toHaveLength(2);
expect(() => getAllByPlaceholderText('no placeholder')).toThrow(
'Unable to find an element with placeholder: no placeholder'
);
expect(queryAllByPlaceholderText(/fresh/i)).toEqual(inputs);
expect(queryAllByPlaceholderText('no placeholder')).toHaveLength(0);
});
test('getByDisplayValue, queryByDisplayValue', () => {
const { getByDisplayValue, queryByDisplayValue } = render(<Banana />);
const input = getByDisplayValue(/custom/i);
expect(input.props.value).toBe(INPUT_FRESHNESS);
const sameInput = getByDisplayValue(INPUT_FRESHNESS);
expect(sameInput.props.value).toBe(INPUT_FRESHNESS);
expect(() => getByDisplayValue('no value')).toThrow(
'Unable to find an element with displayValue: no value'
);
expect(queryByDisplayValue(/custom/i)).toBe(input);
expect(queryByDisplayValue('no value')).toBeNull();
expect(() => queryByDisplayValue(/fresh/i)).toThrow(
'Found multiple elements with display value: /fresh/i'
);
});
test('getByDisplayValue, queryByDisplayValue get element by default value only when value is undefined', () => {
const { getByDisplayValue, queryByDisplayValue } = render(<Banana />);
expect(() => getByDisplayValue(DEFAULT_INPUT_CHEF)).toThrow();
expect(queryByDisplayValue(DEFAULT_INPUT_CHEF)).toBeNull();
expect(() => getByDisplayValue('hello')).toThrow();
expect(queryByDisplayValue('hello')).toBeNull();
expect(getByDisplayValue(DEFAULT_INPUT_CUSTOMER)).toBeTruthy();
expect(queryByDisplayValue(DEFAULT_INPUT_CUSTOMER)).toBeTruthy();
});
test('getAllByDisplayValue, queryAllByDisplayValue', () => {
const { getAllByDisplayValue, queryAllByDisplayValue } = render(<Banana />);
const inputs = getAllByDisplayValue(/fresh/i);
expect(inputs).toHaveLength(2);
expect(() => getAllByDisplayValue('no value')).toThrow(
'Unable to find an element with displayValue: no value'
);
expect(queryAllByDisplayValue(/fresh/i)).toEqual(inputs);
expect(queryAllByDisplayValue('no value')).toHaveLength(0);
});
test('UNSAFE_getByProps, UNSAFE_queryByProps', () => {
const { UNSAFE_getByProps, UNSAFE_queryByProps } = render(<Banana />);
const primaryType = UNSAFE_getByProps({ type: 'primary' });