-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Marble testing for when inner observables unsubscribe #428
Comments
one thought I had was reusing the let a = hot('--1--^--------2--------3-----');
let b = hot('--4--^-----5----------------6------7---');
let observableLookup = { a: a, b: b };
let e1 = hot('----^------a-------b-------', observableLookup);
let expected = '---------^-2-----(!^)----6------7---';
expectObservable(e1.switch()).toBe(expected).withSubs([a, b]).withUnsubs([a]); .... it's not a particularly good idea, but it's a start. I don't really like that it junks up the expected marbles, though. |
Perhaps the inner subs and unsubs could be in different marble diagrams. The worst part though will be doing this without adding test specific code to the library. We may have to create custom |
To mirror RxJS 4, the equivalent of this type of call https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/selectmany.js#L240-L244 in our marble diagram tests would be let a = hot('--1--^--------2--------3-----');
let asubs = '------------^-------!';
let b = hot('--4--^-----5----------------6------7---');
let bsubs = '--------------------^------------------';
let observableLookup = { a: a, b: b };
let e1 = hot('----^------a-------b-------', observableLookup);
let expected = '---------2-------------6------7---';
expectObservable(e1.switch()).toBe(expected);
expect(a.subscriptions).toBe(asubs);
expect(b.subscriptions).toBe(bsubs); I'm not sure though when should the first |
The thing about it, is we know that all observables there have a subscription point. And that, in part, that subscription point can be inferred by the marble tests we already have in existance. Subscription starts when the marble line starts, in essence. So really, I think we only need to assert unsubscriptions when (and if) they happen. |
Let me get it right, you're suggesting this?: let a = hot('--1--^--------2--------3-----');
let aunsubs = '--------!';
let b = hot('--4--^-----5----------------6------7---');
let bunsubs = '------------------';
let e1 = hot('----^------a-------b-------', { a, b });
let expected = '---------2-------------6------7---';
expectObservable(e1.switch()).toBe(expected);
expect(a.unsubscriptions).toBe(aunsubs);
expect(b.unsubscriptions).toBe(bunsubs); I bumped into a case where I want to have multiple subscribers to a shared Observable, so I need Ideally, I'd like to write this: var e1 = cold( '--1--2------3--------4---5---6--7--|');
var asubs = '---^---------------------------------!';
var aexpects = '--1--2------3--------4---5---6--7-'
var bsubs = '---------^-----------------!';
var bexpects = '(12)--3--------4--'
var csubs = '------------------^---------------------!';
var cexpects = '(123)-4---5---6--7--|'
var shared = e1.shareReplay(3);
expectObservable(shared, asubs).toBe(aexpects);
expectObservable(shared, bsubs).toBe(bexpects);
expectObservable(shared, csubs).toBe(cexpects); This proposed API wouldn't be an obstacle for the previous suggestion I gave. In fact I think they could be used together, for instance: var e1 = cold( '--1--2------3--------4---5---6--7--|');
var asubs = '---^---------------------------------!';
var aexpects = '--1--2------3--------4---5---6--7-'
var bsubs = '---------^-----------------!';
var bexpects = '(12)--3--------4--'
var csubs = '------------------^---------------------!';
var cexpects = '(123)-4---5---6--7--|'
var shared = e1.shareReplay(3);
expectObservable(shared, asubs).toBe(aexpects);
expectObservable(shared, bsubs).toBe(bexpects);
expectObservable(shared, csubs).toBe(cexpects);
expect(shared.subscriptions).toBe([asubs, bsubs, csubs]); // <--- this |
I like it, but that will only tell the test when to subscribe and unsubscribe. We still don't have a way to assert when inner observables unsubscribe or subscribe. But I think we can use the same diagrams. Think of testing So we can take the same subscription diagrames say something like: |
Are we roughly in agreement about the overall approach? I can try tackling this issue and also making some tests with any helper I build. (Although I would start work on this only next Monday because here it's already Friday evening.) |
I think so. No worries, on the delay. I'm unsure if you've looked into it, but basically there are instance methods on |
Working on this now. Essentially building |
@Blesh I identified a case where it would make sense to assert when the inner observables subscribe as well as unsubscribe. it('should mergeMap many outer values to many inner values', function () {
var values = {i: 'foo', j: 'bar', k: 'baz', l: 'qux'};
var e1 = hot('-a-------b-------c-------d-------|');
var inner = cold('----i---j---k---l---|', values);
var expected = '-----i---j---(ki)(lj)(ki)(lj)(ki)(lj)k---l---|';
expectObservable(e1.mergeMap(function(value) { return inner; }))
.toBe(expected, values);
}); Could be adapted to assert also: it('should mergeMap many outer values to many inner values', function () {
var values = {i: 'foo', j: 'bar', k: 'baz', l: 'qux'};
var e1 = hot('-a-------b-------c-------d-------|');
var inner = cold('----i---j---k---l---|', values);
var innersubs =['-^-------------------!',
'---------^-------------------!',
'-----------------^-------------------!',
'-------------------------^-------------------!']
var expected = '-----i---j---(ki)(lj)(ki)(lj)(ki)(lj)k---l---|';
expectObservable(e1.mergeMap(function(value) { return inner; }))
.toBe(expected, values);
expectSubscriptions(inner.subscriptions).toBe(innersubs);
}); Roger? |
Add expectSubscription(coldOrHotTestObservable.subscriptions).toBe(unsubs) feature to test utilities. Create multiple test utility classes such as ColdObservable, HotObservable, SubscriptionLog, TestMessage, etc. Also fix minor issues with VirtualTimeScheduler and Subject. Subject._subscribe() was taking an Observer, but its parent Observable._subscribe() was taking a Subscriber, so this commit changes Subject._subscribe() to take a Subscriber as well. This facilitates usage in HotObservable, for example. Resolves issue ReactiveX#428.
Should now be done with PR #463. |
Add expectSubscription(coldOrHotTestObservable.subscriptions).toBe(unsubs) feature to test utilities. Create multiple test utility classes such as ColdObservable, HotObservable, SubscriptionLog, TestMessage, etc. Also fix minor issues with VirtualTimeScheduler and Subject. Subject._subscribe() was taking an Observer, but its parent Observable._subscribe() was taking a Subscriber, so this commit changes Subject._subscribe() to take a Subscriber as well. This facilitates usage in HotObservable, for example. Resolves issue ReactiveX#428.
Add expectSubscription(coldOrHotTestObservable.subscriptions).toBe(unsubs) feature to test utilities. Create multiple test utility classes such as ColdObservable, HotObservable, SubscriptionLog, TestMessage, etc. Also fix minor issues with VirtualTimeScheduler and Subject. Subject._subscribe() was taking an Observer, but its parent Observable._subscribe() was taking a Subscriber, so this commit changes Subject._subscribe() to take a Subscriber as well. This facilitates usage in HotObservable, for example. Resolves issue ReactiveX#428.
Add expectSubscription(coldOrHotTestObservable.subscriptions).toBe(unsubs) feature to test utilities. Create multiple test utility classes such as ColdObservable, HotObservable, SubscriptionLog, TestMessage, etc. Also fix minor issues with VirtualTimeScheduler and Subject. Subject._subscribe() was taking an Observer, but its parent Observable._subscribe() was taking a Subscriber, so this commit changes Subject._subscribe() to take a Subscriber as well. This facilitates usage in HotObservable, for example. Resolves issue #428.
This issue can be closed. |
This is related to discussion in #423 ...
Basically the problem is that in something like
switch
, we don't have a way of asserting when inner subscriptions were unsubscribed from.The text was updated successfully, but these errors were encountered: