Files
pybricks-code/src/utils/index.test.ts
T

155 lines
4.6 KiB
TypeScript

// SPDX-License-Identifier: MIT
// Copyright (c) 2020-2022 The Pybricks Authors
import { acquireLock, assert, defined, ensureError, hex, maybe, timestamp } from '.';
test('assert', () => {
const assertTrue = jest.fn(() => assert(true, 'should not throw'));
assertTrue();
expect(assertTrue).toHaveReturned();
expect(() => assert(false, 'should throw')).toThrow();
});
describe('defined', () => {
expect(() => defined('test')).not.toThrow();
expect(() => defined(undefined)).toThrowError();
});
describe('maybe', () => {
test('resolved', async () => {
const [result, error] = await maybe(Promise.resolve('test'));
expect(result).toBe('test');
expect(error).toBeUndefined();
});
test('rejected', async () => {
const [result, error] = await maybe(Promise.reject(new Error('test')));
expect(result).toBeUndefined();
expect(error).toBeInstanceOf(Error);
});
});
test('hex', () => {
expect(hex(0, 2)).toBe('0x00');
expect(hex(1, 4)).toBe('0x0001');
expect(hex(2, 8)).toBe('0x00000002');
});
test('ensureError', () => {
const err = new Error('test error');
expect(ensureError(err)).toBe(err);
const stringToErrorMessage = 'not an Error';
const stringToError = expect(ensureError(stringToErrorMessage));
stringToError.toHaveProperty('name', 'Error');
stringToError.toHaveProperty('message', stringToErrorMessage);
});
describe('timestamp', () => {
it('should not contain spaces', () => {
expect(timestamp()).not.toContain(' ');
});
it('should not contain colons', () => {
expect(timestamp()).not.toContain(':');
});
it('should not contain periods', () => {
expect(timestamp()).not.toContain('.');
});
it('should not contain letters', () => {
expect(timestamp()).not.toMatch(/[A-Za-z]/);
});
});
describe('acquireLock', () => {
it.each([true, false])('should acquire lock when shared is %o', async () => {
const releaseLock = await acquireLock('test');
try {
expect(releaseLock).toBeDefined();
} finally {
await releaseLock?.();
}
});
it.each([true, false])(
'should fail to acquire exclusive second lock when first lock shared is %o',
async (shared) => {
const releaseLock = await acquireLock('test', shared);
try {
const releaseLock2 = await acquireLock('test');
try {
expect(releaseLock2).toBeUndefined();
} finally {
await releaseLock2?.();
}
} finally {
await releaseLock?.();
}
},
);
it('should acquire shared second lock when first lock is shared', async () => {
const releaseLock = await acquireLock('test', true);
try {
const releaseLock2 = await acquireLock('test', true);
try {
expect(releaseLock2).toBeDefined();
} finally {
await releaseLock2?.();
}
} finally {
await releaseLock?.();
}
});
it('should fail to acquire shared second lock when first lock is exclusive', async () => {
const releaseLock = await acquireLock('test');
try {
const releaseLock2 = await acquireLock('test', true);
try {
expect(releaseLock2).toBeUndefined();
} finally {
await releaseLock2?.();
}
} finally {
await releaseLock?.();
}
});
it('should acquire second lock when first lock is released', async () => {
const releaseLock = await acquireLock('test');
try {
expect(releaseLock).toBeDefined();
} finally {
await releaseLock?.();
}
const releaseLock2 = await acquireLock('test');
try {
expect(releaseLock2).toBeDefined();
} finally {
await releaseLock2?.();
}
});
it('should fail to acquire second lock when first lock is released but release is not awaited', async () => {
const releaseLock = await acquireLock('test');
try {
expect(releaseLock).toBeDefined();
// not awaited!
releaseLock?.();
const releaseLock2 = await acquireLock('test');
try {
expect(releaseLock2).toBeUndefined();
} finally {
await releaseLock2?.();
}
} finally {
await releaseLock?.();
}
});
});