Skip to content

Commit

Permalink
Adding more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jdalrymple committed Dec 14, 2023
1 parent 7d79ea0 commit e8cf765
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 39 deletions.
1 change: 1 addition & 0 deletions .codeclimate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ version: '2'

exclude_patterns:
- '**/test/'
- '**/examples/'
- '.yarn/'
8 changes: 4 additions & 4 deletions src/Deque.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
// Deque is based on https://github.com/petkaantonov/deque/blob/master/js/deque.js
// Released under the MIT License: https://github.com/petkaantonov/deque/blob/6ef4b6400ad3ba82853fdcc6531a38eb4f78c18c/LICENSE
/*eslint-disable*/
export const MIN_CAPACITY = 4;
export const MAX_CAPACITY = 1073741824;
export const RESIZE_MULTIPLER = 1;

function arrayMove(src: any[], srcIndex: number, dst: any[], dstIndex: number, len: number) {
for (let j = 0; j < len; ++j) {
dst[j + dstIndex] = src[j + srcIndex];
Expand All @@ -20,10 +24,6 @@ function pow2AtLeast(n: number) {
return n + 1;
}

export const MIN_CAPACITY = 4;
export const MAX_CAPACITY = 1073741824;
export const RESIZE_MULTIPLER = 1;

export function getCapacity(capacity: number) {
return pow2AtLeast(Math.min(Math.max(MIN_CAPACITY, capacity), MAX_CAPACITY));
}
Expand Down
2 changes: 1 addition & 1 deletion src/Sema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export class Sema<T = string> {
capacity?: number;
} = {},
) {
if (isFn(pauseFn) !== isFn(resumeFn)) {
if (isFn(pauseFn) && !isFn(resumeFn)) {
throw new Error('pauseFn and resumeFn must be both set for pausing');
}

Expand Down
115 changes: 82 additions & 33 deletions test/Sema.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,8 @@
import { Sema } from '../src/index';
import { Sema } from '../src/Sema';

describe('General', () => {
test('Pausing works', () => {
const pauseFn = jest.fn();
const resumeFn = jest.fn();
const s = new Sema(5, { pauseFn, resumeFn });

for (let i = 0; i < 5; i += 1) {
// eslint-disable-next-line
s.acquire().catch(console.error);
}

expect(pauseFn).not.toHaveBeenCalled();
expect(resumeFn).not.toHaveBeenCalled();

// eslint-disable-next-line
s.acquire().catch(console.error);
expect(pauseFn).toHaveBeenCalled();
s.release();
s.release();
expect(resumeFn).toHaveBeenCalled();
describe('Sema.constructor', () => {
it('should throw an error if a pauseFn is passed, but a resumeFn isnt', () => {
expect(() => new Sema(3, { pauseFn: () => 3 })).toThrow();
});

test('initFn is called properly', () => {
Expand All @@ -29,6 +12,17 @@ describe('General', () => {
expect(s).toBeInstanceOf(Sema);
expect(initFn).toHaveReturnedTimes(3);
});
});

describe('Sema.acquire', () => {
it('should aquire a sephamore', async () => {
const s = new Sema(1);

const token = await s.acquire();

expect(token).toBe('1');
expect(s.waiting()).toEqual(0);
});

test('Tokens are returned properly', async () => {
let maxConcurrency = 0;
Expand All @@ -47,17 +41,6 @@ describe('General', () => {
});
});

describe('Sema.acquire', () => {
it('should aquire a sephamore', async () => {
const s = new Sema(1);

const token = await s.acquire();

expect(token).toBe('1');
expect(s.waiting()).toEqual(0);
});
});

describe('Sema.tryAcquire', () => {
it('should return undefined no sephamores are free', async () => {
const s = new Sema(1);
Expand All @@ -79,6 +62,59 @@ describe('Sema.release', () => {
expect(s.tryAcquire()).toBeDefined();
expect(s.tryAcquire()).toBeUndefined();
});

it('should use the release token value if an initFn is passed during instance creation', () => {
const s = new Sema(1, { initFn: () => 1 });

/* eslint-disable @typescript-eslint/ban-ts-comment, no-underscore-dangle */

// @ts-expect-error
const spy = jest.spyOn(s.releaseEmitter, 'emit');

/* eslint-enable */

expect(s.tryAcquire()).toBeDefined();

s.release(1);

expect(spy).toHaveBeenCalledWith('release', 1);
});

it('should use the default token value if an initFn is not passed during instance creation', () => {
const s = new Sema(1);

/* eslint-disable @typescript-eslint/ban-ts-comment, no-underscore-dangle */
// @ts-expect-error
const spy = jest.spyOn(s.releaseEmitter, 'emit');
/* eslint-enable */

expect(s.tryAcquire()).toBeDefined();

s.release();

expect(spy).toHaveBeenCalledWith('release', '1');
});

it('should execute the pause function once the limit is met', () => {
const pauseFn = jest.fn();
const resumeFn = jest.fn();
const s = new Sema(5, { pauseFn, resumeFn });

for (let i = 0; i < 5; i += 1) {
// eslint-disable-next-line
s.acquire().catch(console.error);
}

expect(pauseFn).not.toHaveBeenCalled();
expect(resumeFn).not.toHaveBeenCalled();

// eslint-disable-next-line
s.acquire().catch(console.error);
expect(pauseFn).toHaveBeenCalled();
s.release();
s.release();
expect(resumeFn).toHaveBeenCalled();
});
});

describe('Sema.waiting', () => {
Expand Down Expand Up @@ -131,7 +167,7 @@ describe('Sema.waiting', () => {
expect(s.waiting()).toEqual(0);
});

it('should hanlde greater maxConcurrency', async () => {
it('should handle greater maxConcurrency', async () => {
const s = new Sema(3);

await s.acquire();
Expand All @@ -144,3 +180,16 @@ describe('Sema.waiting', () => {
expect(s.waiting()).toEqual(0);
});
});

describe('Sema.drain', () => {
it('should acquire the maxConcurrency of sephamores', async () => {
const s = new Sema(3);

const spy = jest.spyOn(s, 'acquire');

const all = await s.drain();

expect(all.length).toBe(3);
expect(spy).toHaveBeenCalledTimes(3);
});
});
9 changes: 8 additions & 1 deletion test/Utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Sema } from '../src/Sema';

import { createRateLimiter } from '../src/Utils';

jest.useFakeTimers();
Expand Down Expand Up @@ -79,4 +78,12 @@ describe('createRateLimiter', () => {

expect(acquireFn).toHaveBeenCalledTimes(1);
});

it('should throw an error if the rptu is not an integer', () => {
expect(() => createRateLimiter(0.5)).toThrow();
});

it('should throw an error if the rptu is negative', () => {
expect(() => createRateLimiter(-5)).toThrow();
});
});
13 changes: 13 additions & 0 deletions test/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Sema, createRateLimiter } from '../src/index';

describe('Exports', () => {
it('should export Sema', () => {
expect(Sema).toBeDefined();
expect(Sema).toBeInstanceOf(Object);
});

it('should export createRateLimiter helper function', () => {
expect(createRateLimiter).toBeDefined();
expect(createRateLimiter).toBeInstanceOf(Function);
});
});

0 comments on commit e8cf765

Please sign in to comment.