UNPKG

@stillrivercode/agentic-workflow-template

Version:

NPM package to create AI-powered GitHub workflow automation projects

284 lines (234 loc) 9.02 kB
const fs = require('fs-extra'); const path = require('path'); const { findPackageRoot } = require('../create-project'); // Mock fs-extra jest.mock('fs-extra'); describe('findPackageRoot Function', () => { beforeEach(() => { jest.clearAllMocks(); }); describe('when package.json is found in directory tree', () => { it('should find package root in current directory', () => { const testDir = '/test/current'; const packageJsonPath = path.join(testDir, 'package.json'); // Mock fs.existsSync to return true for the package.json and essential files fs.existsSync.mockImplementation((filePath) => { return ( filePath === packageJsonPath || filePath === path.join(testDir, 'cli/') || filePath === path.join(testDir, 'scripts/') || filePath === path.join(testDir, 'package.json') ); }); // Mock fs.readJsonSync to return the correct package fs.readJsonSync.mockReturnValue({ name: '@stillrivercode/agentic-workflow-template', version: '1.0.0', }); const result = findPackageRoot(testDir); expect(result).toBe(testDir); }); it('should find package root in parent directory', () => { const testDir = '/test/current/nested'; const parentDir = '/test/current'; const packageJsonPath = path.join(parentDir, 'package.json'); // Mock fs.existsSync to return true only for parent directory fs.existsSync.mockImplementation((filePath) => { return ( filePath === packageJsonPath || filePath === path.join(parentDir, 'cli/') || filePath === path.join(parentDir, 'scripts/') || filePath === path.join(parentDir, 'package.json') ); }); fs.readJsonSync.mockReturnValue({ name: '@stillrivercode/agentic-workflow-template', version: '1.0.0', }); const result = findPackageRoot(testDir); expect(result).toBe(parentDir); }); it('should skip wrong packages and continue searching', () => { const testDir = '/test/current/nested'; const wrongPackageDir = '/test/current/nested'; const correctPackageDir = '/test/current'; const wrongPackageJsonPath = path.join(wrongPackageDir, 'package.json'); const correctPackageJsonPath = path.join( correctPackageDir, 'package.json' ); fs.existsSync.mockImplementation((filePath) => { return ( filePath === wrongPackageJsonPath || filePath === correctPackageJsonPath ); }); fs.readJsonSync.mockImplementation((filePath) => { if (filePath === wrongPackageJsonPath) { return { name: 'some-other-package', version: '1.0.0' }; } if (filePath === correctPackageJsonPath) { return { name: '@stillrivercode/agentic-workflow-template', version: '1.0.0', }; } }); const result = findPackageRoot(testDir); expect(result).toBe(correctPackageDir); }); it('should skip directories missing essential template files', () => { const testDir = '/test/current/nested'; const incompleteDir = '/test/current/nested'; const completeDir = '/test/current'; const incompletePackageJsonPath = path.join( incompleteDir, 'package.json' ); const completePackageJsonPath = path.join(completeDir, 'package.json'); fs.existsSync.mockImplementation((filePath) => { // Both directories have package.json if ( filePath === incompletePackageJsonPath || filePath === completePackageJsonPath ) { return true; } // Incomplete directory is missing scripts/ if ( filePath === path.join(incompleteDir, 'cli/') || filePath === path.join(incompleteDir, 'package.json') ) { return true; } if (filePath === path.join(incompleteDir, 'scripts/')) { return false; } // Complete directory has all files if ( filePath === path.join(completeDir, 'cli/') || filePath === path.join(completeDir, 'scripts/') || filePath === path.join(completeDir, 'package.json') ) { return true; } return false; }); fs.readJsonSync.mockReturnValue({ name: '@stillrivercode/agentic-workflow-template', version: '1.0.0', }); const result = findPackageRoot(testDir); expect(result).toBe(completeDir); }); it('should handle corrupted package.json files', () => { const testDir = '/test/current'; const packageJsonPath = path.join(testDir, 'package.json'); fs.existsSync.mockImplementation((filePath) => { return filePath === packageJsonPath; }); // Mock readJsonSync to throw an error (corrupted JSON) fs.readJsonSync.mockImplementation(() => { throw new Error('Invalid JSON'); }); // Should fall back to require.resolve behavior jest.doMock( '@stillrivercode/agentic-workflow-template/package.json', () => ({}), { virtual: true } ); const result = findPackageRoot(testDir); // Should return fallback (parent directory) expect(result).toBe(path.join(testDir, '..')); }); }); describe('when package.json is not found in directory tree', () => { it('should handle directory traversal exhaustion gracefully', () => { const testDir = '/some/path'; // Mock fs.existsSync to always return false (no package.json found anywhere) fs.existsSync.mockReturnValue(false); // Mock require.resolve to fail const originalResolve = require.resolve; require.resolve = jest.fn().mockImplementation(() => { throw new Error('Cannot resolve module'); }); const result = findPackageRoot(testDir); // Should fall back to parent directory when all else fails expect(result).toBe(path.join(testDir, '..')); // Restore original require.resolve require.resolve = originalResolve; }); it('should use final fallback when require.resolve fails', () => { const testDir = '/test/current'; // Mock fs.existsSync to return false fs.existsSync.mockReturnValue(false); // Mock require.resolve to throw an error const originalResolve = require.resolve; require.resolve = jest.fn().mockImplementation(() => { throw new Error('Cannot resolve module'); }); const result = findPackageRoot(testDir); expect(result).toBe(path.join(testDir, '..')); // Restore original require.resolve require.resolve = originalResolve; }); }); describe('edge cases', () => { it('should handle reaching filesystem root', () => { const testDir = '/'; fs.existsSync.mockReturnValue(false); // Mock require.resolve to fail const originalResolve = require.resolve; require.resolve = jest.fn().mockImplementation(() => { throw new Error('Cannot resolve module'); }); const result = findPackageRoot(testDir); expect(result).toBe(path.join(testDir, '..')); // Restore original require.resolve require.resolve = originalResolve; }); it('should handle deeply nested directories', () => { const testDir = '/very/deep/nested/directory/structure'; const rootDir = '/very'; const packageJsonPath = path.join(rootDir, 'package.json'); fs.existsSync.mockImplementation((filePath) => { // Package.json exists at root if (filePath === packageJsonPath) return true; // Essential files exist at root if ( filePath === path.join(rootDir, 'cli/') || filePath === path.join(rootDir, 'scripts/') || filePath === path.join(rootDir, 'package.json') ) { return true; } return false; }); fs.readJsonSync.mockReturnValue({ name: '@stillrivercode/agentic-workflow-template', version: '1.0.0', }); const result = findPackageRoot(testDir); expect(result).toBe(rootDir); }); it('should handle absolute paths correctly', () => { const testDir = '/test/current'; const packageJsonPath = path.join(testDir, 'package.json'); fs.existsSync.mockImplementation((filePath) => { // Package.json and essential files exist return ( filePath === packageJsonPath || filePath === path.join(testDir, 'cli/') || filePath === path.join(testDir, 'scripts/') || filePath === path.join(testDir, 'package.json') ); }); fs.readJsonSync.mockReturnValue({ name: '@stillrivercode/agentic-workflow-template', version: '1.0.0', }); const result = findPackageRoot(testDir); expect(result).toBe(testDir); }); }); });