UNPKG

@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
"use strict"; 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