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