Skip to content
This repository was archived by the owner on Jul 30, 2020. It is now read-only.

Commit c57ab20

Browse files
committed
feat(events): allow custom events and handle onChangeText
1 parent 07cc152 commit c57ab20

File tree

3 files changed

+63
-21
lines changed

3 files changed

+63
-21
lines changed

examples/__tests__/input-event.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,26 +38,27 @@ const setup = () => {
3838

3939
test('It should keep a $ in front of the input', () => {
4040
const { input } = setup();
41-
fireEvent.change(input, { text: 23 });
41+
42+
fireEvent.change(input, { nativeEvent: { text: 23 } });
4243
expect(input.props.value).toBe('$23');
4344
});
4445
test('It should allow a $ to be in the input when the value is changed', () => {
4546
const { input } = setup();
46-
fireEvent.change(input, { text: '$23.0' });
47+
fireEvent.change(input, { nativeEvent: { text: '$23.0' } });
4748
expect(input.props.value).toBe('$23.0');
4849
});
4950

5051
test('It should not allow letters to be inputted', () => {
5152
const { input } = setup();
5253
expect(input.props.value).toBe('');
53-
fireEvent.change(input, { text: 'Good Day' });
54+
fireEvent.change(input, { nativeEvent: { text: 'Good Day' } });
5455
expect(input.props.value).toBe('');
5556
});
5657

5758
test('It should allow the $ to be deleted', () => {
5859
const { input } = setup();
59-
fireEvent.change(input, { text: '23' });
60+
fireEvent.change(input, { nativeEvent: { text: '23' } });
6061
expect(input.props.value).toBe('$23');
61-
fireEvent.change(input, { text: '' });
62+
fireEvent.change(input, { nativeEvent: { text: '' } });
6263
expect(input.props.value).toBe('');
6364
});

src/__tests__/events.js

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,48 @@ test('onChange works', () => {
1111
expect(handleChange).toHaveBeenCalledTimes(1);
1212
});
1313

14+
test('onChangeText works', () => {
15+
function OnChangeText() {
16+
const [text, setText] = React.useState('first');
17+
18+
return <TextInput onChangeText={setText} value={text} testID="input" />;
19+
}
20+
21+
const { getByTestId } = render(<OnChangeText />);
22+
const input = getByTestId('input');
23+
24+
expect(input.props.value).toBe('first');
25+
fireEvent.changeText(input, 'second');
26+
expect(input.props.value).toBe('second');
27+
});
28+
1429
test('calling `fireEvent` directly works too', () => {
1530
const handleEvent = jest.fn();
1631
const { rootInstance } = render(<Button onPress={handleEvent} title="test" />);
32+
1733
fireEvent(rootInstance, new NativeEvent('press'));
34+
expect(handleEvent).toBeCalledTimes(1);
35+
});
36+
37+
test('calling a custom event works as well', () => {
38+
const event = { nativeEvent: { value: 'testing' } };
39+
const onMyEvent = jest.fn(({ nativeEvent }) => expect(nativeEvent).toEqual({ value: 'testing' }));
40+
const MyComponent = ({ onMyEvent }) => <TextInput value="test" onChange={onMyEvent} />;
41+
42+
const { rootInstance } = render(<MyComponent onMyEvent={onMyEvent} />);
43+
fireEvent(rootInstance, new NativeEvent('myEvent', event));
44+
45+
expect(onMyEvent).toHaveBeenCalledWith({
46+
nativeEvent: { value: 'testing' },
47+
type: 'CustomEvent',
48+
});
1849
});
1950

2051
test('calling a handler when there is no valid target throws', () => {
21-
const spy = jest.fn();
22-
const { getByTestId } = render(<Image onPress={spy} testID="image" />);
52+
const handleEvent = jest.fn();
53+
const { getByTestId } = render(<Image onPress={handleEvent} testID="image" />);
2354
expect(() => fireEvent.press(getByTestId('image'))).toThrow();
24-
expect(spy).toBeCalledTimes(0);
55+
expect(handleEvent).toBeCalledTimes(0);
2556
});
2657

2758
test('calling an event that has no defined handler throws', () => {
@@ -30,8 +61,8 @@ test('calling an event that has no defined handler throws', () => {
3061
});
3162

3263
test('calling an event sets nativeEvent properly', () => {
33-
const event = { value: 'testing' };
34-
const onChange = jest.fn(({ nativeEvent }) => expect(nativeEvent).toEqual(event));
64+
const event = { nativeEvent: { value: 'testing' } };
65+
const onChange = jest.fn(({ nativeEvent }) => expect(nativeEvent).toEqual({ value: 'testing' }));
3566

3667
const { getByValue } = render(<TextInput value="test" onChange={onChange} />);
3768
fireEvent.change(getByValue('test'), event);

src/events.js

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ const eventMap = {
3333
'TextInput',
3434
],
3535
},
36+
changeText: {
37+
type: 'ChangeEvent',
38+
validTargets: ['TextInput'],
39+
},
3640
contentSizeChange: {
3741
type: 'ContentSizeChangeEvent',
3842
validTargets: ['VirtualizedList', 'FlatList', 'SectionList', 'TextInput', 'ScrollView'],
@@ -190,16 +194,22 @@ const eventMap = {
190194
type: 'SyntheticEvent',
191195
validTargets: ['Image'],
192196
},
197+
198+
// Custom events, like a component onWhatever callback
199+
custom: {
200+
type: 'CustomEvent',
201+
validTargets: [],
202+
},
193203
};
194204

195205
class NativeEvent {
196-
constructor(typeArg, eventInit = {}) {
197-
const config = eventMap[typeArg];
206+
constructor(typeArg, event = {}) {
207+
const config = eventMap[typeArg] || eventMap.custom;
208+
const { validTargets = [], ...rest } = event;
198209

199210
this.typeArg = typeArg;
200-
this.nativeEvent = eventInit;
201-
this.type = config.type;
202-
this.validTargets = config.validTargets;
211+
this.event = typeof event === 'object' ? { type: config.type, ...rest } : event;
212+
this.validTargets = [...config.validTargets, ...validTargets];
203213
}
204214

205215
set target(target) {
@@ -216,11 +226,11 @@ function getEventHandlerName(key) {
216226
}
217227

218228
function isValidTarget(element, event) {
219-
return (
220-
event.validTargets.includes(element.type) ||
221-
event.validTargets.includes(element.type.name) ||
222-
event.validTargets.includes(element.type.displayName)
223-
);
229+
return event.validTargets.length
230+
? event.validTargets.includes(element.type) ||
231+
event.validTargets.includes(element.type.name) ||
232+
event.validTargets.includes(element.type.displayName)
233+
: true;
224234
}
225235

226236
function findEventHandler(element, event) {
@@ -242,7 +252,7 @@ function findEventHandler(element, event) {
242252
function fireEvent(element, event) {
243253
event.target = findEventHandler(element, event);
244254

245-
return event.target(event);
255+
return event.target(event.event);
246256
}
247257

248258
Object.keys(eventMap).forEach(key => {

0 commit comments

Comments
 (0)