@hirez_io/observer-spy
Advanced tools
Comparing version 1.4.0 to 2.0.0
export { ObserverSpy } from './observer-spy'; | ||
export { ObserverSpyWithSubscription, SubscriberSpy } from './subscriber-spy'; | ||
export { subscribeSpyTo, subscribeAndSpyOn } from './subscribe-spy-to'; | ||
export { SubscriberSpy } from './subscriber-spy'; | ||
export { subscribeSpyTo } from './subscribe-spy-to'; | ||
export { fakeTime } from './fake-time'; | ||
export { autoUnsubscribe, queueForAutoUnsubscribe } from './auto-unsubscribe'; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -6,7 +6,5 @@ "use strict"; | ||
var subscriber_spy_1 = require("./subscriber-spy"); | ||
exports.ObserverSpyWithSubscription = subscriber_spy_1.ObserverSpyWithSubscription; | ||
exports.SubscriberSpy = subscriber_spy_1.SubscriberSpy; | ||
var subscribe_spy_to_1 = require("./subscribe-spy-to"); | ||
exports.subscribeSpyTo = subscribe_spy_to_1.subscribeSpyTo; | ||
exports.subscribeAndSpyOn = subscribe_spy_to_1.subscribeAndSpyOn; | ||
var fake_time_1 = require("./fake-time"); | ||
@@ -13,0 +11,0 @@ exports.fakeTime = fake_time_1.fakeTime; |
@@ -7,7 +7,12 @@ import { Observer } from 'rxjs'; | ||
errorValue: any; | ||
errorIsExpected: boolean; | ||
onCompleteCallback: (() => void) | undefined; | ||
} | ||
export interface ObserverSpyConfig { | ||
expectErrors: boolean; | ||
} | ||
export declare class ObserverSpy<T> implements Observer<T> { | ||
private onNextValues; | ||
private state; | ||
constructor(config?: ObserverSpyConfig); | ||
next(value: T): void; | ||
@@ -18,2 +23,3 @@ error(errorVal: any): void; | ||
onComplete(callback: () => void): void; | ||
expectErrors(): void; | ||
getValuesLength(): number; | ||
@@ -20,0 +26,0 @@ getValues(): any[]; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var ObserverSpy = /** @class */ (function () { | ||
function ObserverSpy() { | ||
function ObserverSpy(config) { | ||
this.onNextValues = []; | ||
@@ -12,3 +12,7 @@ this.state = { | ||
onCompleteCallback: undefined, | ||
errorIsExpected: false, | ||
}; | ||
if (config && config.expectErrors) { | ||
this.expectErrors(); | ||
} | ||
} | ||
@@ -20,2 +24,5 @@ ObserverSpy.prototype.next = function (value) { | ||
ObserverSpy.prototype.error = function (errorVal) { | ||
if (!this.state.errorIsExpected) { | ||
throw errorVal; | ||
} | ||
this.state.errorValue = errorVal; | ||
@@ -43,2 +50,5 @@ this.state.errorWasCalled = true; | ||
}; | ||
ObserverSpy.prototype.expectErrors = function () { | ||
this.state.errorIsExpected = true; | ||
}; | ||
ObserverSpy.prototype.getValuesLength = function () { | ||
@@ -45,0 +55,0 @@ return this.onNextValues.length; |
import { Observable } from 'rxjs'; | ||
import { SubscriberSpy } from './subscriber-spy'; | ||
export declare function subscribeSpyTo<T>(observableUnderTest: Observable<T>): SubscriberSpy<T>; | ||
import { ObserverSpyConfig } from './observer-spy'; | ||
export declare function subscribeSpyTo<T>(observableUnderTest: Observable<T>, config?: ObserverSpyConfig): SubscriberSpy<T>; | ||
export declare function subscribeAndSpyOn<T>(observableUnderTest: Observable<T>): SubscriberSpy<T>; | ||
//# sourceMappingURL=subscribe-spy-to.d.ts.map |
@@ -5,4 +5,4 @@ "use strict"; | ||
var subscriber_spy_1 = require("./subscriber-spy"); | ||
function subscribeSpyTo(observableUnderTest) { | ||
var spy = new subscriber_spy_1.SubscriberSpy(observableUnderTest); | ||
function subscribeSpyTo(observableUnderTest, config) { | ||
var spy = new subscriber_spy_1.SubscriberSpy(observableUnderTest, config); | ||
auto_unsubscribe_1.queueForAutoUnsubscribe(spy); | ||
@@ -9,0 +9,0 @@ return spy; |
import { Subscription, Observable, Unsubscribable } from 'rxjs'; | ||
import { ObserverSpy } from '.'; | ||
import { ObserverSpyConfig } from './observer-spy'; | ||
export declare class SubscriberSpy<T> extends ObserverSpy<T> implements Unsubscribable { | ||
subscription: Subscription; | ||
constructor(observableUnderTest: Observable<T>); | ||
constructor(observableUnderTest: Observable<T>, config?: ObserverSpyConfig); | ||
unsubscribe(): void; | ||
@@ -7,0 +8,0 @@ } |
@@ -20,4 +20,4 @@ "use strict"; | ||
__extends(SubscriberSpy, _super); | ||
function SubscriberSpy(observableUnderTest) { | ||
var _this = _super.call(this) || this; | ||
function SubscriberSpy(observableUnderTest, config) { | ||
var _this = _super.call(this, config) || this; | ||
_this.subscription = new rxjs_1.Subscription(); | ||
@@ -24,0 +24,0 @@ _this.subscription.add(observableUnderTest.subscribe(_this)); |
{ | ||
"name": "@hirez_io/observer-spy", | ||
"version": "1.4.0", | ||
"version": "2.0.0", | ||
"repository": { | ||
@@ -19,2 +19,3 @@ "type": "git", | ||
"build": "run-s clean compile", | ||
"generate-toc": "doctoc README.md", | ||
"test": "jest", | ||
@@ -62,2 +63,3 @@ "test:watch": "jest --watch", | ||
"cz-conventional-changelog": "3.1.0", | ||
"doctoc": "1.4.0", | ||
"husky": "4.2.5", | ||
@@ -64,0 +66,0 @@ "jest": "^25.4.0", |
@@ -22,4 +22,40 @@ # @hirez_io/observer-spy 👀💪 | ||
<br/> | ||
# Table of Contents | ||
<!-- START doctoc generated TOC please keep comment here to allow auto update --> | ||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> | ||
- [Installation](#installation) | ||
- [The Problem](#the-problem-testing-rxjs-observables-is-hard-) | ||
- [The Solution](#the-solution-observer-spies-) | ||
- [Usage](#usage) | ||
- [`subscribeSpyTo(observable)`](#const-observerspy--subscribespytoobservable) | ||
- [`onComplete` (using `async` + `await`)](#wait-for-oncomplete-before-expecting-the-result-using-async--await) | ||
- [Spying on Errors (`expectErrors`)](#spy-on-errors-with-receivederror-and-geterror) | ||
- [Manually Creating Spies](#manually-using-new-observerspy) | ||
- [Auto Unsubscribing](#auto-unsubscribing) | ||
- [Testing Sync Logic](#testing-sync-logic) | ||
- [Testing Async Logic](#testing-async-logic) | ||
- [▶ RxJS + Angular: use `fakeAsync`](#%E2%96%B6-rxjs---angular-use-fakeasync) | ||
- [▶ RxJS + Promises: use `async` + `await`](#%E2%96%B6-rxjs--promises-use-async--await) | ||
- [▶ RxJS Timers / Animations: use `fakeTime`](#%E2%96%B6-rxjs-timers--animations-use-faketime) | ||
- [▶ RxJS + _AJAX_ calls:](#%E2%96%B6-rxjs--_ajax_-calls) | ||
- [🧠 Wanna become a PRO Observables tester?](#-wanna-become-a-pro-observables-tester) | ||
- [How to Contribute](#contributing) | ||
- [Code Of Conduct](#code-of-conduct) | ||
- [Contributors ✨](#contributors-) | ||
- [License](#license) | ||
<!-- END doctoc generated TOC please keep comment here to allow auto update --> | ||
<br/> | ||
## Installation | ||
@@ -213,2 +249,5 @@ | ||
#### ⚠ You MUST configure `expectErrors` to catch errors! | ||
This 👆 is to avoid swallowing unexpected errors ([more details here](https://github.com/hirezio/observer-spy/issues/20)) | ||
```js | ||
@@ -220,3 +259,3 @@ | ||
const observerSpy = subscribeSpyTo(fakeObservable); | ||
const observerSpy = subscribeSpyTo(fakeObservable, {expectErrors: true}); | ||
@@ -263,2 +302,21 @@ expect(observerSpy.receivedError()).toBe(true); | ||
If you need to spy on errors, make sure to set the `expectErrors` property: | ||
```js | ||
it('should spy on Observable errors', () => { | ||
const fakeObservable = throwError('OOPS'); | ||
const observerSpy = new ObserverSpy({expectErrors: true}); // <-- IMPORTANT | ||
// BTW, this could also be set like this: | ||
observerSpy.expectErrors(); // <-- ALTERNATIVE WAY TO SET IT | ||
fakeObservable.subscribe(observerSpy); | ||
expect(observerSpy.receivedError()).toBe(true); | ||
}); | ||
``` | ||
<br/> | ||
@@ -351,5 +409,5 @@ | ||
Use `fakeTime` with `flush()` to simulate the passage of time ([detailed explanation](#-for-time-based-rxjs-code-timeouts--intervals--animations---use-faketime)) - | ||
Use `fakeTime` with `flush()` to simulate the passage of time ([detailed explanation](#-rxjs-timers--animations-use-faketime)) - | ||
[](#-for-time-based-rxjs-code-timeouts--intervals--animations---use-faketime) | ||
[](#-rxjs-timers--animations-use-faketime) | ||
@@ -356,0 +414,0 @@ |
export { ObserverSpy } from './observer-spy'; | ||
export { ObserverSpyWithSubscription, SubscriberSpy } from './subscriber-spy'; | ||
export { subscribeSpyTo, subscribeAndSpyOn } from './subscribe-spy-to'; | ||
export { SubscriberSpy } from './subscriber-spy'; | ||
export { subscribeSpyTo } from './subscribe-spy-to'; | ||
export { fakeTime } from './fake-time'; | ||
export { autoUnsubscribe, queueForAutoUnsubscribe } from './auto-unsubscribe'; |
@@ -122,8 +122,7 @@ import { Observable, of, throwError } from 'rxjs'; | ||
describe('GIVEN observable throws WHEN subscribing', () => { | ||
const FAKE_ERROR_MESSAGE = 'FAKE ERROR'; | ||
function getThrowingObservable() { | ||
const observerSpy: ObserverSpy<string> = new ObserverSpy(); | ||
const throwingObservable: Observable<string> = throwError('FAKE ERROR'); | ||
const throwingObservable: Observable<string> = throwError(FAKE_ERROR_MESSAGE); | ||
return { | ||
observerSpy, | ||
throwingObservable, | ||
@@ -133,5 +132,16 @@ }; | ||
it('should know whether it got an "error" notification', () => { | ||
const { observerSpy, throwingObservable } = getThrowingObservable(); | ||
it('should throw the original error if "expectErrors" is NOT configured', () => { | ||
const observerSpy: ObserverSpy<string> = new ObserverSpy(); | ||
try { | ||
observerSpy.error(FAKE_ERROR_MESSAGE); | ||
} catch (expectedError) { | ||
expect(expectedError).toBe(FAKE_ERROR_MESSAGE); | ||
} | ||
}); | ||
it('should know whether it got an "error" notification if "expectErrors" is configured', () => { | ||
const observerSpy: ObserverSpy<string> = new ObserverSpy(); | ||
observerSpy.expectErrors(); | ||
const { throwingObservable } = getThrowingObservable(); | ||
throwingObservable.subscribe(observerSpy).unsubscribe(); | ||
@@ -142,10 +152,11 @@ | ||
it('should return the error object it received', () => { | ||
const { observerSpy, throwingObservable } = getThrowingObservable(); | ||
it('should return the error object it received if "expectErrors" is configured', () => { | ||
const observerSpy: ObserverSpy<string> = new ObserverSpy({ expectErrors: true }); | ||
const { throwingObservable } = getThrowingObservable(); | ||
throwingObservable.subscribe(observerSpy).unsubscribe(); | ||
expect(observerSpy.getError()).toEqual('FAKE ERROR'); | ||
expect(observerSpy.getError()).toEqual(FAKE_ERROR_MESSAGE); | ||
}); | ||
}); | ||
}); |
@@ -8,5 +8,10 @@ import { Observer } from 'rxjs'; | ||
errorValue: any; | ||
errorIsExpected: boolean; | ||
onCompleteCallback: (() => void) | undefined; | ||
} | ||
export interface ObserverSpyConfig { | ||
expectErrors: boolean; | ||
} | ||
export class ObserverSpy<T> implements Observer<T> { | ||
@@ -21,4 +26,11 @@ private onNextValues: T[] = []; | ||
onCompleteCallback: undefined, | ||
errorIsExpected: false, | ||
}; | ||
constructor(config?: ObserverSpyConfig) { | ||
if (config && config.expectErrors) { | ||
this.expectErrors(); | ||
} | ||
} | ||
next(value: T): void { | ||
@@ -30,2 +42,5 @@ this.onNextValues.push(value); | ||
error(errorVal: any): void { | ||
if (!this.state.errorIsExpected) { | ||
throw errorVal; | ||
} | ||
this.state.errorValue = errorVal; | ||
@@ -59,2 +74,6 @@ this.state.errorWasCalled = true; | ||
expectErrors() { | ||
this.state.errorIsExpected = true; | ||
} | ||
getValuesLength(): number { | ||
@@ -61,0 +80,0 @@ return this.onNextValues.length; |
@@ -1,2 +0,2 @@ | ||
import { Subject } from 'rxjs'; | ||
import { Subject, throwError } from 'rxjs'; | ||
import { subscribeSpyTo } from './subscribe-spy-to'; | ||
@@ -20,2 +20,8 @@ | ||
}); | ||
it('should respect "expectErrors" configuration', () => { | ||
const observerSpy = subscribeSpyTo(throwError('FAKE ERROR'), { expectErrors: true }); | ||
expect(observerSpy.getError()).toBe('FAKE ERROR'); | ||
}); | ||
}); |
import { Observable } from 'rxjs'; | ||
import { queueForAutoUnsubscribe } from './auto-unsubscribe'; | ||
import { SubscriberSpy } from './subscriber-spy'; | ||
import { ObserverSpyConfig } from './observer-spy'; | ||
export function subscribeSpyTo<T>(observableUnderTest: Observable<T>) { | ||
const spy = new SubscriberSpy(observableUnderTest); | ||
export function subscribeSpyTo<T>( | ||
observableUnderTest: Observable<T>, | ||
config?: ObserverSpyConfig | ||
) { | ||
const spy = new SubscriberSpy(observableUnderTest, config); | ||
queueForAutoUnsubscribe(spy); | ||
@@ -8,0 +12,0 @@ return spy; |
import { Subscription, Observable, Unsubscribable } from 'rxjs'; | ||
import { ObserverSpy } from '.'; | ||
import { ObserverSpyConfig } from './observer-spy'; | ||
@@ -7,4 +8,4 @@ export class SubscriberSpy<T> extends ObserverSpy<T> implements Unsubscribable { | ||
constructor(observableUnderTest: Observable<T>) { | ||
super(); | ||
constructor(observableUnderTest: Observable<T>, config?: ObserverSpyConfig) { | ||
super(config); | ||
this.subscription.add(observableUnderTest.subscribe(this)); | ||
@@ -11,0 +12,0 @@ } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
287817
782
583
19