Files
libsignal/rust/bridge/node/futures/tests/node-tests/test/basic.js

148 lines
4.4 KiB
JavaScript

//
// Copyright 2020-2021 Signal Messenger, LLC.
// SPDX-License-Identifier: AGPL-3.0-only
//
/* eslint-env es2017 */
import { use, assert } from 'chai';
import chaiAsPromised from 'chai-as-promised';
import { createRequire } from 'node:module';
use(chaiAsPromised);
const require = createRequire(import.meta.url)
const native = require(process.env.SIGNAL_NEON_FUTURES_TEST_LIB);
function promisify(operation) {
return function() {
return new Promise((resolve, reject) => {
try {
operation(...arguments, resolve);
} catch (error) {
reject(error);
}
});
};
}
describe('native', () => {
it('can fulfill promises', async () => {
const result = await promisify(native.incrementAsync)(Promise.resolve(5));
assert.equal(result, 6);
});
it('can handle rejection', async () => {
const result = await promisify(native.incrementAsync)(
Promise.reject('badness')
);
assert.equal(result, 'error: badness');
});
it("doesn't crash on bad promises", async () => {
const result = await promisify(native.incrementAsync)({
then: function(resolve, reject) {
queueMicrotask(() => {
resolve(5);
assert.throws(() => resolve(-5), /promise settled twice/);
});
},
});
assert.equal(result, 6);
});
it('can handle store-like callbacks', async () => {
const result = await native.doubleNameFromStore({
getName: () => Promise.resolve('Moxie'),
});
assert.equal(result, 'Moxie Moxie');
});
it('can handle store-like callbacks that fail', async () => {
const promise = native.doubleNameFromStore({
getName: () => Promise.reject('uh oh'),
});
await assert.isRejected(promise, /rejected: uh oh/);
});
it('can handle parallel store-like callbacks', async () => {
const result = await native.doubleNameFromStoreUsingJoin({
getName: () => Promise.resolve('Moxie'),
});
assert.equal(result, 'Moxie Moxie');
});
it('can handle parallel store-like callbacks that fail', async () => {
const promise = native.doubleNameFromStoreUsingJoin({
getName: () => Promise.reject('uh oh'),
});
await assert.isRejected(promise, /rejected: uh oh/);
});
describe('promises', () => {
it('can fulfill promises', async () => {
const result = await native.incrementPromise(Promise.resolve(5));
assert.equal(result, 6);
const result2 = await native.incrementCallbackPromise(async () => 7);
assert.equal(result2, 8);
});
it('can handle rejection', async () => {
const promise = native.incrementPromise(Promise.reject('badness'));
await assert.isRejected(promise, /badness/);
});
it('recovers from non-promises', async () => {
assert.throws(
() => native.incrementPromise('badness'),
/failed to downcast .+ to object/
);
});
});
describe('panic recovery', () => {
it('handles pre-await panics', async () => {
const promise = native.panicPreAwait(Promise.resolve(6));
await assert.isRejected(promise, /unexpected panic: check for this/);
});
it('handles callback panics', async () => {
const promise = native.panicDuringCallback(Promise.resolve(6));
await assert.isRejected(promise, /unexpected panic: check for this/);
});
it('handles post-await panics', async () => {
const promise = native.panicPostAwait(Promise.resolve(6));
await assert.isRejected(promise, /unexpected panic: check for this/);
});
it('handles settle panics', async () => {
const promise = native.panicDuringSettle(Promise.resolve(6));
await assert.isRejected(promise, /unexpected panic: check for this/);
});
});
describe('exception recovery', () => {
it('handles pre-await throws', async () => {
const promise = native.throwPreAwait(Promise.resolve(6));
await assert.isRejected(promise, /^check for this$/);
});
it('handles callback throws', async () => {
const promise = native.throwDuringCallback(Promise.resolve(6));
await assert.isRejected(promise, /^check for this$/);
});
it('handles post-await throws', async () => {
const promise = native.throwPostAwait(Promise.resolve(6));
await assert.isRejected(promise, /^check for this$/);
});
it('handles settle throws', async () => {
const promise = native.throwDuringSettle(Promise.resolve(6));
await assert.isRejected(promise, /^check for this$/);
});
});
});