MVVM - Introduce some helpers for snapshot management (#30398)
* Introduce snapshot class to track snapshot updates This avoids the hassle of having to manually call emit. * Better viewmodel ergonomics - Rename `SubscriptionViewModel` to `BaseViewModel`. I feel this is appropriate since that class does more than just manage subscriptions. - `getSnapshot` is no longer an abstract method. It's simply a method that returns the current snapshot state. This ensures that getSnapshot result is cached by default which is required by `useSyncExternalStore`. - `props` are a property of the base vm class so that actual VMs don't have to keep creating this property. * Update `TextualEventViewModel` * Fix test * Rename `TextualEvent` to `TextualEventView` * Fix snapshot object not being merged * Rename directory to `EventTileView` * Fix broken snapshot * Add test for snapshot class
This commit is contained in:
41
test/viewmodels/base/Snapshot-test.ts
Normal file
41
test/viewmodels/base/Snapshot-test.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
Copyright 2025 New Vector Ltd.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { Snapshot } from "../../../src/viewmodels/base/Snapshot";
|
||||
|
||||
interface TestSnapshot {
|
||||
key1: string;
|
||||
key2: number;
|
||||
key3: boolean;
|
||||
}
|
||||
|
||||
describe("Snapshot", () => {
|
||||
it("should accept an initial value", () => {
|
||||
const snapshot = new Snapshot<TestSnapshot>({ key1: "foo", key2: 5, key3: false }, jest.fn());
|
||||
expect(snapshot.current).toStrictEqual({ key1: "foo", key2: 5, key3: false });
|
||||
});
|
||||
|
||||
it("should call emit callback when state changes", () => {
|
||||
const emit = jest.fn();
|
||||
const snapshot = new Snapshot<TestSnapshot>({ key1: "foo", key2: 5, key3: false }, emit);
|
||||
snapshot.merge({ key3: true });
|
||||
expect(emit).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("should swap out entire snapshot on set call", () => {
|
||||
const snapshot = new Snapshot<TestSnapshot>({ key1: "foo", key2: 5, key3: false }, jest.fn());
|
||||
const newValue = { key1: "bar", key2: 8, key3: true };
|
||||
snapshot.set(newValue);
|
||||
expect(snapshot.current).toStrictEqual(newValue);
|
||||
});
|
||||
|
||||
it("should merge partial snapshot on merge call", () => {
|
||||
const snapshot = new Snapshot<TestSnapshot>({ key1: "foo", key2: 5, key3: false }, jest.fn());
|
||||
snapshot.merge({ key2: 10 });
|
||||
expect(snapshot.current).toStrictEqual({ key1: "foo", key2: 10, key3: false });
|
||||
});
|
||||
});
|
||||
@@ -8,10 +8,16 @@ Please see LICENSE files in the repository root for full details.
|
||||
import { MatrixEvent, MatrixEventEvent } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import { TextualEventViewModel } from "../../../src/viewmodels/event-tiles/TextualEventViewModel";
|
||||
import { stubClient } from "../../test-utils";
|
||||
|
||||
jest.mock("../../../src/TextForEvent.tsx", () => ({
|
||||
textForEvent: jest.fn().mockReturnValue("Test Message"),
|
||||
}));
|
||||
|
||||
describe("TextualEventViewModel", () => {
|
||||
it("should update when the sentinel updates", () => {
|
||||
const fakeEvent = new MatrixEvent({});
|
||||
stubClient();
|
||||
|
||||
const vm = new TextualEventViewModel({
|
||||
showHiddenEvents: false,
|
||||
|
||||
Reference in New Issue
Block a user