import { describe, it, expect } from 'vitest'; import { createMemFs } from '../mem-fs'; describe('createMemFs', () => { it('writeFile/readFile binary roundtrip (Uint8Array)', async () => { const fs = createMemFs().promises; const data = new Uint8Array([1, 2, 3, 4]); await fs.writeFile('/a.bin', data); const result = await fs.readFile('/a.bin', undefined); expect(result).toBeInstanceOf(Uint8Array); expect(Array.from(result as Uint8Array)).toEqual([1, 2, 3, 4]); }); it('writeFile/readFile utf8 roundtrip via {encoding:"utf8"}', async () => { const fs = createMemFs().promises; await fs.writeFile('/hello.txt', 'hello Relicario'); const result = await fs.readFile('/hello.txt', { encoding: 'utf8' }); expect(result).toBe('hello Relicario'); }); it('writeFile/readFile utf8 roundtrip via string encoding arg', async () => { const fs = createMemFs().promises; await fs.writeFile('/hello2.txt', 'hola Relicario'); const result = await fs.readFile('/hello2.txt', 'utf8'); expect(result).toBe('hola Relicario'); }); it('writeFile copies a subarray view correctly', async () => { const fs = createMemFs().promises; const bigBuf = new Uint8Array([0, 1, 10, 20, 30, 99, 99]); const view = bigBuf.subarray(2, 5); // [10, 20, 30] await fs.writeFile('/sub.bin', view); // Mutate the original buffer — stored copy must be unaffected bigBuf[2] = 0xff; bigBuf[3] = 0xff; bigBuf[4] = 0xff; const result = await fs.readFile('/sub.bin', undefined); expect(Array.from(result as Uint8Array)).toEqual([10, 20, 30]); }); it('readdir returns only immediate children for explicit mkdir dirs', async () => { const fs = createMemFs().promises; await fs.mkdir('/mydir'); await fs.writeFile('/mydir/file1.txt', 'a'); await fs.writeFile('/mydir/file2.txt', 'b'); await fs.mkdir('/mydir/subdir'); const entries = await fs.readdir('/mydir'); expect(entries.sort()).toEqual(['file1.txt', 'file2.txt', 'subdir'].sort()); }); it('readdir returns only immediate children for implicit dirs', async () => { const fs = createMemFs().promises; // Write a deeply nested file without explicit mkdir await fs.writeFile('/a/b/c.txt', 'test'); const aEntries = await fs.readdir('/a'); expect(aEntries).toEqual(['b']); const bEntries = await fs.readdir('/a/b'); expect(bEntries).toEqual(['c.txt']); }); it('stat: a written file isFile()', async () => { const fs = createMemFs().promises; await fs.writeFile('/statfile.txt', 'data'); const st = await fs.stat('/statfile.txt'); expect(st.isFile()).toBe(true); expect(st.isDirectory()).toBe(false); expect(st.isSymbolicLink()).toBe(false); expect(typeof st.size).toBe('number'); expect(typeof st.ino).toBe('number'); expect(typeof st.mode).toBe('number'); }); it('stat: an implicit parent directory isDirectory()', async () => { const fs = createMemFs().promises; await fs.writeFile('/c/items/x.enc', new Uint8Array([9])); const st = await fs.stat('/c/items'); expect(st.isDirectory()).toBe(true); expect(st.isFile()).toBe(false); }); it('stat: missing path throws ENOENT', async () => { const fs = createMemFs().promises; await expect(fs.stat('/does/not/exist')).rejects.toMatchObject({ code: 'ENOENT' }); }); it('unlink removes a file (subsequent readFile throws ENOENT)', async () => { const fs = createMemFs().promises; await fs.writeFile('/todelete.txt', 'bye'); await fs.unlink('/todelete.txt'); await expect(fs.readFile('/todelete.txt', undefined)).rejects.toMatchObject({ code: 'ENOENT' }); }); it('readlink and symlink are functions (regression guard for isomorphic-git bindFs)', () => { const { promises } = createMemFs(); expect(typeof promises.readlink).toBe('function'); expect(typeof promises.symlink).toBe('function'); }); });