Skip to content

Commit

Permalink
Add .range() method (#51)
Browse files Browse the repository at this point in the history
Co-authored-by: Sindre Sorhus <sindresorhus@gmail.com>
  • Loading branch information
Richienb and sindresorhus committed Jul 18, 2020
1 parent 2638400 commit aa0a2e4
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 1 deletion.
20 changes: 20 additions & 0 deletions index.d.ts
Expand Up @@ -55,6 +55,26 @@ type Delay = {
}
): delay.ClearablePromise<T>;

/**
Create a promise which resolves after a random amount of milliseconds between `minimum` and `maximum` has passed.
Useful for tests and web scraping since they can have unpredictable performance. For example, if you have a test that asserts a method should not take longer than a certain amount of time, and then run it on a CI, it could take longer. So with `.range()`, you could give it a threshold instead.
@param minimum - Minimum amount of milliseconds to delay the promise.
@param maximum - Maximum amount of milliseconds to delay the promise.
@returns A promise which resolves after a random amount of milliseconds between `maximum` and `maximum` has passed.
*/
range<T>(
minimum: number,
maximum: number,
options?: delay.Options & {
/**
Value to resolve in the returned promise.
*/
value: T;
}
): delay.ClearablePromise<T>;

/**
Create a promise which rejects after the specified `milliseconds`.
Expand Down
4 changes: 4 additions & 0 deletions index.js
@@ -1,5 +1,8 @@
'use strict';

// From https://github.com/sindresorhus/random-int/blob/c37741b56f76b9160b0b63dae4e9c64875128146/index.js#L13-L15
const randomInteger = (minimum, maximum) => Math.floor((Math.random() * (maximum - minimum + 1)) + minimum);

const createAbortError = () => {
const error = new Error('Delay aborted');
error.name = 'AbortError';
Expand Down Expand Up @@ -56,6 +59,7 @@ const createDelay = ({clearTimeout: defaultClear, setTimeout: set, willResolve})

const delay = createDelay({willResolve: true});
delay.reject = createDelay({willResolve: false});
delay.range = (minimum, maximum, options) => delay(randomInteger(minimum, maximum), options);
delay.createWithTimers = ({clearTimeout, setTimeout}) => {
const delay = createDelay({clearTimeout, setTimeout, willResolve: true});
delay.reject = createDelay({clearTimeout, setTimeout, willResolve: false});
Expand Down
2 changes: 2 additions & 0 deletions index.test-d.ts
Expand Up @@ -11,6 +11,8 @@ expectType<ClearablePromise<void>>(
delay(200, {signal: new AbortController().signal})
);

expectType<ClearablePromise<number>>(delay.range(50, 200, {value: 0}));

expectType<ClearablePromise<never>>(delay.reject(200, {value: '🦄'}));
expectType<ClearablePromise<never>>(delay.reject(200, {value: 0}));

Expand Down
5 changes: 4 additions & 1 deletion package.json
Expand Up @@ -36,7 +36,10 @@
"async",
"await",
"promises",
"bluebird"
"bluebird",
"threshold",
"range",
"random"
],
"devDependencies": {
"abort-controller": "^3.0.0",
Expand Down
8 changes: 8 additions & 0 deletions readme.md
Expand Up @@ -36,7 +36,15 @@ Create a promise which resolves after the specified `milliseconds`.

Create a promise which rejects after the specified `milliseconds`.

### delay.range(minimum, maximum, [options])

Create a promise which resolves after a random amount of milliseconds between `minimum` and `maximum` has passed.

Useful for tests and web scraping since they can have unpredictable performance. For example, if you have a test that asserts a method should not take longer than a certain amount of time, and then run it on a CI, it could take longer. So with `.range()`, you could give it a threshold instead.

#### milliseconds
#### mininum
#### maximum

Type: `number`

Expand Down
6 changes: 6 additions & 0 deletions test.js
Expand Up @@ -163,3 +163,9 @@ test('can create a new instance with fixed timeout methods', async t => {
t.is(cleared.length, 1);
t.is(cleared[0], callbacks[2].handle);
});

test('returns a promise that is resolved in a random range of time', async t => {
const end = timeSpan();
await m.range(50, 150);
t.true(inRange(end(), 30, 170), 'is delayed');
});

0 comments on commit aa0a2e4

Please sign in to comment.