workbenchTestServices.ts ×76

Frontier kind: Code frontier

unlabeled · c_a673a1563d29

859 tests · 23235 LOC · 122 files · introduces 0 tests · 597 LOC · 2 files

Introduces — evidence that enters the hierarchy at this concept

Code
77 ranges597 lines · 2 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
2649 ranges23235 lines · 122 files · Browse complete extent
All tests (intent)
859 testsBrowse complete intent

Neighbourhood graph

The orange circle is the focus. Violet and green circles are every ancestor and descendant, broader and narrower, at any distance; blue squares and pink diamonds are the introduced files and exact introduced tests of every visible concept, not only the focus's. Arrows point from broader to narrower concepts and bridge only concepts omitted from this view. Undirected links show source or test introduction. Concept and file size follows LOC; exact test nodes use test-count units.

Introduced files, introduced tests, and structurally relevant concept specialization

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the native relationship evidence on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the native relationship evidence on this page while the interactive map is unavailable.

Native relationship evidence

Every exact file and test below is linked only from the concept that introduces it.

Introduced tests

Every collected test enters the hierarchy at exactly one concept.

No tests are introduced at this concept. Its intent tests are introduced by other concepts.

Introduced code

Every collected source range enters the hierarchy at exactly one concept.

2 files ranked by introduced lines: 597 introduced LOC across 77 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/workbench/test/common/workbenchTestServices.ts 376 introduced LOC · 76 ranges

Open complete file

