99 lines
3.9 KiB
TypeScript
99 lines
3.9 KiB
TypeScript
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');
|
|
});
|
|
});
|