-
-
Notifications
You must be signed in to change notification settings - Fork 31.6k
/
Menu.spec.js
186 lines (160 loc) · 6.71 KB
/
Menu.spec.js
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
/* eslint-env mocha */
import React from 'react';
import {mount, shallow} from 'enzyme';
import {spy} from 'sinon';
import {assert} from 'chai';
import Menu from './Menu';
import MenuItem from '../MenuItem';
import Divider from '../Divider';
import getMuiTheme from '../styles/getMuiTheme';
import keycode from 'keycode';
describe('<Menu />', () => {
const muiTheme = getMuiTheme();
const shallowWithContext = (node) => shallow(node, {context: {muiTheme}});
const mountWithContext = (node) => mount(node, {context: {muiTheme}});
const keycodeEvent = (key) => ({keyCode: keycode(key)});
describe('onMenuItemFocusChange', () => {
function createMenu(props) {
return (
<Menu {...props}>
<MenuItem primaryText="item 1" />
<Divider />
<MenuItem primaryText="item 2" />
<MenuItem primaryText="item 3" />
</Menu>
);
}
it('is invoked when using the arrow key to go down to the bottom and back up to the top', () => {
const onMenuItemFocusChangeSpy = spy();
const menu = createMenu({
disableAutoFocus: false,
onMenuItemFocusChange: onMenuItemFocusChangeSpy,
});
const wrapper = mountWithContext(menu);
assert.deepEqual(onMenuItemFocusChangeSpy.args[0], [null, 0],
'initial focus should invoke callback with 0');
onMenuItemFocusChangeSpy.reset();
wrapper.simulate('keydown', keycodeEvent('down'));
assert.strictEqual(onMenuItemFocusChangeSpy.args[0][1], 1,
'down-arrow invokes callback with index 1');
onMenuItemFocusChangeSpy.reset();
wrapper.simulate('keydown', keycodeEvent('down'));
assert.strictEqual(onMenuItemFocusChangeSpy.args[0][1], 2,
'down-arrow invokes callback with index 2');
onMenuItemFocusChangeSpy.reset();
wrapper.simulate('keydown', keycodeEvent('down'));
assert.strictEqual(onMenuItemFocusChangeSpy.args[0][1], 2,
'down-arrow at end invokes callback with unchanged index');
onMenuItemFocusChangeSpy.reset();
wrapper.simulate('keydown', keycodeEvent('up'));
assert.strictEqual(onMenuItemFocusChangeSpy.args[0][1], 1,
'up-arrow invokes callback with 1');
onMenuItemFocusChangeSpy.reset();
wrapper.simulate('keydown', keycodeEvent('up'));
assert.strictEqual(onMenuItemFocusChangeSpy.args[0][1], 0,
'up-arrow invokes callback with 0');
onMenuItemFocusChangeSpy.reset();
wrapper.simulate('keydown', keycodeEvent('up'));
assert.strictEqual(onMenuItemFocusChangeSpy.args[0][1], 0,
'up-arrow at top invokes callback with unchanged index');
onMenuItemFocusChangeSpy.reset();
wrapper.unmount(); // Otherwise the timer in FocusRipple keeps Node from exiting
});
it('is invoked when props change', () => {
const onMenuItemFocusChangeSpy = spy();
const menu = createMenu({
disableAutoFocus: true,
onMenuItemFocusChange: onMenuItemFocusChangeSpy,
});
const wrapper = mountWithContext(menu);
assert.strictEqual(onMenuItemFocusChangeSpy.callCount, 0,
'should not be called when creating with disableAutoFocus=true');
onMenuItemFocusChangeSpy.reset();
wrapper.setProps({disableAutoFocus: false});
assert.deepEqual(onMenuItemFocusChangeSpy.args[0], [null, 0],
'changing disableAutoFocus to false invokes callback');
onMenuItemFocusChangeSpy.reset();
wrapper.setProps({disableAutoFocus: true});
assert.deepEqual(onMenuItemFocusChangeSpy.args[0], [null, -1],
'changing disableAutoFocus to true invokes callback');
onMenuItemFocusChangeSpy.reset();
wrapper.unmount(); // Otherwise the timer in FocusRipple keeps Node from exiting
});
it('is invoked for hotkeys', () => {
const onMenuItemFocusChangeSpy = spy();
const menu = (
<Menu
disableAutoFocus={false}
onMenuItemFocusChange={onMenuItemFocusChangeSpy}
>
<MenuItem primaryText="a00" />
<MenuItem primaryText="b11" />
<Divider />
<MenuItem primaryText="b00" />
</Menu>
);
const wrapper = mountWithContext(menu);
wrapper.simulate('keydown', keycodeEvent('b'));
assert.strictEqual(onMenuItemFocusChangeSpy.args[0][1], 0,
'"b" invokes callback with focus index 0');
onMenuItemFocusChangeSpy.reset();
wrapper.simulate('keydown', keycodeEvent('0'));
// The Divider is incorrectly counted by Menu.setFocusIndexStartsWith().
assert.strictEqual(onMenuItemFocusChangeSpy.args[0][1], 3,
'"b0" invokes callback with focus index 3, which is probably a bug');
onMenuItemFocusChangeSpy.reset();
wrapper.simulate('keydown', keycodeEvent('0'));
assert.strictEqual(onMenuItemFocusChangeSpy.args[0][1], 3,
'"b0" invokes callback with focus index 3');
onMenuItemFocusChangeSpy.reset();
wrapper.simulate('keydown', keycodeEvent('!'));
// It seems like the focus index should be changed to -1 here.
assert.strictEqual(onMenuItemFocusChangeSpy.callCount, 0,
'"b00!" does not change the focus index, which is probably a bug');
onMenuItemFocusChangeSpy.reset();
wrapper.unmount(); // Otherwise the timer in FocusRipple keeps Node from exiting
});
});
it('should render MenuItem and Divider children', () => {
const wrapper = shallowWithContext(
<Menu>
<MenuItem primaryText="item 1" />
<Divider />
<MenuItem primaryText="item 2" />
</Menu>
);
const menuItemsAndDividers = wrapper.children().children().children();
assert.strictEqual(menuItemsAndDividers.length, 3, 'there should be three children');
assert.strictEqual(menuItemsAndDividers.get(0).type, MenuItem, 'first child should be a MenuItem');
assert.strictEqual(menuItemsAndDividers.get(1).type, Divider, 'second child should be a Divider');
assert.strictEqual(menuItemsAndDividers.get(2).type, MenuItem, 'third child should be a MenuItem');
assert.deepEqual(
menuItemsAndDividers.get(1).props.style,
{
marginTop: 7,
marginBottom: 8,
},
'the Divider gets default styles'
);
});
it("should merge the Divider's styles over the Menu's default divider styles", () => {
const style = {
color: 'red',
marginTop: '999px',
};
const wrapper = shallowWithContext(
<Menu>
<Divider style={style} />
</Menu>
);
const divider = wrapper.find(Divider);
assert.strictEqual(divider.length, 1, 'there should be one divider child');
assert.deepEqual(
divider.props().style,
Object.assign({}, style, {
marginBottom: 8,
}),
"existing styles should be merged over Menu's styles"
);
});
});