Skip to content

Commit

Permalink
Subject specs run mode (#6925)
Browse files Browse the repository at this point in the history
* chore(BehaviorSubject): convert BehaviorSubject tests to run mode

* chore: add subject tests to prettier configuration

Co-authored-by: Nicholas Jamieson <nicholas@cartant.com>
  • Loading branch information
tmair and cartant committed Apr 17, 2022
1 parent f327ccf commit 2dd61ef
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 131 deletions.
2 changes: 1 addition & 1 deletion .prettierrc.json
Expand Up @@ -10,7 +10,7 @@
}
},
{
"files": ["spec/operators/**/*.ts"],
"files": ["spec/operators/**/*.ts", "spec/subjects/**/*.ts"],
"options": {
"requirePragma": false
}
Expand Down
16 changes: 8 additions & 8 deletions spec/subjects/AsyncSubject-spec.ts
Expand Up @@ -196,13 +196,13 @@ describe('AsyncSubject', () => {
const subject = new AsyncSubject<number>();
let calls = 0;
subject.subscribe({
next: value => {
next: (value) => {
calls++;
if (calls < 2) {
// if this is more than 1, we're reentrant, and that's bad.
subject.complete();
}
}
},
});

subject.next(1);
Expand All @@ -215,13 +215,13 @@ describe('AsyncSubject', () => {
const subject = new AsyncSubject<number>();
let calls = 0;
subject.subscribe({
next: value => {
next: (value) => {
calls++;
if (calls < 2) {
// if this is more than 1, we're reentrant, and that's bad.
subject.next(value + 1);
}
}
},
});

subject.next(1);
Expand All @@ -231,18 +231,18 @@ describe('AsyncSubject', () => {
});

it('should allow reentrant subscriptions', () => {
const subject = new AsyncSubject<number>()
const subject = new AsyncSubject<number>();
let results: any[] = [];

subject.subscribe({
next: (value) => {
subject.subscribe({
next: value => results.push('inner: ' + (value + value)),
complete: () => results.push('inner: done')
next: (value) => results.push('inner: ' + (value + value)),
complete: () => results.push('inner: done'),
});
results.push('outer: ' + value);
},
complete: () => results.push('outer: done')
complete: () => results.push('outer: done'),
});

subject.next(1);
Expand Down
148 changes: 88 additions & 60 deletions spec/subjects/BehaviorSubject-spec.ts
@@ -1,11 +1,18 @@
import { expect } from 'chai';
import { hot, expectObservable } from '../helpers/marble-testing';
import { BehaviorSubject, Subject, ObjectUnsubscribedError, of } from 'rxjs';
import { tap, mergeMapTo } from 'rxjs/operators';
import { asInteropSubject } from '../helpers/interop-helper';
import { TestScheduler } from 'rxjs/testing';
import { observableMatcher } from '../helpers/observableMatcher';

/** @test {BehaviorSubject} */
describe('BehaviorSubject', () => {
let testScheduler: TestScheduler;

beforeEach(() => {
testScheduler = new TestScheduler(observableMatcher);
});

it('should extend Subject', () => {
const subject = new BehaviorSubject(null);
expect(subject).to.be.instanceof(Subject);
Expand All @@ -19,8 +26,7 @@ describe('BehaviorSubject', () => {
}).to.throw(Error, 'derp');
});

it('should throw an ObjectUnsubscribedError if getValue() is called ' +
'and the BehaviorSubject has been unsubscribed', () => {
it('should throw an ObjectUnsubscribedError if getValue() is called and the BehaviorSubject has been unsubscribed', () => {
const subject = new BehaviorSubject('hi there');
subject.unsubscribe();
expect(() => {
Expand Down Expand Up @@ -63,9 +69,12 @@ describe('BehaviorSubject', () => {
const expected = ['foo', 'bar'];
let i = 0;

subject.subscribe({ next: (x: string) => {
expect(x).to.equal(expected[i++]);
}, complete: done });
subject.subscribe({
next: (x: string) => {
expect(x).to.equal(expected[i++]);
},
complete: done,
});

subject.next('bar');
subject.complete();
Expand All @@ -81,9 +90,12 @@ describe('BehaviorSubject', () => {
expect(x).to.equal(expected[i++]);
});

subject.subscribe({ next: (x: string) => {
expect(x).to.equal(expected[j++]);
}, complete: done });
subject.subscribe({
next: (x: string) => {
expect(x).to.equal(expected[j++]);
},
complete: done,
});

expect(subject.observers.length).to.equal(2);
subject.next('foo');
Expand Down Expand Up @@ -130,65 +142,78 @@ describe('BehaviorSubject', () => {
});

it('should replay the previous value when subscribed', () => {
const behaviorSubject = new BehaviorSubject('0');
function feedNextIntoSubject(x: string) { behaviorSubject.next(x); }
function feedErrorIntoSubject(err: any) { behaviorSubject.error(err); }
function feedCompleteIntoSubject() { behaviorSubject.complete(); }

const sourceTemplate = '-1-2-3----4------5-6---7--8----9--|';
const subscriber1 = hot(' (a|) ').pipe(mergeMapTo(behaviorSubject));
const unsub1 = ' ! ';
const expected1 = ' 3---4------5-6-- ';
const subscriber2 = hot(' (b|) ').pipe(mergeMapTo(behaviorSubject));
const unsub2 = ' ! ';
const expected2 = ' 4----5-6---7-- ';
const subscriber3 = hot(' (c|) ').pipe(mergeMapTo(behaviorSubject));
const expected3 = ' 8---9--|';

expectObservable(hot(sourceTemplate).pipe(
tap(
{ next: feedNextIntoSubject, error: feedErrorIntoSubject, complete: feedCompleteIntoSubject }
)
)).toBe(sourceTemplate);
expectObservable(subscriber1, unsub1).toBe(expected1);
expectObservable(subscriber2, unsub2).toBe(expected2);
expectObservable(subscriber3).toBe(expected3);
testScheduler.run(({ hot, expectObservable }) => {
const behaviorSubject = new BehaviorSubject('0');
function feedNextIntoSubject(x: string) {
behaviorSubject.next(x);
}
function feedErrorIntoSubject(err: any) {
behaviorSubject.error(err);
}
function feedCompleteIntoSubject() {
behaviorSubject.complete();
}

const sourceTemplate = ' -1-2-3----4------5-6---7--8----9--|';
const subscriber1 = hot('------(a|) ').pipe(mergeMapTo(behaviorSubject));
const unsub1 = ' ---------------------! ';
const expected1 = ' ------3---4------5-6-- ';
const subscriber2 = hot('------------(b|) ').pipe(mergeMapTo(behaviorSubject));
const unsub2 = ' -------------------------! ';
const expected2 = ' ------------4----5-6---7-- ';
const subscriber3 = hot('---------------------------(c|) ').pipe(mergeMapTo(behaviorSubject));
const expected3 = ' ---------------------------8---9--|';

expectObservable(
hot(sourceTemplate).pipe(tap({ next: feedNextIntoSubject, error: feedErrorIntoSubject, complete: feedCompleteIntoSubject }))
).toBe(sourceTemplate);
expectObservable(subscriber1, unsub1).toBe(expected1);
expectObservable(subscriber2, unsub2).toBe(expected2);
expectObservable(subscriber3).toBe(expected3);
});
});

it('should emit complete when subscribed after completed', () => {
const behaviorSubject = new BehaviorSubject('0');
function feedNextIntoSubject(x: string) { behaviorSubject.next(x); }
function feedErrorIntoSubject(err: any) { behaviorSubject.error(err); }
function feedCompleteIntoSubject() { behaviorSubject.complete(); }

const sourceTemplate = '-1-2-3--4--|';
const subscriber1 = hot(' (a|)').pipe(
mergeMapTo(behaviorSubject)
);
const expected1 = ' | ';

expectObservable(hot(sourceTemplate).pipe(
tap(
{ next: feedNextIntoSubject, error: feedErrorIntoSubject, complete: feedCompleteIntoSubject }
)
)).toBe(sourceTemplate);
expectObservable(subscriber1).toBe(expected1);
testScheduler.run(({ hot, expectObservable }) => {
const behaviorSubject = new BehaviorSubject('0');
function feedNextIntoSubject(x: string) {
behaviorSubject.next(x);
}
function feedErrorIntoSubject(err: any) {
behaviorSubject.error(err);
}
function feedCompleteIntoSubject() {
behaviorSubject.complete();
}

const sourceTemplate = ' -1-2-3--4--| ';
const subscriber1 = hot('---------------(a|)').pipe(mergeMapTo(behaviorSubject));
const expected1 = ' ---------------| ';

expectObservable(
hot(sourceTemplate).pipe(tap({ next: feedNextIntoSubject, error: feedErrorIntoSubject, complete: feedCompleteIntoSubject }))
).toBe(sourceTemplate);
expectObservable(subscriber1).toBe(expected1);
});
});

it('should be an Observer which can be given to Observable.subscribe', (done) => {
const source = of(1, 2, 3, 4, 5);
const subject = new BehaviorSubject(0);
const expected = [0, 1, 2, 3, 4, 5];

subject.subscribe(
{ next: (x: number) => {
subject.subscribe({
next: (x: number) => {
expect(x).to.equal(expected.shift());
}, error: (x) => {
},
error: (x) => {
done(new Error('should not be called'));
}, complete: () => {
},
complete: () => {
expect(subject.value).to.equal(5);
done();
} });
},
});

source.subscribe(subject);
});
Expand All @@ -202,16 +227,19 @@ describe('BehaviorSubject', () => {
const subject = new BehaviorSubject(0);
const expected = [0, 1, 2, 3, 4, 5];

subject.subscribe(
{ next: (x: number) => {
subject.subscribe({
next: (x: number) => {
expect(x).to.equal(expected.shift());
}, error: (x) => {
},
error: (x) => {
done(new Error('should not be called'));
}, complete: () => {
},
complete: () => {
expect(subject.value).to.equal(5);
done();
} });
},
});

source.subscribe(asInteropSubject(subject));
source.subscribe(asInteropSubject(subject));
});
});

0 comments on commit 2dd61ef

Please sign in to comment.