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";
describe("find-composite", () => {
let composite: Composite<{ id: string; parentId?: string; someProperty: string }>;
let composite: Composite<{ id: string; parentId?: string }>;
beforeEach(() => {
composite = getComposite({
source: [
{ id: "some-root-id", someProperty: "some-value" },
{ id: "some-child-id", parentId: "some-root-id", someProperty: "some-value" },
{ id: "some-irrelevant-grandchild-id", parentId: "some-child-id", someProperty: "some-value" },
{ id: "some-grandchild-id", parentId: "some-child-id", someProperty: "some-value" },
{ id: "some-root-id" },
{ id: "some-child-id", parentId: "some-root-id" },
{ id: "some-grandchild-id", parentId: "some-child-id" },
{ id: "some-other-grandchild-id", parentId: "some-child-id" },
],
rootId: "some-root-id",
@ -25,28 +25,62 @@ describe("find-composite", () => {
it("when finding root using path, does so", () => {
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", () => {
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", () => {
const actual = findComposite(
"some-root-id.some-child-id.some-grandchild-id",
"some-root-id",
"some-child-id",
"some-grandchild-id",
)(composite);
expect(actual?.id).toBe("some-grandchild-id");
expect(actual.id).toBe("some-grandchild-id");
});
it("when finding with non existing path, returns undefined", () => {
const actual = findComposite("some-root-id.some-non-existing-path")(
composite,
);
it("when finding with non existing leaf-level path, throws", () => {
expect(() => {
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.
*/
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 =
(path: string) =>
<T>(composite: Composite<T>): Composite<T> | undefined =>
new Map(getCompositeNormalization(composite)).get(path);
(...path: string[]) =>
<T>(composite: Composite<T>): Composite<T> => {
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";
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 = {
id: "some-root-id",
parentId: undefined,
@ -31,12 +31,12 @@ describe("get-composite-normalization", () => {
const actual = getCompositeNormalization(composite);
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 }),
],
]);

View File

@ -8,15 +8,17 @@ export const getCompositeNormalization = <T>(composite: Composite<T>) => {
const _normalizeComposite = <T>(
composite: Composite<T>,
previousPath: string[] = [],
): (readonly [path: string, composite: Composite<T>])[] => {
): (readonly [path: string[], composite: Composite<T>])[] => {
const currentPath = [...previousPath, composite.id];
const pathAndCompositeTuple = [currentPath.join("."), composite] as const;
const pathAndCompositeTuple = [currentPath, composite] as const;
return [
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",
};
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 = {
id: "some-child-id-1",
parentId: "some-id-1",
parentId: "some-root-id",
orderNumber: 1,
};
const someChildItem2 = {
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,
};
const items = [
someRootItem,
// Note: not in order yet.
someItem2,
someItem1,
someChildItem2,
someChildItem1,
someGrandchildItem2,
someGrandchildItem1,
];
const composite = getComposite({
@ -52,10 +52,10 @@ describe("get-composite-paths", () => {
expect(actual).toEqual([
"some-root-id",
"some-root-id.some-id-1",
"some-root-id.some-id-1.some-child-id-1",
"some-root-id.some-id-1.some-child-id-2",
"some-root-id.some-id-2",
"some-root-id -> some-child-id-1",
"some-root-id -> some-child-id-1 -> some-grandchild-id-1",
"some-root-id -> some-child-id-1 -> some-grandchild-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 = (
composite: Composite<unknown>,
): string[] => pipeline(composite, getCompositeNormalization, map(([path]) => path));
): string[] => pipeline(composite, getCompositeNormalization, map(([path]) => path.join(" -> ")));