diff --git a/src/common/utils/find-exactly-one/find-exactly-one.test.ts b/src/common/utils/find-exactly-one/find-exactly-one.test.ts new file mode 100644 index 0000000000..08dbb9ce72 --- /dev/null +++ b/src/common/utils/find-exactly-one/find-exactly-one.test.ts @@ -0,0 +1,34 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ + +import { findExactlyOne } from "./find-exactly-one"; + +describe("find-exactly-one", () => { + it("when predicate matches to single item, returns the item", () => { + const actual = findExactlyOne((item) => item === "some-item")([ + "some-item", + "some-other-item", + ]); + + expect(actual).toBe("some-item"); + }); + + it("when predicate matches to many items, throws", () => { + expect(() => { + findExactlyOne((item) => item === "some-item")([ + "some-item", + "some-item", + ]); + }).toThrow("Tried to find exactly one, but found many"); + }); + + it("when predicate does not match, throws", () => { + expect(() => { + findExactlyOne((item) => item === "some-item")([ + "some-other-item", + ]); + }).toThrow("Tried to find exactly one, but didn't find any"); + }); +}); diff --git a/src/common/utils/find-exactly-one/find-exactly-one.ts b/src/common/utils/find-exactly-one/find-exactly-one.ts new file mode 100644 index 0000000000..181720d8b1 --- /dev/null +++ b/src/common/utils/find-exactly-one/find-exactly-one.ts @@ -0,0 +1,21 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +export const findExactlyOne = (predicate: (item: T) => boolean) => (collection: T[]): T => { + const itemsFound = collection.filter(predicate); + + if (!itemsFound.length) { + throw new Error( + "Tried to find exactly one, but didn't find any", + ); + } + + if (itemsFound.length > 1) { + throw new Error( + "Tried to find exactly one, but found many", + ); + } + + return itemsFound[0]; +};