Skip to content

Commit

Permalink
Add the utils randomInt and randomItem
Browse files Browse the repository at this point in the history
Fix #202
  • Loading branch information
antoine4livre authored and titouanmathis committed Feb 20, 2024
1 parent f803fa0 commit afb33c6
Show file tree
Hide file tree
Showing 7 changed files with 226 additions and 0 deletions.
21 changes: 21 additions & 0 deletions packages/docs/utils/randomInt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# randomInt

Get a random integer between bounds.

## Usage

```js
import { randomInt } from '@studiometa/js-toolkit/utils';

randomInt(10); // an integer between 0 and 10
randomInt(20, 10); // an integer between 10 and 20
```

### Parameters

- `a` (`number`): lower bound
- `b` (`number`): upper bound (default: `0`)

### Return value

This function returns a random `number` between the `a` and `b` values.
23 changes: 23 additions & 0 deletions packages/docs/utils/randomItem.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# randomItem

Get a random item of an array or a random character of a string.

## Usage

```js
import { randomItem } from '@studiometa/js-toolkit/utils';

const items = ['a', 'b', 'c', 'd', 'e', 'f'];
randomItem(items); // one of the value in `items`

const string = 'abcdef';
randomItem(string); // one of the letter in `string`
```

### Parameters

- `items` (`array|string`): array or string

### Return value

This function returns a random item of an array, a random character of a string or `undefined` if the array or string is empty.
1 change: 1 addition & 0 deletions packages/js-toolkit/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ export { Queue } from './Queue.js';
export { SmartQueue } from './SmartQueue.js';
export * from './dom/index.js';
export * from './wait.js';
export * from './random.js';
25 changes: 25 additions & 0 deletions packages/js-toolkit/utils/random.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { isArray, isString } from './is';

/**
* Get a random integer between bounds
*
* @param {number} a Lower bound
* @param {number} b Upper bound
* @returns {number}
*/
export function randomInt(a: number, b = 0): number {
return Math.floor(Math.random() * (a - b + 1)) + b;
}

/**
* Get a random item of an array or a random character of a string
*
* @param {T[] | string} items Array or string
* @returns {T | undefined}
*/
export function randomItem<T>(items: T[] | string): T | string | undefined {
if (!isArray(items) && !isString(items)) {
throw new Error('randomItem() expects an array or a string as argument.');
}
return items.length > 0 ? items[randomInt(items.length - 1)] : undefined;
}
102 changes: 102 additions & 0 deletions packages/tests/utils/__snapshots__/index.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Bun Snapshot v1, https://goo.gl/fbAQLP

exports[`@studiometa/js-toolkit/utils exports should export all scripts 1`] = `
[
"Queue",
"SmartQueue",
"addClass",
"addStyle",
"animate",
"boundingRectToCircle",
"clamp",
"clamp01",
"collideCircleCircle",
"collideCircleRect",
"collidePointCircle",
"collidePointRect",
"collideRectRect",
"createEaseInOut",
"createEaseOut",
"damp",
"debounce",
"domScheduler",
"ease",
"easeInCirc",
"easeInCubic",
"easeInExpo",
"easeInOutCirc",
"easeInOutCubic",
"easeInOutExpo",
"easeInOutQuad",
"easeInOutQuart",
"easeInOutQuint",
"easeInOutSine",
"easeInQuad",
"easeInQuart",
"easeInQuint",
"easeInSine",
"easeOutCirc",
"easeOutCubic",
"easeOutExpo",
"easeOutQuad",
"easeOutQuart",
"easeOutQuint",
"easeOutSine",
"endsWith",
"getAncestorWhere",
"getAncestorWhereUntil",
"getComponentResolver",
"getOffsetSizes",
"hasWindow",
"historyPush",
"historyReplace",
"inertiaFinalValue",
"isArray",
"isBoolean",
"isDefined",
"isDev",
"isEmptyString",
"isFunction",
"isNumber",
"isObject",
"isString",
"keyCodes",
"lerp",
"map",
"matrix",
"memoize",
"nextFrame",
"nextMicrotask",
"nextTick",
"noop",
"noopValue",
"objectToURLSearchParams",
"randomInt",
"randomItem",
"removeClass",
"removeStyle",
"round",
"saveActiveElement",
"scrollTo",
"startsWith",
"throttle",
"toggleClass",
"transform",
"transition",
"trapFocus",
"tween",
"untrapFocus",
"useScheduler",
"wait",
"withLeadingCharacters",
"withLeadingSlash",
"withTrailingCharacters",
"withTrailingSlash",
"withoutLeadingCharacters",
"withoutLeadingCharactersRecursive",
"withoutLeadingSlash",
"withoutTrailingCharacters",
"withoutTrailingCharactersRecursive",
"withoutTrailingSlash",
]
`;
8 changes: 8 additions & 0 deletions packages/tests/utils/index.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { describe, it, expect } from 'bun:test';
import * as utils from '@studiometa/js-toolkit/utils';

describe('@studiometa/js-toolkit/utils exports', () => {
it('should export all scripts', () => {
expect(Object.keys(utils)).toMatchSnapshot();
});
});
46 changes: 46 additions & 0 deletions packages/tests/utils/random.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { describe, it, expect } from 'bun:test';
import { randomInt, randomItem } from '@studiometa/js-toolkit/utils';

describe('randomInt method', () => {
it('should return a random integer between bounds values', () => {
for (const [a, b] of new Array(10).fill([10, 20])) {
const result1 = randomInt(a);
expect(result1).toBeGreaterThanOrEqual(0);
expect(result1).toBeLessThanOrEqual(a);

const result2 = randomInt(a, b);
expect(result2).toBeGreaterThanOrEqual(a);
expect(result2).toBeLessThanOrEqual(b);
}
});
});

describe('randomItem method', () => {
it('should return a random item of the provided array', () => {
const items = ['a', 'b', 'c', 'd', 'e', 'f'];
expect(items).toContain(randomItem(items));
});

it('should return a random character of the provided string', () => {
const items = 'abcdef';
expect(items).toContain(randomItem(items));
});

it('should return undefined if the array is empty', () => {
const emptyArray = [];
expect(randomItem(emptyArray)).toBeUndefined();
});

it('should return undefined if the string is empty', () => {
const emptyString = [];
expect(randomItem(emptyString)).toBeUndefined();
});

it('should return undefined if the provided parameter is not valid', () => {
for (const parameter of [{ 0: 'value0', 1: 'value1', 2: 'value2' }, 3, true]) {
expect(() => {
randomItem(parameter);
}).toThrow();
}
});
});

0 comments on commit afb33c6

Please sign in to comment.