1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Make composite able to have custom handler for missing parent ids

This will be useful next for application menu items, where a missing parent id cannot be fatal.

Co-authored-by: Janne Savolainen <janne.savolainen@live.fi>

Signed-off-by: Iku-turso <mikko.aspiala@gmail.com>
This commit is contained in:
Iku-turso 2022-10-11 14:39:41 +03:00 committed by Janne Savolainen
parent 0e550d496c
commit 822f4394fe
No known key found for this signature in database
GPG Key ID: 8C6CFB2FFFE8F68A
2 changed files with 68 additions and 9 deletions

View File

@ -4,6 +4,7 @@
*/
import { sortBy } from "lodash/fp";
import type { Composite } from "./get-composite";
import getComposite from "./get-composite";
import { getCompositePaths } from "./get-composite-paths/get-composite-paths";
@ -165,7 +166,7 @@ describe("get-composite", () => {
);
});
it("given missing parent ids, throws", () => {
it("given items with missing parent ids, when creating composite without handling for unknown parents, throws", () => {
const someItem = {
someId: "some-id",
someParentId: undefined,
@ -186,10 +187,54 @@ describe("get-composite", () => {
getParentId: (x) => x.someParentId,
});
}).toThrow(
'Tried to get a composite but encountered missing parent ids: "some-missing-id"',
`Tried to get a composite but encountered missing parent ids: "some-missing-id".
Available parent ids are:
"some-id",
"some-other-id"`,
);
});
describe("given items with missing parent ids, when creating composite with handling for missing parents", () => {
let composite: Composite<any>;
let handleMissingParentIdMock: jest.Mock;
beforeEach(() => {
const someItem = {
id: "some-root-id",
parentId: undefined,
};
const someItemWithMissingParentId = {
id: "some-orphan-id",
// Note: missing parent id makes the item orphan.
parentId: "some-missing-id",
};
const items = [someItem, someItemWithMissingParentId];
handleMissingParentIdMock = jest.fn();
composite = getComposite({
source: items,
handleMissingParentIds: handleMissingParentIdMock,
});
});
it("creates composite without the orphan item, and without throwing", () => {
const paths = getCompositePaths(composite);
expect(paths).toEqual(["some-root-id"]);
});
it("handles the missing parent ids", () => {
expect(handleMissingParentIdMock).toHaveBeenCalledWith({
missingParentIds: ["some-missing-id"],
availableParentIds: ["some-root-id", "some-orphan-id"],
});
});
});
it("given undefined ids, throws", () => {
const root = {
someParentId: undefined,

View File

@ -30,12 +30,14 @@ export default <T>({
getId = get("id"),
getParentId = get("parentId"),
getOrderedChildren = (things: T[]) => sortBy("orderNumber", things),
handleMissingParentIds = throwMissingParentIds,
}: {
source: T[];
rootId?: string;
getId?: (thing: T) => string;
getParentId?: (thing: T) => string | undefined;
getOrderedChildren?: (things: T[]) => T[];
handleMissingParentIds?: (parentIdsForHandling: ParentIdsForHandling) => void;
}) => {
const undefinedIds = pipeline(
source,
@ -68,14 +70,10 @@ export default <T>({
const allParentIds = pipeline(source, map(getParentId), uniq, compact);
const unknownParentIds = without(allIds, allParentIds);
const missingParentIds = without(allIds, allParentIds);
if (unknownParentIds.length) {
throw new Error(
`Tried to get a composite but encountered missing parent ids: "${unknownParentIds
.map((x) => String(x))
.join('", "')}"`,
);
if (missingParentIds.length) {
handleMissingParentIds({ missingParentIds, availableParentIds: allIds });
}
const toComposite = (thing: T): Composite<T> => {
@ -118,3 +116,19 @@ export default <T>({
return toComposite(roots[0]);
};
interface ParentIdsForHandling {
missingParentIds: string[];
availableParentIds: string[];
}
const throwMissingParentIds = ({
missingParentIds,
availableParentIds,
}: ParentIdsForHandling) => {
throw new Error(
`Tried to get a composite but encountered missing parent ids: "${missingParentIds.join(
'", "',
)}".\n\nAvailable parent ids are:\n"${availableParentIds.join('",\n"')}"`,
);
};