Skip to content

Commit 260b096

Browse files
committed
Fix cluster's invalid argument could lead to bugs.
1 parent 598dbe1 commit 260b096

File tree

4 files changed

+77
-0
lines changed

4 files changed

+77
-0
lines changed

src/array/cluster.ts

+10
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { IllegalSizeError } from 'radashi'
2+
13
/**
24
* Splits a single list into many lists of the desired size.
35
*
@@ -13,6 +15,14 @@ export function cluster<T, Size extends number = 2>(
1315
array: readonly T[],
1416
size: Size = 2 as Size,
1517
): Cluster<T, Size>[] {
18+
if (size <= 0 || Number.isNaN(size)) {
19+
throw new IllegalSizeError(`Size must be 1 or more, the size is ${size}`)
20+
}
21+
22+
if (size === Number.POSITIVE_INFINITY) {
23+
throw new IllegalSizeError(`Size must not be Infinity, the size is ${size}`)
24+
}
25+
1626
const clusters: T[][] = []
1727
for (let i = 0; i < array.length; i += size) {
1828
clusters.push(array.slice(i, i + size))

src/errors.ts

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export class IllegalSizeError extends Error {
2+
constructor(private _message = 'Size must not be less than 0') {
3+
super(_message)
4+
super.name = IllegalSizeError.name
5+
}
6+
7+
get message(): string {
8+
return this._message
9+
}
10+
}

src/mod.ts

+1
Original file line numberDiff line numberDiff line change
@@ -150,3 +150,4 @@ export * from './typed/isWeakMap.ts'
150150
export * from './typed/isWeakSet.ts'
151151

152152
export * from './types.ts'
153+
export * from './errors.ts'

tests/array/cluster.test.ts

+56
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,60 @@ describe('cluster', () => {
1818
expect(c).toEqual([1, 1, 1])
1919
expect(d).toEqual([2, 2])
2020
})
21+
22+
test('handles empty array', () => {
23+
const result = _.cluster([], 2);
24+
expect(result).toEqual([]);
25+
});
26+
27+
test('creates individual clusters when size is 1', () => {
28+
const list = [1, 2, 3, 4];
29+
const result = _.cluster(list, 1);
30+
expect(result).toEqual([[1], [2], [3], [4]]);
31+
});
32+
33+
test('creates a single cluster when size exceeds array length', () => {
34+
const list = [1, 2, 3];
35+
const result = _.cluster(list, 5);
36+
expect(result).toEqual([[1, 2, 3]]);
37+
});
38+
39+
test('throws error when size is 0', () => {
40+
const list = [1, 2, 3];
41+
const size = 0
42+
expect(() => _.cluster(list, size)).toThrow(_.IllegalSizeError);
43+
expect(() => _.cluster(list, size)).toThrow(`Size must be 1 or more, the size is ${size}`);
44+
});
45+
46+
test('throws error when size is negative', () => {
47+
const list = [1, 2, 3];
48+
const size = -2
49+
expect(() => _.cluster(list, size)).toThrow(_.IllegalSizeError);
50+
expect(() => _.cluster(list, size)).toThrow(`Size must be 1 or more, the size is ${size}`);
51+
});
52+
53+
test('uses default size of 2 when no size provided', () => {
54+
const list = [1, 2, 3, 4, 5];
55+
const actualResult = _.cluster(list);
56+
expect(actualResult).toEqual([[1, 2], [3, 4], [5]]);
57+
});
58+
59+
// THINK FURTHER
60+
test('throws error when size is NaN or Infinity', () => {
61+
const list = [1, 2, 3];
62+
expect(() => _.cluster(list, Number.NaN)).toThrow();
63+
expect(() => _.cluster(list, Number.POSITIVE_INFINITY)).toThrow();
64+
});
65+
66+
test('handles arrays with mixed data types', () => {
67+
const list = [1, 'a', true, {}, null];
68+
const actualResult = _.cluster(list, 2);
69+
expect(actualResult).toEqual([[1, 'a'], [true, {}], [null]]);
70+
});
71+
72+
test('handles very large size values', () => {
73+
const list = [1, 2, 3];
74+
const actualResult = _.cluster(list, Number.MAX_SAFE_INTEGER);
75+
expect(actualResult).toEqual([[1, 2, 3]]);
76+
});
2177
})

0 commit comments

Comments
 (0)