@zenfs/core
Version:
A filesystem, anywhere
94 lines (82 loc) • 3.2 kB
text/typescript
// SPDX-License-Identifier: LGPL-3.0-or-later
import { join } from '@zenfs/core/path';
import type { Exception } from 'kerium';
import assert from 'node:assert/strict';
import { suite, test } from 'node:test';
import { fs } from '../common.js';
suite('Links', () => {
const target = '/a1.js',
symlink = 'symlink1.js',
hardlink = 'link1.js';
test('symlink', async () => {
await fs.promises.symlink(target, symlink);
});
test('lstat', async () => {
const stats = await fs.promises.lstat(symlink);
assert(stats.isSymbolicLink());
});
test('lstat file inside symlinked directory #241', async () => {
await fs.promises.mkdir('/a');
await fs.promises.writeFile('/a/hello.txt', 'hello world');
await fs.promises.symlink('/a', '/b');
const stat = await fs.promises.lstat('/b/hello.txt');
assert(stat.isFile());
});
test('readlink', async () => {
const destination = await fs.promises.readlink(symlink);
assert.equal(destination, target);
assert.throws(() => fs.readlinkSync(destination));
});
test('read target contents', async () => {
assert.equal(await fs.promises.readFile(target, 'utf-8'), await fs.promises.readFile(symlink, 'utf-8'));
});
test('nested symlinks', async () => {
// Create the real directory structure
const realDir = '/real-dir';
const realFile = '/real-dir/realfile.txt';
const fileContent = 'hello world';
await fs.promises.mkdir(realDir);
await fs.promises.writeFile(realFile, fileContent);
// Create first symlink (symlink-dir -> real-dir)
const symlinkDir = '/symlink-dir';
await fs.promises.symlink(realDir, symlinkDir);
const symfile = 'symfile.txt';
const symlinkFile = join(realDir, symfile);
// Create second symlink (symlink-dir -> real-dir)
await fs.promises.symlink(realFile, symlinkFile);
// Now access file through nested symlinks
const nestedPath = join(symlinkDir, symfile);
// Verify realpath resolution
const resolvedPath = await fs.promises.realpath(nestedPath);
assert.equal(resolvedPath, realFile);
// Verify content can be read through nested symlinks
const content = await fs.promises.readFile(nestedPath, 'utf8');
assert.notEqual(content, '/real-dir/realfile.txt');
assert.equal(content, fileContent);
});
test('unlink', async () => {
await fs.promises.unlink(symlink);
assert(!(await fs.promises.exists(symlink)));
assert(await fs.promises.exists(target));
});
test('link', async t => {
const _ = await fs.promises.link(target, hardlink).catch((e: Exception) => {
if (e.code == 'ENOSYS') return e;
throw e;
});
if (_) {
return t.skip('Backend does not support hard links');
}
const targetContent = await fs.promises.readFile(target, 'utf8');
const linkContent = await fs.promises.readFile(hardlink, 'utf8');
assert.equal(targetContent, linkContent);
});
test('file inside symlinked directory', async () => {
await fs.promises.symlink('.', 'link');
const targetContent = await fs.promises.readFile(target, 'utf8');
const link = join('link', target);
assert((await fs.promises.realpath(link)) === target);
const linkContent = await fs.promises.readFile(link, 'utf8');
assert.equal(targetContent, linkContent);
});
});