Skip to content

Commit

Permalink
fix(helpers): prevent uniqueArray from hanging (#2239)
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewmayer authored Jul 27, 2023
1 parent 052a00c commit 3dece09
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 1 deletion.
10 changes: 9 additions & 1 deletion src/modules/helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,11 @@ export class HelpersModule {
* and outputs a unique array of strings based on that source.
* This method does not store the unique state between invocations.
*
* If there are not enough unique values to satisfy the length, if
* the source is an array, it will only return as many items as are
* in the array. If the source is a function, it will return after
* a maximum number of attempts has been reached.
*
* @template T The type of the elements.
*
* @param source The strings to choose from or a function that generates a string.
Expand All @@ -671,8 +676,11 @@ export class HelpersModule {
const set = new Set<T>();
try {
if (typeof source === 'function') {
while (set.size < length) {
const maxAttempts = 1000 * length;
let attempts = 0;
while (set.size < length && attempts < maxAttempts) {
set.add(source());
attempts++;
}
}
} catch {
Expand Down
8 changes: 8 additions & 0 deletions test/helpers.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,14 @@ describe('helpers', () => {
expect(unique).toHaveLength(input.length);
});

it('function with length longer than possible values returns', () => {
const fn = () => faker.helpers.arrayElement(['a', 'b']);
const length = 3;
const unique = faker.helpers.uniqueArray(fn, length);
expect(unique).not.toContainDuplicates();
expect(unique).toHaveLength(2);
});

it('works as expected when seeded', () => {
const input = ['a', 'a', 'a', 'a', 'a', 'f', 'g', 'h', 'i', 'j'];
const length = 5;
Expand Down

0 comments on commit 3dece09

Please sign in to comment.