diff --git a/packages/core/src/storage/FileSystem.ts b/packages/core/src/storage/FileSystem.ts index d08684243f8986cea7e90cb9de27b89bf5a65aba..9b24e932954b51627395339d1e29c9b2484e10f0 100644 --- a/packages/core/src/storage/FileSystem.ts +++ b/packages/core/src/storage/FileSystem.ts @@ -39,9 +39,24 @@ export class InMemoryFileSystem implements GenericFileSystem { } } +export function getNodeFS(): GenericFileSystem { + const fs = require('fs/promises'); + return { + exists: async (path: string) => { + try { + await fs.access(path); + return true; + } catch { + return false; + } + }, + ...fs + } +} + let fs = null; try { - fs = require("fs"); + fs = getNodeFS(); } catch (e) { fs = new InMemoryFileSystem(); } diff --git a/packages/core/src/tests/InMemoryFileSystem.test.ts b/packages/core/src/tests/InMemoryFileSystem.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..ac09d816448810567dc880a3e8997f88dae7a442 --- /dev/null +++ b/packages/core/src/tests/InMemoryFileSystem.test.ts @@ -0,0 +1,90 @@ +import { GenericFileSystem, getNodeFS, InMemoryFileSystem } from "../storage/FileSystem"; +import os from 'os'; +import path from 'path'; + +type FileSystemUnderTest = { + name: string, + prepare: () => Promise<any>, + cleanup: () => Promise<any>, + implementation: GenericFileSystem, + tempDir: string +}; + +const nodeFS = getNodeFS() as GenericFileSystem & any; + +describe.each<FileSystemUnderTest>([ + { + name: 'InMemoryFileSystem', + prepare: async () => {}, + cleanup: async function() { + this.implementation = new InMemoryFileSystem(); + }, + implementation: new InMemoryFileSystem(), + tempDir: './' + }, + { + name: 'Node.js fs', + prepare: async function() { + this.tempDir = await nodeFS.mkdtemp(path.join(os.tmpdir(), 'jest-')); + }, + cleanup: async function() { + await nodeFS.rm(this.tempDir, { recursive: true }); + }, + implementation: nodeFS, + tempDir: './' + } +])("Test %s", (testParams) => { + let testFS: GenericFileSystem; + let tempDir: string; + + beforeEach(async () => { + await testParams.prepare(); + testFS = testParams.implementation; + tempDir = testParams.tempDir; + }); + + afterEach(async () => { + await testParams.cleanup(); + }); + + test("initializes", () => { + expect(testFS).toBeTruthy(); + }); + + describe("writeFile", () => { + it("writes file to memory", async () => { + await testFS.writeFile(`${tempDir}/test.txt`, "Hello, world!"); + expect(await testFS.readFile(`${tempDir}/test.txt`, "utf-8")).toBe("Hello, world!"); + }); + + it("overwrites existing file", async () => { + await testFS.writeFile(`${tempDir}/test.txt`, "Hello, world!"); + await testFS.writeFile(`${tempDir}/test.txt`, "Hello, again!"); + expect(await testFS.readFile(`${tempDir}/test.txt`, "utf-8")).toBe("Hello, again!"); + }); + }); + + describe("readFile", () => { + it("throws error for non-existing file", async () => { + await expect(testFS.readFile(`${tempDir}/not_exist.txt`, "utf-8")).rejects.toThrow(); + }); + }); + + describe("exists", () => { + it("returns true for existing file", async () => { + await testFS.writeFile(`${tempDir}/test.txt`, "Hello, world!"); + expect(await testFS.exists(`${tempDir}/test.txt`)).toBe(true); + }); + + it("returns false for non-existing file", async () => { + expect(await testFS.exists(`${tempDir}/not_exist.txt`)).toBe(false); + }); + }); + + describe("mkdir", () => { + it("creates directory if it doesn't exist", async () => { + await testFS.mkdir(`${tempDir}/testDir`); + expect(await testFS.exists(`${tempDir}/testDir`)).toBe(true); + }); + }); +}); diff --git a/packages/core/test.txt b/packages/core/test.txt new file mode 100644 index 0000000000000000000000000000000000000000..5dd01c177f5d7d1be5346a5bc18a569a7410c2ef --- /dev/null +++ b/packages/core/test.txt @@ -0,0 +1 @@ +Hello, world! \ No newline at end of file