Skip to content

Commit

Permalink
feat(observables): added returnSubject to observable
Browse files Browse the repository at this point in the history
now it's possible to get the underlying subject behind Observables returning methods
  • Loading branch information
shairez committed Jan 5, 2020
1 parent e8bb340 commit 8a753ce
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 2 deletions.
3 changes: 3 additions & 0 deletions src/create-spy-from-class.types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Subject } from 'rxjs';

export interface SpyFunctionReturnValueContainer {
value: any;
}
Expand All @@ -12,4 +14,5 @@ export interface CalledWithObject {
nextOneTimeWith?(value?: any): void;
throwWith?(value: any): void;
complete?(): void;
returnSubject?<R = any>(): Subject<R>;
}
60 changes: 59 additions & 1 deletion src/observables/observable-spy-utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { FakeChildClass, FakeClass } from '../test-utils/fake-classes-to-test';
import { take } from 'rxjs/operators';
import { Spy } from '../spy.types';
import * as errorHandling from '../errors/error-handling';
import { Subject } from 'rxjs';

let fakeClassSpy: Spy<FakeClass>;
let fakeChildClassSpy: Spy<FakeChildClass>;
Expand Down Expand Up @@ -86,6 +87,27 @@ describe('createSpyFromClass', () => {
expect(completed).toBe(true);
});
});

describe('GIVEN returnSubject is configured THEN do not emit', () => {
let subject: Subject<any>;
Given(() => {
subject = fakeClassSpy.observableMethod.and.returnSubject();
});

Then(() => {
expect(actualResult).toBeNull();
});

describe('GIVEN subject emits THEN capture the emitted message', () => {
Given(() => {
subject.next(fakeValue);
});

Then(() => {
expect(actualResult).toBe(fakeValue);
});
});
});
});

describe('WHEN Observable returning method is called with exact params', () => {
Expand Down Expand Up @@ -261,7 +283,7 @@ describe('createSpyFromClass', () => {
});
});

describe('GIVEN calledWith of complete is configured with the wrong params THEN throw an error', () => {
describe('GIVEN mustBeCalledWith of complete is configured with the wrong params THEN throw an error', () => {
Given(() => {
fakeClassSpy.observableMethod.mustBeCalledWith(WRONG_VALUE).complete();
});
Expand All @@ -272,6 +294,42 @@ describe('createSpyFromClass', () => {
});
});
});

describe('GIVEN calledWith of returnSubject is configured with the right params THEN emit successfully', () => {
Given(() => {
const subject = fakeClassSpy.observableMethod
.calledWith(...fakeArgs)
.returnSubject();
subject.next(fakeValue);
});

Then(() => {
expect(actualResult).toEqual(fakeValue);
});
});

describe('GIVEN calledWith of returnSubject is configured with wrong params THEN do not throw an error', () => {
Given(() => {
fakeClassSpy.observableMethod.calledWith(WRONG_VALUE).returnSubject();
});

Then(() => {
expect(throwArgumentsErrorSpyFunction).not.toHaveBeenCalled();
});
});

describe(`GIVEN mustBeCalledWith of returnSubject is configured with the wrong params
THEN throw an error`, () => {
Given(() => {
fakeClassSpy.observableMethod.mustBeCalledWith(WRONG_VALUE).returnSubject();
});

Then(() => {
verifyArgumentsErrorWasThrown({
actualArgs: fakeArgs
});
});
});
});

describe('WHEN calling a Subject returning method', () => {
Expand Down
10 changes: 10 additions & 0 deletions src/observables/observable-spy-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ export function observablifySpyFunction(
valueContainer.value = subject;
subject.complete();
};

spyFunction.and.returnSubject = function complete() {
valueContainer.value = subject;
return subject;
};
}

export function addObservableHandlingToCalledWith(
Expand Down Expand Up @@ -59,5 +64,10 @@ export function addObservableHandlingToCalledWith(
calledWithObject.argsToValuesMap.set(calledWithArgs, subject);
};

calledWithObject.returnSubject = function() {
calledWithObject.argsToValuesMap.set(calledWithArgs, subject);
return subject;
};

return calledWithObject;
}
3 changes: 2 additions & 1 deletion src/spy.types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/// <reference types="jasmine" />
import { Observable } from 'rxjs';
import { Observable, Subject } from 'rxjs';

export type Spy<T> = { [k in keyof T]: AddSpyTypes<T[k]> };

Expand All @@ -25,6 +25,7 @@ export interface ObservableSpyMethod<T> {
nextOneTimeWith(value?: T): void; // emit one value and completes
throwWith(value: any): void;
complete(): void;
returnSubject<R = any>(): Subject<R>;
}

export interface SpyMethod {
Expand Down

0 comments on commit 8a753ce

Please sign in to comment.