-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathbun-shell-path-fix.test.mjs
More file actions
110 lines (95 loc) · 3.84 KB
/
bun-shell-path-fix.test.mjs
File metadata and controls
110 lines (95 loc) · 3.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/**
* Tests for Bun runtime shell path issue fix
*
* This addresses GitHub issue #42: Bun runtime shell path issues
* The issue was that string interpolation in template literals was incorrectly quoting
* complete command strings, causing shell commands to fail execution.
*/
import { test, expect, describe } from 'bun:test';
import { $ } from '../src/$.mjs';
// Test both Bun and Node.js runtimes
const isBun = typeof globalThis.Bun !== 'undefined';
const runtime = isBun ? 'Bun' : 'Node.js';
describe(`String interpolation fix for ${runtime}`, () => {
test('Template literal without interpolation should work', async () => {
const result = await $`echo hello`;
expect(result.stdout.toString().trim()).toBe('hello');
});
test('String interpolation with complete command should work', async () => {
const cmd = 'echo hello';
const result = await $`${cmd}`;
expect(result.stdout.toString().trim()).toBe('hello');
});
test('String interpolation with command and args should work', async () => {
const cmd = 'echo "hello world"';
const result = await $`${cmd}`;
expect(result.stdout.toString().trim()).toBe('hello world');
});
test('Mixed template literal with interpolation should work', async () => {
const arg = 'hello';
const result = await $`echo ${arg}`;
expect(result.stdout.toString().trim()).toBe('hello');
});
test('Complex shell commands via interpolation should work', async () => {
const cmd = 'echo hello | wc -w';
const result = await $`${cmd}`;
expect(result.stdout.toString().trim()).toBe('1');
});
test('Shell operators in interpolated commands should work', async () => {
const cmd = 'test -f /bin/sh && echo "sh exists"';
const result = await $`${cmd}`;
expect(result.stdout.toString().trim()).toBe('sh exists');
});
test('Commands with special characters should work', async () => {
const cmd = 'echo "test $HOME" | head -1';
const result = await $`${cmd}`;
expect(result.stdout.toString()).toContain('test ');
});
test('Multiple argument interpolation should still quote properly', async () => {
const arg1 = 'hello';
const arg2 = 'world with spaces';
const result = await $`echo ${arg1} ${arg2}`;
expect(result.stdout.toString().trim()).toBe('hello world with spaces');
});
test('Empty command string should not cause issues', async () => {
const cmd = '';
// This should not fail catastrophically
try {
await $`${cmd}`;
} catch (error) {
// It's expected to fail, but not with our quoting issue
expect(error.message).not.toContain('not found');
}
});
test('Command with unsafe characters should be handled correctly', async () => {
// This tests that we don't break security when fixing the quoting issue
const unsafeCmd = 'echo "safe"; echo "also safe"';
const result = await $`${unsafeCmd}`;
const lines = result.stdout.toString().trim().split('\n');
expect(lines).toContain('safe');
expect(lines).toContain('also safe');
});
});
// Additional runtime-specific tests
if (isBun) {
describe('Bun-specific shell path tests', () => {
test('Bun.spawn compatibility is maintained', async () => {
const result = await $`pwd`;
expect(result.stdout.toString().trim()).toContain('/');
});
test('Bun runtime detection works correctly', async () => {
// This is more of a meta-test to ensure our runtime detection is correct
expect(typeof globalThis.Bun).toBe('object');
});
});
} else {
describe('Node.js-specific shell path tests', () => {
test('Node.js child_process compatibility is maintained', async () => {
const result = await $`pwd`;
expect(result.stdout.toString().trim()).toContain('/');
});
test('Node.js runtime detection works correctly', async () => {
expect(typeof process.version).toBe('string');
});
});
}