Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/services/commands/test/common/commandService.test.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
import assert from 'assert';
6
import { DisposableStore } from '../../../../../base/common/lifecycle.js';
7
import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../base/test/common/utils.js';
8
import { CommandsRegistry } from '../../../../../platform/commands/common/commands.js';
9
import { InstantiationService } from '../../../../../platform/instantiation/common/instantiationService.js';
10
import { NullLogService } from '../../../../../platform/log/common/log.js';
11
import { NullExtensionService } from '../../../extensions/common/extensions.js';
12
import { CommandService } from '../../common/commandService.js';
13
14
suite('CommandService', function () {
15
16
const store = ensureNoDisposablesAreLeakedInTestSuite();
17
18
setup(function () {
19
store.add(CommandsRegistry.registerCommand('foo', function () { }));
20
});
21
22
test('activateOnCommand', () => {
23
24
let lastEvent: string;
25
26
const service = store.add(new CommandService(new InstantiationService(), new class extends NullExtensionService {
27
override activateByEvent(activationEvent: string): Promise<void> {
28
lastEvent = activationEvent;
29
return super.activateByEvent(activationEvent);
30
}
31
}, new NullLogService()));
32
33
return service.executeCommand('foo').then(() => {
34
assert.ok(lastEvent, 'onCommand:foo');
35
return service.executeCommand('unknownCommandId');
36
}).then(() => {
37
assert.ok(false);
38
}, () => {
39
assert.ok(lastEvent, 'onCommand:unknownCommandId');
40
});
41
});
42
43
test('fwd activation error', async function () {
44
45
const extensionService = new class extends NullExtensionService {
46
override activateByEvent(activationEvent: string): Promise<void> {
47
return Promise.reject(new Error('bad_activate'));
48
}
49
};
50
51
const service = store.add(new CommandService(new InstantiationService(), extensionService, new NullLogService()));
52
53
await extensionService.whenInstalledExtensionsRegistered();
54
55
return service.executeCommand('foo').then(() => assert.ok(false), err => {
56
assert.strictEqual(err.message, 'bad_activate');
57
});
58
});
59
60
test('!onReady, but executeCommand', function () {
61
62
let callCounter = 0;
63
const reg = CommandsRegistry.registerCommand('bar', () => callCounter += 1);
64
65
const service = store.add(new CommandService(new InstantiationService(), new class extends NullExtensionService {
66
override whenInstalledExtensionsRegistered() {
67
return new Promise<boolean>(_resolve => { /*ignore*/ });
68
}
69
}, new NullLogService()));
70
71
service.executeCommand('bar');
72
assert.strictEqual(callCounter, 1);
73
reg.dispose();
74
});
75
76
test('issue #34913: !onReady, unknown command', function () {
77
78
let callCounter = 0;
79
let resolveFunc: Function;
80
const whenInstalledExtensionsRegistered = new Promise<boolean>(_resolve => { resolveFunc = _resolve; });
81
82
const service = store.add(new CommandService(new InstantiationService(), new class extends NullExtensionService {
83
override whenInstalledExtensionsRegistered() {
84
return whenInstalledExtensionsRegistered;
85
}
86
}, new NullLogService()));
87
88
const r = service.executeCommand('bar');
89
assert.strictEqual(callCounter, 0);
90
91
const reg = CommandsRegistry.registerCommand('bar', () => callCounter += 1);
92
resolveFunc!(true);
93
94
return r.then(() => {
95
reg.dispose();
96
assert.strictEqual(callCounter, 1);
97
});
98
});
99
100
test('Stop waiting for * extensions to activate when trigger is satisfied #62457', function () {
101
102
let callCounter = 0;
103
const disposable = new DisposableStore();
104
const events: string[] = [];
105
const service = store.add(new CommandService(new InstantiationService(), new class extends NullExtensionService {
106
107
override activateByEvent(event: string): Promise<void> {
108
events.push(event);
109
if (event === '*') {
110
return new Promise(() => { }); //forever promise...
111
}
112
if (event.indexOf('onCommand:') === 0) {
113
return new Promise(resolve => {
114
setTimeout(() => {
115
const reg = CommandsRegistry.registerCommand(event.substr('onCommand:'.length), () => {
116
callCounter += 1;
117
});
118
disposable.add(reg);
119
resolve();
120
}, 0);
121
});
122
}
123
return Promise.resolve();
124
}
125
126
}, new NullLogService()));
127
128
return service.executeCommand('farboo').then(() => {
129
assert.strictEqual(callCounter, 1);
130
assert.deepStrictEqual(events.sort(), ['*', 'onCommand:farboo'].sort());
131
}).finally(() => {
132
disposable.dispose();
133
});
134
});
135
136
test('issue #71471: wait for onCommand activation even if a command is registered', () => {
137
const expectedOrder: string[] = ['registering command', 'resolving activation event', 'executing command'];
138
const actualOrder: string[] = [];
139
const disposables = new DisposableStore();
140
const service = store.add(new CommandService(new InstantiationService(), new class extends NullExtensionService {
141
142
override activateByEvent(event: string): Promise<void> {
143
if (event === '*') {
144
return new Promise(() => { }); //forever promise...
145
}
146
if (event.indexOf('onCommand:') === 0) {
147
return new Promise(resolve => {
148
setTimeout(() => {
149
// Register the command after some time
150
actualOrder.push('registering command');
151
const reg = CommandsRegistry.registerCommand(event.substr('onCommand:'.length), () => {
152
actualOrder.push('executing command');
153
});
154
disposables.add(reg);
155
156
setTimeout(() => {
157
// Resolve the activation event after some more time
158
actualOrder.push('resolving activation event');
159
resolve();
160
}, 10);
161
}, 10);
162
});
163
}
164
return Promise.resolve();
165
}
166
167
}, new NullLogService()));
168
169
return service.executeCommand('farboo2').then(() => {
170
assert.deepStrictEqual(actualOrder, expectedOrder);
171
}).finally(() => {
172
disposables.dispose();
173
});
174
});
175
176
test('issue #142155: execute commands synchronously if possible', async () => {
177
const actualOrder: string[] = [];
178
179
const disposables = new DisposableStore();
180
disposables.add(CommandsRegistry.registerCommand(`bizBaz`, () => {
181
actualOrder.push('executing command');
182
}));
183
const extensionService = new class extends NullExtensionService {
184
override activationEventIsDone(_activationEvent: string): boolean {
185
return true;
186
}
187
};
188
const service = store.add(new CommandService(new InstantiationService(), extensionService, new NullLogService()));
189
190
await extensionService.whenInstalledExtensionsRegistered();
191
192
try {
193
actualOrder.push(`before call`);
194
const promise = service.executeCommand('bizBaz');
195
actualOrder.push(`after call`);
196
await promise;
197
actualOrder.push(`resolved`);
198
assert.deepStrictEqual(actualOrder, [
199
'before call',
200
'executing command',
201
'after call',
202
'resolved'
203
]);
204
} finally {
205
disposables.dispose();
206
}
207
});
208
});
209
210