Skip to content

Commit 3dece09

Browse files
authored
fix(helpers): prevent uniqueArray from hanging (#2239)
1 parent 052a00c commit 3dece09

2 files changed

Lines changed: 17 additions & 1 deletion

File tree

src/modules/helpers/index.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,11 @@ export class HelpersModule {
649649
* and outputs a unique array of strings based on that source.
650650
* This method does not store the unique state between invocations.
651651
*
652+
* If there are not enough unique values to satisfy the length, if
653+
* the source is an array, it will only return as many items as are
654+
* in the array. If the source is a function, it will return after
655+
* a maximum number of attempts has been reached.
656+
*
652657
* @template T The type of the elements.
653658
*
654659
* @param source The strings to choose from or a function that generates a string.
@@ -671,8 +676,11 @@ export class HelpersModule {
671676
const set = new Set<T>();
672677
try {
673678
if (typeof source === 'function') {
674-
while (set.size < length) {
679+
const maxAttempts = 1000 * length;
680+
let attempts = 0;
681+
while (set.size < length && attempts < maxAttempts) {
675682
set.add(source());
683+
attempts++;
676684
}
677685
}
678686
} catch {

test/helpers.spec.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,14 @@ describe('helpers', () => {
806806
expect(unique).toHaveLength(input.length);
807807
});
808808

809+
it('function with length longer than possible values returns', () => {
810+
const fn = () => faker.helpers.arrayElement(['a', 'b']);
811+
const length = 3;
812+
const unique = faker.helpers.uniqueArray(fn, length);
813+
expect(unique).not.toContainDuplicates();
814+
expect(unique).toHaveLength(2);
815+
});
816+
809817
it('works as expected when seeded', () => {
810818
const input = ['a', 'a', 'a', 'a', 'a', 'f', 'g', 'h', 'i', 'j'];
811819
const length = 5;

0 commit comments

Comments
 (0)