aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Cheng <[email protected]>2023-01-26 11:09:47 -0500
committerGitHub <[email protected]>2023-01-26 16:09:47 +0000
commitb86638d478fa21fafa9aaa3e247a08b479bf5a9d (patch)
treecd897a089b3b27e75158e758c38bebba97a0a8a8
parentc7ce35a47d336de3ac6f73efd7390ba696b6a4b2 (diff)
downloadfaker-b86638d478fa21fafa9aaa3e247a08b479bf5a9d.tar.xz
faker-b86638d478fa21fafa9aaa3e247a08b479bf5a9d.zip
feat(helpers): add length range support in `arrayElements` (#1772)
-rw-r--r--src/modules/helpers/index.ts39
-rw-r--r--test/__snapshots__/helpers.spec.ts.snap24
-rw-r--r--test/helpers.spec.ts46
3 files changed, 96 insertions, 13 deletions
diff --git a/src/modules/helpers/index.ts b/src/modules/helpers/index.ts
index 8492a096..a4ecdf71 100644
--- a/src/modules/helpers/index.ts
+++ b/src/modules/helpers/index.ts
@@ -561,13 +561,14 @@ export class HelpersModule {
*
* @template T The type of the entries to pick from.
* @param array Array to pick the value from.
- * @param count Number of elements to pick.
+ * @param count Number or range of elements to pick.
* When not provided, random number of elements will be picked.
* When value exceeds array boundaries, it will be limited to stay inside.
*
* @example
* faker.helpers.arrayElements(['cat', 'dog', 'mouse']) // ['mouse', 'cat']
* faker.helpers.arrayElements([1, 2, 3, 4, 5], 2) // [4, 2]
+ * faker.helpers.arrayElements([1, 2, 3, 4, 5], { min: 2, max: 4 }) // [3, 5, 1]
*
* @since 6.3.0
*/
@@ -575,22 +576,36 @@ export class HelpersModule {
// TODO @Shinigami92 2022-04-30: We want to remove this default value, but currently it's not possible because some definitions could be empty
// See https://github.com/faker-js/faker/issues/893
array: ReadonlyArray<T> = ['a', 'b', 'c'] as unknown as ReadonlyArray<T>,
- count?: number
+ count?:
+ | number
+ | {
+ /**
+ * The minimum number of elements to pick.
+ */
+ min: number;
+ /**
+ * The maximum number of elements to pick.
+ */
+ max: number;
+ }
): T[] {
- if (typeof count !== 'number') {
- count =
- array.length === 0
- ? 0
- : this.faker.number.int({ min: 1, max: array.length });
- } else if (count > array.length) {
- count = array.length;
- } else if (count < 0) {
- count = 0;
+ if (array.length === 0) {
+ return [];
+ }
+
+ const numElements = this.rangeToNumber(
+ count ?? { min: 1, max: array.length }
+ );
+
+ if (numElements >= array.length) {
+ return this.shuffle(array);
+ } else if (numElements <= 0) {
+ return [];
}
const arrayCopy = array.slice(0);
let i = array.length;
- const min = i - count;
+ const min = i - numElements;
let temp: T;
let index: number;
diff --git a/test/__snapshots__/helpers.spec.ts.snap b/test/__snapshots__/helpers.spec.ts.snap
index ca5ae30a..3b149cf6 100644
--- a/test/__snapshots__/helpers.spec.ts.snap
+++ b/test/__snapshots__/helpers.spec.ts.snap
@@ -29,6 +29,13 @@ exports[`helpers > 42 > arrayElements > with array and count 1`] = `
]
`;
+exports[`helpers > 42 > arrayElements > with array and count range 1`] = `
+[
+ "d",
+ "l",
+]
+`;
+
exports[`helpers > 42 > fake > with a dynamic template 1`] = `"my string: Cky2eiXX/J"`;
exports[`helpers > 42 > fake > with a static template 1`] = `"my test string"`;
@@ -218,6 +225,16 @@ exports[`helpers > 1211 > arrayElements > with array and count 1`] = `
]
`;
+exports[`helpers > 1211 > arrayElements > with array and count range 1`] = `
+[
+ "e",
+ "l",
+ "o",
+ "l",
+ " ",
+]
+`;
+
exports[`helpers > 1211 > fake > with a dynamic template 1`] = `"my string: wKti5-}$_/"`;
exports[`helpers > 1211 > fake > with a static template 1`] = `"my test string"`;
@@ -403,6 +420,13 @@ exports[`helpers > 1337 > arrayElements > with array and count 1`] = `
]
`;
+exports[`helpers > 1337 > arrayElements > with array and count range 1`] = `
+[
+ "e",
+ "W",
+]
+`;
+
exports[`helpers > 1337 > fake > with a dynamic template 1`] = `"my string: 9U/4:SK$>6"`;
exports[`helpers > 1337 > fake > with a static template 1`] = `"my test string"`;
diff --git a/test/helpers.spec.ts b/test/helpers.spec.ts
index 0e75e10f..b991cbac 100644
--- a/test/helpers.spec.ts
+++ b/test/helpers.spec.ts
@@ -76,7 +76,11 @@ describe('helpers', () => {
t.describe('arrayElements', (t) => {
t.it('noArgs')
.it('with array', 'Hello World!'.split(''))
- .it('with array and count', 'Hello World!'.split(''), 3);
+ .it('with array and count', 'Hello World!'.split(''), 3)
+ .it('with array and count range', 'Hello World!'.split(''), {
+ min: 1,
+ max: 5,
+ });
});
t.describe('shuffle', (t) => {
@@ -281,6 +285,46 @@ describe('helpers', () => {
expect(subset).toHaveLength(new Set(subset).size);
});
+ it('should return a subset with random elements in the array for a length range', () => {
+ const testArray = ['hello', 'to', 'you', 'my', 'friend'];
+ const subset = faker.helpers.arrayElements(testArray, {
+ min: 2,
+ max: 4,
+ });
+
+ // Check length
+ expect(subset.length).toBeGreaterThanOrEqual(2);
+ expect(subset.length).toBeLessThanOrEqual(4);
+
+ // Check elements
+ subset.forEach((element) => {
+ expect(testArray).toContain(element);
+ });
+
+ // Check uniqueness
+ expect(subset).not.toContainDuplicates();
+ });
+
+ it('should return an array with all elements when count > array length', () => {
+ const testArray = ['hello', 'to', 'you', 'my', 'friend'];
+ const subset = faker.helpers.arrayElements(testArray, 6);
+
+ // Check length
+ expect(subset.length).toEqual(5);
+
+ // Check elements
+ subset.forEach((element) => {
+ expect(testArray).toContain(element);
+ });
+ });
+
+ it('should return an empty array when array length > 0 and count = 0', () => {
+ const testArray = ['hello', 'to', 'you', 'my', 'friend'];
+ const result = faker.helpers.arrayElements(testArray, 0);
+
+ expect(result).toHaveLength(0);
+ });
+
it('should return an empty array when receiving an empty array', () => {
const result = faker.helpers.arrayElements([]);