Skip to content

Commit 05bee73

Browse files
BarryThePenguinsindresorhus
authored andcommitted
Close #165 PR: Support Observable. Fixes #84
1 parent b24b2ea commit 05bee73

File tree

6 files changed

+191
-2
lines changed

6 files changed

+191
-2
lines changed

lib/assert.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
'use strict';
22
var assert = require('core-assert');
3+
var observableSymbol = require('./symbol')('observable');
34
var x = module.exports;
45

56
Object.defineProperty(x, 'AssertionError', {value: assert.AssertionError});
67

8+
function noop() {}
9+
710
function create(val, expected, operator, msg, fn) {
811
return {
912
actual: val,
@@ -69,10 +72,14 @@ x.notSame = function (val, expected, msg) {
6972
};
7073

7174
x.throws = function (fn, err, msg) {
75+
if (fn && fn[observableSymbol]) {
76+
fn = fn[observableSymbol]().forEach(noop);
77+
}
78+
7279
if (fn && fn.then) {
7380
return fn
7481
.then(function () {
75-
x.throws(function () {}, err, msg);
82+
x.throws(noop, err, msg);
7683
}, function (fnErr) {
7784
x.throws(function () {
7885
throw fnErr;
@@ -95,6 +102,10 @@ x.throws = function (fn, err, msg) {
95102
};
96103

97104
x.doesNotThrow = function (fn, msg) {
105+
if (fn && fn[observableSymbol]) {
106+
fn = fn[observableSymbol]().forEach(noop);
107+
}
108+
98109
if (fn && fn.then) {
99110
return fn
100111
.catch(function (err) {

lib/symbol.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
function polyfillSymbol(key) {
2+
if (typeof Symbol === 'function' && !Symbol[key]) {
3+
Object.defineProperty(Symbol, key, {
4+
value: Symbol(key)
5+
});
6+
}
7+
}
8+
9+
polyfillSymbol('observable');
10+
11+
module.exports = function (key) {
12+
if (typeof Symbol !== 'undefined' && Symbol[key]) {
13+
return Symbol[key];
14+
} else if (typeof Symbol !== 'undefined' && typeof Symbol.for === 'function') {
15+
return Symbol.for(key);
16+
}
17+
return '@@' + key;
18+
};

lib/test.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ var setImmediate = require('set-immediate-shim');
55
var fnName = require('fn-name');
66
var co = require('co-with-promise');
77
var maxTimeout = require('max-timeout');
8+
var observableSymbol = require('./symbol')('observable');
89
var assert = require('./assert');
910

11+
function noop() {}
12+
1013
function Test(title, fn) {
1114
if (!(this instanceof Test)) {
1215
return new Test(title, fn);
@@ -56,6 +59,10 @@ Object.keys(assert).forEach(function (el) {
5659
try {
5760
var fn = assert[el].apply(assert, arguments);
5861

62+
if (fn && fn[observableSymbol]) {
63+
fn = fn[observableSymbol]().forEach(noop);
64+
}
65+
5966
if (fn && fn.then) {
6067
return fn
6168
.then(function () {
@@ -112,6 +119,10 @@ Test.prototype.run = function () {
112119
try {
113120
var ret = this.fn(this);
114121

122+
if (ret && ret[observableSymbol]) {
123+
ret = ret[observableSymbol]().forEach(noop);
124+
}
125+
115126
if (ret && typeof ret.then === 'function') {
116127
ret
117128
.then(function () {

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@
9696
"signal-exit": "^2.1.2",
9797
"tap-spec": "^4.1.0",
9898
"tape": "^4.0.0",
99-
"xo": "*"
99+
"xo": "*",
100+
"zen-observable": "^0.1.6"
100101
}
101102
}

test/fixture/observable.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
var Promise = require('bluebird');
2+
3+
// global Promise for zen-observable
4+
if (!global.Promise) {
5+
Object.defineProperty(global, 'Promise', {
6+
value: Promise,
7+
configurable: true,
8+
enumerable: false,
9+
writable: true
10+
});
11+
}
12+
13+
module.exports = require('zen-observable');

test/test.js

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ var test = require('tape');
77
var Runner = require('../lib/runner');
88
var fork = require('../lib/fork');
99
var ava = require('../lib/test');
10+
var Observable = require('./fixture/observable');
1011

1112
function execCli(args, cb) {
1213
if (!Array.isArray(args)) {
@@ -97,6 +98,25 @@ test('plan assertions with support for promises', function (t) {
9798
});
9899
});
99100

101+
test('plan assertions with support for observables', function (t) {
102+
ava(function (a) {
103+
a.plan(2);
104+
105+
var observable = Observable.of();
106+
107+
setTimeout(function () {
108+
a.pass();
109+
a.pass();
110+
}, 200);
111+
112+
return observable;
113+
}).run().then(function (a) {
114+
t.is(a.planCount, 2);
115+
t.is(a.assertCount, 2);
116+
t.end();
117+
});
118+
});
119+
100120
test('run more assertions than planned', function (t) {
101121
ava(function (a) {
102122
a.plan(2);
@@ -276,6 +296,94 @@ test('handle throws with false-positive promise', function (t) {
276296
});
277297
});
278298

299+
test('handle throws with thrown observable', function (t) {
300+
ava(function (a) {
301+
a.plan(1);
302+
303+
var observable = new Observable(function (observer) {
304+
observer.error(new Error());
305+
});
306+
a.throws(observable);
307+
}).run().then(function (a) {
308+
t.false(a.assertError);
309+
t.end();
310+
});
311+
});
312+
313+
test('handle throws with long running thrown observable', function (t) {
314+
ava(function (a) {
315+
a.plan(1);
316+
317+
var observable = new Observable(function (observer) {
318+
setTimeout(function () {
319+
observer.error(new Error('abc'));
320+
}, 2000);
321+
});
322+
323+
a.throws(observable, /abc/);
324+
}).run().then(function (a) {
325+
t.false(a.assertError);
326+
t.end();
327+
});
328+
});
329+
330+
test('handle throws with completed observable', function (t) {
331+
ava(function (a) {
332+
a.plan(1);
333+
334+
var observable = Observable.of();
335+
a.throws(observable);
336+
}).run().catch(function (err) {
337+
t.true(err);
338+
t.is(err.name, 'AssertionError');
339+
t.end();
340+
});
341+
});
342+
343+
test('handle throws with regex', function (t) {
344+
ava(function (a) {
345+
a.plan(1);
346+
347+
var observable = new Observable(function (observer) {
348+
observer.error(new Error('abc'));
349+
});
350+
a.throws(observable, /abc/);
351+
}).run().then(function (a) {
352+
t.false(a.assertionError);
353+
t.end();
354+
});
355+
});
356+
357+
test('handle throws with string', function (t) {
358+
ava(function (a) {
359+
a.plan(1);
360+
361+
var observable = new Observable(function (observer) {
362+
observer.error(new Error('abc'));
363+
});
364+
a.throws(observable, 'abc');
365+
}).run().then(function (a) {
366+
t.false(a.assertionError);
367+
t.end();
368+
});
369+
});
370+
371+
test('handle throws with false-positive observable', function (t) {
372+
ava(function (a) {
373+
a.plan(1);
374+
375+
var observable = new Observable(function (observer) {
376+
observer.next(new Error());
377+
observer.complete();
378+
});
379+
a.throws(observable);
380+
}).run().catch(function (err) {
381+
t.true(err);
382+
t.is(err.name, 'AssertionError');
383+
t.end();
384+
});
385+
});
386+
279387
test('handle doesNotThrow with error', function (t) {
280388
ava(function (a) {
281389
a.doesNotThrow(function () {
@@ -328,6 +436,33 @@ test('handle doesNotThrow with rejected promise', function (t) {
328436
});
329437
});
330438

439+
test('handle doesNotThrow with completed observable', function (t) {
440+
ava(function (a) {
441+
a.plan(1);
442+
443+
var observable = Observable.of();
444+
a.doesNotThrow(observable);
445+
}).run().then(function (a) {
446+
t.false(a.assertError);
447+
t.end();
448+
});
449+
});
450+
451+
test('handle doesNotThrow with thrown observable', function (t) {
452+
ava(function (a) {
453+
a.plan(1);
454+
455+
var observable = new Observable(function (observer) {
456+
observer.error(new Error());
457+
});
458+
a.doesNotThrow(observable);
459+
}).run().catch(function (err) {
460+
t.true(err);
461+
t.is(err.name, 'AssertionError');
462+
t.end();
463+
});
464+
});
465+
331466
test('run functions after last planned assertion', function (t) {
332467
var i = 0;
333468

0 commit comments

Comments
 (0)