|
4 | 4 | *--------------------------------------------------------------------------------------------*/
|
5 | 5 |
|
6 | 6 | import { Terminal } from 'xterm';
|
7 |
| -import { strictEqual } from 'assert'; |
| 7 | +import { strictEqual, deepStrictEqual } from 'assert'; |
8 | 8 | import { timeout } from 'vs/base/common/async';
|
9 | 9 | import * as sinon from 'sinon';
|
10 |
| -import { ShellIntegrationAddon } from 'vs/platform/terminal/common/xterm/shellIntegrationAddon'; |
| 10 | +import { parseKeyValueAssignment, ShellIntegrationAddon } from 'vs/platform/terminal/common/xterm/shellIntegrationAddon'; |
11 | 11 | import { ITerminalCapabilityStore, TerminalCapability } from 'vs/platform/terminal/common/capabilities/capabilities';
|
12 | 12 | import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
|
13 | 13 | import { ILogService, NullLogService } from 'vs/platform/log/common/log';
|
@@ -58,12 +58,90 @@ suite('ShellIntegrationAddon', () => {
|
58 | 58 | await writeP(xterm, '\x1b]633;P;Cwd=/foo\x07');
|
59 | 59 | strictEqual(capabilities.has(TerminalCapability.CwdDetection), true);
|
60 | 60 | });
|
| 61 | + |
61 | 62 | test('should pass cwd sequence to the capability', async () => {
|
62 | 63 | const mock = shellIntegrationAddon.getCwdDectionMock();
|
63 | 64 | mock.expects('updateCwd').once().withExactArgs('/foo');
|
64 | 65 | await writeP(xterm, '\x1b]633;P;Cwd=/foo\x07');
|
65 | 66 | mock.verify();
|
66 | 67 | });
|
| 68 | + |
| 69 | + test('detect ITerm sequence: `OSC 1337 ; CurrentDir=<Cwd> ST`', async () => { |
| 70 | + type TestCase = [title: string, input: string, expected: string]; |
| 71 | + const cases: TestCase[] = [ |
| 72 | + ['root', '/', '/'], |
| 73 | + ['non-root', '/some/path', '/some/path'], |
| 74 | + ]; |
| 75 | + for (const x of cases) { |
| 76 | + const [title, input, expected] = x; |
| 77 | + const mock = shellIntegrationAddon.getCwdDectionMock(); |
| 78 | + mock.expects('updateCwd').once().withExactArgs(expected).named(title); |
| 79 | + await writeP(xterm, `\x1b]1337;CurrentDir=${input}\x07`); |
| 80 | + mock.verify(); |
| 81 | + } |
| 82 | + }); |
| 83 | + |
| 84 | + suite('detect `SetCwd` sequence: `OSC 7; scheme://cwd ST`', async () => { |
| 85 | + test('should accept well-formatted URLs', async () => { |
| 86 | + type TestCase = [title: string, input: string, expected: string]; |
| 87 | + const cases: TestCase[] = [ |
| 88 | + // Different hostname values: |
| 89 | + ['empty hostname, pointing root', 'file:///', '/'], |
| 90 | + ['empty hostname', 'file:///test-root/local', '/test-root/local'], |
| 91 | + ['non-empty hostname', 'file://some-hostname/test-root/local', '/test-root/local'], |
| 92 | + // URL-encoded chars: |
| 93 | + ['URL-encoded value (1)', 'file:///test-root/%6c%6f%63%61%6c', '/test-root/local'], |
| 94 | + ['URL-encoded value (2)', 'file:///test-root/local%22', '/test-root/local"'], |
| 95 | + ['URL-encoded value (3)', 'file:///test-root/local"', '/test-root/local"'], |
| 96 | + ]; |
| 97 | + for (const x of cases) { |
| 98 | + const [title, input, expected] = x; |
| 99 | + const mock = shellIntegrationAddon.getCwdDectionMock(); |
| 100 | + mock.expects('updateCwd').once().withExactArgs(expected).named(title); |
| 101 | + await writeP(xterm, `\x1b]7;${input}\x07`); |
| 102 | + mock.verify(); |
| 103 | + } |
| 104 | + }); |
| 105 | + |
| 106 | + test('should ignore ill-formatted URLs', async () => { |
| 107 | + type TestCase = [title: string, input: string]; |
| 108 | + const cases: TestCase[] = [ |
| 109 | + // Different hostname values: |
| 110 | + ['no hostname, pointing root', 'file://'], |
| 111 | + // Non-`file` scheme values: |
| 112 | + ['no scheme (1)', '/test-root'], |
| 113 | + ['no scheme (2)', '//test-root'], |
| 114 | + ['no scheme (3)', '///test-root'], |
| 115 | + ['no scheme (4)', ':///test-root'], |
| 116 | + ['http', 'http:///test-root'], |
| 117 | + ['ftp', 'ftp:///test-root'], |
| 118 | + ['ssh', 'ssh:///test-root'], |
| 119 | + ]; |
| 120 | + |
| 121 | + for (const x of cases) { |
| 122 | + const [title, input] = x; |
| 123 | + const mock = shellIntegrationAddon.getCwdDectionMock(); |
| 124 | + mock.expects('updateCwd').never().named(title); |
| 125 | + await writeP(xterm, `\x1b]7;${input}\x07`); |
| 126 | + mock.verify(); |
| 127 | + } |
| 128 | + }); |
| 129 | + }); |
| 130 | + |
| 131 | + test('detect `SetWindowsFrindlyCwd` sequence: `OSC 9 ; 9 ; <cwd> ST`', async () => { |
| 132 | + type TestCase = [title: string, input: string, expected: string]; |
| 133 | + const cases: TestCase[] = [ |
| 134 | + ['root', '/', '/'], |
| 135 | + ['non-root', '/some/path', '/some/path'], |
| 136 | + ]; |
| 137 | + for (const x of cases) { |
| 138 | + const [title, input, expected] = x; |
| 139 | + const mock = shellIntegrationAddon.getCwdDectionMock(); |
| 140 | + mock.expects('updateCwd').once().withExactArgs(expected).named(title); |
| 141 | + await writeP(xterm, `\x1b]9;9;${input}\x07`); |
| 142 | + mock.verify(); |
| 143 | + } |
| 144 | + }); |
67 | 145 | });
|
68 | 146 |
|
69 | 147 | suite('command tracking', async () => {
|
@@ -134,3 +212,23 @@ suite('ShellIntegrationAddon', () => {
|
134 | 212 | });
|
135 | 213 | });
|
136 | 214 | });
|
| 215 | + |
| 216 | +test('parseKeyValueAssignment', () => { |
| 217 | + type TestCase = [title: string, input: string, expected: [key: string, value: string | undefined]]; |
| 218 | + const cases: TestCase[] = [ |
| 219 | + ['empty', '', ['', undefined]], |
| 220 | + ['no "=" sign', 'some-text', ['some-text', undefined]], |
| 221 | + ['empty value', 'key=', ['key', '']], |
| 222 | + ['empty key', '=value', ['', 'value']], |
| 223 | + ['normal', 'key=value', ['key', 'value']], |
| 224 | + ['multiple "=" signs (1)', 'key==value', ['key', '=value']], |
| 225 | + ['multiple "=" signs (2)', 'key=value===true', ['key', 'value===true']], |
| 226 | + ['just a "="', '=', ['', '']], |
| 227 | + ['just a "=="', '==', ['', '=']], |
| 228 | + ]; |
| 229 | + |
| 230 | + cases.forEach(x => { |
| 231 | + const [title, input, [key, value]] = x; |
| 232 | + deepStrictEqual(parseKeyValueAssignment(input), { key, value }, title); |
| 233 | + }); |
| 234 | +}); |
0 commit comments