Test MediaViewModel

This was the result of me playing around with RxJS marble testing to understand how to get things done with its TestScheduler. I discovered that it lacks a clear way to fire arbitrary actions during the test, so I built a small helper function called schedule which does this for us.
This commit is contained in:
Robin
2024-08-30 19:09:42 -04:00
parent 3e57a7692c
commit 9d5145a7a6
2 changed files with 169 additions and 2 deletions

View File

@@ -1,5 +1,5 @@
/*
Copyright 2023 New Vector Ltd
Copyright 2023-2024 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -13,7 +13,9 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { vi } from "vitest";
import { map } from "rxjs";
import { RunHelpers, TestScheduler } from "rxjs/testing";
import { expect, vi } from "vitest";
export function withFakeTimers(continuation: () => void): void {
vi.useFakeTimers();
@@ -23,3 +25,36 @@ export function withFakeTimers(continuation: () => void): void {
vi.useRealTimers();
}
}
export interface OurRunHelpers extends RunHelpers {
/**
* Schedules a sequence of actions to happen, as described by a marble
* diagram.
*/
schedule: (marbles: string, actions: Record<string, () => void>) => void;
}
/**
* Run Observables with a scheduler that virtualizes time, for testing purposes.
*/
export function withTestScheduler(
continuation: (helpers: OurRunHelpers) => void,
): void {
new TestScheduler((actual, expected) => {
expect(actual).deep.equals(expected);
}).run((helpers) =>
continuation({
...helpers,
schedule(marbles, actions) {
const actionsObservable = helpers
.cold(marbles)
.pipe(map((value) => actions[value]()));
const results = Object.fromEntries(
Object.keys(actions).map((value) => [value, undefined] as const),
);
// Run the actions and verify that none of them error
helpers.expectObservable(actionsObservable).toBe(marbles, results);
},
}),
);
}