mirror of
https://github.com/bitwarden/browser.git
synced 2025-01-31 22:51:28 +01:00
Add matchers for Observable emissions
This commit is contained in:
parent
0425b03ba1
commit
3d2cfa952f
@ -1 +1,2 @@
|
|||||||
export * from "./to-equal-buffer";
|
export * from "./to-equal-buffer";
|
||||||
|
export * from "./to-emit";
|
||||||
|
54
libs/common/spec/matchers/to-emit.spec.ts
Normal file
54
libs/common/spec/matchers/to-emit.spec.ts
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import { Subject } from "rxjs";
|
||||||
|
|
||||||
|
describe("toEmit", () => {
|
||||||
|
let subject: Subject<boolean>;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
subject = new Subject<boolean>();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
subject.complete();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should pass if the observable emits", () => {
|
||||||
|
subject.next(true);
|
||||||
|
expect(subject).toEmit();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should fail if the observable does not emit", () => {
|
||||||
|
expect(subject).not.toEmit(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should fail if the observable emits after the timeout", () => {
|
||||||
|
setTimeout(() => subject.next(true), 100);
|
||||||
|
expect(subject).not.toEmit(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("toEmitValue", () => {
|
||||||
|
let subject: Subject<boolean>;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
subject = new Subject<boolean>();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should pass if the observable emits the expected value", () => {
|
||||||
|
subject.next(true);
|
||||||
|
expect(subject).toEmitValue(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should fail if the observable does not emit the expected value", () => {
|
||||||
|
subject.next(true);
|
||||||
|
expect(subject).not.toEmitValue(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should fail if the observable does not emit anything", () => {
|
||||||
|
expect(subject).not.toEmitValue(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should fail if the observable emits the expected value after the timeout", () => {
|
||||||
|
setTimeout(() => subject.next(true), 100);
|
||||||
|
expect(subject).not.toEmitValue(true);
|
||||||
|
});
|
||||||
|
});
|
62
libs/common/spec/matchers/to-emit.ts
Normal file
62
libs/common/spec/matchers/to-emit.ts
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import { Observable, Subscription } from "rxjs";
|
||||||
|
|
||||||
|
/** Asserts that an observable emitted any value */
|
||||||
|
export const toEmit: jest.CustomMatcher = async function toEmit<T>(
|
||||||
|
received: Observable<T>,
|
||||||
|
timeoutMs = 100
|
||||||
|
) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
let subscription: Subscription = undefined;
|
||||||
|
const timeout = setTimeout(() => {
|
||||||
|
subscription?.unsubscribe();
|
||||||
|
resolve({
|
||||||
|
pass: false,
|
||||||
|
message: () => "expected observable to emit",
|
||||||
|
});
|
||||||
|
}, timeoutMs);
|
||||||
|
|
||||||
|
subscription = received.subscribe(() => {
|
||||||
|
clearTimeout(timeout);
|
||||||
|
resolve({
|
||||||
|
pass: true,
|
||||||
|
message: () => "expected observable not to emit",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Asserts that the first value emitted from an observable is equal to the expected value.
|
||||||
|
* Optionally, a comparer function can be provided to compare the values. By default, a strict equality check is used.
|
||||||
|
*/
|
||||||
|
export const toEmitValue: jest.CustomMatcher = async function toEmitValue<T>(
|
||||||
|
received: Observable<T>,
|
||||||
|
expected: T,
|
||||||
|
comparer?: (a: T, b: T) => boolean,
|
||||||
|
timeoutMs = 100
|
||||||
|
) {
|
||||||
|
comparer = comparer ?? ((a, b) => a === b);
|
||||||
|
let emitted = false;
|
||||||
|
const value = await new Promise<T>((resolve) => {
|
||||||
|
let subscription: Subscription = undefined;
|
||||||
|
const timeout = setTimeout(() => {
|
||||||
|
subscription?.unsubscribe();
|
||||||
|
resolve(undefined);
|
||||||
|
}, timeoutMs);
|
||||||
|
|
||||||
|
subscription = received.subscribe((value) => {
|
||||||
|
clearTimeout(timeout);
|
||||||
|
emitted = true;
|
||||||
|
resolve(value);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
pass: emitted && comparer(value, expected),
|
||||||
|
message: () =>
|
||||||
|
comparer(value, expected)
|
||||||
|
? emitted
|
||||||
|
? `expected observable not to emit ${expected}`
|
||||||
|
: `expected observable to emit ${expected}, but it did not emit`
|
||||||
|
: `expected observable to emit ${expected}, but it emitted `,
|
||||||
|
};
|
||||||
|
};
|
@ -1,6 +1,6 @@
|
|||||||
import { webcrypto } from "crypto";
|
import { webcrypto } from "crypto";
|
||||||
|
|
||||||
import { toEqualBuffer } from "./spec";
|
import { toEmit, toEmitValue, toEqualBuffer } from "./spec";
|
||||||
|
|
||||||
Object.defineProperty(window, "crypto", {
|
Object.defineProperty(window, "crypto", {
|
||||||
value: webcrypto,
|
value: webcrypto,
|
||||||
@ -10,8 +10,16 @@ Object.defineProperty(window, "crypto", {
|
|||||||
|
|
||||||
expect.extend({
|
expect.extend({
|
||||||
toEqualBuffer: toEqualBuffer,
|
toEqualBuffer: toEqualBuffer,
|
||||||
|
toEmit: toEmit,
|
||||||
|
toEmitValue: toEmitValue,
|
||||||
});
|
});
|
||||||
|
|
||||||
export interface CustomMatchers<R = unknown> {
|
export interface CustomMatchers<R = unknown> {
|
||||||
toEqualBuffer(expected: Uint8Array | ArrayBuffer): R;
|
toEqualBuffer(expected: Uint8Array | ArrayBuffer): R;
|
||||||
|
toEmit(timeoutMs?: number): R;
|
||||||
|
toEmitValue(
|
||||||
|
expected: unknown,
|
||||||
|
comparer?: (a: unknown, b: unknown) => boolean,
|
||||||
|
timeoutMs?: number
|
||||||
|
): R;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user