Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/test/common/workbenchTestServices.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
6
import { join } from '../../../base/common/path.js';
7
import { basename, isEqual, isEqualOrParent } from '../../../base/common/resources.js';
8
import { URI } from '../../../base/common/uri.js';
9
import { Event, Emitter } from '../../../base/common/event.js';
10
import { IConfigurationService } from '../../../platform/configuration/common/configuration.js';
11
import { IWorkspaceContextService, IWorkspace, WorkbenchState, IWorkspaceFolder, IWorkspaceFoldersChangeEvent, Workspace, IWorkspaceFoldersWillChangeEvent, ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier } from '../../../platform/workspace/common/workspace.js';
12
import { TestWorkspace } from '../../../platform/workspace/test/common/testWorkspace.js';
13
import { ITextResourcePropertiesService } from '../../../editor/common/services/textResourceConfiguration.js';
14
import { isLinux, isMacintosh } from '../../../base/common/platform.js';
15
import { InMemoryStorageService, WillSaveStateReason } from '../../../platform/storage/common/storage.js';
16
import { IWorkingCopy, IWorkingCopyBackup, WorkingCopyCapabilities } from '../../services/workingCopy/common/workingCopy.js';
17
import { NullExtensionService } from '../../services/extensions/common/extensions.js';
18
import { IWorkingCopyFileService, IWorkingCopyFileOperationParticipant, WorkingCopyFileEvent, IDeleteOperation, ICopyOperation, IMoveOperation, IFileOperationUndoRedoInfo, ICreateFileOperation, ICreateOperation, IStoredFileWorkingCopySaveParticipant, IStoredFileWorkingCopySaveParticipantContext } from '../../services/workingCopy/common/workingCopyFileService.js';
19
import { IDisposable, Disposable } from '../../../base/common/lifecycle.js';
20
import { IBaseFileStat, IFileStatWithMetadata } from '../../../platform/files/common/files.js';
21
import { ISaveOptions, IRevertOptions, SaveReason, GroupIdentifier } from '../../common/editor.js';
22
import { CancellationToken } from '../../../base/common/cancellation.js';
23
import product from '../../../platform/product/common/product.js';
24
import { IActivity, IActivityService } from '../../services/activity/common/activity.js';
25
import { IStoredFileWorkingCopySaveEvent } from '../../services/workingCopy/common/storedFileWorkingCopy.js';
26
import { AbstractLoggerService, ILogger, LogLevel, NullLogger } from '../../../platform/log/common/log.js';
27
import { IResourceEditorInput } from '../../../platform/editor/common/editor.js';
28
import { EditorInput } from '../../common/editor/editorInput.js';
29
import { IHistoryService } from '../../services/history/common/history.js';
30
import { IAutoSaveConfiguration, IAutoSaveMode, IFilesConfigurationService } from '../../services/filesConfiguration/common/filesConfigurationService.js';
31
import { IWorkspaceTrustEnablementService, IWorkspaceTrustManagementService, IWorkspaceTrustRequestService, IWorkspaceTrustTransitionParticipant, IWorkspaceTrustUriInfo, WorkspaceTrustRequestOptions, WorkspaceTrustUriResponse } from '../../../platform/workspace/common/workspaceTrust.js';
32
import { IMarker, IMarkerData, IMarkerService, IResourceMarker, MarkerStatistics } from '../../../platform/markers/common/markers.js';
33
import { IProgress, IProgressStep } from '../../../platform/progress/common/progress.js';
34
import { IUserDataProfileService } from '../../services/userDataProfile/common/userDataProfile.js';
35
import { toUserDataProfile } from '../../../platform/userDataProfile/common/userDataProfile.js';
36
37
export class TestLoggerService extends AbstractLoggerService {
38
constructor(logsHome?: URI) {
39
super(LogLevel.Info, logsHome ?? URI.file('tests').with({ scheme: 'vscode-tests' }));
40
}
41
protected doCreateLogger(): ILogger { return new NullLogger(); }
42
}
43
44
export class TestTextResourcePropertiesService implements ITextResourcePropertiesService {
45
46
declare readonly _serviceBrand: undefined;
47
48
constructor(
49
@IConfigurationService private readonly configurationService: IConfigurationService,
50
) {
51
}
52
53
getEOL(resource: URI, language?: string): string {
54
const eol = this.configurationService.getValue('files.eol', { overrideIdentifier: language, resource });
55
if (eol && typeof eol === 'string' && eol !== 'auto') {
56
return eol;
57
}
58
return (isLinux || isMacintosh) ? '\n' : '\r\n';
59
}
60
}
61
62
export class TestUserDataProfileService implements IUserDataProfileService {
63
64
readonly _serviceBrand: undefined;
65
readonly onDidChangeCurrentProfile = Event.None;
66
readonly currentProfile = toUserDataProfile('test', 'test', URI.file('tests').with({ scheme: 'vscode-tests' }), URI.file('tests').with({ scheme: 'vscode-tests' }));
67
async updateCurrentProfile(): Promise<void> { }
68
}
69
70
export class TestContextService implements IWorkspaceContextService {
71
72
declare readonly _serviceBrand: undefined;
73
74
private workspace: Workspace;
75
private options: object;
76
77
private readonly _onDidChangeWorkspaceName: Emitter<void>;
78
get onDidChangeWorkspaceName(): Event<void> { return this._onDidChangeWorkspaceName.event; }
79
80
private readonly _onWillChangeWorkspaceFolders: Emitter<IWorkspaceFoldersWillChangeEvent>;
81
get onWillChangeWorkspaceFolders(): Event<IWorkspaceFoldersWillChangeEvent> { return this._onWillChangeWorkspaceFolders.event; }
82
83
private readonly _onDidChangeWorkspaceFolders: Emitter<IWorkspaceFoldersChangeEvent>;
84
get onDidChangeWorkspaceFolders(): Event<IWorkspaceFoldersChangeEvent> { return this._onDidChangeWorkspaceFolders.event; }
85
86
private readonly _onDidChangeWorkbenchState: Emitter<WorkbenchState>;
87
get onDidChangeWorkbenchState(): Event<WorkbenchState> { return this._onDidChangeWorkbenchState.event; }
88
89
constructor(workspace = TestWorkspace, options = null) {
90
this.workspace = workspace;
91
this.options = options || Object.create(null);
92
this._onDidChangeWorkspaceName = new Emitter<void>();
93
this._onWillChangeWorkspaceFolders = new Emitter<IWorkspaceFoldersWillChangeEvent>();
94
this._onDidChangeWorkspaceFolders = new Emitter<IWorkspaceFoldersChangeEvent>();
95
this._onDidChangeWorkbenchState = new Emitter<WorkbenchState>();
96
}
97
98
getFolders(): IWorkspaceFolder[] {
99
return this.workspace ? this.workspace.folders : [];
100
}
101
102
getWorkbenchState(): WorkbenchState {
103
if (this.workspace.configuration) {
104
return WorkbenchState.WORKSPACE;
105
}
106
107
if (this.workspace.folders.length) {
108
return WorkbenchState.FOLDER;
109
}
110
111
return WorkbenchState.EMPTY;
112
}
113
114
getCompleteWorkspace(): Promise<IWorkspace> {
115
return Promise.resolve(this.getWorkspace());
116
}
117
118
getWorkspace(): IWorkspace {
119
return this.workspace;
120
}
121
122
getWorkspaceFolder(resource: URI): IWorkspaceFolder | null {
123
return this.workspace.getFolder(resource);
124
}
125
126
setWorkspace(workspace: any): void {
127
this.workspace = workspace;
128
}
129
130
getOptions() {
131
return this.options;
132
}
133
134
updateOptions() { }
135
136
isInsideWorkspace(resource: URI): boolean {
137
if (resource && this.workspace) {
138
return isEqualOrParent(resource, this.workspace.folders[0].uri);
139
}
140
141
return false;
142
}
143
144
toResource(workspaceRelativePath: string): URI {
145
return URI.file(join('C:\\', workspaceRelativePath));
146
}
147
148
isCurrentWorkspace(workspaceIdOrFolder: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | URI): boolean {
149
return URI.isUri(workspaceIdOrFolder) && isEqual(this.workspace.folders[0].uri, workspaceIdOrFolder);
150
}
151
}
152
153
export class TestStorageService extends InMemoryStorageService {
154
155
testEmitWillSaveState(reason: WillSaveStateReason): void {
156
super.emitWillSaveState(reason);
157
}
158
}
159
160
export class TestHistoryService implements IHistoryService {
161
162
declare readonly _serviceBrand: undefined;
163
164
constructor(private root?: URI) { }
165
166
async reopenLastClosedEditor(): Promise<void> { }
167
async goForward(): Promise<void> { }
168
async goBack(): Promise<void> { }
169
async goPrevious(): Promise<void> { }
170
async goLast(): Promise<void> { }
171
removeFromHistory(_input: EditorInput | IResourceEditorInput): void { }
172
clear(): void { }
173
clearRecentlyOpened(): void { }
174
getHistory(): readonly (EditorInput | IResourceEditorInput)[] { return []; }
175
async openNextRecentlyUsedEditor(group?: GroupIdentifier): Promise<void> { }
176
async openPreviouslyUsedEditor(group?: GroupIdentifier): Promise<void> { }
177
getLastActiveWorkspaceRoot(_schemeFilter: string): URI | undefined { return this.root; }
178
getLastActiveFile(_schemeFilter: string): URI | undefined { return undefined; }
179
}
180
181
export class TestWorkingCopy extends Disposable implements IWorkingCopy {
182
183
private readonly _onDidChangeDirty = this._register(new Emitter<void>());
184
readonly onDidChangeDirty = this._onDidChangeDirty.event;
185
186
private readonly _onDidChangeContent = this._register(new Emitter<void>());
187
readonly onDidChangeContent = this._onDidChangeContent.event;
188
189
private readonly _onDidSave = this._register(new Emitter<IStoredFileWorkingCopySaveEvent>());
190
readonly onDidSave = this._onDidSave.event;
191
192
readonly capabilities = WorkingCopyCapabilities.None;
193
194
readonly name;
195
196
private dirty = false;
197
198
constructor(readonly resource: URI, isDirty = false, readonly typeId = 'testWorkingCopyType') {
199
super();
200
201
this.name = basename(this.resource);
202
this.dirty = isDirty;
203
}
204
205
setDirty(dirty: boolean): void {
206
if (this.dirty !== dirty) {
207
this.dirty = dirty;
208
this._onDidChangeDirty.fire();
209
}
210
}
211
212
setContent(content: string): void {
213
this._onDidChangeContent.fire();
214
}
215
216
isDirty(): boolean {
217
return this.dirty;
218
}
219
220
isModified(): boolean {
221
return this.isDirty();
222
}
223
224
async save(options?: ISaveOptions, stat?: IFileStatWithMetadata): Promise<boolean> {
225
this._onDidSave.fire({ reason: options?.reason ?? SaveReason.EXPLICIT, stat: stat ?? createFileStat(this.resource), source: options?.source });
226
227
return true;
228
}
229
230
async revert(options?: IRevertOptions): Promise<void> {
231
this.setDirty(false);
232
}
233
234
async backup(token: CancellationToken): Promise<IWorkingCopyBackup> {
235
return {};
236
}
237
}
238
239
export function createFileStat(resource: URI, readonly = false, isFile?: boolean, isDirectory?: boolean, isSymbolicLink?: boolean, children?: { resource: URI; isFile?: boolean; isDirectory?: boolean; isSymbolicLink?: boolean }[] | undefined): IFileStatWithMetadata {
240
return {
241
resource,
242
etag: Date.now().toString(),
243
mtime: Date.now(),
244
ctime: Date.now(),
245
size: 42,
246
isFile: isFile ?? true,
247
isDirectory: isDirectory ?? false,
248
isSymbolicLink: isSymbolicLink ?? false,
249
readonly,
250
locked: false,
251
name: basename(resource),
252
children: children?.map(c => createFileStat(c.resource, false, c.isFile, c.isDirectory, c.isSymbolicLink)),
253
};
254
}
255
256
export class TestWorkingCopyFileService implements IWorkingCopyFileService {
257
258
declare readonly _serviceBrand: undefined;
259
260
onWillRunWorkingCopyFileOperation: Event<WorkingCopyFileEvent> = Event.None;
261
onDidFailWorkingCopyFileOperation: Event<WorkingCopyFileEvent> = Event.None;
262
onDidRunWorkingCopyFileOperation: Event<WorkingCopyFileEvent> = Event.None;
263
264
addFileOperationParticipant(participant: IWorkingCopyFileOperationParticipant): IDisposable { return Disposable.None; }
265
266
readonly hasSaveParticipants = false;
267
addSaveParticipant(participant: IStoredFileWorkingCopySaveParticipant): IDisposable { return Disposable.None; }
268
async runSaveParticipants(workingCopy: IWorkingCopy, context: IStoredFileWorkingCopySaveParticipantContext, progress: IProgress<IProgressStep>, token: CancellationToken): Promise<void> { }
269
270
async delete(operations: IDeleteOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise<void> { }
271
272
registerWorkingCopyProvider(provider: (resourceOrFolder: URI) => IWorkingCopy[]): IDisposable { return Disposable.None; }
273
274
getDirty(resource: URI): IWorkingCopy[] { return []; }
275
276
create(operations: ICreateFileOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise<IFileStatWithMetadata[]> { throw new Error('Method not implemented.'); }
277
createFolder(operations: ICreateOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise<IFileStatWithMetadata[]> { throw new Error('Method not implemented.'); }
278
279
move(operations: IMoveOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise<IFileStatWithMetadata[]> { throw new Error('Method not implemented.'); }
280
281
copy(operations: ICopyOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise<IFileStatWithMetadata[]> { throw new Error('Method not implemented.'); }
282
}
283
284
export function mock<T>(): Ctor<T> {
285
return function () { } as any;
286
}
287
288
export interface Ctor<T> {
289
new(): T;
290
}
291
292
export class TestExtensionService extends NullExtensionService { }
293
294
export const TestProductService = { _serviceBrand: undefined, ...product };
295
296
export class TestActivityService implements IActivityService {
297
_serviceBrand: undefined;
298
onDidChangeActivity = Event.None;
299
getViewContainerActivities(viewContainerId: string): IActivity[] {
300
return [];
301
}
302
getActivity(id: string): IActivity[] {
303
return [];
304
}
305
showViewContainerActivity(viewContainerId: string, badge: IActivity): IDisposable {
306
return this;
307
}
308
showViewActivity(viewId: string, badge: IActivity): IDisposable {
309
return this;
310
}
311
showAccountsActivity(activity: IActivity): IDisposable {
312
return this;
313
}
314
showGlobalActivity(activity: IActivity): IDisposable {
315
return this;
316
}
317
318
dispose() { }
319
}
320
321
export const NullFilesConfigurationService = new class implements IFilesConfigurationService {
322
323
_serviceBrand: undefined;
324
325
readonly onDidChangeAutoSaveConfiguration = Event.None;
326
readonly onDidChangeAutoSaveDisabled = Event.None;
327
readonly onDidChangeReadonly = Event.None;
328
readonly onDidChangeFilesAssociation = Event.None;
329
330
readonly isHotExitEnabled = false;
331
readonly hotExitConfiguration = undefined;
332
333
getAutoSaveConfiguration(): IAutoSaveConfiguration { throw new Error('Method not implemented.'); }
334
getAutoSaveMode(): IAutoSaveMode { throw new Error('Method not implemented.'); }
335
hasShortAutoSaveDelay(): boolean { throw new Error('Method not implemented.'); }
336
toggleAutoSave(): Promise<void> { throw new Error('Method not implemented.'); }
337
enableAutoSaveAfterShortDelay(resourceOrEditor: URI | EditorInput): IDisposable { throw new Error('Method not implemented.'); }
338
disableAutoSave(resourceOrEditor: URI | EditorInput): IDisposable { throw new Error('Method not implemented.'); }
339
isReadonly(resource: URI, stat?: IBaseFileStat | undefined): boolean { return false; }
340
async updateReadonly(resource: URI, readonly: boolean | 'toggle' | 'reset'): Promise<void> { }
341
preventSaveConflicts(resource: URI, language?: string | undefined): boolean { throw new Error('Method not implemented.'); }
342
};
343
344
export class TestWorkspaceTrustEnablementService implements IWorkspaceTrustEnablementService {
345
_serviceBrand: undefined;
346
347
constructor(private isEnabled: boolean = true) { }
348
349
isWorkspaceTrustEnabled(): boolean {
350
return this.isEnabled;
351
}
352
}
353
354
export class TestWorkspaceTrustManagementService extends Disposable implements IWorkspaceTrustManagementService {
355
_serviceBrand: undefined;
356
357
private _onDidChangeTrust = this._register(new Emitter<boolean>());
358
onDidChangeTrust = this._onDidChangeTrust.event;
359
360
private _onDidChangeTrustedFolders = this._register(new Emitter<void>());
361
onDidChangeTrustedFolders = this._onDidChangeTrustedFolders.event;
362
363
private _onDidInitiateWorkspaceTrustRequestOnStartup = this._register(new Emitter<void>());
364
onDidInitiateWorkspaceTrustRequestOnStartup = this._onDidInitiateWorkspaceTrustRequestOnStartup.event;
365
366
367
constructor(
368
private trusted: boolean = true
369
) {
370
super();
371
}
372
373
get acceptsOutOfWorkspaceFiles(): boolean {
374
throw new Error('Method not implemented.');
375
}
376
377
set acceptsOutOfWorkspaceFiles(value: boolean) {
378
throw new Error('Method not implemented.');
379
}
380
381
addWorkspaceTrustTransitionParticipant(participant: IWorkspaceTrustTransitionParticipant): IDisposable {
382
throw new Error('Method not implemented.');
383
}
384
385
getTrustedUris(): URI[] {
386
throw new Error('Method not implemented.');
387
}
388
389
setParentFolderTrust(trusted: boolean): Promise<void> {
390
throw new Error('Method not implemented.');
391
}
392
393
getUriTrustInfo(uri: URI): Promise<IWorkspaceTrustUriInfo> {
394
throw new Error('Method not implemented.');
395
}
396
397
async setTrustedUris(folders: URI[]): Promise<void> {
398
throw new Error('Method not implemented.');
399
}
400
401
async setUrisTrust(uris: URI[], trusted: boolean): Promise<void> {
402
throw new Error('Method not implemented.');
403
}
404
405
canSetParentFolderTrust(): boolean {
406
throw new Error('Method not implemented.');
407
}
408
409
canSetWorkspaceTrust(): boolean {
410
throw new Error('Method not implemented.');
411
}
412
413
isWorkspaceTrusted(): boolean {
414
return this.trusted;
415
}
416
417
isWorkspaceTrustForced(): boolean {
418
return false;
419
}
420
421
get workspaceTrustInitialized(): Promise<void> {
422
return Promise.resolve();
423
}
424
425
get workspaceResolved(): Promise<void> {
426
return Promise.resolve();
427
}
428
429
async setWorkspaceTrust(trusted: boolean): Promise<void> {
430
if (this.trusted !== trusted) {
431
this.trusted = trusted;
432
this._onDidChangeTrust.fire(this.trusted);
433
}
434
}
435
}
436
437
export class TestWorkspaceTrustRequestService extends Disposable implements IWorkspaceTrustRequestService {
438
_serviceBrand: any;
439
440
private readonly _onDidInitiateOpenFilesTrustRequest = this._register(new Emitter<void>());
441
readonly onDidInitiateOpenFilesTrustRequest = this._onDidInitiateOpenFilesTrustRequest.event;
442
443
private readonly _onDidInitiateWorkspaceTrustRequest = this._register(new Emitter<WorkspaceTrustRequestOptions>());
444
readonly onDidInitiateWorkspaceTrustRequest = this._onDidInitiateWorkspaceTrustRequest.event;
445
446
private readonly _onDidInitiateWorkspaceTrustRequestOnStartup = this._register(new Emitter<void>());
447
readonly onDidInitiateWorkspaceTrustRequestOnStartup = this._onDidInitiateWorkspaceTrustRequestOnStartup.event;
448
449
constructor(private readonly _trusted: boolean) {
450
super();
451
}
452
453
requestOpenUrisHandler = async (uris: URI[]) => {
454
return WorkspaceTrustUriResponse.Open;
455
};
456
457
requestOpenFilesTrust(uris: URI[]): Promise<WorkspaceTrustUriResponse> {
458
return this.requestOpenUrisHandler(uris);
459
}
460
461
async completeOpenFilesTrustRequest(result: WorkspaceTrustUriResponse, saveResponse: boolean): Promise<void> {
462
throw new Error('Method not implemented.');
463
}
464
465
cancelWorkspaceTrustRequest(): void {
466
throw new Error('Method not implemented.');
467
}
468
469
async completeWorkspaceTrustRequest(trusted?: boolean): Promise<void> {
470
throw new Error('Method not implemented.');
471
}
472
473
async requestWorkspaceTrust(options?: WorkspaceTrustRequestOptions): Promise<boolean> {
474
return this._trusted;
475
}
476
477
requestWorkspaceTrustOnStartup(): void {
478
throw new Error('Method not implemented.');
479
}
480
}
481
482
export class TestMarkerService implements IMarkerService {
483
484
_serviceBrand: undefined;
485
486
onMarkerChanged = Event.None;
487
488
getStatistics(): MarkerStatistics { throw new Error('Method not implemented.'); }
489
changeOne(owner: string, resource: URI, markers: IMarkerData[]): void { }
490
changeAll(owner: string, data: IResourceMarker[]): void { }
491
remove(owner: string, resources: URI[]): void { }
492
read(filter?: { owner?: string | undefined; resource?: URI | undefined; severities?: number | undefined; take?: number | undefined } | undefined): IMarker[] { return []; }
493
installResourceFilter(resource: URI, reason: string): IDisposable {
494
return { dispose: () => { /* TODO: Implement cleanup logic */ } };
495
}
496
}
497
498