diff --git a/frontend/sync-client/src/file-operations/file-operations.test.ts b/frontend/sync-client/src/file-operations/file-operations.test.ts index 43308f8c..0d947e88 100644 --- a/frontend/sync-client/src/file-operations/file-operations.test.ts +++ b/frontend/sync-client/src/file-operations/file-operations.test.ts @@ -7,94 +7,108 @@ import { FileOperations } from "./file-operations"; import { Logger } from "../tracing/logger"; import { assertSetContainsExactly } from "../utils/assert-set-contains-exactly"; import type { FileSystemOperations } from "./filesystem-operations"; +import init, { base64ToBytes } from "sync_lib"; +import fs from "fs"; + +class MockDatabase implements Partial { + public getLatestDocumentByRelativePath( + _find: RelativePath + ): DocumentRecord | undefined { + // no-op + return undefined; + } + + public move( + _oldRelativePath: RelativePath, + _newRelativePath: RelativePath + ): void { + // no-op + } +} + +class FakeFileSystemOperations implements FileSystemOperations { + public readonly names = new Set(); + + public async listAllFiles(): Promise { + throw new Error("Method not implemented."); + } + public async read(_path: RelativePath): Promise { + throw new Error("Method not implemented."); + } + public async write( + path: RelativePath, + _content: Uint8Array + ): Promise { + this.names.add(path); + } + public async atomicUpdateText( + _path: RelativePath, + _updater: (currentContent: string) => string + ): Promise { + throw new Error("Method not implemented."); + } + public async getFileSize(_path: RelativePath): Promise { + throw new Error("Method not implemented."); + } + public async getModificationTime(_path: RelativePath): Promise { + throw new Error("Method not implemented."); + } + public async exists(path: RelativePath): Promise { + return this.names.has(path); + } + public async createDirectory(_path: RelativePath): Promise { + // this is called but irrelevant for this mock + } + public async delete(_path: RelativePath): Promise { + throw new Error("Method not implemented."); + } + public async rename( + oldPath: RelativePath, + newPath: RelativePath + ): Promise { + this.names.delete(oldPath); + this.names.add(newPath); + } +} describe("File operations", () => { - class MockDatabase implements Partial { - public getLatestDocumentByRelativePath( - _find: RelativePath - ): DocumentRecord | undefined { - // no-op - return undefined; - } + beforeEach(async () => { + const wasmBin = fs.readFileSync( + "../../backend/sync_lib/pkg/sync_lib_bg.wasm" + ); + await init({ module_or_path: wasmBin }); + }); - public move( - _oldRelativePath: RelativePath, - _newRelativePath: RelativePath - ): void { - // no-op - } - } - - class FakeFileSystemOperations implements FileSystemOperations { - public readonly names = new Set(); - - public async listAllFiles(): Promise { - throw new Error("Method not implemented."); - } - public async read(_path: RelativePath): Promise { - throw new Error("Method not implemented."); - } - public async write( - path: RelativePath, - _content: Uint8Array - ): Promise { - this.names.add(path); - } - public async atomicUpdateText( - _path: RelativePath, - _updater: (currentContent: string) => string - ): Promise { - throw new Error("Method not implemented."); - } - public async getFileSize(_path: RelativePath): Promise { - throw new Error("Method not implemented."); - } - public async getModificationTime(_path: RelativePath): Promise { - throw new Error("Method not implemented."); - } - public async exists(path: RelativePath): Promise { - return this.names.has(path); - } - public async createDirectory(_path: RelativePath): Promise { - // this is called but irrelevant for this mock - } - public async delete(_path: RelativePath): Promise { - throw new Error("Method not implemented."); - } - public async rename( - oldPath: RelativePath, - newPath: RelativePath - ): Promise { - this.names.delete(oldPath); - this.names.add(newPath); - } - } - - test("should deconflict renames", async () => { - const fs = new FakeFileSystemOperations(); + it("should deconflict renames", async () => { + const fileSystemOperations = new FakeFileSystemOperations(); const fileOperations = new FileOperations( new Logger(), new MockDatabase() as Database, // eslint-disable-line @typescript-eslint/no-unsafe-type-assertion - fs + fileSystemOperations ); await fileOperations.create("a", new Uint8Array()); - assertSetContainsExactly(fs.names, "a"); + assertSetContainsExactly(fileSystemOperations.names, "a"); await fileOperations.move("a", "b"); - assertSetContainsExactly(fs.names, "b"); + assertSetContainsExactly(fileSystemOperations.names, "b"); await fileOperations.create("c", new Uint8Array()); - assertSetContainsExactly(fs.names, "b", "c"); + assertSetContainsExactly(fileSystemOperations.names, "b", "c"); await fileOperations.move("c", "b"); - assertSetContainsExactly(fs.names, "b", "b (1)"); + assertSetContainsExactly(fileSystemOperations.names, "b", "b (1)"); await fileOperations.create("c", new Uint8Array()); await fileOperations.move("c", "b"); - assertSetContainsExactly(fs.names, "b", "b (1)", "b (2)"); + assertSetContainsExactly( + fileSystemOperations.names, + "b", + "b (1)", + "b (2)" + ); }); - test("should deconflict renames with file extension", async () => { + it("should deconflict renames with file extension", async () => { const fs = new FakeFileSystemOperations(); const fileOperations = new FileOperations( new Logger(), @@ -124,7 +138,7 @@ describe("File operations", () => { ); }); - test("should deconflict renames with paths", async () => { + it("should deconflict renames with paths", async () => { const fs = new FakeFileSystemOperations(); const fileOperations = new FileOperations( new Logger(),