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:
parent
0e550d496c
commit
822f4394fe
@ -4,6 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { sortBy } from "lodash/fp";
|
import { sortBy } from "lodash/fp";
|
||||||
|
import type { Composite } from "./get-composite";
|
||||||
import getComposite from "./get-composite";
|
import getComposite from "./get-composite";
|
||||||
import { getCompositePaths } from "./get-composite-paths/get-composite-paths";
|
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 = {
|
const someItem = {
|
||||||
someId: "some-id",
|
someId: "some-id",
|
||||||
someParentId: undefined,
|
someParentId: undefined,
|
||||||
@ -186,10 +187,54 @@ describe("get-composite", () => {
|
|||||||
getParentId: (x) => x.someParentId,
|
getParentId: (x) => x.someParentId,
|
||||||
});
|
});
|
||||||
}).toThrow(
|
}).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", () => {
|
it("given undefined ids, throws", () => {
|
||||||
const root = {
|
const root = {
|
||||||
someParentId: undefined,
|
someParentId: undefined,
|
||||||
|
|||||||
@ -30,12 +30,14 @@ export default <T>({
|
|||||||
getId = get("id"),
|
getId = get("id"),
|
||||||
getParentId = get("parentId"),
|
getParentId = get("parentId"),
|
||||||
getOrderedChildren = (things: T[]) => sortBy("orderNumber", things),
|
getOrderedChildren = (things: T[]) => sortBy("orderNumber", things),
|
||||||
|
handleMissingParentIds = throwMissingParentIds,
|
||||||
}: {
|
}: {
|
||||||
source: T[];
|
source: T[];
|
||||||
rootId?: string;
|
rootId?: string;
|
||||||
getId?: (thing: T) => string;
|
getId?: (thing: T) => string;
|
||||||
getParentId?: (thing: T) => string | undefined;
|
getParentId?: (thing: T) => string | undefined;
|
||||||
getOrderedChildren?: (things: T[]) => T[];
|
getOrderedChildren?: (things: T[]) => T[];
|
||||||
|
handleMissingParentIds?: (parentIdsForHandling: ParentIdsForHandling) => void;
|
||||||
}) => {
|
}) => {
|
||||||
const undefinedIds = pipeline(
|
const undefinedIds = pipeline(
|
||||||
source,
|
source,
|
||||||
@ -68,14 +70,10 @@ export default <T>({
|
|||||||
|
|
||||||
const allParentIds = pipeline(source, map(getParentId), uniq, compact);
|
const allParentIds = pipeline(source, map(getParentId), uniq, compact);
|
||||||
|
|
||||||
const unknownParentIds = without(allIds, allParentIds);
|
const missingParentIds = without(allIds, allParentIds);
|
||||||
|
|
||||||
if (unknownParentIds.length) {
|
if (missingParentIds.length) {
|
||||||
throw new Error(
|
handleMissingParentIds({ missingParentIds, availableParentIds: allIds });
|
||||||
`Tried to get a composite but encountered missing parent ids: "${unknownParentIds
|
|
||||||
.map((x) => String(x))
|
|
||||||
.join('", "')}"`,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const toComposite = (thing: T): Composite<T> => {
|
const toComposite = (thing: T): Composite<T> => {
|
||||||
@ -118,3 +116,19 @@ export default <T>({
|
|||||||
|
|
||||||
return toComposite(roots[0]);
|
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"')}"`,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user