wix-style-react
Version:
wix-style-react
227 lines • 9.25 kB
JavaScript
import React, { memo } from 'react';
import SidebarItemNext from '../SidebarItemNext';
import SidebarSubMenuNext from '../SidebarSubMenuNext';
import { extractItemNodes, getItemPath, getMenuPath, getMaxDepth, pick, } from './utils';
const CustomItem = (props) => (React.createElement(SidebarItemNext, { ...props }));
const CustomSubMenu = memo((props) => (React.createElement(SidebarSubMenuNext, { ...props })));
describe('extractItemNodes', () => {
it('should extract menu structure from sidebar JSX elements', () => {
const { items, keyToParentKey } = extractItemNodes(React.createElement(React.Fragment, null,
React.createElement(SidebarItemNext, { itemKey: "i1" }),
React.createElement(SidebarSubMenuNext, { itemKey: "m2" },
React.createElement(SidebarItemNext, { itemKey: "m2-i1" }),
React.createElement(SidebarItemNext, { itemKey: "m2-i2" })),
React.createElement(SidebarSubMenuNext, { itemKey: "m3" },
React.createElement(SidebarSubMenuNext, { itemKey: "m3-m1" },
React.createElement(SidebarItemNext, { itemKey: "m3-m1-i1" })))));
expect(items).toEqual([
{
itemKey: 'i1',
},
{
itemKey: 'm2',
items: [{ itemKey: 'm2-i1' }, { itemKey: 'm2-i2' }],
},
{
itemKey: 'm3',
items: [
{
itemKey: 'm3-m1',
items: [{ itemKey: 'm3-m1-i1' }],
},
],
},
]);
expect(keyToParentKey).toEqual({
'm2-i1': 'm2',
'm2-i2': 'm2',
'm3-m1': 'm3',
'm3-m1-i1': 'm3-m1',
});
});
it('should handle empty children', () => {
const { items, keyToParentKey } = extractItemNodes(null);
expect(items).toEqual([]);
expect(keyToParentKey).toEqual({});
});
it('should ignore JSX elements without itemKey', () => {
const { items, keyToParentKey } = extractItemNodes(React.createElement(React.Fragment, null,
React.createElement("div", null),
React.createElement("div", null,
React.createElement(SidebarItemNext, { itemKey: "i1" }),
React.createElement("div", null,
React.createElement(SidebarSubMenuNext, { itemKey: "m2" },
React.createElement(SidebarItemNext, { itemKey: "m2-i1" }),
React.createElement("span", null,
React.createElement(SidebarItemNext, { itemKey: "m2-i2" }))),
React.createElement(SidebarSubMenuNext, { itemKey: "m3" },
React.createElement(SidebarSubMenuNext, { itemKey: "m3-m1" },
React.createElement("div", null,
React.createElement(SidebarItemNext, { itemKey: "m3-m1-i1" }))))))));
expect(items).toEqual([
{
itemKey: 'i1',
},
{
itemKey: 'm2',
items: [{ itemKey: 'm2-i1' }, { itemKey: 'm2-i2' }],
},
{
itemKey: 'm3',
items: [
{
itemKey: 'm3-m1',
items: [{ itemKey: 'm3-m1-i1' }],
},
],
},
]);
expect(keyToParentKey).toEqual({
'm2-i1': 'm2',
'm2-i2': 'm2',
'm3-m1': 'm3',
'm3-m1-i1': 'm3-m1',
});
});
it('should handle custom menu and item components', () => {
const { items, keyToParentKey } = extractItemNodes(React.createElement(React.Fragment, null,
React.createElement(CustomItem, { itemKey: "i1" }),
React.createElement(CustomSubMenu, { itemKey: "m2" },
React.createElement(CustomItem, { itemKey: "m2-i1" }),
React.createElement(CustomItem, { itemKey: "m2-i2" })),
React.createElement(CustomSubMenu, { itemKey: "m3" },
React.createElement(CustomSubMenu, { itemKey: "m3-m1" },
React.createElement("div", { itemKey: "m3-m1-i1" })))));
expect(items).toEqual([
{
itemKey: 'i1',
},
{
itemKey: 'm2',
items: [{ itemKey: 'm2-i1' }, { itemKey: 'm2-i2' }],
},
{
itemKey: 'm3',
items: [
{
itemKey: 'm3-m1',
items: [{ itemKey: 'm3-m1-i1' }],
},
],
},
]);
expect(keyToParentKey).toEqual({
'm2-i1': 'm2',
'm2-i2': 'm2',
'm3-m1': 'm3',
'm3-m1-i1': 'm3-m1',
});
});
});
describe('getItemPath', () => {
it('should return path to the item', () => {
const keyToParentKey = {
'm2-i1': 'm2',
'm2-i2': 'm2',
'm3-m1': 'm3',
'm3-m1-i1': 'm3-m1',
};
const result = getItemPath(keyToParentKey, 'm3-m1-i1');
expect(result).toEqual(['m3', 'm3-m1', 'm3-m1-i1']);
});
it('should return an array containing the key itself if parent is not found', () => {
const keyToParentKey = {
'm2-i1': 'm2',
'm2-i2': 'm2',
'm3-m1': 'm3',
'm3-m1-i1': 'm3-m1',
};
const result = getItemPath(keyToParentKey, 'abc');
// TODO: probably should return an empty array. Doesn't change sidebar behavior though.
expect(result).toEqual(['abc']);
});
});
describe('getMenuPath', () => {
it('should return path to the parent menu if the target is an item', () => {
const keyToParentKey = {
'm2-i1': 'm2',
'm2-i2': 'm2',
'm3-m1': 'm3',
'm3-m1-i1': 'm3-m1',
};
const result = getMenuPath(keyToParentKey, 'm3-m1-i1');
expect(result).toEqual(['m3', 'm3-m1']);
});
it('should return path to the menu itself if the target is a menu', () => {
const keyToParentKey = {
'm2-i1': 'm2',
'm2-i2': 'm2',
'm3-m1': 'm3',
'm3-m1-i1': 'm3-m1',
};
const result = getMenuPath(keyToParentKey, 'm3-m1');
expect(result).toEqual(['m3', 'm3-m1']);
});
it('should return an empty array if the key is not found', () => {
const keyToParentKey = {
'm2-i1': 'm2',
'm2-i2': 'm2',
'm3-m1': 'm3',
'm3-m1-i1': 'm3-m1',
};
const result = getMenuPath(keyToParentKey, 'abc');
expect(result).toEqual([]);
});
});
describe('getMaxDepth', () => {
it('should return the maximum depth of the menu structure', () => {
{
const { items } = extractItemNodes(React.createElement(SidebarItemNext, { itemKey: "i1" }));
const maxDepth = getMaxDepth(items);
expect(maxDepth).toBe(1);
}
{
const { items } = extractItemNodes(React.createElement(React.Fragment, null,
React.createElement(SidebarSubMenuNext, { itemKey: "m1" },
React.createElement(SidebarItemNext, { itemKey: "m1-i1" }),
React.createElement(SidebarItemNext, { itemKey: "m1-i2" }))));
const maxDepth = getMaxDepth(items);
expect(maxDepth).toBe(2);
}
{
const { items } = extractItemNodes(React.createElement(React.Fragment, null,
React.createElement(SidebarSubMenuNext, { itemKey: "m1" },
React.createElement(SidebarSubMenuNext, { itemKey: "m1-m1" },
React.createElement(SidebarItemNext, { itemKey: "m1-m1-i1" })))));
const maxDepth = getMaxDepth(items);
expect(maxDepth).toBe(3);
}
});
it('should return 0 if there are no items', () => {
const maxDepth = getMaxDepth([]);
expect(maxDepth).toBe(0);
});
});
describe('pick', () => {
it('should return an object with the specified keys', () => {
const object = { foo: 'bar', baz: 'qux', quux: 'corge' };
const result = pick(object, ['foo', 'quux']);
expect(result).toEqual({ foo: 'bar', quux: 'corge' });
});
it('should return an empty object if no keys are specified', () => {
const object = { foo: 'bar', baz: 'qux', quux: 'corge' };
const result = pick(object, []);
expect(result).toEqual({});
});
it('should return an empty object if the specified keys do not exist in the object', () => {
const object = { foo: 'bar', baz: 'qux', quux: 'corge' };
const result = pick(object, ['abc', 'def']);
expect(result).toEqual({});
});
it('should not treat keys as paths', () => {
const object = { foo: { bar: 'baz' } };
const result = pick(object, ['foo.bar']);
expect(result).toEqual({});
});
});
//# sourceMappingURL=utils.spec.js.map