mirror of
https://github.com/samanhappy/mcphub.git
synced 2025-12-24 10:49:35 -05:00
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: samanhappy <2755122+samanhappy@users.noreply.github.com> Co-authored-by: samanhappy <samanhappy@gmail.com>
132 lines
4.9 KiB
TypeScript
132 lines
4.9 KiB
TypeScript
// Test for CLI path handling functionality
|
|
import path from 'path';
|
|
import { pathToFileURL } from 'url';
|
|
|
|
describe('CLI Path Handling', () => {
|
|
describe('Cross-platform ESM URL conversion', () => {
|
|
it('should convert Unix-style absolute path to file:// URL', () => {
|
|
const unixPath = '/home/user/project/dist/index.js';
|
|
const fileUrl = pathToFileURL(unixPath).href;
|
|
|
|
expect(fileUrl).toMatch(/^file:\/\//);
|
|
expect(fileUrl).toContain('index.js');
|
|
});
|
|
|
|
it('should handle relative paths correctly', () => {
|
|
const relativePath = path.join(process.cwd(), 'dist', 'index.js');
|
|
const fileUrl = pathToFileURL(relativePath).href;
|
|
|
|
expect(fileUrl).toMatch(/^file:\/\//);
|
|
expect(fileUrl).toContain('dist');
|
|
expect(fileUrl).toContain('index.js');
|
|
});
|
|
|
|
it('should produce valid URL format', () => {
|
|
const testPath = path.join(process.cwd(), 'test', 'file.js');
|
|
const fileUrl = pathToFileURL(testPath).href;
|
|
|
|
// Should be a valid URL
|
|
expect(() => new URL(fileUrl)).not.toThrow();
|
|
|
|
// Should start with file://
|
|
expect(fileUrl.startsWith('file://')).toBe(true);
|
|
});
|
|
|
|
it('should handle paths with spaces', () => {
|
|
const pathWithSpaces = path.join(process.cwd(), 'my folder', 'dist', 'index.js');
|
|
const fileUrl = pathToFileURL(pathWithSpaces).href;
|
|
|
|
expect(fileUrl).toMatch(/^file:\/\//);
|
|
expect(fileUrl).toContain('index.js');
|
|
// Spaces should be URL-encoded
|
|
expect(fileUrl).toContain('%20');
|
|
});
|
|
|
|
it('should handle paths with special characters', () => {
|
|
const pathWithSpecialChars = path.join(process.cwd(), 'test@dir', 'file#1.js');
|
|
const fileUrl = pathToFileURL(pathWithSpecialChars).href;
|
|
|
|
expect(fileUrl).toMatch(/^file:\/\//);
|
|
// Special characters should be URL-encoded
|
|
expect(() => new URL(fileUrl)).not.toThrow();
|
|
});
|
|
|
|
// Windows-specific path handling simulation
|
|
it('should handle Windows-style paths correctly', () => {
|
|
// Simulate a Windows path structure
|
|
// Note: On non-Windows systems, this creates a relative path,
|
|
// but the test verifies the conversion mechanism works
|
|
const mockWindowsPath = 'C:\\Users\\User\\project\\dist\\index.js';
|
|
|
|
// On Windows, pathToFileURL would convert C:\ to file:///C:/
|
|
// On Unix, it treats it as a relative path, but the conversion still works
|
|
const fileUrl = pathToFileURL(mockWindowsPath).href;
|
|
|
|
expect(fileUrl).toMatch(/^file:\/\//);
|
|
expect(fileUrl).toContain('index.js');
|
|
});
|
|
});
|
|
|
|
describe('Path normalization', () => {
|
|
it('should normalize path separators', () => {
|
|
const mixedPath = path.join('dist', 'index.js');
|
|
const fileUrl = pathToFileURL(path.resolve(mixedPath)).href;
|
|
|
|
expect(fileUrl).toMatch(/^file:\/\//);
|
|
// All separators should be forward slashes in URL
|
|
expect(fileUrl.split('file://')[1]).not.toContain('\\');
|
|
});
|
|
|
|
it('should handle multiple consecutive slashes', () => {
|
|
const messyPath = path.normalize('/dist//index.js');
|
|
const fileUrl = pathToFileURL(path.resolve(messyPath)).href;
|
|
|
|
expect(fileUrl).toMatch(/^file:\/\//);
|
|
expect(() => new URL(fileUrl)).not.toThrow();
|
|
});
|
|
});
|
|
|
|
describe('Path resolution for CLI use case', () => {
|
|
it('should convert package root path to valid import URL', () => {
|
|
const packageRoot = process.cwd();
|
|
const entryPath = path.join(packageRoot, 'dist', 'index.js');
|
|
const entryUrl = pathToFileURL(entryPath).href;
|
|
|
|
expect(entryUrl).toMatch(/^file:\/\//);
|
|
expect(entryUrl).toContain('dist');
|
|
expect(entryUrl).toContain('index.js');
|
|
expect(() => new URL(entryUrl)).not.toThrow();
|
|
});
|
|
|
|
it('should handle nested directory structures', () => {
|
|
const deepPath = path.join(process.cwd(), 'a', 'b', 'c', 'd', 'file.js');
|
|
const fileUrl = pathToFileURL(deepPath).href;
|
|
|
|
expect(fileUrl).toMatch(/^file:\/\//);
|
|
expect(fileUrl).toContain('file.js');
|
|
expect(() => new URL(fileUrl)).not.toThrow();
|
|
});
|
|
|
|
it('should produce URL compatible with dynamic import()', () => {
|
|
// This test verifies the exact pattern used in bin/cli.js
|
|
const projectRoot = process.cwd();
|
|
const entryPath = path.join(projectRoot, 'dist', 'index.js');
|
|
const entryUrl = pathToFileURL(entryPath).href;
|
|
|
|
// The URL should be valid for import()
|
|
expect(entryUrl).toMatch(/^file:\/\//);
|
|
expect(typeof entryUrl).toBe('string');
|
|
|
|
// Verify the URL format is valid
|
|
const urlObj = new URL(entryUrl);
|
|
expect(urlObj.protocol).toBe('file:');
|
|
expect(urlObj.href).toBe(entryUrl);
|
|
|
|
// On Windows, pathToFileURL converts 'C:\path' to 'file:///C:/path'
|
|
// On Unix, it converts '/path' to 'file:///path'
|
|
// Both formats are valid for dynamic import()
|
|
expect(entryUrl).toContain('index.js');
|
|
});
|
|
});
|
|
});
|