Skip to content

Commit e812c1e

Browse files
committed
tests
1 parent f8bded6 commit e812c1e

3 files changed

Lines changed: 262 additions & 40 deletions

File tree

src/components/PanelMenuWrapper.js

Lines changed: 4 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import PropTypes from 'prop-types';
22
import React, {cloneElement, Component} from 'react';
33
import SidebarGroup from './sidebar/SidebarGroup';
44
import {bem} from 'lib';
5+
import sortMenu from 'lib/sortMenu';
56

67
class PanelsWithSidebar extends Component {
78
constructor(props) {
@@ -45,55 +46,18 @@ class PanelsWithSidebar extends Component {
4546
);
4647
}
4748

48-
getUniqueValues(value, index, self) {
49-
return self.indexOf(value) === index;
50-
}
51-
5249
computeMenuOptions(props) {
5350
const {children, order} = props;
5451
const sections = [];
5552
const groupLookup = {};
5653
let groupIndex;
57-
const orderedChildren = React.Children.toArray(children);
54+
const panels = React.Children.toArray(children);
5855

5956
if (order) {
60-
const groupOrder = order.map(panel => panel.group).filter(this.getUniqueValues);
61-
const nameOrder = order.map(panel => panel.name).filter(this.getUniqueValues);
62-
63-
orderedChildren.sort((a, b) => {
64-
const panelAHasCustomOrder = groupOrder.includes(a.props.group);
65-
const panelBHasCustomOrder = groupOrder.includes(b.props.group);
66-
67-
// if one of the elements is not in the groupOrder array, then it goes to the end of the list
68-
if (panelAHasCustomOrder && !panelBHasCustomOrder) {
69-
return -1;
70-
}
71-
if (!panelAHasCustomOrder && panelBHasCustomOrder) {
72-
return 1;
73-
}
74-
75-
// if both elements are not in the groupOrder array, they get sorted alphabetically,
76-
// by group, then by name
77-
if (!panelAHasCustomOrder && !panelBHasCustomOrder) {
78-
const sortByGroup =
79-
a.props.group === b.props.group ? 0 : a.props.group < b.props.group ? -1 : 1;
80-
const sortByName =
81-
a.props.name === b.props.name ? 0 : a.props.name < b.props.name ? -1 : 1;
82-
return sortByGroup || sortByName;
83-
}
84-
85-
// if both elements are in the groupOrder array, they get sorted according to their order in
86-
// the groupOrder, then nameOrder arrays.
87-
if (panelAHasCustomOrder && panelBHasCustomOrder) {
88-
const sortByGroup = groupOrder.indexOf(a.props.group) - groupOrder.indexOf(b.props.group);
89-
const sortByName = nameOrder.indexOf(a.props.name) - nameOrder.indexOf(b.props.name);
90-
return sortByGroup || sortByName;
91-
}
92-
return 0;
93-
});
57+
sortMenu(panels, order);
9458
}
9559

96-
orderedChildren.forEach(child => {
60+
panels.forEach(child => {
9761
if (!child) {
9862
return;
9963
}

src/lib/__tests__/sortMenu-test.js

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
import sortMenu from '../sortMenu';
2+
3+
describe('sortMenu', () => {
4+
it('modifies original array to follow the group, then name order provided', () => {
5+
const initialArray = [
6+
{props: {group: 'DEV', name: 'Inspector'}},
7+
{props: {group: 'DEV', name: 'JSON'}},
8+
];
9+
const orderProp = [{group: 'DEV', name: 'JSON'}, {group: 'DEV', name: 'Inspector'}];
10+
sortMenu(initialArray, orderProp);
11+
12+
expect(initialArray[0].props.name).toBe('JSON');
13+
expect(initialArray[1].props.name).toBe('Inspector');
14+
});
15+
16+
it('sorts the array by group, then by name', () => {
17+
const initialArray = [
18+
{props: {group: 'Structure', name: 'Create'}},
19+
{props: {group: 'Structure', name: 'Subplots'}},
20+
{props: {group: 'Style', name: 'Color Bars'}},
21+
{props: {group: 'Style', name: 'Annotation'}},
22+
{props: {group: 'DEV', name: 'Inspector'}},
23+
{props: {group: 'DEV', name: 'JSON'}},
24+
];
25+
26+
const orderProp = [
27+
{group: 'DEV', name: 'JSON'},
28+
{group: 'DEV', name: 'Inspector'},
29+
{group: 'Structure', name: 'Subplots'},
30+
{group: 'Structure', name: 'Create'},
31+
{group: 'Style', name: 'Color Bars'},
32+
{group: 'Style', name: 'Annotation'},
33+
];
34+
35+
sortMenu(initialArray, orderProp);
36+
expect(initialArray[0].props.group).toBe('DEV');
37+
expect(initialArray[0].props.name).toBe('JSON');
38+
expect(initialArray[1].props.group).toBe('DEV');
39+
expect(initialArray[1].props.name).toBe('Inspector');
40+
expect(initialArray[2].props.group).toBe('Structure');
41+
expect(initialArray[2].props.name).toBe('Subplots');
42+
expect(initialArray[3].props.group).toBe('Structure');
43+
expect(initialArray[3].props.name).toBe('Create');
44+
expect(initialArray[4].props.group).toBe('Style');
45+
expect(initialArray[4].props.name).toBe('Color Bars');
46+
expect(initialArray[5].props.group).toBe('Style');
47+
expect(initialArray[5].props.name).toBe('Annotation');
48+
});
49+
50+
it('puts not mentionned panels to the bottom of list and sorts alphabetically', () => {
51+
const initialArray = [
52+
{props: {group: 'DEV', name: 'JSON'}},
53+
{props: {group: 'DEV', name: 'Inspector'}},
54+
{props: {group: 'Structure', name: 'Create'}},
55+
{props: {group: 'Structure', name: 'Subplots'}},
56+
{props: {group: 'Style', name: 'Color Bars'}},
57+
{props: {group: 'Style', name: 'Annotation'}},
58+
];
59+
const orderProp = [
60+
{group: 'Structure', name: 'Subplots'},
61+
{group: 'Structure', name: 'Create'},
62+
{group: 'Style', name: 'Color Bars'},
63+
{group: 'Style', name: 'Annotation'},
64+
];
65+
66+
sortMenu(initialArray, orderProp);
67+
expect(initialArray[0].props.group).toBe('Structure');
68+
expect(initialArray[0].props.name).toBe('Subplots');
69+
expect(initialArray[1].props.group).toBe('Structure');
70+
expect(initialArray[1].props.name).toBe('Create');
71+
expect(initialArray[2].props.group).toBe('Style');
72+
expect(initialArray[2].props.name).toBe('Color Bars');
73+
expect(initialArray[3].props.group).toBe('Style');
74+
expect(initialArray[3].props.name).toBe('Annotation');
75+
expect(initialArray[4].props.group).toBe('DEV');
76+
expect(initialArray[4].props.name).toBe('Inspector');
77+
expect(initialArray[5].props.group).toBe('DEV');
78+
expect(initialArray[5].props.name).toBe('JSON');
79+
});
80+
81+
it('orders not mentionned subpanels at the end, alphabetically', () => {
82+
const initialArray = [
83+
{props: {group: 'Style', name: 'General'}},
84+
{props: {group: 'Style', name: 'Traces'}},
85+
{props: {group: 'Style', name: 'Axes'}},
86+
{props: {group: 'Structure', name: 'Create'}},
87+
];
88+
const orderProp = [{group: 'Style', name: 'Traces'}, {group: 'Structure', name: 'Create'}];
89+
90+
sortMenu(initialArray, orderProp);
91+
expect(initialArray[0].props.group).toBe('Style');
92+
expect(initialArray[0].props.name).toBe('Traces');
93+
expect(initialArray[1].props.group).toBe('Style');
94+
expect(initialArray[1].props.name).toBe('Axes');
95+
expect(initialArray[2].props.group).toBe('Style');
96+
expect(initialArray[2].props.name).toBe('General');
97+
expect(initialArray[3].props.group).toBe('Structure');
98+
expect(initialArray[3].props.name).toBe('Create');
99+
});
100+
101+
it('ignores non existent panel groups', () => {
102+
const initialArray = [
103+
{props: {group: 'Structure', name: 'Create'}},
104+
{props: {group: 'Structure', name: 'Subplots'}},
105+
{props: {group: 'Style', name: 'Color Bars'}},
106+
{props: {group: 'Style', name: 'Annotation'}},
107+
];
108+
109+
const orderProp = [
110+
{group: 'Non Existent', name: 'Subplots'},
111+
{group: 'Structure', name: 'Create'},
112+
{group: 'Style', name: 'Color Bars'},
113+
{group: 'Style', name: 'Annotation'},
114+
];
115+
116+
sortMenu(initialArray, orderProp);
117+
expect(initialArray[0].props.group).toBe('Structure');
118+
expect(initialArray[0].props.name).toBe('Create');
119+
expect(initialArray[1].props.group).toBe('Structure');
120+
expect(initialArray[1].props.name).toBe('Subplots');
121+
expect(initialArray[2].props.group).toBe('Style');
122+
expect(initialArray[2].props.name).toBe('Color Bars');
123+
expect(initialArray[3].props.group).toBe('Style');
124+
expect(initialArray[3].props.name).toBe('Annotation');
125+
});
126+
127+
it('ignores non existent panel names', () => {
128+
const initialArray = [
129+
{props: {group: 'Structure', name: 'Subplots'}},
130+
{props: {group: 'Structure', name: 'Create'}},
131+
{props: {group: 'Style', name: 'Color Bars'}},
132+
{props: {group: 'Style', name: 'Annotation'}},
133+
];
134+
135+
const orderProp = [
136+
{group: 'Structure', name: 'Non Existent'},
137+
{group: 'Style', name: 'Color Bars'},
138+
{group: 'Style', name: 'Annotation'},
139+
];
140+
141+
sortMenu(initialArray, orderProp);
142+
expect(initialArray[0].props.group).toBe('Style');
143+
expect(initialArray[0].props.name).toBe('Color Bars');
144+
expect(initialArray[1].props.group).toBe('Style');
145+
expect(initialArray[1].props.name).toBe('Annotation');
146+
expect(initialArray[2].props.group).toBe('Structure');
147+
expect(initialArray[2].props.name).toBe('Create');
148+
expect(initialArray[3].props.group).toBe('Structure');
149+
expect(initialArray[3].props.name).toBe('Subplots');
150+
});
151+
152+
it('ignores invalid combinations', () => {
153+
const initialArray = [
154+
{props: {group: 'Structure', name: 'Subplots'}},
155+
{props: {group: 'Structure', name: 'Create'}},
156+
{props: {group: 'Style', name: 'Color Bars'}},
157+
{props: {group: 'Style', name: 'Annotation'}},
158+
];
159+
160+
const orderProp = [
161+
{group: 'Structure', name: 'Annotation'},
162+
{group: 'Style', name: 'Color Bars'},
163+
{group: 'Style', name: 'Annotation'},
164+
];
165+
166+
sortMenu(initialArray, orderProp);
167+
expect(initialArray[0].props.group).toBe('Style');
168+
expect(initialArray[0].props.name).toBe('Color Bars');
169+
expect(initialArray[1].props.group).toBe('Style');
170+
expect(initialArray[1].props.name).toBe('Annotation');
171+
expect(initialArray[2].props.group).toBe('Structure');
172+
expect(initialArray[2].props.name).toBe('Create');
173+
expect(initialArray[3].props.group).toBe('Structure');
174+
expect(initialArray[3].props.name).toBe('Subplots');
175+
});
176+
});

src/lib/sortMenu.js

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
function getUniqueValues(value, index, self) {
2+
return self.indexOf(value) === index;
3+
}
4+
5+
function sortAlphabetically(a, b) {
6+
const sortByGroup = a.props.group === b.props.group ? 0 : a.props.group < b.props.group ? -1 : 1;
7+
const sortByName = a.props.name === b.props.name ? 0 : a.props.name < b.props.name ? -1 : 1;
8+
return sortByGroup || sortByName;
9+
}
10+
11+
export default function sortMenu(panels, order) {
12+
// validates order, if a desired panel matches no panel in the panels array,
13+
// it is excluded from ordering considerations
14+
15+
// eslint-disable-next-line
16+
order = order.filter(desiredPanel =>
17+
panels.some(
18+
actualPanel =>
19+
actualPanel.props.name === desiredPanel.name &&
20+
actualPanel.props.group === desiredPanel.group
21+
)
22+
);
23+
24+
const desiredGroupOrder = order.map(panel => panel.group).filter(getUniqueValues);
25+
const desiredNameOrder = order.map(panel => panel.name).filter(getUniqueValues);
26+
27+
panels.sort((a, b) => {
28+
const panelAHasGroupCustomOrder = desiredGroupOrder.includes(a.props.group);
29+
const panelBHasGroupCustomOrder = desiredGroupOrder.includes(b.props.group);
30+
31+
// if one of the elements is not in the desiredGroupOrder array, then it goes to the end of the list
32+
if (panelAHasGroupCustomOrder && !panelBHasGroupCustomOrder) {
33+
return -1;
34+
}
35+
if (!panelAHasGroupCustomOrder && panelBHasGroupCustomOrder) {
36+
return 1;
37+
}
38+
39+
// if both elements are not in the desiredGroupOrder array, they get sorted alphabetically,
40+
// by group, then by name
41+
if (!panelAHasGroupCustomOrder && !panelBHasGroupCustomOrder) {
42+
return sortAlphabetically(a, b);
43+
}
44+
45+
// if both elements are in the desiredGroupOrder array, they get sorted according to their order in
46+
// the desiredGroupOrder, then desiredNameOrder arrays.
47+
if (panelAHasGroupCustomOrder && panelBHasGroupCustomOrder) {
48+
const indexOfGroupA = desiredGroupOrder.indexOf(a.props.group);
49+
const indexOfGroupB = desiredGroupOrder.indexOf(b.props.group);
50+
51+
if (indexOfGroupA < indexOfGroupB) {
52+
return -1;
53+
}
54+
55+
if (indexOfGroupA > indexOfGroupB) {
56+
return 1;
57+
}
58+
59+
if (indexOfGroupA === indexOfGroupB) {
60+
const panelAHasNameCustomOrder = desiredNameOrder.includes(a.props.name);
61+
const panelBHasNameCustomOrder = desiredNameOrder.includes(b.props.name);
62+
63+
if (!panelAHasNameCustomOrder || !panelBHasNameCustomOrder) {
64+
if (panelAHasNameCustomOrder && !panelBHasNameCustomOrder) {
65+
return -1;
66+
}
67+
if (!panelAHasNameCustomOrder && panelBHasNameCustomOrder) {
68+
return 1;
69+
}
70+
if (!panelAHasNameCustomOrder && !panelBHasNameCustomOrder) {
71+
return sortAlphabetically(a, b);
72+
}
73+
}
74+
75+
if (panelAHasNameCustomOrder && panelBHasNameCustomOrder) {
76+
return desiredNameOrder.indexOf(a.props.name) - desiredNameOrder.indexOf(b.props.name);
77+
}
78+
}
79+
}
80+
return 0;
81+
});
82+
}

0 commit comments

Comments
 (0)