1 > /*--------------------------------------------------------------------------------------------- workbenchTestServices.ts
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 { DeferredPromise, timeout } from '../../../base/common/async.js';
7 > import { bufferToStream, readableToBuffer, VSBuffer, VSBufferReadable } from '../../../base/common/buffer.js';
8 > import { CancellationToken } from '../../../base/common/cancellation.js';
9 > import { Emitter, Event } from '../../../base/common/event.js';
10 > import { Iterable } from '../../../base/common/iterator.js';
11 > import { Disposable, IDisposable, toDisposable } from '../../../base/common/lifecycle.js';
12 > import { ResourceMap, ResourceSet } from '../../../base/common/map.js';
13 > import { Schemas } from '../../../base/common/network.js';
14 > import { observableValue } from '../../../base/common/observable.js';
15 > import { join } from '../../../base/common/path.js';
16 > import { isLinux, isMacintosh } from '../../../base/common/platform.js';
17 > import { basename, isEqual, isEqualOrParent } from '../../../base/common/resources.js';
18 > import { URI } from '../../../base/common/uri.js';
19 > import { ITextResourcePropertiesService } from '../../../editor/common/services/textResourceConfiguration.js';
20 > import { IConfigurationService } from '../../../platform/configuration/common/configuration.js';
21 > import { IResourceEditorInput } from '../../../platform/editor/common/editor.js';
22 > import { FileChangesEvent, FileOperationEvent, FileSystemProviderCapabilities, IBaseFileStat, ICreateFileOptions, IFileContent, IFileService, IFileStat, IFileStatResult, IFileStatWithMetadata, IFileStatWithPartialMetadata, IFileStreamContent, IFileSystemProvider, IFileSystemProviderActivationEvent, IFileSystemProviderCapabilitiesChangeEvent, IFileSystemWatcher, IReadFileOptions, IReadFileStreamOptions, IResolveFileOptions, IResolveMetadataFileOptions, IWatchOptions, IWatchOptionsWithCorrelation, IWriteFileOptions } from '../../../platform/files/common/files.js';
23 > import { AbstractLoggerService, ILogger, LogLevel, NullLogger } from '../../../platform/log/common/log.js';
24 > import { IMarker, IMarkerData, IMarkerService, IResourceMarker, MarkerStatistics } from '../../../platform/markers/common/markers.js';
25 > import product from '../../../platform/product/common/product.js';
26 > import { IProgress, IProgressStep } from '../../../platform/progress/common/progress.js';
27 > import { InMemoryStorageService, WillSaveStateReason } from '../../../platform/storage/common/storage.js';
28 > import { toUserDataProfile } from '../../../platform/userDataProfile/common/userDataProfile.js';
29 > import { ISingleFolderWorkspaceIdentifier, IWorkspace, IWorkspaceContextService, IWorkspaceFolder, IWorkspaceFoldersChangeEvent, IWorkspaceFoldersWillChangeEvent, IWorkspaceIdentifier, WorkbenchState, Workspace } from '../../../platform/workspace/common/workspace.js';
30 > import { IWorkspaceTrustEnablementService, IWorkspaceTrustManagementService, IWorkspaceTrustRequestService, IWorkspaceTrustTransitionParticipant, IWorkspaceTrustUriInfo, ResourceTrustRequestOptions, WorkspaceTrustRequestOptions, WorkspaceTrustUriResponse } from '../../../platform/workspace/common/workspaceTrust.js';
31 > import { TestWorkspace } from '../../../platform/workspace/test/common/testWorkspace.js';
32 > import { GroupIdentifier, IRevertOptions, ISaveOptions, SaveReason } from '../../common/editor.js';
33 > import { EditorInput } from '../../common/editor/editorInput.js';
34 > import { IActivity, IActivityService } from '../../services/activity/common/activity.js';
35 > import { ChatEntitlement, ChatEntitlementContext, IChatEntitlementService } from '../../services/chat/common/chatEntitlementService.js';
36 > import { Lazy } from '../../../base/common/lazy.js';
37 > import { NullExtensionService } from '../../services/extensions/common/extensions.js';
38 > import { IAutoSaveConfiguration, IAutoSaveMode, IFilesConfigurationService } from '../../services/filesConfiguration/common/filesConfigurationService.js';
39 > import { IHistoryService } from '../../services/history/common/history.js';
40 > import { BeforeShutdownErrorEvent, ILifecycleService, InternalBeforeShutdownEvent, LifecyclePhase, ShutdownReason, StartupKind, WillShutdownEvent } from '../../services/lifecycle/common/lifecycle.js';
41 > import { IResourceEncoding } from '../../services/textfile/common/textfiles.js';
42 > import { IUserDataProfileService } from '../../services/userDataProfile/common/userDataProfile.js';
43 > import { IStoredFileWorkingCopySaveEvent } from '../../services/workingCopy/common/storedFileWorkingCopy.js';
44 > import { IWorkingCopy, IWorkingCopyBackup, WorkingCopyCapabilities } from '../../services/workingCopy/common/workingCopy.js';
45 > import { ICopyOperation, ICreateFileOperation, ICreateOperation, IDeleteOperation, IFileOperationUndoRedoInfo, IMoveOperation, IStoredFileWorkingCopySaveParticipant, IStoredFileWorkingCopySaveParticipantContext, IWorkingCopyFileOperationParticipant, IWorkingCopyFileService, WorkingCopyFileEvent } from '../../services/workingCopy/common/workingCopyFileService.js';
46 >
47 > export class TestLoggerService extends AbstractLoggerService {
48 > constructor(logsHome?: URI) {
49 super(LogLevel.Info, logsHome ?? URI.file('tests').with({ scheme: 'vscode-tests' }));
50 }
51 > protected doCreateLogger(): ILogger { return new NullLogger(); } workbenchTestServices.ts
52 > }
53 >
54 > export class TestTextResourcePropertiesService implements ITextResourcePropertiesService {
55 >
56 > declare readonly _serviceBrand: undefined;
57 >
58 > constructor(
59 @IConfigurationService private readonly configurationService: IConfigurationService,
60 ) {
61 }
63 > getEOL(resource: URI, language?: string): string {
64 const eol = this.configurationService.getValue('files.eol', { overrideIdentifier: language, resource });
65 if (eol && typeof eol === 'string' && eol !== 'auto') {
68 return (isLinux || isMacintosh) ? '\n' : '\r\n';
69 }
71 >
72 > export class TestUserDataProfileService implements IUserDataProfileService {
73
74 readonly _serviceBrand: undefined;
75 readonly onDidChangeCurrentProfile = Event.None;
76 readonly currentProfile = toUserDataProfile('test', 'test', URI.file('tests').with({ scheme: 'vscode-tests' }), URI.file('tests').with({ scheme: 'vscode-tests' }));
77 > async updateCurrentProfile(): Promise<void> { } workbenchTestServices.ts
78 > }
79 >
80 > export class TestContextService implements IWorkspaceContextService {
81 >
82 > declare readonly _serviceBrand: undefined;
83 >
84 > private workspace: Workspace;
85 > private options: object;
86 >
87 > private readonly _onDidChangeWorkspaceName: Emitter<void>;
88 > get onDidChangeWorkspaceName(): Event<void> { return this._onDidChangeWorkspaceName.event; }
89 >
90 > private readonly _onWillChangeWorkspaceFolders: Emitter<IWorkspaceFoldersWillChangeEvent>;
91 > get onWillChangeWorkspaceFolders(): Event<IWorkspaceFoldersWillChangeEvent> { return this._onWillChangeWorkspaceFolders.event; }
92 >
93 > private readonly _onDidChangeWorkspaceFolders: Emitter<IWorkspaceFoldersChangeEvent>;
94 > get onDidChangeWorkspaceFolders(): Event<IWorkspaceFoldersChangeEvent> { return this._onDidChangeWorkspaceFolders.event; }
95 >
96 > private readonly _onDidChangeWorkbenchState: Emitter<WorkbenchState>;
97 > get onDidChangeWorkbenchState(): Event<WorkbenchState> { return this._onDidChangeWorkbenchState.event; }
98 >
99 > constructor(workspace = TestWorkspace, options = null) {
100 this.workspace = workspace;
101 this.options = options || Object.create(null);
105 this._onDidChangeWorkbenchState = new Emitter<WorkbenchState>();
106 }
108 > getFolders(): IWorkspaceFolder[] {
109 return this.workspace ? this.workspace.folders : [];
110 }
112 > getWorkbenchState(): WorkbenchState {
113 if (this.workspace.configuration) {
114 return WorkbenchState.WORKSPACE;
121 return WorkbenchState.EMPTY;
122 }
124 > hasWorkspaceData(): boolean {
125 return this.getWorkbenchState() !== WorkbenchState.EMPTY;
126 }
128 > getCompleteWorkspace(): Promise<IWorkspace> {
129 return Promise.resolve(this.getWorkspace());
130 }
132 > getWorkspace(): IWorkspace {
133 return this.workspace;
134 }
136 > getWorkspaceFolder(resource: URI): IWorkspaceFolder | null {
137 return this.workspace.getFolder(resource);
138 }
140 > setWorkspace(workspace: any): void {
141 this.workspace = workspace;
142 }
144 > getOptions() {
145 return this.options;
146 }
148 > updateOptions() { }
149 >
150 > isInsideWorkspace(resource: URI): boolean {
151 if (resource && this.workspace) {
152 return isEqualOrParent(resource, this.workspace.folders[0].uri);
155 return false;
156 }
158 > toResource(workspaceRelativePath: string): URI {
159 return URI.file(join('C:\\', workspaceRelativePath));
160 }
162 > isCurrentWorkspace(workspaceIdOrFolder: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | URI): boolean {
163 return URI.isUri(workspaceIdOrFolder) && isEqual(this.workspace.folders[0].uri, workspaceIdOrFolder);
164 }
166 >
167 > export class TestStorageService extends InMemoryStorageService {
168 >
169 > testEmitWillSaveState(reason: WillSaveStateReason): void {
170 super.emitWillSaveState(reason);
171 }
173 >
174 > export class TestHistoryService implements IHistoryService {
175 >
176 > declare readonly _serviceBrand: undefined;
177 >
178 > constructor(private root?: URI) { }
179 >
180 > async reopenLastClosedEditor(): Promise<void> { }
181 > async goForward(): Promise<void> { }
182 > async goBack(): Promise<void> { }
183 > async goPrevious(): Promise<void> { }
184 > async goLast(): Promise<void> { }
185 > removeFromHistory(_input: EditorInput | IResourceEditorInput): void { }
186 > clear(): void { }
187 > clearRecentlyOpened(): void { }
188 > getHistory(): readonly (EditorInput | IResourceEditorInput)[] { return []; }
189 > async openNextRecentlyUsedEditor(group?: GroupIdentifier): Promise<void> { }
190 > async openPreviouslyUsedEditor(group?: GroupIdentifier): Promise<void> { }
191 > getLastActiveWorkspaceRoot(_schemeFilter: string): URI | undefined { return this.root; }
192 > getLastActiveFile(_schemeFilter: string): URI | undefined { return undefined; }
193 > }
194 >
195 > export class TestWorkingCopy extends Disposable implements IWorkingCopy {
196 >
197 > private readonly _onDidChangeDirty = this._register(new Emitter<void>());
198 > readonly onDidChangeDirty = this._onDidChangeDirty.event;
199 >
200 > private readonly _onDidChangeContent = this._register(new Emitter<void>());
201 > readonly onDidChangeContent = this._onDidChangeContent.event;
202 >
203 > private readonly _onDidSave = this._register(new Emitter<IStoredFileWorkingCopySaveEvent>());
204 > readonly onDidSave = this._onDidSave.event;
205 >
206 > readonly capabilities = WorkingCopyCapabilities.None;
207 >
208 > readonly name;
209 >
210 > private dirty = false;
211 >
212 > constructor(readonly resource: URI, isDirty = false, readonly typeId = 'testWorkingCopyType') {
213 super();
214
216 this.dirty = isDirty;
217 }
219 > setDirty(dirty: boolean): void {
220 if (this.dirty !== dirty) {
221 this.dirty = dirty;
223 }
224 }
226 > setContent(content: string): void {
227 this._onDidChangeContent.fire();
228 }
230 > isDirty(): boolean {
231 return this.dirty;
232 }
234 > isModified(): boolean {
235 return this.isDirty();
236 }
238 > async save(options?: ISaveOptions, stat?: IFileStatWithMetadata): Promise<boolean> {
239 this._onDidSave.fire({ reason: options?.reason ?? SaveReason.EXPLICIT, stat: stat ?? createFileStat(this.resource), source: options?.source });
240
241 return true;
242 }
244 > async revert(options?: IRevertOptions): Promise<void> {
245 this.setDirty(false);
246 }
248 > async backup(token: CancellationToken): Promise<IWorkingCopyBackup> {
249 return {};
250 }
252 >
253 > export function createFileStat(resource: URI, readonly = false, isFile?: boolean, isDirectory?: boolean, isSymbolicLink?: boolean, children?: { resource: URI; isFile?: boolean; isDirectory?: boolean; isSymbolicLink?: boolean; executable?: boolean }[] | undefined, executable?: boolean): IFileStatWithMetadata {
254 return {
255 resource,
268 };
269 }
271 > export class TestWorkingCopyFileService implements IWorkingCopyFileService {
272
273 declare readonly _serviceBrand: undefined;
280
281 readonly hasSaveParticipants = false;
282 > addSaveParticipant(participant: IStoredFileWorkingCopySaveParticipant): IDisposable { return Disposable.None; } workbenchTestServices.ts
283 > async runSaveParticipants(workingCopy: IWorkingCopy, context: IStoredFileWorkingCopySaveParticipantContext, progress: IProgress<IProgressStep>, token: CancellationToken): Promise<void> { }
284 >
285 > async delete(operations: IDeleteOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise<void> { }
286 >
287 > registerWorkingCopyProvider(provider: (resourceOrFolder: URI) => IWorkingCopy[]): IDisposable { return Disposable.None; }
288 >
289 > getDirty(resource: URI): IWorkingCopy[] { return []; }
290 >
291 > create(operations: ICreateFileOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise<IFileStatWithMetadata[]> { throw new Error('Method not implemented.'); }
292 > createFolder(operations: ICreateOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise<IFileStatWithMetadata[]> { throw new Error('Method not implemented.'); }
293 >
294 > move(operations: IMoveOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise<IFileStatWithMetadata[]> { throw new Error('Method not implemented.'); }
295 >
296 > copy(operations: ICopyOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise<IFileStatWithMetadata[]> { throw new Error('Method not implemented.'); }
297 > }
298 >
299 > export function mock<T>(): Ctor<T> {
300 // eslint-disable-next-line local/code-no-any-casts
301 return function () { } as any;
302 }
304 > export interface Ctor<T> {
305 > new(): T;
306 > }
307 >
308 > export class TestExtensionService extends NullExtensionService { }
309 >
310 > export const TestProductService = { _serviceBrand: undefined, ...product };
311 >
312 > export class TestActivityService implements IActivityService {
313 _serviceBrand: undefined;
314 onDidChangeActivity = Event.None;
315 > getViewContainerActivities(viewContainerId: string): IActivity[] { workbenchTestServices.ts
316 return [];
317 }
318 > getActivity(id: string): IActivity[] { workbenchTestServices.ts
319 return [];
320 }
321 > showViewContainerActivity(viewContainerId: string, badge: IActivity): IDisposable { workbenchTestServices.ts
322 return this;
323 }
324 > showViewActivity(viewId: string, badge: IActivity): IDisposable { workbenchTestServices.ts
325 return this;
326 }
327 > showAccountsActivity(activity: IActivity): IDisposable { workbenchTestServices.ts
328 return this;
329 }
330 > showGlobalActivity(activity: IActivity): IDisposable { workbenchTestServices.ts
331 return this;
332 }
334 > dispose() { }
335 > }
336 >
337 > export const NullFilesConfigurationService = new class implements IFilesConfigurationService {
338 >
339 > _serviceBrand: undefined;
340 >
341 > readonly onDidChangeAutoSaveConfiguration = Event.None;
342 > readonly onDidChangeAutoSaveDisabled = Event.None;
343 > readonly onDidChangeReadonly = Event.None;
344 > readonly onDidChangeFilesAssociation = Event.None;
345 >
346 > readonly isHotExitEnabled = false;
347 > readonly hotExitConfiguration = undefined;
348 >
349 > getAutoSaveConfiguration(): IAutoSaveConfiguration { throw new Error('Method not implemented.'); }
350 > getAutoSaveMode(): IAutoSaveMode { throw new Error('Method not implemented.'); }
351 > hasShortAutoSaveDelay(): boolean { throw new Error('Method not implemented.'); }
352 > toggleAutoSave(): Promise<void> { throw new Error('Method not implemented.'); }
353 > enableAutoSaveAfterShortDelay(resourceOrEditor: URI | EditorInput): IDisposable { throw new Error('Method not implemented.'); }
354 > disableAutoSave(resourceOrEditor: URI | EditorInput): IDisposable { throw new Error('Method not implemented.'); }
355 > isReadonly(resource: URI, stat?: IBaseFileStat | undefined): boolean { return false; }
356 > async updateReadonly(_resource: URI | URI[], _readonly: boolean | 'toggle' | 'reset'): Promise<void> { }
357 > preventSaveConflicts(resource: URI, language?: string | undefined): boolean { throw new Error('Method not implemented.'); }
358 > };
359 >
360 > export class TestWorkspaceTrustEnablementService implements IWorkspaceTrustEnablementService {
361 > _serviceBrand: undefined;
362 >
363 > constructor(private isEnabled: boolean = true) { }
364 >
365 > isWorkspaceTrustEnabled(): boolean {
366 return this.isEnabled;
367 }
369 >
370 > export class TestWorkspaceTrustManagementService extends Disposable implements IWorkspaceTrustManagementService {
371 > _serviceBrand: undefined;
372 >
373 > private _onDidChangeTrust = this._register(new Emitter<boolean>());
374 > onDidChangeTrust = this._onDidChangeTrust.event;
375 >
376 > private _onDidChangeTrustedFolders = this._register(new Emitter<void>());
377 > onDidChangeTrustedFolders = this._onDidChangeTrustedFolders.event;
378 >
379 > private _onDidInitiateWorkspaceTrustRequestOnStartup = this._register(new Emitter<void>());
380 > onDidInitiateWorkspaceTrustRequestOnStartup = this._onDidInitiateWorkspaceTrustRequestOnStartup.event;
381 >
382 >
383 > constructor(
384 private trusted: boolean = true,
385 private trustedUris: ResourceSet = new ResourceSet()
387 super();
388 }
390 > get acceptsOutOfWorkspaceFiles(): boolean {
391 throw new Error('Method not implemented.');
392 }
394 > set acceptsOutOfWorkspaceFiles(value: boolean) {
395 throw new Error('Method not implemented.');
396 }
398 > addWorkspaceTrustTransitionParticipant(participant: IWorkspaceTrustTransitionParticipant): IDisposable {
399 throw new Error('Method not implemented.');
400 }
402 > getTrustedUris(): URI[] {
403 throw new Error('Method not implemented.');
404 }
406 > setParentFolderTrust(trusted: boolean): Promise<void> {
407 throw new Error('Method not implemented.');
408 }
410 > getUriTrustInfo(uri: URI): Promise<IWorkspaceTrustUriInfo> {
411 return Promise.resolve({ trusted: this.trustedUris.has(uri), uri });
412 }
414 > async setTrustedUris(folders: URI[]): Promise<void> {
415 this.trustedUris = new ResourceSet(folders);
416 }
418 > async setUrisTrust(uris: URI[], trusted: boolean): Promise<void> {
419 throw new Error('Method not implemented.');
420 }
422 > canSetParentFolderTrust(): boolean {
423 throw new Error('Method not implemented.');
424 }
426 > canSetWorkspaceTrust(): boolean {
427 throw new Error('Method not implemented.');
428 }
430 > isWorkspaceTrusted(): boolean {
431 return this.trusted;
432 }
434 > isWorkspaceTrustForced(): boolean {
435 return false;
436 }
438 > get workspaceTrustInitialized(): Promise<void> {
439 return Promise.resolve();
440 }
442 > get workspaceResolved(): Promise<void> {
443 return Promise.resolve();
444 }
446 > async setWorkspaceTrust(trusted: boolean): Promise<void> {
447 if (this.trusted !== trusted) {
448 this.trusted = trusted;
450 }
451 }
453 >
454 > export class TestWorkspaceTrustRequestService extends Disposable implements IWorkspaceTrustRequestService {
455 > _serviceBrand: any;
456 >
457 > private readonly _onDidInitiateOpenFilesTrustRequest = this._register(new Emitter<void>());
458 > readonly onDidInitiateOpenFilesTrustRequest = this._onDidInitiateOpenFilesTrustRequest.event;
459 >
460 > private readonly _onDidInitiateResourcesTrustRequest = this._register(new Emitter<ResourceTrustRequestOptions>());
461 > readonly onDidInitiateResourcesTrustRequest = this._onDidInitiateResourcesTrustRequest.event;
462 >
463 > private readonly _onDidInitiateWorkspaceTrustRequest = this._register(new Emitter<WorkspaceTrustRequestOptions>());
464 > readonly onDidInitiateWorkspaceTrustRequest = this._onDidInitiateWorkspaceTrustRequest.event;
465 >
466 > private readonly _onDidInitiateWorkspaceTrustRequestOnStartup = this._register(new Emitter<void>());
467 > readonly onDidInitiateWorkspaceTrustRequestOnStartup = this._onDidInitiateWorkspaceTrustRequestOnStartup.event;
468 >
469 > constructor(private readonly _trusted: boolean) {
470 super();
471 }
474 return WorkspaceTrustUriResponse.Open;
475 };
477 > requestOpenFilesTrust(uris: URI[]): Promise<WorkspaceTrustUriResponse> {
478 return this.requestOpenUrisHandler(uris);
479 }
481 > async completeOpenFilesTrustRequest(result: WorkspaceTrustUriResponse, saveResponse: boolean): Promise<void> {
482 throw new Error('Method not implemented.');
483 }
485 > async completeResourcesTrustRequest(uri: URI, result: WorkspaceTrustUriResponse): Promise<void> {
486 throw new Error('Method not implemented.');
487 }
489 > async requestResourcesTrust(options: ResourceTrustRequestOptions): Promise<boolean | undefined> {
490 return this._trusted;
491 }
493 > cancelWorkspaceTrustRequest(): void {
494 throw new Error('Method not implemented.');
495 }
497 > async completeWorkspaceTrustRequest(trusted?: boolean): Promise<void> {
498 throw new Error('Method not implemented.');
499 }
501 > async requestWorkspaceTrust(options?: WorkspaceTrustRequestOptions): Promise<boolean> {
502 return this._trusted;
503 }
505 > requestWorkspaceTrustOnStartup(): void {
506 throw new Error('Method not implemented.');
507 }
509 >
510 > export class TestMarkerService implements IMarkerService {
511
512 _serviceBrand: undefined;
513
514 onMarkerChanged = Event.None;
516 > getStatistics(): MarkerStatistics { throw new Error('Method not implemented.'); }
517 > changeOne(owner: string, resource: URI, markers: IMarkerData[]): void { }
518 > changeAll(owner: string, data: IResourceMarker[]): void { }
519 > remove(owner: string, resources: URI[]): void { }
520 > read(filter?: { owner?: string | undefined; resource?: URI | undefined; severities?: number | undefined; take?: number | undefined } | undefined): IMarker[] { return []; }
521 > installResourceFilter(resource: URI, reason: string): IDisposable {
522 return { dispose: () => { /* TODO: Implement cleanup logic */ } };
523 }
525 >
526 > export class TestFileService implements IFileService {
527
528 declare readonly _serviceBrand: undefined;
695
696 readonly watches: URI[] = [];
697 > watch(_resource: URI, options: IWatchOptionsWithCorrelation): IFileSystemWatcher; workbenchTestServices.ts
698 > watch(_resource: URI): IDisposable;
699 > watch(_resource: URI): IDisposable {
700 this.watches.push(_resource);
701
702 return toDisposable(() => this.watches.splice(this.watches.indexOf(_resource), 1));
703 }
705 > getWriteEncoding(_resource: URI): IResourceEncoding { return { encoding: 'utf8', hasBOM: false }; }
706 > dispose(): void { }
707 >
708 > async canCreateFile(source: URI, options?: ICreateFileOptions): Promise<Error | true> { return true; }
709 > async canMove(source: URI, target: URI, overwrite?: boolean | undefined): Promise<Error | true> { return true; }
710 > async canCopy(source: URI, target: URI, overwrite?: boolean | undefined): Promise<Error | true> { return true; }
711 > async canDelete(resource: URI, options?: { useTrash?: boolean | undefined; recursive?: boolean | undefined } | undefined): Promise<Error | true> { return true; }
712 > }
713 >
714 > /**
715 > * TestFileService with in-memory file storage.
716 > * Use this when your test needs to write files and read them back.
717 > */
718 > export class InMemoryTestFileService extends TestFileService {
719
720 private files = new ResourceMap<VSBuffer>();
722 > override clearTracking(): void {
723 super.clearTracking();
724 this.files.clear();
725 }
727 > override async readFile(resource: URI, options?: IReadFileOptions | undefined): Promise<IFileContent> {
728 if (this.readShouldThrowError) {
729 throw this.readShouldThrowError;
747 };
748 }
750 > override async writeFile(resource: URI, bufferOrReadable: VSBuffer | VSBufferReadable, options?: IWriteFileOptions): Promise<IFileStatWithMetadata> {
751 await timeout(0);
752
768 return createFileStat(resource, this.readonly);
769 }
771 > override async del(resource: URI, _options?: { useTrash?: boolean; recursive?: boolean }): Promise<void> {
772 this.files.delete(resource);
773 this.notExistsSet.set(resource, true);
774 }
776 > override async exists(resource: URI): Promise<boolean> {
777 const inMemory = this.files.has(resource);
778 if (inMemory) {
782 return super.exists(resource);
783 }
785 >
786 > export class TestChatEntitlementService implements IChatEntitlementService {
787
788 _serviceBrand: undefined;
824 readonly clientByokEnabled = false;
825 readonly hasByokModels = false;
827 >
828 > export class TestLifecycleService extends Disposable implements ILifecycleService {
829
830 declare readonly _serviceBrand: undefined;
884
885 shutdownJoiners: Promise<void>[] = [];
887 > fireShutdown(reason = ShutdownReason.QUIT): void {
888 this.shutdownJoiners = [];
889
898 });
899 }
901 > fireBeforeShutdown(event: InternalBeforeShutdownEvent): void { this._onBeforeShutdown.fire(event); }
902 >
903 > fireWillShutdown(event: WillShutdownEvent): void { this._onWillShutdown.fire(event); }
904 >
905 > async shutdown(): Promise<void> {
906 this.fireShutdown();
907 }
src/vs/workbench/services/workingCopy/common/workingCopy.ts 221 introduced LOC · 1 range

Open complete file

1 > /*--------------------------------------------------------------------------------------------- workingCopy.ts
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 { Event } from '../../../../base/common/event.js';
7 > import { URI } from '../../../../base/common/uri.js';
8 > import { ISaveOptions, IRevertOptions, SaveReason, SaveSource } from '../../../common/editor.js';
9 > import { CancellationToken } from '../../../../base/common/cancellation.js';
10 > import { VSBufferReadable, VSBufferReadableStream } from '../../../../base/common/buffer.js';
11 >
12 > export const enum WorkingCopyCapabilities {
13 >
14 > /**
15 > * Signals no specific capability for the working copy.
16 > */
17 > None = 0,
18 >
19 > /**
20 > * Signals that the working copy requires
21 > * additional input when saving, e.g. an
22 > * associated path to save to.
23 > */
24 > Untitled = 1 << 1,
25 >
26 > /**
27 > * The working copy will not indicate that
28 > * it is dirty and unsaved content will be
29 > * discarded without prompting if closed.
30 > */
31 > Scratchpad = 1 << 2
32 > }
33 >
34 > /**
35 > * Data to be associated with working copy backups. Use
36 > * `IWorkingCopyBackupService.resolve(workingCopy)` to
37 > * retrieve the backup when loading the working copy.
38 > */
39 > export interface IWorkingCopyBackup {
40 >
41 > /**
42 > * Any serializable metadata to be associated with the backup.
43 > */
44 > meta?: IWorkingCopyBackupMeta;
45 >
46 > /**
47 > * The actual snapshot of the contents of the working copy at
48 > * the time the backup was made.
49 > */
50 > content?: VSBufferReadable | VSBufferReadableStream;
51 > }
52 >
53 > /**
54 > * Working copy backup metadata that can be associated
55 > * with the backup.
56 > *
57 > * Some properties may be reserved as outlined here and
58 > * cannot be used.
59 > */
60 > export interface IWorkingCopyBackupMeta {
61 >
62 > /**
63 > * Any property needs to be serializable through JSON.
64 > */
65 > [key: string]: unknown;
66 >
67 > /**
68 > * `typeId` is a reserved property that cannot be used
69 > * as backup metadata.
70 > */
71 > typeId?: never;
72 > }
73 >
74 > /**
75 > * @deprecated it is important to provide a type identifier
76 > * for working copies to enable all capabilities.
77 > */
78 > export const NO_TYPE_ID = '';
79 >
80 > /**
81 > * Every working copy has in common that it is identified by
82 > * a resource `URI` and a `typeId`. There can only be one
83 > * working copy registered with the same `URI` and `typeId`.
84 > */
85 > export interface IWorkingCopyIdentifier {
86 >
87 > /**
88 > * The type identifier of the working copy for grouping
89 > * working copies of the same domain together.
90 > *
91 > * There can only be one working copy for a given resource
92 > * and type identifier.
93 > */
94 > readonly typeId: string;
95 >
96 > /**
97 > * The resource of the working copy must be unique for
98 > * working copies of the same `typeId`.
99 > */
100 > readonly resource: URI;
101 > }
102 >
103 > export interface IWorkingCopySaveEvent {
104 >
105 > /**
106 > * The reason why the working copy was saved.
107 > */
108 > readonly reason?: SaveReason;
109 >
110 > /**
111 > * The source of the working copy save request.
112 > */
113 > readonly source?: SaveSource;
114 > }
115 >
116 > /**
117 > * A working copy is an abstract concept to unify handling of
118 > * data that can be worked on (e.g. edited) in an editor.
119 > *
120 > *
121 > * A working copy resource may be the backing store of the data
122 > * (e.g. a file on disk), but that is not a requirement. If
123 > * your working copy is file based, consider to use the
124 > * `IFileWorkingCopy` instead that simplifies a lot of things
125 > * when working with file based working copies.
126 > */
127 > export interface IWorkingCopy extends IWorkingCopyIdentifier {
128 >
129 > /**
130 > * Human readable name of the working copy.
131 > */
132 > readonly name: string;
133 >
134 > /**
135 > * The capabilities of the working copy.
136 > */
137 > readonly capabilities: WorkingCopyCapabilities;
138 >
139 >
140 > //#region Events
141 >
142 > /**
143 > * Used by the workbench to signal if the working copy
144 > * is dirty or not. Typically a working copy is dirty
145 > * once changed until saved or reverted.
146 > */
147 > readonly onDidChangeDirty: Event<void>;
148 >
149 > /**
150 > * Used by the workbench e.g. to trigger auto-save
151 > * (unless this working copy is untitled) and backups.
152 > */
153 > readonly onDidChangeContent: Event<void>;
154 >
155 > /**
156 > * Used by the workbench e.g. to track local history
157 > * (unless this working copy is untitled).
158 > */
159 > readonly onDidSave: Event<IWorkingCopySaveEvent>;
160 >
161 > //#endregion
162 >
163 >
164 > //#region Dirty Tracking
165 >
166 > /**
167 > * Indicates that the file has unsaved changes
168 > * and should confirm before closing.
169 > */
170 > isDirty(): boolean;
171 >
172 > /**
173 > * Indicates that the file has unsaved changes.
174 > * Used for backup tracking and accounts for
175 > * working copies that are never dirty e.g.
176 > * scratchpads.
177 > */
178 > isModified(): boolean;
179 >
180 > //#endregion
181 >
182 >
183 > //#region Save / Backup
184 >
185 > /**
186 > * The delay in milliseconds to wait before triggering
187 > * a backup after the content of the model has changed.
188 > *
189 > * If not configured, a sensible default will be taken
190 > * based on user settings.
191 > */
192 > readonly backupDelay?: number;
193 >
194 > /**
195 > * The workbench may call this method often after it receives
196 > * the `onDidChangeContent` event for the working copy. The motivation
197 > * is to allow to quit VSCode with dirty working copies present.
198 > *
199 > * Providers of working copies should use `IWorkingCopyBackupService.resolve(workingCopy)`
200 > * to retrieve the backup metadata associated when loading the working copy.
201 > *
202 > * @param token support for cancellation
203 > */
204 > backup(token: CancellationToken): Promise<IWorkingCopyBackup>;
205 >
206 > /**
207 > * Asks the working copy to save. If the working copy was dirty, it is
208 > * expected to be non-dirty after this operation has finished.
209 > *
210 > * @returns `true` if the operation was successful and `false` otherwise.
211 > */
212 > save(options?: ISaveOptions): Promise<boolean>;
213 >
214 > /**
215 > * Asks the working copy to revert. If the working copy was dirty, it is
216 > * expected to be non-dirty after this operation has finished.
217 > */
218 > revert(options?: IRevertOptions): Promise<void>;
219 >
220 > //#endregion
221 > }