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

Make composite not care about in formatting of ids

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-21 12:36:50 +03:00
parent f4fc38b161
commit 5b9ce7bbb2
6 changed files with 108 additions and 47 deletions

View File

@ -7,15 +7,15 @@ import getComposite from "../get-composite/get-composite";
import { findComposite } from "./find-composite"; import { findComposite } from "./find-composite";
describe("find-composite", () => { describe("find-composite", () => {
let composite: Composite<{ id: string; parentId?: string; someProperty: string }>; let composite: Composite<{ id: string; parentId?: string }>;
beforeEach(() => { beforeEach(() => {
composite = getComposite({ composite = getComposite({
source: [ source: [
{ id: "some-root-id", someProperty: "some-value" }, { id: "some-root-id" },
{ id: "some-child-id", parentId: "some-root-id", someProperty: "some-value" }, { id: "some-child-id", parentId: "some-root-id" },
{ id: "some-irrelevant-grandchild-id", parentId: "some-child-id", someProperty: "some-value" }, { id: "some-grandchild-id", parentId: "some-child-id" },
{ id: "some-grandchild-id", parentId: "some-child-id", someProperty: "some-value" }, { id: "some-other-grandchild-id", parentId: "some-child-id" },
], ],
rootId: "some-root-id", rootId: "some-root-id",
@ -25,28 +25,62 @@ describe("find-composite", () => {
it("when finding root using path, does so", () => { it("when finding root using path, does so", () => {
const actual = findComposite("some-root-id")(composite); const actual = findComposite("some-root-id")(composite);
expect(actual?.id).toBe("some-root-id"); expect(actual.id).toBe("some-root-id");
}); });
it("when finding child using path, does so", () => { it("when finding child using path, does so", () => {
const actual = findComposite("some-root-id.some-child-id")(composite); const actual = findComposite("some-root-id", "some-child-id")(composite);
expect(actual?.id).toBe("some-child-id"); expect(actual.id).toBe("some-child-id");
}); });
it("when finding grandchild using path, does so", () => { it("when finding grandchild using path, does so", () => {
const actual = findComposite( const actual = findComposite(
"some-root-id.some-child-id.some-grandchild-id", "some-root-id",
"some-child-id",
"some-grandchild-id",
)(composite); )(composite);
expect(actual?.id).toBe("some-grandchild-id"); expect(actual.id).toBe("some-grandchild-id");
}); });
it("when finding with non existing path, returns undefined", () => { it("when finding with non existing leaf-level path, throws", () => {
const actual = findComposite("some-root-id.some-non-existing-path")( expect(() => {
composite, findComposite(
); "some-root-id",
"some-child-id",
"some-non-existing-grandchild-id",
)(composite);
}).toThrow(`Tried to find 'some-root-id -> some-child-id -> some-non-existing-grandchild-id' from a composite, but found nothing.
expect(actual).toBe(undefined); Node 'some-root-id -> some-child-id' had only following children:
some-grandchild-id
some-other-grandchild-id`);
});
it("when finding with non-existing mid-level path, throws", () => {
expect(() => {
findComposite(
"some-root-id",
"some-non-existing-child-id",
"some-non-existing-grandchild-id",
)(composite);
}).toThrow(`Tried to find 'some-root-id -> some-non-existing-child-id -> some-non-existing-grandchild-id' from a composite, but found nothing.
Node 'some-root-id' had only following children:
some-child-id`);
});
it("when finding with non-existing root-level path, throws", () => {
expect(() => {
findComposite(
"some-non-existing-root-id",
"some-non-existing-child-id",
"some-non-existing-grandchild-id",
)(composite);
}).toThrow(`Tried to find 'some-non-existing-root-id -> some-non-existing-child-id -> some-non-existing-grandchild-id' from a composite, but found nothing.
Node 'some-root-id' had only following children:
some-child-id`);
}); });
}); });

View File

@ -3,9 +3,34 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import type { Composite } from "../get-composite/get-composite"; import type { Composite } from "../get-composite/get-composite";
import { getCompositeNormalization } from "../get-composite-normalization/get-composite-normalization";
const _findComposite = <T>(currentLeftIds: string[], currentId: string, currentRightIds: string[], composite: Composite<T>): Composite<T> => {
const [nextId, ...nextRightIds] = currentRightIds;
const nextLeftIds = [...currentLeftIds, currentId];
if (currentRightIds.length === 0 && composite.id === currentId) {
return composite;
}
const foundChildComposite = composite.children.find((child) => child.id === nextId);
if (foundChildComposite) {
return _findComposite(nextLeftIds, nextId, nextRightIds, foundChildComposite);
}
const fullPathString = [...currentLeftIds, currentId, ...currentRightIds].join(" -> ");
throw new Error(`Tried to find '${fullPathString}' from a composite, but found nothing.
Node '${[...currentLeftIds, composite.id].join(" -> ")}' had only following children:
${composite.children.map((child) => child.id).join("\n")}`);
};
export const findComposite = export const findComposite =
(path: string) => (...path: string[]) =>
<T>(composite: Composite<T>): Composite<T> | undefined => <T>(composite: Composite<T>): Composite<T> => {
new Map(getCompositeNormalization(composite)).get(path); const [currentId, ...rightIds] = path;
const leftIds: string[] = [];
return _findComposite(leftIds, currentId, rightIds, composite);
};

View File

@ -6,7 +6,7 @@ import { getCompositeNormalization } from "./get-composite-normalization";
import getComposite from "../get-composite/get-composite"; import getComposite from "../get-composite/get-composite";
describe("get-composite-normalization", () => { describe("get-composite-normalization", () => {
it("given a composite, flattens it to path and composite", () => { it("given a composite, flattens it to paths and composites", () => {
const someRootItem = { const someRootItem = {
id: "some-root-id", id: "some-root-id",
parentId: undefined, parentId: undefined,
@ -31,12 +31,12 @@ describe("get-composite-normalization", () => {
const actual = getCompositeNormalization(composite); const actual = getCompositeNormalization(composite);
expect(actual).toEqual([ expect(actual).toEqual([
["some-root-id", expect.objectContaining({ value: someRootItem })], [["some-root-id"], expect.objectContaining({ value: someRootItem })],
["some-root-id.some-id", expect.objectContaining({ value: someItem })], [["some-root-id", "some-id"], expect.objectContaining({ value: someItem })],
[ [
"some-root-id.some-id.some-child-id", ["some-root-id", "some-id", "some-child-id"],
expect.objectContaining({ value: someNestedItem }), expect.objectContaining({ value: someNestedItem }),
], ],
]); ]);

View File

@ -8,15 +8,17 @@ export const getCompositeNormalization = <T>(composite: Composite<T>) => {
const _normalizeComposite = <T>( const _normalizeComposite = <T>(
composite: Composite<T>, composite: Composite<T>,
previousPath: string[] = [], previousPath: string[] = [],
): (readonly [path: string, composite: Composite<T>])[] => { ): (readonly [path: string[], composite: Composite<T>])[] => {
const currentPath = [...previousPath, composite.id]; const currentPath = [...previousPath, composite.id];
const pathAndCompositeTuple = [currentPath.join("."), composite] as const; const pathAndCompositeTuple = [currentPath, composite] as const;
return [ return [
pathAndCompositeTuple, pathAndCompositeTuple,
...composite.children.flatMap((x) => _normalizeComposite(x, currentPath)), ...composite.children.flatMap((child) =>
_normalizeComposite(child, currentPath),
),
]; ];
}; };

View File

@ -11,37 +11,37 @@ describe("get-composite-paths", () => {
id: "some-root-id", id: "some-root-id",
}; };
const someItem1 = {
id: "some-id-1",
parentId: "some-root-id",
orderNumber: 1,
};
const someItem2 = {
id: "some-id-2",
parentId: "some-root-id",
orderNumber: 2,
};
const someChildItem1 = { const someChildItem1 = {
id: "some-child-id-1", id: "some-child-id-1",
parentId: "some-id-1", parentId: "some-root-id",
orderNumber: 1, orderNumber: 1,
}; };
const someChildItem2 = { const someChildItem2 = {
id: "some-child-id-2", id: "some-child-id-2",
parentId: "some-id-1", parentId: "some-root-id",
orderNumber: 2,
};
const someGrandchildItem1 = {
id: "some-grandchild-id-1",
parentId: "some-child-id-1",
orderNumber: 1,
};
const someGrandchildItem2 = {
id: "some-grandchild-id-2",
parentId: "some-child-id-1",
orderNumber: 2, orderNumber: 2,
}; };
const items = [ const items = [
someRootItem, someRootItem,
// Note: not in order yet. // Note: not in order yet.
someItem2,
someItem1,
someChildItem2, someChildItem2,
someChildItem1, someChildItem1,
someGrandchildItem2,
someGrandchildItem1,
]; ];
const composite = getComposite({ const composite = getComposite({
@ -52,10 +52,10 @@ describe("get-composite-paths", () => {
expect(actual).toEqual([ expect(actual).toEqual([
"some-root-id", "some-root-id",
"some-root-id.some-id-1", "some-root-id -> some-child-id-1",
"some-root-id.some-id-1.some-child-id-1", "some-root-id -> some-child-id-1 -> some-grandchild-id-1",
"some-root-id.some-id-1.some-child-id-2", "some-root-id -> some-child-id-1 -> some-grandchild-id-2",
"some-root-id.some-id-2", "some-root-id -> some-child-id-2",
]); ]);
}); });
}); });

View File

@ -9,4 +9,4 @@ import { getCompositeNormalization } from "../get-composite-normalization/get-co
export const getCompositePaths = ( export const getCompositePaths = (
composite: Composite<unknown>, composite: Composite<unknown>,
): string[] => pipeline(composite, getCompositeNormalization, map(([path]) => path)); ): string[] => pipeline(composite, getCompositeNormalization, map(([path]) => path.join(" -> ")));