Created
September 27, 2017 13:08
-
-
Save akaztp/281234860955c156ab34339952c3168c to your computer and use it in GitHub Desktop.
An helper class to assert if an Observer produces the specified values.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Observable } from 'rxjs/Observable'; | |
import { Subscription } from 'rxjs/Subscription'; | |
import 'rxjs/add/operator/delay'; | |
/** | |
* An helper class to assert if an Observer produces the specified values. | |
* It does not care about the time between values produced by the observer. | |
* Returns a promise that either completes if test passed ok, or reject with an error message if not. | |
* @param obs$ The observer to test. | |
* @param values The array of values to expect in the observable. | |
* @param expectComplete If at the end of the expected values, the observer is expected to complete. | |
* @param errorAfter If after the specified number of values the observer is expected to error. | |
* @param matcher An equality function for matching the observable values with the values array provided. | |
*/ | |
export function matchObservable<T>( | |
obs$: Observable<T>, | |
values: Array<T>, | |
expectComplete: boolean = true, | |
errorAfter: number = -1, | |
matcher: (actual: T, expected: T) => boolean = (a, b) => a === b, | |
): Promise<void> | |
{ | |
return new Promise<void>(matchObs); | |
function matchObs(resolve: () => void, reject: (reason: any) => void) | |
{ | |
let expectedStep = 0; | |
// the next .delay(0) makes sure that the subscription callbacks are called only after the subs local var is filled up | |
const subs: Subscription = obs$.delay(0).subscribe( | |
(value) => | |
{ | |
if (expectedStep >= values.length) | |
{ | |
subs.unsubscribe(); | |
reject('Too many values on observable: ' + JSON.stringify(value)); | |
} | |
else | |
{ | |
if (matcher(value, values[expectedStep]) === false) | |
{ | |
subs.unsubscribe(); | |
reject('Values are expected to match: ' + JSON.stringify(value) | |
+ ' and ' + JSON.stringify(values[expectedStep])); | |
} | |
else | |
{ | |
// expect(value).toEqual(values[expectedStep]); | |
expectedStep++; | |
if (!expectComplete && expectedStep === values.length) | |
{ | |
subs.unsubscribe(); | |
resolve(); | |
} | |
} | |
} | |
}, | |
(error) => | |
{ | |
subs.unsubscribe(); | |
if (errorAfter >= 0 && expectedStep === errorAfter) | |
resolve(); | |
else | |
reject('Observable errored unexpectedly. Error: ' + error.toString()); | |
}, | |
() => | |
{ | |
subs.unsubscribe(); | |
if (expectedStep === values.length) | |
resolve(); | |
else | |
reject(`Observable completed unexpectedly after ${expectedStep} value emissions. ` | |
+ (expectedStep < values.length | |
? 'Missing values from observable.' | |
: 'Too many values on observable.')); | |
} | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment