@mdfriday/foundry
Version:
The core engine of MDFriday. Convert Markdown and shortcodes into fully themed static sites – Hugo-style, powered by TypeScript.
279 lines • 13 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
const basefs_1 = require("../entity/basefs");
const path = __importStar(require("path"));
// Mock dependencies
jest.mock('../vo/filemeta');
jest.mock('../vo/fileinfo');
jest.mock('../vo/file');
jest.mock('../vo/dir');
jest.mock('@pkg/log');
describe('BaseFs Entity', () => {
let mockFs;
let baseFs;
let roots;
beforeEach(() => {
roots = ['/root1', '/root2'];
mockFs = {
create: jest.fn(),
mkdir: jest.fn(),
mkdirAll: jest.fn(),
open: jest.fn(),
openFile: jest.fn(),
remove: jest.fn(),
removeAll: jest.fn(),
rename: jest.fn(),
stat: jest.fn(),
name: jest.fn().mockReturnValue('MockFs'),
chmod: jest.fn(),
chown: jest.fn(),
chtimes: jest.fn(),
};
baseFs = new basefs_1.BaseFs(mockFs, roots);
});
afterEach(() => {
jest.clearAllMocks();
});
describe('constructor', () => {
it('should initialize with filesystem and roots', () => {
expect(baseFs.fs).toBe(mockFs);
expect(baseFs.roots).toBe(roots);
});
});
describe('toAbsolutePath', () => {
it('should return name when no roots are provided', () => {
const emptyRootsFs = new basefs_1.BaseFs(mockFs, []);
const result = emptyRootsFs.toAbsolutePath('test.txt');
expect(result).toBe('test.txt');
});
it('should return root when name is empty', () => {
const result = baseFs.toAbsolutePath('');
expect(result).toBe('/root1');
});
it('should join root with relative path', () => {
const result = baseFs.toAbsolutePath('test.txt');
expect(result).toBe(path.join('/root1', 'test.txt'));
});
it('should return absolute path when it starts with root', () => {
const absPath = '/root1/test.txt';
const result = baseFs.toAbsolutePath(absPath);
expect(result).toBe(absPath);
});
it('should treat absolute path as relative when it does not start with root', () => {
const result = baseFs.toAbsolutePath('/other/test.txt');
expect(result).toBe(path.join('/root1', 'other/test.txt'));
});
});
describe('getRoot', () => {
it('should return matching root for given name', () => {
const result = baseFs.getRoot('/root2/test.txt');
expect(result).toBe('/root2');
});
it('should return first matching root', () => {
const result = baseFs.getRoot('/root1/test.txt');
expect(result).toBe('/root1');
});
it('should return empty string when no root matches', () => {
const result = baseFs.getRoot('/other/test.txt');
expect(result).toBe('');
});
});
describe('stat', () => {
it('should stat file and return FileInfo with metadata', async () => {
const mockFileInfo = {
isDir: jest.fn().mockReturnValue(false),
name: jest.fn().mockReturnValue('test.txt'),
size: jest.fn().mockReturnValue(100),
mode: jest.fn().mockReturnValue(0o644),
modTime: jest.fn().mockReturnValue(new Date()),
sys: jest.fn().mockReturnValue(null),
};
const mockWrappedFileInfo = {
meta: jest.fn().mockReturnValue({
setOpenFunc: jest.fn(),
setComponentRoot: jest.fn(),
}),
};
mockFs.stat.mockResolvedValue(mockFileInfo);
const { newFileInfo } = require('../vo/fileinfo');
newFileInfo.mockReturnValue(mockWrappedFileInfo);
const result = await baseFs.stat('test.txt');
expect(mockFs.stat).toHaveBeenCalledWith(path.join('/root1', 'test.txt'));
expect(newFileInfo).toHaveBeenCalledWith(mockFileInfo, path.join('/root1', 'test.txt'));
expect(mockWrappedFileInfo.meta().setComponentRoot).toHaveBeenCalledWith('/root1');
expect(mockWrappedFileInfo.meta().setOpenFunc).toHaveBeenCalled();
expect(result).toBe(mockWrappedFileInfo);
});
it('should stat directory and return FileInfo with directory opener', async () => {
const mockFileInfo = {
isDir: jest.fn().mockReturnValue(true),
name: jest.fn().mockReturnValue('testdir'),
size: jest.fn().mockReturnValue(0),
mode: jest.fn().mockReturnValue(0o755),
modTime: jest.fn().mockReturnValue(new Date()),
sys: jest.fn().mockReturnValue(null),
};
const mockWrappedFileInfo = {
meta: jest.fn().mockReturnValue({
setOpenFunc: jest.fn(),
}),
};
mockFs.stat.mockResolvedValue(mockFileInfo);
const { newFileInfo } = require('../vo/fileinfo');
newFileInfo.mockReturnValue(mockWrappedFileInfo);
const result = await baseFs.stat('testdir');
expect(mockFs.stat).toHaveBeenCalledWith(path.join('/root1', 'testdir'));
expect(newFileInfo).toHaveBeenCalledWith(mockFileInfo, path.join('/root1', 'testdir'));
expect(mockWrappedFileInfo.meta().setOpenFunc).toHaveBeenCalled();
expect(result).toBe(mockWrappedFileInfo);
});
it('should propagate errors from underlying filesystem', async () => {
const error = new Error('File not found');
mockFs.stat.mockRejectedValue(error);
await expect(baseFs.stat('nonexistent.txt')).rejects.toThrow(error);
});
});
describe('open', () => {
it('should open file when it is not a directory', async () => {
const mockFileInfo = {
isDir: jest.fn().mockReturnValue(false),
name: jest.fn().mockReturnValue('test.txt'),
size: jest.fn().mockReturnValue(100),
mode: jest.fn().mockReturnValue(0o644),
modTime: jest.fn().mockReturnValue(new Date()),
sys: jest.fn().mockReturnValue(null),
};
const mockFile = {};
mockFs.stat.mockResolvedValue(mockFileInfo);
mockFs.open.mockResolvedValue(mockFile);
const mockWrappedFile = {};
const { newFileWithMeta } = require('../vo/file');
const { newFileMeta } = require('../vo/filemeta');
newFileMeta.mockReturnValue({ setComponentRoot: jest.fn() });
newFileWithMeta.mockReturnValue(mockWrappedFile);
const result = await baseFs.open('test.txt');
expect(mockFs.stat).toHaveBeenCalledWith(path.join('/root1', 'test.txt'));
expect(result).toBe(mockWrappedFile);
});
it('should open directory when it is a directory', async () => {
const mockFileInfo = {
isDir: jest.fn().mockReturnValue(true),
name: jest.fn().mockReturnValue('testdir'),
size: jest.fn().mockReturnValue(0),
mode: jest.fn().mockReturnValue(0o755),
modTime: jest.fn().mockReturnValue(new Date()),
sys: jest.fn().mockReturnValue(null),
};
const mockFile = {};
mockFs.stat.mockResolvedValue(mockFileInfo);
mockFs.open.mockResolvedValue(mockFile);
const mockDirFile = {};
const { newDirFile } = require('../vo/dir');
const { newFileMeta } = require('../vo/filemeta');
newFileMeta.mockReturnValue({ setComponentRoot: jest.fn() });
newDirFile.mockReturnValue(mockDirFile);
const result = await baseFs.open('testdir');
expect(mockFs.stat).toHaveBeenCalledWith(path.join('/root1', 'testdir'));
expect(result).toBe(mockDirFile);
});
});
describe('filesystem delegation methods', () => {
it('should delegate create with absolute path', async () => {
const mockFile = {};
mockFs.create.mockResolvedValue(mockFile);
const result = await baseFs.create('test.txt');
expect(mockFs.create).toHaveBeenCalledWith(path.join('/root1', 'test.txt'));
expect(result).toBe(mockFile);
});
it('should delegate mkdir with absolute path', async () => {
await baseFs.mkdir('testdir', 0o755);
expect(mockFs.mkdir).toHaveBeenCalledWith(path.join('/root1', 'testdir'), 0o755);
});
it('should delegate mkdirAll with absolute path', async () => {
await baseFs.mkdirAll('test/deep/dir', 0o755);
expect(mockFs.mkdirAll).toHaveBeenCalledWith(path.join('/root1', 'test/deep/dir'), 0o755);
});
it('should delegate openFile with absolute path', async () => {
const mockFile = {};
mockFs.openFile.mockResolvedValue(mockFile);
const result = await baseFs.openFile('test.txt', 1, 0o644);
expect(mockFs.openFile).toHaveBeenCalledWith(path.join('/root1', 'test.txt'), 1, 0o644);
expect(result).toBe(mockFile);
});
it('should delegate remove with absolute path', async () => {
await baseFs.remove('test.txt');
expect(mockFs.remove).toHaveBeenCalledWith(path.join('/root1', 'test.txt'));
});
it('should delegate removeAll with absolute path', async () => {
await baseFs.removeAll('testdir');
expect(mockFs.removeAll).toHaveBeenCalledWith(path.join('/root1', 'testdir'));
});
it('should delegate rename with absolute paths', async () => {
await baseFs.rename('old.txt', 'new.txt');
expect(mockFs.rename).toHaveBeenCalledWith(path.join('/root1', 'old.txt'), path.join('/root1', 'new.txt'));
});
it('should delegate chmod with absolute path', async () => {
await baseFs.chmod('test.txt', 0o644);
expect(mockFs.chmod).toHaveBeenCalledWith(path.join('/root1', 'test.txt'), 0o644);
});
it('should delegate chown with absolute path', async () => {
await baseFs.chown('test.txt', 1000, 1000);
expect(mockFs.chown).toHaveBeenCalledWith(path.join('/root1', 'test.txt'), 1000, 1000);
});
it('should delegate chtimes with absolute path', async () => {
const atime = new Date('2023-01-01');
const mtime = new Date('2023-01-02');
await baseFs.chtimes('test.txt', atime, mtime);
expect(mockFs.chtimes).toHaveBeenCalledWith(path.join('/root1', 'test.txt'), atime, mtime);
});
});
describe('name', () => {
it('should return name with underlying filesystem name', () => {
const result = baseFs.name();
expect(result).toBe('BaseFs(MockFs)');
expect(mockFs.name).toHaveBeenCalledTimes(1);
});
});
describe('newBaseFs factory function', () => {
it('should create new BaseFs instance', () => {
const result = (0, basefs_1.newBaseFs)(mockFs, roots);
expect(result).toBeInstanceOf(basefs_1.BaseFs);
expect(result.fs).toBe(mockFs);
expect(result.roots).toBe(roots);
});
});
});
//# sourceMappingURL=entity-basefs.test.js.map