mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-16 00:22:34 +00:00
Adds defensive escaping for exclamation marks in case delayed expansion is enabled in the user's cmd.exe environment.
85 lines
3.2 KiB
TypeScript
85 lines
3.2 KiB
TypeScript
import { describe, it, expect, beforeEach, afterEach } from 'bun:test';
|
|
|
|
// We need to mock process.platform for cross-platform testing
|
|
const originalPlatform = process.platform;
|
|
|
|
describe('escapeShellArg', () => {
|
|
describe('Unix (non-Windows)', () => {
|
|
beforeEach(() => {
|
|
Object.defineProperty(process, 'platform', { value: 'linux' });
|
|
});
|
|
afterEach(() => {
|
|
Object.defineProperty(process, 'platform', { value: originalPlatform });
|
|
});
|
|
|
|
it('wraps argument in double quotes', async () => {
|
|
const { escapeShellArg } = await import('../../../src/utils/shell-executor');
|
|
expect(escapeShellArg('arg')).toBe('"arg"');
|
|
});
|
|
|
|
it('escapes inner double quotes with backslash', async () => {
|
|
const { escapeShellArg } = await import('../../../src/utils/shell-executor');
|
|
expect(escapeShellArg('say "hello"')).toBe('"say \\"hello\\""');
|
|
});
|
|
|
|
it('handles paths with spaces', async () => {
|
|
const { escapeShellArg } = await import('../../../src/utils/shell-executor');
|
|
expect(escapeShellArg('/path/to/my file')).toBe('"/path/to/my file"');
|
|
});
|
|
|
|
it('handles empty string', async () => {
|
|
const { escapeShellArg } = await import('../../../src/utils/shell-executor');
|
|
expect(escapeShellArg('')).toBe('""');
|
|
});
|
|
});
|
|
|
|
describe('Windows (cmd.exe)', () => {
|
|
beforeEach(() => {
|
|
Object.defineProperty(process, 'platform', { value: 'win32' });
|
|
});
|
|
afterEach(() => {
|
|
Object.defineProperty(process, 'platform', { value: originalPlatform });
|
|
});
|
|
|
|
it('wraps argument in double quotes', async () => {
|
|
const { escapeShellArg } = await import('../../../src/utils/shell-executor');
|
|
expect(escapeShellArg('arg')).toBe('"arg"');
|
|
});
|
|
|
|
it('escapes inner double quotes by doubling them', async () => {
|
|
const { escapeShellArg } = await import('../../../src/utils/shell-executor');
|
|
expect(escapeShellArg('say "hello"')).toBe('"say ""hello"""');
|
|
});
|
|
|
|
it('escapes percent signs', async () => {
|
|
const { escapeShellArg } = await import('../../../src/utils/shell-executor');
|
|
expect(escapeShellArg('%PATH%')).toBe('"%%PATH%%"');
|
|
});
|
|
|
|
it('escapes caret characters', async () => {
|
|
const { escapeShellArg } = await import('../../../src/utils/shell-executor');
|
|
expect(escapeShellArg('a^b')).toBe('"a^^b"');
|
|
});
|
|
|
|
it('replaces newlines with spaces', async () => {
|
|
const { escapeShellArg } = await import('../../../src/utils/shell-executor');
|
|
expect(escapeShellArg('line1\nline2')).toBe('"line1 line2"');
|
|
});
|
|
|
|
it('replaces tabs with spaces', async () => {
|
|
const { escapeShellArg } = await import('../../../src/utils/shell-executor');
|
|
expect(escapeShellArg('col1\tcol2')).toBe('"col1 col2"');
|
|
});
|
|
|
|
it('handles Windows paths with spaces', async () => {
|
|
const { escapeShellArg } = await import('../../../src/utils/shell-executor');
|
|
expect(escapeShellArg('C:\\Program Files\\App')).toBe('"C:\\Program Files\\App"');
|
|
});
|
|
|
|
it('escapes exclamation marks for delayed expansion', async () => {
|
|
const { escapeShellArg } = await import('../../../src/utils/shell-executor');
|
|
expect(escapeShellArg('hello!')).toBe('"hello^^!"');
|
|
});
|
|
});
|
|
});
|