Skip to content

Commit

Permalink
Merge pull request #3361 from benlesh/refactor-bindNodeCallback
Browse files Browse the repository at this point in the history
Refactor bind node callback
  • Loading branch information
benlesh authored Mar 2, 2018
2 parents 725dcb4 + 3ec9dd6 commit 0a3a04a
Show file tree
Hide file tree
Showing 3 changed files with 342 additions and 355 deletions.
148 changes: 74 additions & 74 deletions spec/observables/bindNodeCallback-spec.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import { expect } from 'chai';
import * as sinon from 'sinon';
import * as Rx from '../../src/Rx';
import { bindNodeCallback } from '../../src';
import { TestScheduler } from '../../src/testing';

declare const rxTestScheduler: Rx.TestScheduler;
const Observable = Rx.Observable;
declare const rxTestScheduler: TestScheduler;

/** @test {bindNodeCallback} */
describe('Observable.bindNodeCallback', () => {
describe('bindNodeCallback', () => {
describe('when not scheduled', () => {
it('should emit undefined when callback is called without success arguments', () => {
function callback(cb) {
function callback(cb: Function) {
cb(null);
}

const boundCallback = Observable.bindNodeCallback(callback);
const results = [];
const boundCallback = bindNodeCallback(callback);
const results: Array<number | string> = [];

boundCallback()
.subscribe((x: any) => {
Expand All @@ -27,14 +27,14 @@ describe('Observable.bindNodeCallback', () => {
});

it('should emit one value from a callback', () => {
function callback(datum, cb) {
function callback(datum: number, cb: Function) {
cb(null, datum);
}
const boundCallback = Observable.bindNodeCallback(callback);
const results = [];
const boundCallback = bindNodeCallback<number>(callback);
const results: Array<number | string> = [];

boundCallback(42)
.subscribe((x: number) => {
.subscribe(x => {
results.push(x);
}, null, () => {
results.push('done');
Expand All @@ -44,11 +44,11 @@ describe('Observable.bindNodeCallback', () => {
});

it('should set context of callback to context of boundCallback', () => {
function callback(cb) {
function callback(this: { datum: number }, cb: Function) {
cb(null, this.datum);
}
const boundCallback = Observable.bindNodeCallback(callback);
const results = [];
const boundCallback = bindNodeCallback(callback);
const results: Array<number | string> = [];

boundCallback.call({datum: 42})
.subscribe(
Expand All @@ -61,14 +61,14 @@ describe('Observable.bindNodeCallback', () => {
});

it('should emit one value chosen by a selector', () => {
function callback(datum, cb) {
function callback(datum: number, cb: Function) {
cb(null, datum);
}
const boundCallback = Observable.bindNodeCallback(callback, (datum: any) => datum);
const results = [];
const boundCallback = bindNodeCallback(callback, (datum: any) => datum);
const results: Array<number | string> = [];

boundCallback(42)
.subscribe((x: number) => {
.subscribe(x => {
results.push(x);
}, null, () => {
results.push('done');
Expand All @@ -80,55 +80,55 @@ describe('Observable.bindNodeCallback', () => {
it('should raise error from callback', () => {
const error = new Error();

function callback(cb) {
function callback(cb: Function) {
cb(error);
}

const boundCallback = Observable.bindNodeCallback(callback);
const results = [];
const boundCallback = bindNodeCallback(callback);
const results: Array<number | string> = [];

boundCallback()
.subscribe(() => {
throw 'should not next';
throw new Error('should not next');
}, (err: any) => {
results.push(err);
}, () => {
throw 'should not complete';
throw new Error('should not complete');
});

expect(results).to.deep.equal([error]);
});

it('should emit an error when the selector throws', () => {
function callback(cb) {
function callback(cb: Function) {
cb(null, 42);
}

const expected = new Error('Yikes!');
const boundCallback = Observable.bindNodeCallback(callback, (err: any) => { throw expected; });
const boundCallback = bindNodeCallback(callback, (err: any) => { throw expected; });

boundCallback()
.subscribe(() => {
throw 'should not next';
throw new Error('should not next');
}, (err: any) => {
expect(err).to.equal(expected);
}, () => {
throw 'should not complete';
throw new Error('should not complete');
});
});

it('should not emit, throw or complete if immediately unsubscribed', (done: MochaDone) => {
const nextSpy = sinon.spy();
const throwSpy = sinon.spy();
const completeSpy = sinon.spy();
let timeout;
function callback(datum, cb) {
let timeout: number;
function callback(datum: number, cb: Function) {
// Need to cb async in order for the unsub to trigger
timeout = setTimeout(() => {
cb(null, datum);
});
}
const subscription = Observable.bindNodeCallback(callback)(42)
const subscription = bindNodeCallback(callback)(42)
.subscribe(nextSpy, throwSpy, completeSpy);
subscription.unsubscribe();

Expand All @@ -145,12 +145,12 @@ describe('Observable.bindNodeCallback', () => {

describe('when scheduled', () => {
it('should emit undefined when callback is called without success arguments', () => {
function callback(cb) {
function callback(cb: Function) {
cb(null);
}

const boundCallback = Observable.bindNodeCallback(callback, null, rxTestScheduler);
const results = [];
const boundCallback = bindNodeCallback(callback, null, rxTestScheduler);
const results: Array<number | string> = [];

boundCallback()
.subscribe((x: any) => {
Expand All @@ -165,14 +165,14 @@ describe('Observable.bindNodeCallback', () => {
});

it('should emit one value from a callback', () => {
function callback(datum, cb) {
function callback(datum: number, cb: Function) {
cb(null, datum);
}
const boundCallback = Observable.bindNodeCallback(callback, null, rxTestScheduler);
const results = [];
const boundCallback = bindNodeCallback<number>(callback, null, rxTestScheduler);
const results: Array<number | string> = [];

boundCallback(42)
.subscribe((x: number) => {
.subscribe(x => {
results.push(x);
}, null, () => {
results.push('done');
Expand All @@ -184,11 +184,11 @@ describe('Observable.bindNodeCallback', () => {
});

it('should set context of callback to context of boundCallback', () => {
function callback(cb) {
function callback(this: { datum: number }, cb: Function) {
cb(null, this.datum);
}
const boundCallback = Observable.bindNodeCallback(callback, null, rxTestScheduler);
const results = [];
const boundCallback = bindNodeCallback(callback, null, rxTestScheduler);
const results: Array<number | string> = [];

boundCallback.call({datum: 42})
.subscribe(
Expand All @@ -204,18 +204,18 @@ describe('Observable.bindNodeCallback', () => {

it('should error if callback throws', () => {
const expected = new Error('haha no callback for you');
function callback(datum, cb) {
function callback(datum: number, cb: Function) {
throw expected;
}
const boundCallback = Observable.bindNodeCallback(callback, null, rxTestScheduler);
const boundCallback = bindNodeCallback(callback, null, rxTestScheduler);

boundCallback(42)
.subscribe((x: number) => {
throw 'should not next';
.subscribe(x => {
throw new Error('should not next');
}, (err: any) => {
expect(err).to.equal(expected);
}, () => {
throw 'should not complete';
throw new Error('should not complete');
});

rxTestScheduler.flush();
Expand All @@ -224,20 +224,20 @@ describe('Observable.bindNodeCallback', () => {
it('should raise error from callback', () => {
const error = new Error();

function callback(cb) {
function callback(cb: Function) {
cb(error);
}

const boundCallback = Observable.bindNodeCallback(callback, null, rxTestScheduler);
const results = [];
const boundCallback = bindNodeCallback(callback, null, rxTestScheduler);
const results: Array<number | string> = [];

boundCallback()
.subscribe(() => {
throw 'should not next';
throw new Error('should not next');
}, (err: any) => {
results.push(err);
}, () => {
throw 'should not complete';
throw new Error('should not complete');
});

rxTestScheduler.flush();
Expand All @@ -247,35 +247,35 @@ describe('Observable.bindNodeCallback', () => {

it('should error if selector throws', () => {
const expected = new Error('what? a selector? I don\'t think so');
function callback(datum, cb) {
function callback(datum: number, cb: Function) {
cb(null, datum);
}
function selector() {
throw expected;
}
const boundCallback = Observable.bindNodeCallback(callback, selector, rxTestScheduler);
const boundCallback = bindNodeCallback(callback, selector, rxTestScheduler);

boundCallback(42)
.subscribe((x: any) => {
throw 'should not next';
throw new Error('should not next');
}, (err: any) => {
expect(err).to.equal(expected);
}, () => {
throw 'should not complete';
throw new Error('should not complete');
});

rxTestScheduler.flush();
});

it('should use a selector', () => {
function callback(datum, cb) {
function callback(datum: number, cb: Function) {
cb(null, datum);
}
function selector(x) {
function selector(x: number) {
return x + '!!!';
}
const boundCallback = Observable.bindNodeCallback(callback, selector, rxTestScheduler);
const results = [];
const boundCallback = bindNodeCallback(callback, selector, rxTestScheduler);
const results: Array<number | string> = [];

boundCallback(42)
.subscribe((x: string) => {
Expand All @@ -291,14 +291,14 @@ describe('Observable.bindNodeCallback', () => {
});

it('should pass multiple inner arguments as an array', () => {
function callback(datum, cb) {
function callback(datum: number, cb: Function) {
cb(null, datum, 1, 2, 3);
}
const boundCallback = Observable.bindNodeCallback(callback, null, rxTestScheduler);
const results = [];
const boundCallback = bindNodeCallback<number[]>(callback, null, rxTestScheduler);
const results: Array<number[] | string> = [];

boundCallback(42)
.subscribe((x: number) => {
.subscribe(x => {
results.push(x);
}, null, () => {
results.push('done');
Expand All @@ -310,18 +310,18 @@ describe('Observable.bindNodeCallback', () => {
});

it('should pass multiple inner arguments to the selector if there is one', () => {
function callback(datum, cb) {
function callback(datum: number, cb: Function) {
cb(null, datum, 1, 2, 3);
}
function selector(a, b, c, d) {
function selector(a: number, b: number, c: number, d: number) {
expect([a, b, c, d]).to.deep.equal([42, 1, 2, 3]);
return a + b + c + d;
}
const boundCallback = Observable.bindNodeCallback(callback, selector, rxTestScheduler);
const results = [];
const boundCallback = bindNodeCallback(callback, selector, rxTestScheduler);
const results: Array<number | string> = [];

boundCallback(42)
.subscribe((x: number) => {
.subscribe(x => {
results.push(x);
}, null, () => {
results.push('done');
Expand All @@ -334,23 +334,23 @@ describe('Observable.bindNodeCallback', () => {

it('should cache value for next subscription and not call callbackFunc again', () => {
let calls = 0;
function callback(datum, cb) {
function callback(datum: number, cb: Function) {
calls++;
cb(null, datum);
}
const boundCallback = Observable.bindNodeCallback(callback, null, rxTestScheduler);
const results1 = [];
const results2 = [];
const boundCallback = bindNodeCallback<number>(callback, null, rxTestScheduler);
const results1: Array<number | string> = [];
const results2: Array<number | string> = [];

const source = boundCallback(42);

source.subscribe((x: number) => {
source.subscribe(x => {
results1.push(x);
}, null, () => {
results1.push('done');
});

source.subscribe((x: number) => {
source.subscribe(x => {
results2.push(x);
}, null, () => {
results2.push('done');
Expand All @@ -362,4 +362,4 @@ describe('Observable.bindNodeCallback', () => {
expect(results1).to.deep.equal([42, 'done']);
expect(results2).to.deep.equal([42, 'done']);
});
});
});
Loading

0 comments on commit 0a3a04a

Please sign in to comment.