diff --git a/src/util.test.ts b/src/util.test.ts index 1376ae780..d6fc6aad0 100644 --- a/src/util.test.ts +++ b/src/util.test.ts @@ -539,3 +539,27 @@ test("checkDiskUsage succeeds and produces positive numbers", async (t) => { t.true(diskUsage.numTotalBytes > 0); } }); + +test("joinAtMost - behaves like join if limit is <= 0", (t) => { + const sep = ", "; + const array: string[] = new Array(10).fill("test"); + t.is(util.joinAtMost(array, sep, 0), array.join(sep)); + t.is(util.joinAtMost(array, sep, -1), array.join(sep)); +}); + +test("joinAtMost - behaves like join if limit is >= the size of the array", (t) => { + const sep = ", "; + const array: string[] = new Array(10).fill("test"); + t.is(util.joinAtMost(array, sep, 10), array.join(sep)); + t.is(util.joinAtMost(array, sep, 11), array.join(sep)); +}); + +test("joinAtMost - truncates list if array is > than limit", (t) => { + const sep = ", "; + const array: string[] = Array.from(new Array(10), (_, i) => `test${i + 1}`); + const result = util.joinAtMost(array, sep, 5); + t.not(result, array.join(sep)); + t.assert(result.endsWith(", ...")); + t.assert(result.includes("test5")); + t.false(result.includes("test6")); +}); diff --git a/src/util.ts b/src/util.ts index a06a60bfe..327fce0c7 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1270,3 +1270,25 @@ export enum CleanupLevel { Clear = "clear", Overlay = "overlay", } + +/** + * Like `join`, but limits the number of elements that are joined together to `limit` + * and appends `...` if the limit is exceeded. + * + * @param array The array to join. + * @param separator The separator to join the array with. + * @param limit The maximum number of elements from `array` to join. + * @returns The result of joining at most `limit`-many elements from `array`. + */ +export function joinAtMost( + array: string[], + separator: string, + limit: number, +): string { + if (limit > 0 && array.length > limit) { + array = array.slice(0, limit); + array.push("..."); + } + + return array.join(separator); +}