/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { join } from 'vs/base/common/path'; import { basename, isEqual, isEqualOrParent } from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; import { Event, Emitter } from 'vs/base/common/event'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IWorkspaceContextService, IWorkspace, WorkbenchState, IWorkspaceFolder, IWorkspaceFoldersChangeEvent, Workspace, IWorkspaceFoldersWillChangeEvent, ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace'; import { TestWorkspace } from 'vs/platform/workspace/test/common/testWorkspace'; import { ITextResourcePropertiesService } from 'vs/editor/common/services/textResourceConfiguration'; import { isLinux, isMacintosh } from 'vs/base/common/platform'; import { InMemoryStorageService, WillSaveStateReason } from 'vs/platform/storage/common/storage'; import { IWorkingCopy, IWorkingCopyBackup, WorkingCopyCapabilities } from 'vs/workbench/services/workingCopy/common/workingCopy'; import { NullExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { IWorkingCopyFileService, IWorkingCopyFileOperationParticipant, WorkingCopyFileEvent, IDeleteOperation, ICopyOperation, IMoveOperation, IFileOperationUndoRedoInfo, ICreateFileOperation, ICreateOperation, IStoredFileWorkingCopySaveParticipant } from 'vs/workbench/services/workingCopy/common/workingCopyFileService'; import { IDisposable, Disposable } from 'vs/base/common/lifecycle'; import { IFileStatWithMetadata } from 'vs/platform/files/common/files'; import { ISaveOptions, IRevertOptions, SaveReason } from 'vs/workbench/common/editor'; import { CancellationToken } from 'vs/base/common/cancellation'; import product from 'vs/platform/product/common/product'; import { IActivity, IActivityService } from 'vs/workbench/services/activity/common/activity'; import { IStoredFileWorkingCopySaveEvent } from 'vs/workbench/services/workingCopy/common/storedFileWorkingCopy'; export class TestTextResourcePropertiesService implements ITextResourcePropertiesService { declare readonly _serviceBrand: undefined; constructor( @IConfigurationService private readonly configurationService: IConfigurationService, ) { } getEOL(resource: URI, language?: string): string { const eol = this.configurationService.getValue('files.eol', { overrideIdentifier: language, resource }); if (eol && typeof eol === 'string' && eol !== 'auto') { return eol; } return (isLinux || isMacintosh) ? '\n' : '\r\n'; } } export class TestContextService implements IWorkspaceContextService { declare readonly _serviceBrand: undefined; private workspace: Workspace; private options: object; private readonly _onDidChangeWorkspaceName: Emitter; get onDidChangeWorkspaceName(): Event { return this._onDidChangeWorkspaceName.event; } private readonly _onWillChangeWorkspaceFolders: Emitter; get onWillChangeWorkspaceFolders(): Event { return this._onWillChangeWorkspaceFolders.event; } private readonly _onDidChangeWorkspaceFolders: Emitter; get onDidChangeWorkspaceFolders(): Event { return this._onDidChangeWorkspaceFolders.event; } private readonly _onDidChangeWorkbenchState: Emitter; get onDidChangeWorkbenchState(): Event { return this._onDidChangeWorkbenchState.event; } constructor(workspace = TestWorkspace, options = null) { this.workspace = workspace; this.options = options || Object.create(null); this._onDidChangeWorkspaceName = new Emitter(); this._onWillChangeWorkspaceFolders = new Emitter(); this._onDidChangeWorkspaceFolders = new Emitter(); this._onDidChangeWorkbenchState = new Emitter(); } getFolders(): IWorkspaceFolder[] { return this.workspace ? this.workspace.folders : []; } getWorkbenchState(): WorkbenchState { if (this.workspace.configuration) { return WorkbenchState.WORKSPACE; } if (this.workspace.folders.length) { return WorkbenchState.FOLDER; } return WorkbenchState.EMPTY; } getCompleteWorkspace(): Promise { return Promise.resolve(this.getWorkspace()); } getWorkspace(): IWorkspace { return this.workspace; } getWorkspaceFolder(resource: URI): IWorkspaceFolder | null { return this.workspace.getFolder(resource); } setWorkspace(workspace: any): void { this.workspace = workspace; } getOptions() { return this.options; } updateOptions() { } isInsideWorkspace(resource: URI): boolean { if (resource && this.workspace) { return isEqualOrParent(resource, this.workspace.folders[0].uri); } return false; } toResource(workspaceRelativePath: string): URI { return URI.file(join('C:\\', workspaceRelativePath)); } isCurrentWorkspace(workspaceIdOrFolder: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | URI): boolean { return URI.isUri(workspaceIdOrFolder) && isEqual(this.workspace.folders[0].uri, workspaceIdOrFolder); } } export class TestStorageService extends InMemoryStorageService { override emitWillSaveState(reason: WillSaveStateReason): void { super.emitWillSaveState(reason); } } export class TestWorkingCopy extends Disposable implements IWorkingCopy { private readonly _onDidChangeDirty = this._register(new Emitter()); readonly onDidChangeDirty = this._onDidChangeDirty.event; private readonly _onDidChangeContent = this._register(new Emitter()); readonly onDidChangeContent = this._onDidChangeContent.event; private readonly _onDidSave = this._register(new Emitter()); readonly onDidSave = this._onDidSave.event; readonly capabilities = WorkingCopyCapabilities.None; readonly name = basename(this.resource); private dirty = false; constructor(readonly resource: URI, isDirty = false, readonly typeId = 'testWorkingCopyType') { super(); this.dirty = isDirty; } setDirty(dirty: boolean): void { if (this.dirty !== dirty) { this.dirty = dirty; this._onDidChangeDirty.fire(); } } setContent(content: string): void { this._onDidChangeContent.fire(); } isDirty(): boolean { return this.dirty; } async save(options?: ISaveOptions, stat?: IFileStatWithMetadata): Promise { this._onDidSave.fire({ reason: options?.reason ?? SaveReason.EXPLICIT, stat: stat ?? createFileStat(this.resource), source: options?.source }); return true; } async revert(options?: IRevertOptions): Promise { this.setDirty(false); } async backup(token: CancellationToken): Promise { return {}; } } export function createFileStat(resource: URI, readonly = false): IFileStatWithMetadata { return { resource, etag: Date.now().toString(), mtime: Date.now(), ctime: Date.now(), size: 42, isFile: true, isDirectory: false, isSymbolicLink: false, readonly, name: basename(resource), children: undefined }; } export class TestWorkingCopyFileService implements IWorkingCopyFileService { declare readonly _serviceBrand: undefined; onWillRunWorkingCopyFileOperation: Event = Event.None; onDidFailWorkingCopyFileOperation: Event = Event.None; onDidRunWorkingCopyFileOperation: Event = Event.None; addFileOperationParticipant(participant: IWorkingCopyFileOperationParticipant): IDisposable { return Disposable.None; } readonly hasSaveParticipants = false; addSaveParticipant(participant: IStoredFileWorkingCopySaveParticipant): IDisposable { return Disposable.None; } async runSaveParticipants(workingCopy: IWorkingCopy, context: { reason: SaveReason }, token: CancellationToken): Promise { } async delete(operations: IDeleteOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise { } registerWorkingCopyProvider(provider: (resourceOrFolder: URI) => IWorkingCopy[]): IDisposable { return Disposable.None; } getDirty(resource: URI): IWorkingCopy[] { return []; } create(operations: ICreateFileOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise { throw new Error('Method not implemented.'); } createFolder(operations: ICreateOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise { throw new Error('Method not implemented.'); } move(operations: IMoveOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise { throw new Error('Method not implemented.'); } copy(operations: ICopyOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise { throw new Error('Method not implemented.'); } } export function mock(): Ctor { return function () { } as any; } export interface Ctor { new(): T; } export class TestExtensionService extends NullExtensionService { } export const TestProductService = { _serviceBrand: undefined, ...product }; export class TestActivityService implements IActivityService { _serviceBrand: undefined; showViewContainerActivity(viewContainerId: string, badge: IActivity): IDisposable { return this; } showViewActivity(viewId: string, badge: IActivity): IDisposable { return this; } showAccountsActivity(activity: IActivity): IDisposable { return this; } showGlobalActivity(activity: IActivity): IDisposable { return this; } dispose() { } }