Skip to content
This repository has been archived by the owner on Jul 20, 2020. It is now read-only.

Commit

Permalink
Port StrictPromise from Hypernova
Browse files Browse the repository at this point in the history
This was a recent implementation by me. Figured it should not live in Hypernova if it is actually useful -- the speed of Bluebird but a small (read: strict) interface.

airbnb/hypernova#135
  • Loading branch information
juanca committed Aug 8, 2018
1 parent 82f22a9 commit 38cebdf
Show file tree
Hide file tree
Showing 2 changed files with 237 additions and 2 deletions.
171 changes: 170 additions & 1 deletion index-test.js
Original file line number Diff line number Diff line change
@@ -1 +1,170 @@
const StrictPromise = require('./index.js');
import assert from 'assert';
import StrictPromise from './index.js';

describe('StrictPromise', () => {
describe('static all', () => {
it('resolves when the iterable is empty', (done) => {
StrictPromise.all([]).then(() => {
done();
});
});

it('resolves when the whole iterable is resolved', (done) => {
const resolveWiths = [];
const messages = [
'First resolved.',
'Second resolved.',
'Third resolved',
];

StrictPromise.all([
new StrictPromise((resolve) => {
resolveWiths.push(resolve);
}),
new StrictPromise((resolve) => {
resolveWiths.push(resolve);
}),
new StrictPromise((resolve) => {
resolveWiths.push(resolve);
}),
]).then((resolvedWiths) => {
assert.strictEqual(resolvedWiths[0], messages[0]);
assert.strictEqual(resolvedWiths[1], messages[1]);
assert.strictEqual(resolvedWiths[2], messages[2]);
done();
});

resolveWiths[0](messages[0]);
resolveWiths[1](messages[1]);
resolveWiths[2](messages[2]);
});

it('rejects with the first rejected iterable', (done) => {
let rejectWith;
const message = 'Only one rejected.';

StrictPromise.all([
new StrictPromise(() => {}),
new StrictPromise((resolve, reject) => {
rejectWith = reject;
}),
new StrictPromise(() => {}),
]).then(() => {}, (rejectedWith) => {
assert.strictEqual(rejectedWith, message);
done();
});

rejectWith(message);
});
});

describe('static race', () => {
it('resolves with the first resolved iterable', (done) => {
let resolveWith;
const message = 'It is a resolved race!';

StrictPromise.race([
new StrictPromise(() => {}),
new StrictPromise((resolve) => {
resolveWith = resolve;
}),
new StrictPromise(() => {}),
]).then((resolvedWith) => {
assert.strictEqual(resolvedWith, message);
done();
});

resolveWith(message);
});

it('rejects with the first rejected iterable', (done) => {
let rejectWith;
const message = 'It is a rejected race!';

StrictPromise.race([
new StrictPromise(() => {}),
new StrictPromise((resolve, reject) => {
rejectWith = reject;
}),
new StrictPromise(() => {}),
]).then(() => {}, (rejectedWith) => {
assert.strictEqual(rejectedWith, message);
done();
});

rejectWith(message);
});
});

describe('static reject', () => {
it('rejects with a given reason', (done) => {
const message = 'rejected';

StrictPromise.reject(message).catch((rejectedWith) => {
assert.strictEqual(rejectedWith, message);
done();
});
});
});

describe('static resolve', () => {
it('resolves with a given reason', (done) => {
const message = 'fulfilled';

StrictPromise.resolve(message).then((resolvedWith) => {
assert.strictEqual(resolvedWith, message);
done();
});
});
});

describe('thennable', () => {
it('has a fulfillment callback', (done) => {
let resolveWith;
const message = 'fulfilled';

const promise = new StrictPromise((resolve) => {
resolveWith = resolve;
});

promise.then((resolvedWith) => {
assert.strictEqual(resolvedWith, message);
done();
});

resolveWith(message);
});

it('has a rejection callback', (done) => {
let rejectWith;
const message = 'rejected';

const promise = new StrictPromise((resolve, reject) => {
rejectWith = reject;
});

promise.then(() => {}, (rejectedWith) => {
assert.strictEqual(rejectedWith, message);
done();
});

rejectWith(message);
});
});

it('is catchable', (done) => {
let rejectWith;
const message = 'rejected';

const promise = new StrictPromise((resolve, reject) => {
rejectWith = reject;
});

promise.catch((rejectedWith) => {
assert.strictEqual(rejectedWith, message);
done();
});

rejectWith(message);
});
});
68 changes: 67 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
@@ -1 +1,67 @@
module.exports = {};
import Promise from 'bluebird';

export default class StrictPromise {
constructor(executor) {
this._promise = new Promise(executor);
}

static all(iterable) {
const newPromise = Promise.all(iterable);

const strictPromise = new StrictPromise((resolve, reject) => {
newPromise.then(resolve, reject);
});

return strictPromise;
}

static race(iterable) {
const newPromise = Promise.race(iterable);

const strictPromise = new StrictPromise((resolve, reject) => {
newPromise.then(resolve, reject);
});

return strictPromise;
}

static reject(value) {
const newPromise = Promise.reject(value);

const strictPromise = new StrictPromise((resolve, reject) => {
newPromise.then(resolve, reject);
});

return strictPromise;
}

static resolve(value) {
const newPromise = Promise.resolve(value);

const strictPromise = new StrictPromise((resolve, reject) => {
newPromise.then(resolve, reject);
});

return strictPromise;
}

then(onFulfilled, onRejected) {
const newPromise = this._promise.then(onFulfilled, onRejected);

const strictPromise = new StrictPromise((resolve, reject) => {
newPromise.then(resolve, reject);
});

return strictPromise;
}

catch(onRejected) {
const newPromise = this._promise.catch(onRejected);

const strictPromise = new StrictPromise((resolve, reject) => {
newPromise.then(resolve, reject);
});

return strictPromise;
}
}

0 comments on commit 38cebdf

Please sign in to comment.