@prism-engineer/router
Version:
Type-safe Express.js router with automatic client generation
189 lines • 10.6 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const vitest_1 = require("vitest");
const router_1 = require("../../router");
const path_1 = __importDefault(require("path"));
(0, vitest_1.describe)('Router System - Error Handling', () => {
let router;
(0, vitest_1.beforeEach)(() => {
router = (0, router_1.createRouter)();
vitest_1.vi.clearAllMocks();
});
(0, vitest_1.it)('should handle non-existent directory paths', async () => {
const nonExistentPath = path_1.default.join(__dirname, 'fixtures/does-not-exist');
await (0, vitest_1.expect)(router.loadRoutes(nonExistentPath, /\.ts$/)).rejects.toThrow();
});
(0, vitest_1.it)('should handle invalid regex patterns gracefully', async () => {
const fixturesPath = path_1.default.join(__dirname, 'fixtures/api');
// Invalid regex patterns should be handled
await (0, vitest_1.expect)(router.loadRoutes(fixturesPath, null)).rejects.toThrow();
await (0, vitest_1.expect)(router.loadRoutes(fixturesPath, undefined)).rejects.toThrow();
});
(0, vitest_1.it)('should handle empty directory paths', async () => {
await (0, vitest_1.expect)(router.loadRoutes('', /\.ts$/)).rejects.toThrow();
await (0, vitest_1.expect)(router.loadRoutes(' ', /\.ts$/)).rejects.toThrow();
});
(0, vitest_1.it)('should handle malformed route files without crashing', async () => {
const fixturesPath = path_1.default.join(__dirname, 'fixtures');
// Should handle malformed files gracefully
await (0, vitest_1.expect)(router.loadRoutes(fixturesPath, /malformed\.ts$/)).resolves.not.toThrow();
});
(0, vitest_1.it)('should handle files with invalid exports', async () => {
const fixturesPath = path_1.default.join(__dirname, 'fixtures');
// Malformed file has invalid route exports
await router.loadRoutes(fixturesPath, /malformed\.ts$/);
(0, vitest_1.expect)(router.app).toBeDefined();
});
(0, vitest_1.it)('should handle route files with missing required properties', async () => {
const fixturesPath = path_1.default.join(__dirname, 'fixtures');
// Should handle routes missing path, method, or handler
await router.loadRoutes(fixturesPath, /malformed\.ts$/);
(0, vitest_1.expect)(router.app).toBeDefined();
});
(0, vitest_1.it)('should handle TypeScript compilation errors gracefully', async () => {
const fixturesPath = path_1.default.join(__dirname, 'fixtures');
// Should handle files that might have TS compilation issues
await (0, vitest_1.expect)(router.loadRoutes(fixturesPath, /\.ts$/)).resolves.not.toThrow();
});
(0, vitest_1.it)('should handle circular dependency issues', async () => {
const fixturesPath = path_1.default.join(__dirname, 'fixtures/api');
// Should handle potential circular dependencies in route files
await router.loadRoutes(fixturesPath, /\.ts$/);
(0, vitest_1.expect)(router.app).toBeDefined();
});
(0, vitest_1.it)('should handle extremely long file paths', async () => {
const longPath = path_1.default.join(__dirname, 'fixtures', 'a'.repeat(100));
// Should handle paths that might exceed system limits
await (0, vitest_1.expect)(router.loadRoutes(longPath, /\.ts$/)).rejects.toThrow();
});
(0, vitest_1.it)('should handle special characters in directory paths', async () => {
const specialPath = path_1.default.join(__dirname, 'fixtures with spaces & symbols!');
// Should handle paths with special characters
await (0, vitest_1.expect)(router.loadRoutes(specialPath, /\.ts$/)).rejects.toThrow();
});
(0, vitest_1.it)('should handle concurrent loading errors', async () => {
const validPath = path_1.default.join(__dirname, 'fixtures/api');
const invalidPath = path_1.default.join(__dirname, 'fixtures/nonexistent');
const promises = [
router.loadRoutes(validPath, /\.ts$/),
router.loadRoutes(invalidPath, /\.ts$/)
];
// One should succeed, one should fail
const results = await Promise.allSettled(promises);
(0, vitest_1.expect)(results[0].status).toBe('fulfilled');
(0, vitest_1.expect)(results[1].status).toBe('rejected');
});
(0, vitest_1.it)('should handle route registration errors', async () => {
const fixturesPath = path_1.default.join(__dirname, 'fixtures');
// Should handle files that export non-route objects
await router.loadRoutes(fixturesPath, /malformed\.ts$/);
(0, vitest_1.expect)(router.app).toBeDefined();
});
(0, vitest_1.it)('should handle memory errors with large route sets', async () => {
const fixturesPath = path_1.default.join(__dirname, 'fixtures/api');
// Load routes multiple times to test memory handling
for (let i = 0; i < 10; i++) {
await router.loadRoutes(fixturesPath, /\.ts$/);
}
(0, vitest_1.expect)(router.app).toBeDefined();
});
(0, vitest_1.it)('should handle regex denial of service patterns', async () => {
const fixturesPath = path_1.default.join(__dirname, 'fixtures/api');
// Complex regex that could cause ReDoS
const complexRegex = /^(a+)+$/;
await (0, vitest_1.expect)(router.loadRoutes(fixturesPath, complexRegex)).resolves.not.toThrow();
});
(0, vitest_1.it)('should handle file system race conditions', async () => {
const fixturesPath = path_1.default.join(__dirname, 'fixtures/api');
// Multiple concurrent operations on same directory
const promises = Array(5).fill(null).map(() => router.loadRoutes(fixturesPath, /\.ts$/));
await (0, vitest_1.expect)(Promise.all(promises)).resolves.not.toThrow();
});
(0, vitest_1.it)('should handle symbolic link loops', async () => {
const fixturesPath = path_1.default.join(__dirname, 'fixtures/api');
// Should handle potential symbolic link loops gracefully
await router.loadRoutes(fixturesPath, /\.ts$/);
(0, vitest_1.expect)(router.app).toBeDefined();
});
(0, vitest_1.it)('should handle network file system errors', async () => {
const fixturesPath = path_1.default.join(__dirname, 'fixtures/api');
// Should handle potential network FS issues
await router.loadRoutes(fixturesPath, /\.ts$/);
(0, vitest_1.expect)(router.app).toBeDefined();
});
(0, vitest_1.it)('should handle route handler execution errors', async () => {
const fixturesPath = path_1.default.join(__dirname, 'fixtures/api');
// Routes should load even if handlers might throw at runtime
await router.loadRoutes(fixturesPath, /\.ts$/);
(0, vitest_1.expect)(router.app).toBeDefined();
});
(0, vitest_1.it)('should handle invalid TypeBox schema errors', async () => {
const fixturesPath = path_1.default.join(__dirname, 'fixtures/api');
// Should handle routes with potentially invalid schemas
await router.loadRoutes(fixturesPath, /\.ts$/);
(0, vitest_1.expect)(router.app).toBeDefined();
});
(0, vitest_1.it)('should handle missing dependencies gracefully', async () => {
const fixturesPath = path_1.default.join(__dirname, 'fixtures/api');
// Should handle files that import missing dependencies
await router.loadRoutes(fixturesPath, /\.ts$/);
(0, vitest_1.expect)(router.app).toBeDefined();
});
(0, vitest_1.it)('should handle Express app initialization errors', async () => {
// Test router behavior when Express might have issues
(0, vitest_1.expect)(router.app).toBeDefined();
(0, vitest_1.expect)(typeof router.registerRoute).toBe('function');
});
(0, vitest_1.it)('should handle route path conflicts', async () => {
const v1Path = path_1.default.join(__dirname, 'fixtures/api/v1');
const v2Path = path_1.default.join(__dirname, 'fixtures/api/v2');
// Both have posts.ts - should handle potential conflicts
await router.loadRoutes(v1Path, /posts\.ts$/);
await router.loadRoutes(v2Path, /posts\.ts$/);
(0, vitest_1.expect)(router.app).toBeDefined();
});
(0, vitest_1.it)('should handle middleware registration errors', async () => {
const fixturesPath = path_1.default.join(__dirname, 'fixtures/api');
// Routes with auth middleware should handle registration errors
await router.loadRoutes(fixturesPath, /users\.ts$/);
(0, vitest_1.expect)(router.app).toBeDefined();
});
(0, vitest_1.it)('should handle route parameter validation errors', async () => {
const fixturesPath = path_1.default.join(__dirname, 'fixtures/api');
// Routes with parameters should handle validation errors
await router.loadRoutes(fixturesPath, /users\.ts$/);
(0, vitest_1.expect)(router.app).toBeDefined();
});
(0, vitest_1.it)('should handle stack overflow from recursive operations', async () => {
const fixturesPath = path_1.default.join(__dirname, 'fixtures');
// Should handle deeply nested operations without stack overflow
await router.loadRoutes(fixturesPath, /\.ts$/);
(0, vitest_1.expect)(router.app).toBeDefined();
});
(0, vitest_1.it)('should handle timeout errors for slow operations', async () => {
const fixturesPath = path_1.default.join(__dirname, 'fixtures/api');
const startTime = Date.now();
await router.loadRoutes(fixturesPath, /\.ts$/);
const endTime = Date.now();
// Should complete within reasonable time
(0, vitest_1.expect)(endTime - startTime).toBeLessThan(5000);
});
(0, vitest_1.it)('should handle cleanup after errors', async () => {
const validPath = path_1.default.join(__dirname, 'fixtures/api');
const invalidPath = path_1.default.join(__dirname, 'fixtures/nonexistent');
// After an error, router should still be functional
try {
await router.loadRoutes(invalidPath, /\.ts$/);
}
catch {
// Expected to fail
}
// Should still work after error
await router.loadRoutes(validPath, /\.ts$/);
(0, vitest_1.expect)(router.app).toBeDefined();
});
});
//# sourceMappingURL=error-handling.test.js.map