-
-
Notifications
You must be signed in to change notification settings - Fork 65
/
Copy pathOverflowMenuProvider.test.tsx
192 lines (175 loc) · 5.65 KB
/
OverflowMenuProvider.test.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
import { useOverflowMenu } from '../OverflowMenuContext';
import { Text, View } from 'react-native';
import {
render,
fireEvent,
waitForElementToBeRemoved,
} from '@testing-library/react-native';
import React from 'react';
import { HeaderButtonsProviderDropdownMenu } from '../HeaderButtonsProviderDropdownMenu';
import { HeaderButtonsProviderPlain } from '../HeaderButtonsProviderPlain';
import * as fs from 'node:fs';
import * as path from 'node:path';
import * as child_process from 'node:child_process';
describe('HeaderButtonsProvider renders', () => {
it('only the child when menu is not shown', () => {
const { toJSON } = render(
<HeaderButtonsProviderDropdownMenu stackType={'js'}>
<Text>hello</Text>
</HeaderButtonsProviderDropdownMenu>
);
expect(toJSON()).toMatchInlineSnapshot(`
<Text>
hello
</Text>
`);
});
it('the child and the menu item, when it is displayed by calling presentMenu() that is provided by OverflowMenuContext', async () => {
const menuItemLabel = 'overflow menu item';
const showMenuLabel = 'show menu';
const hideMenuLabel = 'hide menu';
const ButtonThatShowsMenu = () => {
const { presentMenu } = useOverflowMenu();
return (
<Text
onPress={() => {
presentMenu({
elements: <Text key="1">{menuItemLabel}</Text>,
x: 0,
y: 0,
});
}}
>
{showMenuLabel}
</Text>
);
};
const ButtonThatHidesMenu = () => {
const { closeMenu } = useOverflowMenu();
return (
<Text
onPress={() => {
closeMenu();
}}
>
{hideMenuLabel}
</Text>
);
};
const { toJSON, getByText } = render(
<HeaderButtonsProviderDropdownMenu stackType={'js'}>
<View>
<ButtonThatShowsMenu />
<ButtonThatHidesMenu />
</View>
</HeaderButtonsProviderDropdownMenu>
);
const presentMenu = () => fireEvent.press(getByText(showMenuLabel));
const hideMenu = () => fireEvent.press(getByText(hideMenuLabel));
const beforeShown = toJSON();
presentMenu();
expect(toJSON()).toMatchSnapshot();
getByText(menuItemLabel);
hideMenu();
const waitForMenuToHide = async () => {
await waitForElementToBeRemoved(() => getByText(menuItemLabel), {
timeout: 800,
});
};
await waitForMenuToHide();
const afterHidden = toJSON();
expect(afterHidden).toStrictEqual(beforeShown);
});
it('warning is shown if presenting menu is called but wrong provider was used', () => {
const menuItemLabel = 'overflow menu item';
const showMenuLabel = 'show menu';
const ButtonThatShowsMenu = () => {
const { presentMenu } = useOverflowMenu();
return (
<Text
onPress={() => {
presentMenu({
elements: <Text key="1">{menuItemLabel}</Text>,
x: 0,
y: 0,
});
}}
>
{showMenuLabel}
</Text>
);
};
const { getByText } = render(
<HeaderButtonsProviderPlain stackType={'js'}>
<View>
<ButtonThatShowsMenu />
</View>
</HeaderButtonsProviderPlain>
);
const presentMenu = () => fireEvent.press(getByText(showMenuLabel));
const originalWarn = console.warn;
console.warn = jest.fn();
presentMenu();
expect(console.warn).toHaveBeenCalledWith(
expect.stringContaining(
`It seems like you tried to open / close the overflow menu using the overflowMenuPressHandlerDropdownMenu, but you forgot to wrap your root component in <HeaderButtonsProviderDropdownMenu />.`
)
);
console.warn = originalWarn;
});
it(
'when bundling the example app, some files are (not) bundled based on the platform.' +
'This is controlled by the HeaderButtonsProvider and illustrates the bundle savings.',
async () => {
const cwd = process.cwd();
const examplePath = `${cwd}/example/`;
child_process.execSync(
`cd ${examplePath} && yarn requires-ios && yarn requires-android`
);
const filesBundledOnIos = fs.readFileSync(
path.join(examplePath, `requires-ios.txt`),
'utf8'
);
const filesBundledOnAndroid = fs.readFileSync(
path.join(examplePath, `requires-android.txt`),
'utf8'
);
const filterAndExtractFileNames = (output: string) =>
output
.split('\n')
.filter((line) => line.includes('header-buttons/src'))
.map((path) => path.split('/').pop());
const filteredIos = filterAndExtractFileNames(filesBundledOnIos);
const filteredAndroid = filterAndExtractFileNames(filesBundledOnAndroid);
expect(filteredIos).not.toContain('Menu.tsx');
expect(filteredIos).not.toContain(
'HeaderButtonsProviderDropdownMenu.tsx'
);
expect(filteredAndroid).toContain(
'HeaderButtonsProviderDropdownMenu.tsx'
);
expect(filteredAndroid).toContain('Menu.tsx');
// OverflowMenu imports the e2e file which is why it's here
expect(filteredIos).toMatchInlineSnapshot(`
[
"HeaderButtonsProvider.tsx",
"HeaderButtonsProvider.ios.tsx",
"HeaderButtonsProviderPlain.tsx",
"ButtonsWrapper.tsx",
"index.ts",
"HeaderButtonComponentContext.tsx",
"HeaderButton.tsx",
"HeaderButtons.tsx",
"overflowMenuPressHandlers.ts",
"HeaderItems.tsx",
"OverflowMenuContext.tsx",
"MenuItem.tsx",
"OverflowMenu.tsx",
"e2e.ts",
"Divider.tsx",
]
`);
},
20000
);
});