workbenchTestServices.ts 52.7 KB
Newer Older
E
Erich Gamma 已提交
1 2 3 4 5
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

6
import 'vs/workbench/contrib/files/browser/files.contribution'; // load our contribution into the test
7
import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput';
8
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
9
import * as resources from 'vs/base/common/resources';
10
import { URI } from 'vs/base/common/uri';
11 12
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
13
import { IEditorInputWithOptions, CloseDirection, IEditorIdentifier, IUntitledTextResourceInput, IResourceDiffInput, IResourceSideBySideInput, IEditorInput, IEditor, IEditorCloseEvent, IEditorPartOptions, IRevertOptions, GroupIdentifier, EditorInput, EditorOptions, EditorsOrder, IFileEditorInput, IEditorInputFactoryRegistry, IEditorInputFactory, Extensions as EditorExtensions, ISaveOptions, IMoveResult } from 'vs/workbench/common/editor';
14
import { IEditorOpeningEvent, EditorServiceImpl, IEditorGroupView, IEditorGroupsAccessor } from 'vs/workbench/browser/parts/editor/editor';
M
Matt Bierner 已提交
15
import { Event, Emitter } from 'vs/base/common/event';
E
Erich Gamma 已提交
16
import Severity from 'vs/base/common/severity';
17
import { IBackupFileService, IResolvedBackup } from 'vs/workbench/services/backup/common/backup';
18
import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
B
Benjamin Pasero 已提交
19
import { IWorkbenchLayoutService, Parts, Position as PartPosition } from 'vs/workbench/services/layout/browser/layoutService';
20
import { TextModelResolverService } from 'vs/workbench/services/textmodelResolver/common/textModelResolverService';
21
import { ITextModelService } from 'vs/editor/common/services/resolverService';
22
import { IEditorOptions, IResourceInput, IEditorModel } from 'vs/platform/editor/common/editor';
23
import { IUntitledTextEditorService, UntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService';
24
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
25
import { ILifecycleService, BeforeShutdownEvent, ShutdownReason, StartupKind, LifecyclePhase, WillShutdownEvent } from 'vs/platform/lifecycle/common/lifecycle';
J
Johannes Rieken 已提交
26
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
27
import { FileOperationEvent, IFileService, IFileStat, IResolveFileResult, FileChangesEvent, IResolveFileOptions, ICreateFileOptions, IFileSystemProvider, FileSystemProviderCapabilities, IFileChange, IWatchOptions, IStat, FileType, FileDeleteOptions, FileOverwriteOptions, FileWriteOptions, FileOpenOptions, IFileStatWithMetadata, IResolveMetadataFileOptions, IWriteFileOptions, IReadFileOptions, IFileContent, IFileStreamContent, FileOperationError } from 'vs/platform/files/common/files';
28
import { IModelService } from 'vs/editor/common/services/modelService';
29
import { ModeServiceImpl } from 'vs/editor/common/services/modeServiceImpl';
J
Johannes Rieken 已提交
30
import { ModelServiceImpl } from 'vs/editor/common/services/modelServiceImpl';
31
import { IResourceEncoding, ITextFileService, IReadTextFileOptions, ITextFileStreamContent } from 'vs/workbench/services/textfile/common/textfiles';
J
Johannes Rieken 已提交
32 33
import { IModeService } from 'vs/editor/common/services/modeService';
import { IHistoryService } from 'vs/workbench/services/history/common/history';
34
import { IInstantiationService, ServicesAccessor, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
35
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
36
import { MenuBarVisibility, IWindowOpenable, IOpenWindowOptions, IOpenEmptyWindowOptions } from 'vs/platform/windows/common/windows';
S
Sandeep Somavarapu 已提交
37
import { TestWorkspace } from 'vs/platform/workspace/test/common/testWorkspace';
38
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
39
import { IThemeService } from 'vs/platform/theme/common/themeService';
B
Benjamin Pasero 已提交
40
import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService';
S
rename  
Sandeep Somavarapu 已提交
41
import { ITextResourceConfigurationService, ITextResourcePropertiesService } from 'vs/editor/common/services/textResourceConfigurationService';
42
import { IPosition, Position as EditorPosition } from 'vs/editor/common/core/position';
43
import { IMenuService, MenuId, IMenu } from 'vs/platform/actions/common/actions';
I
isidor 已提交
44
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
B
Benjamin Pasero 已提交
45
import { MockContextKeyService, MockKeybindingService } from 'vs/platform/keybinding/test/common/mockKeybindingService';
46
import { ITextBufferFactory, DefaultEndOfLine, EndOfLinePreference, IModelDecorationOptions, ITextModel, ITextSnapshot } from 'vs/editor/common/model';
47
import { Range } from 'vs/editor/common/core/range';
48
import { IConfirmation, IConfirmationResult, IDialogService, IDialogOptions, IPickAndOpenOptions, ISaveDialogOptions, IOpenDialogOptions, IFileDialogService, IShowResult, ConfirmResult } from 'vs/platform/dialogs/common/dialogs';
49 50
import { INotificationService } from 'vs/platform/notification/common/notification';
import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService';
51
import { IExtensionService, NullExtensionService } from 'vs/workbench/services/extensions/common/extensions';
B
Benjamin Pasero 已提交
52
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
B
Benjamin Pasero 已提交
53
import { IDecorationsService, IResourceDecorationChangeEvent, IDecoration, IDecorationData, IDecorationsProvider } from 'vs/workbench/services/decorations/browser/decorations';
54
import { IDisposable, toDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle';
B
Benjamin Pasero 已提交
55
import { IEditorGroupsService, IEditorGroup, GroupsOrder, GroupsArrangement, GroupDirection, IAddGroupOptions, IMergeGroupOptions, IMoveEditorOptions, ICopyEditorOptions, IEditorReplacement, IGroupChangeEvent, IFindGroupScope, EditorGroupLayout, ICloseEditorOptions } from 'vs/workbench/services/editor/common/editorGroupsService';
56
import { IEditorService, IOpenEditorOverrideHandler, IVisibleEditor, ISaveEditorsOptions, IRevertAllEditorsOptions, IResourceEditor } from 'vs/workbench/services/editor/common/editorService';
B
Benjamin Pasero 已提交
57 58
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
import { ICodeEditor, IDiffEditor } from 'vs/editor/browser/editorBrowser';
59
import { IEditorRegistry, EditorDescriptor, Extensions } from 'vs/workbench/browser/editor';
B
Benjamin Pasero 已提交
60
import { IDecorationRenderOptions } from 'vs/editor/common/editorCommon';
B
Benjamin Pasero 已提交
61
import { EditorGroup } from 'vs/workbench/common/editor/editorGroup';
62
import { Dimension } from 'vs/base/browser/dom';
63
import { ILogService, NullLogService } from 'vs/platform/log/common/log';
I
isidor 已提交
64
import { ILabelService } from 'vs/platform/label/common/label';
65
import { timeout } from 'vs/base/common/async';
66
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
67
import { ViewletDescriptor, Viewlet } from 'vs/workbench/browser/viewlet';
68
import { IViewlet } from 'vs/workbench/common/viewlet';
69 70
import { IStorageService } from 'vs/platform/storage/common/storage';
import { isLinux } from 'vs/base/common/platform';
I
isidor 已提交
71
import { LabelService } from 'vs/workbench/services/label/common/labelService';
B
Benjamin Pasero 已提交
72
import { IDimension } from 'vs/platform/layout/browser/layoutService';
73
import { Part } from 'vs/workbench/browser/part';
74 75 76
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
import { IPanel } from 'vs/workbench/common/panel';
import { IBadge } from 'vs/workbench/services/activity/common/activity';
77
import { VSBuffer, VSBufferReadable } from 'vs/base/common/buffer';
78
import { Schemas } from 'vs/base/common/network';
79
import { IProductService } from 'vs/platform/product/common/productService';
80
import product from 'vs/platform/product/common/product';
81
import { IHostService } from 'vs/workbench/services/host/browser/host';
82
import { find } from 'vs/base/common/arrays';
83
import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService';
84
import { IFilesConfigurationService, FilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService';
85
import { IAccessibilityService, AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility';
86 87 88 89 90
import { BrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService';
import { BrowserTextFileService } from 'vs/workbench/services/textfile/browser/browserTextFileService';
import * as CommonWorkbenchTestServices from 'vs/workbench/test/common/workbenchTestServices';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { createTextBufferFactoryFromStream } from 'vs/editor/common/model/textModel';
91 92
import { IRemotePathService } from 'vs/workbench/services/path/common/remotePathService';
import { Direction } from 'vs/base/browser/ui/grid/grid';
93
import { IProgressService, IProgressOptions, IProgressWindowOptions, IProgressNotificationOptions, IProgressCompositeOptions, IProgress, IProgressStep, Progress } from 'vs/platform/progress/common/progress';
94
import { IWorkingCopyFileService, WorkingCopyFileService } from 'vs/workbench/services/workingCopy/common/workingCopyFileService';
95 96
import { UndoRedoService } from 'vs/platform/undoRedo/common/undoRedoService';
import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo';
97 98 99 100 101
import { TextFileEditorModel } from 'vs/workbench/services/textfile/common/textFileEditorModel';
import { Registry } from 'vs/platform/registry/common/platform';
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
import { CancellationToken } from 'vs/base/common/cancellation';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
102 103 104 105 106

export import TestTextResourcePropertiesService = CommonWorkbenchTestServices.TestTextResourcePropertiesService;
export import TestContextService = CommonWorkbenchTestServices.TestContextService;
export import TestStorageService = CommonWorkbenchTestServices.TestStorageService;
export import TestWorkingCopyService = CommonWorkbenchTestServices.TestWorkingCopyService;
B
Benjamin Pasero 已提交
107

S
Sandeep Somavarapu 已提交
108
export function createFileInput(instantiationService: IInstantiationService, resource: URI): FileEditorInput {
109
	return instantiationService.createInstance(FileEditorInput, resource, undefined, undefined);
S
Sandeep Somavarapu 已提交
110 111
}

112 113
export interface ITestInstantiationService extends IInstantiationService {
	stub<T>(service: ServiceIdentifier<T>, ctor: any): T;
E
Erich Gamma 已提交
114 115
}

116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
export function workbenchInstantiationService(overrides?: { textFileService?: (instantiationService: IInstantiationService) => ITextFileService }): ITestInstantiationService {
	const instantiationService = new TestInstantiationService(new ServiceCollection([ILifecycleService, new TestLifecycleService()]));

	instantiationService.stub(IWorkingCopyService, new TestWorkingCopyService());
	instantiationService.stub(IEnvironmentService, TestEnvironmentService);
	const contextKeyService = <IContextKeyService>instantiationService.createInstance(MockContextKeyService);
	instantiationService.stub(IContextKeyService, contextKeyService);
	instantiationService.stub(IProgressService, new TestProgressService());
	const workspaceContextService = new TestContextService(TestWorkspace);
	instantiationService.stub(IWorkspaceContextService, workspaceContextService);
	const configService = new TestConfigurationService();
	instantiationService.stub(IConfigurationService, configService);
	instantiationService.stub(IFilesConfigurationService, new TestFilesConfigurationService(contextKeyService, configService, TestEnvironmentService));
	instantiationService.stub(ITextResourceConfigurationService, new TestTextResourceConfigurationService(configService));
	instantiationService.stub(IUntitledTextEditorService, instantiationService.createInstance(UntitledTextEditorService));
	instantiationService.stub(IStorageService, new TestStorageService());
	instantiationService.stub(IWorkbenchLayoutService, new TestLayoutService());
	instantiationService.stub(IDialogService, new TestDialogService());
	instantiationService.stub(IAccessibilityService, new TestAccessibilityService());
	instantiationService.stub(IFileDialogService, new TestFileDialogService());
	instantiationService.stub(IModeService, instantiationService.createInstance(ModeServiceImpl));
	instantiationService.stub(IHistoryService, new TestHistoryService());
	instantiationService.stub(ITextResourcePropertiesService, new TestTextResourcePropertiesService(configService));
	instantiationService.stub(IUndoRedoService, instantiationService.createInstance(UndoRedoService));
	instantiationService.stub(IModelService, instantiationService.createInstance(ModelServiceImpl));
	instantiationService.stub(IFileService, new TestFileService());
	instantiationService.stub(IBackupFileService, new TestBackupFileService());
	instantiationService.stub(ITelemetryService, NullTelemetryService);
	instantiationService.stub(INotificationService, new TestNotificationService());
	instantiationService.stub(IUntitledTextEditorService, instantiationService.createInstance(UntitledTextEditorService));
	instantiationService.stub(IMenuService, new TestMenuService());
	instantiationService.stub(IKeybindingService, new MockKeybindingService());
	instantiationService.stub(IDecorationsService, new TestDecorationsService());
	instantiationService.stub(IExtensionService, new TestExtensionService());
	instantiationService.stub(IWorkingCopyFileService, instantiationService.createInstance(WorkingCopyFileService));
	instantiationService.stub(ITextFileService, overrides?.textFileService ? overrides.textFileService(instantiationService) : <ITextFileService>instantiationService.createInstance(TestTextFileService));
	instantiationService.stub(IHostService, <IHostService>instantiationService.createInstance(TestHostService));
	instantiationService.stub(ITextModelService, <ITextModelService>instantiationService.createInstance(TextModelResolverService));
	instantiationService.stub(IThemeService, new TestThemeService());
	instantiationService.stub(ILogService, new NullLogService());
	const editorGroupService = new TestEditorGroupsService([new TestEditorGroupView(0)]);
	instantiationService.stub(IEditorGroupsService, editorGroupService);
	instantiationService.stub(ILabelService, <ILabelService>instantiationService.createInstance(LabelService));
	const editorService = new TestEditorService(editorGroupService);
	instantiationService.stub(IEditorService, editorService);
	instantiationService.stub(ICodeEditorService, new TestCodeEditorService());
	instantiationService.stub(IViewletService, new TestViewletService());

	return instantiationService;
}

export class TestServiceAccessor {
	constructor(
		@ILifecycleService public lifecycleService: TestLifecycleService,
		@ITextFileService public textFileService: TestTextFileService,
		@IWorkingCopyFileService public workingCopyFileService: IWorkingCopyFileService,
		@IFilesConfigurationService public filesConfigurationService: TestFilesConfigurationService,
		@IWorkspaceContextService public contextService: TestContextService,
		@IModelService public modelService: ModelServiceImpl,
		@IFileService public fileService: TestFileService,
		@IFileDialogService public fileDialogService: TestFileDialogService,
		@IWorkingCopyService public workingCopyService: IWorkingCopyService,
		@IEditorService public editorService: TestEditorService,
		@IEditorGroupsService public editorGroupService: IEditorGroupsService,
		@IModeService public modeService: IModeService,
		@ITextModelService public textModelResolverService: ITextModelService,
		@IUntitledTextEditorService public untitledTextEditorService: UntitledTextEditorService,
		@IConfigurationService public testConfigurationService: TestConfigurationService,
		@IBackupFileService public backupFileService: TestBackupFileService
	) { }
}

188
export class TestTextFileService extends BrowserTextFileService {
189
	private resolveTextContentError!: FileOperationError | null;
A
Alex Dima 已提交
190 191

	constructor(
192
		@IFileService protected fileService: IFileService,
193
		@IUntitledTextEditorService untitledTextEditorService: IUntitledTextEditorService,
194
		@ILifecycleService lifecycleService: ILifecycleService,
195
		@IInstantiationService instantiationService: IInstantiationService,
196
		@IModelService modelService: IModelService,
197
		@IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService,
198 199
		@IDialogService dialogService: IDialogService,
		@IFileDialogService fileDialogService: IFileDialogService,
S
rename  
Sandeep Somavarapu 已提交
200
		@ITextResourceConfigurationService textResourceConfigurationService: ITextResourceConfigurationService,
201
		@IProductService productService: IProductService,
202
		@IFilesConfigurationService filesConfigurationService: IFilesConfigurationService,
203
		@ITextModelService textModelService: ITextModelService,
204
		@ICodeEditorService codeEditorService: ICodeEditorService,
205 206
		@IRemotePathService remotePathService: IRemotePathService,
		@IWorkingCopyFileService workingCopyFileService: IWorkingCopyFileService
A
Alex Dima 已提交
207
	) {
208 209
		super(
			fileService,
210
			untitledTextEditorService,
211 212 213 214 215 216
			lifecycleService,
			instantiationService,
			modelService,
			environmentService,
			dialogService,
			fileDialogService,
217
			textResourceConfigurationService,
218
			filesConfigurationService,
219
			textModelService,
220
			codeEditorService,
221 222
			remotePathService,
			workingCopyFileService
223
		);
A
Alex Dima 已提交
224
	}
225

B
Benjamin Pasero 已提交
226
	setResolveTextContentErrorOnce(error: FileOperationError): void {
227 228 229
		this.resolveTextContentError = error;
	}

B
Benjamin Pasero 已提交
230
	async readStream(resource: URI, options?: IReadTextFileOptions): Promise<ITextFileStreamContent> {
231 232 233 234
		if (this.resolveTextContentError) {
			const error = this.resolveTextContentError;
			this.resolveTextContentError = null;

B
Benjamin Pasero 已提交
235
			throw error;
236 237
		}

B
Benjamin Pasero 已提交
238 239 240 241 242 243 244 245 246 247 248
		const content = await this.fileService.readFileStream(resource, options);
		return {
			resource: content.resource,
			name: content.name,
			mtime: content.mtime,
			ctime: content.ctime,
			etag: content.etag,
			encoding: 'utf8',
			value: await createTextBufferFactoryFromStream(content.value),
			size: 10
		};
249
	}
A
Alex Dima 已提交
250 251
}

252 253
export const TestEnvironmentService = new BrowserWorkbenchEnvironmentService(Object.create(null));

254 255 256 257 258 259 260 261 262
export class TestProgressService implements IProgressService {

	_serviceBrand: undefined;

	withProgress(
		options: IProgressOptions | IProgressWindowOptions | IProgressNotificationOptions | IProgressCompositeOptions,
		task: (progress: IProgress<IProgressStep>) => Promise<any>,
		onDidCancel?: ((choice?: number | undefined) => void) | undefined
	): Promise<any> {
263
		return task(Progress.None);
264 265 266
	}
}

267 268 269 270
export class TestAccessibilityService implements IAccessibilityService {

	_serviceBrand: undefined;

I
isidor 已提交
271
	onDidChangeScreenReaderOptimized = Event.None;
272

I
isidor 已提交
273
	isScreenReaderOptimized(): boolean { return false; }
274 275
	alwaysUnderlineAccessKeys(): Promise<boolean> { return Promise.resolve(false); }
	setAccessibilitySupport(accessibilitySupport: AccessibilitySupport): void { }
276
	getAccessibilitySupport(): AccessibilitySupport { return AccessibilitySupport.Unknown; }
277 278
}

B
Benjamin Pasero 已提交
279
export class TestDecorationsService implements IDecorationsService {
280

281
	_serviceBrand: undefined;
282

B
Benjamin Pasero 已提交
283
	onDidChangeDecorations: Event<IResourceDecorationChangeEvent> = Event.None;
284

285
	registerDecorationsProvider(_provider: IDecorationsProvider): IDisposable { return Disposable.None; }
286
	getDecoration(_uri: URI, _includeChildren: boolean, _overwrite?: IDecorationData): IDecoration | undefined { return undefined; }
B
Benjamin Pasero 已提交
287 288
}

289
export class TestExtensionService extends NullExtensionService { }
B
Benjamin Pasero 已提交
290 291 292

export class TestMenuService implements IMenuService {

B
Benjamin Pasero 已提交
293
	_serviceBrand: undefined;
B
Benjamin Pasero 已提交
294

295
	createMenu(_id: MenuId, _scopedKeybindingService: IContextKeyService): IMenu {
B
Benjamin Pasero 已提交
296 297
		return {
			onDidChange: Event.None,
R
Rob Lourens 已提交
298
			dispose: () => undefined,
B
Benjamin Pasero 已提交
299 300 301 302 303
			getActions: () => []
		};
	}
}

B
Benjamin Pasero 已提交
304 305
export class TestHistoryService implements IHistoryService {

306
	_serviceBrand: undefined;
B
Benjamin Pasero 已提交
307

308 309 310 311 312 313 314 315 316
	constructor(private root?: URI) { }

	reopenLastClosedEditor(): void { }
	forward(): void { }
	back(): void { }
	last(): void { }
	remove(_input: IEditorInput | IResourceInput): void { }
	clear(): void { }
	clearRecentlyOpened(): void { }
317
	getHistory(): ReadonlyArray<IEditorInput | IResourceInput> { return []; }
318 319 320 321 322
	openNextRecentlyUsedEditor(group?: GroupIdentifier): void { }
	openPreviouslyUsedEditor(group?: GroupIdentifier): void { }
	getLastActiveWorkspaceRoot(_schemeFilter: string): URI | undefined { return this.root; }
	getLastActiveFile(_schemeFilter: string): URI | undefined { return undefined; }
	openLastEditLocation(): void { }
B
Benjamin Pasero 已提交
323 324
}

325
export class TestDialogService implements IDialogService {
326

B
Benjamin Pasero 已提交
327
	_serviceBrand: undefined;
E
Erich Gamma 已提交
328

329 330 331
	confirm(_confirmation: IConfirmation): Promise<IConfirmationResult> { return Promise.resolve({ confirmed: false }); }
	show(_severity: Severity, _message: string, _buttons: string[], _options?: IDialogOptions): Promise<IShowResult> { return Promise.resolve({ choice: 0 }); }
	about(): Promise<void> { return Promise.resolve(); }
E
Erich Gamma 已提交
332 333
}

M
Martin Aeschlimann 已提交
334 335
export class TestFileDialogService implements IFileDialogService {

B
Benjamin Pasero 已提交
336
	_serviceBrand: undefined;
M
Martin Aeschlimann 已提交
337

338 339
	private confirmResult!: ConfirmResult;

340 341 342 343 344 345 346 347
	defaultFilePath(_schemeFilter?: string): URI | undefined { return undefined; }
	defaultFolderPath(_schemeFilter?: string): URI | undefined { return undefined; }
	defaultWorkspacePath(_schemeFilter?: string): URI | undefined { return undefined; }
	pickFileFolderAndOpen(_options: IPickAndOpenOptions): Promise<any> { return Promise.resolve(0); }
	pickFileAndOpen(_options: IPickAndOpenOptions): Promise<any> { return Promise.resolve(0); }
	pickFolderAndOpen(_options: IPickAndOpenOptions): Promise<any> { return Promise.resolve(0); }
	pickWorkspaceAndOpen(_options: IPickAndOpenOptions): Promise<any> { return Promise.resolve(0); }

348
	private fileToSave!: URI;
349 350 351 352 353 354 355 356
	setPickFileToSave(path: URI): void { this.fileToSave = path; }
	pickFileToSave(defaultUri: URI, availableFileSystems?: string[]): Promise<URI | undefined> { return Promise.resolve(this.fileToSave); }

	showSaveDialog(_options: ISaveDialogOptions): Promise<URI | undefined> { return Promise.resolve(undefined); }
	showOpenDialog(_options: IOpenDialogOptions): Promise<URI[] | undefined> { return Promise.resolve(undefined); }

	setConfirmResult(result: ConfirmResult): void { this.confirmResult = result; }
	showSaveConfirm(fileNamesOrResources: (string | URI)[]): Promise<ConfirmResult> { return Promise.resolve(this.confirmResult); }
M
Martin Aeschlimann 已提交
357 358
}

359
export class TestLayoutService implements IWorkbenchLayoutService {
B
Benjamin Pasero 已提交
360

B
Benjamin Pasero 已提交
361
	_serviceBrand: undefined;
E
Erich Gamma 已提交
362

363 364
	dimension: IDimension = { width: 800, height: 600 };

365 366
	container: HTMLElement = window.document.body;

B
Benjamin Pasero 已提交
367
	onZenModeChange: Event<boolean> = Event.None;
S
SteVen Batten 已提交
368 369
	onCenteredLayoutChange: Event<boolean> = Event.None;
	onFullscreenChange: Event<boolean> = Event.None;
370
	onMaximizeChange: Event<boolean> = Event.None;
371
	onPanelPositionChange: Event<string> = Event.None;
372
	onPartVisibilityChange: Event<void> = Event.None;
373
	onLayout = Event.None;
B
Benjamin Pasero 已提交
374

375
	private readonly _onMenubarVisibilityChange = new Emitter<Dimension>();
376 377 378 379 380 381 382 383 384 385 386 387 388
	get onMenubarVisibilityChange(): Event<Dimension> { return this._onMenubarVisibilityChange.event; }

	isRestored(): boolean { return true; }
	hasFocus(_part: Parts): boolean { return false; }
	hasWindowBorder(): boolean { return false; }
	getWindowBorderRadius(): string | undefined { return undefined; }
	isVisible(_part: Parts): boolean { return true; }
	getDimension(_part: Parts): Dimension { return new Dimension(0, 0); }
	getContainer(_part: Parts): HTMLElement { return null!; }
	isTitleBarHidden(): boolean { return false; }
	getTitleBarOffset(): number { return 0; }
	isStatusBarHidden(): boolean { return false; }
	isActivityBarHidden(): boolean { return false; }
B
Benjamin Pasero 已提交
389
	setActivityBarHidden(_hidden: boolean): void { }
390
	isSideBarHidden(): boolean { return false; }
B
Benjamin Pasero 已提交
391 392
	setEditorHidden(_hidden: boolean): Promise<void> { return Promise.resolve(); }
	setSideBarHidden(_hidden: boolean): Promise<void> { return Promise.resolve(); }
393
	isPanelHidden(): boolean { return false; }
B
Benjamin Pasero 已提交
394 395
	setPanelHidden(_hidden: boolean): Promise<void> { return Promise.resolve(); }
	toggleMaximizedPanel(): void { }
396 397 398 399 400
	isPanelMaximized(): boolean { return false; }
	getMenubarVisibility(): MenuBarVisibility { throw new Error('not implemented'); }
	getSideBarPosition() { return 0; }
	getPanelPosition() { return 0; }
	setPanelPosition(_position: PartPosition): Promise<void> { return Promise.resolve(); }
B
Benjamin Pasero 已提交
401 402 403 404 405 406 407 408 409 410
	addClass(_clazz: string): void { }
	removeClass(_clazz: string): void { }
	getMaximumEditorDimensions(): Dimension { throw new Error('not implemented'); }
	getWorkbenchContainer(): HTMLElement { throw new Error('not implemented'); }
	getWorkbenchElement(): HTMLElement { throw new Error('not implemented'); }
	toggleZenMode(): void { }
	isEditorLayoutCentered(): boolean { return false; }
	centerEditorLayout(_active: boolean): void { }
	resizePart(_part: Parts, _sizeChange: number): void { }
	registerPart(part: Part): void { }
411
	isWindowMaximized() { return false; }
B
Benjamin Pasero 已提交
412
	updateWindowMaximizedState(maximized: boolean): void { }
S
SteVen Batten 已提交
413
	getVisibleNeighborPart(part: Parts, direction: Direction): Parts | undefined { return undefined; }
E
Erich Gamma 已提交
414 415
}

416
let activeViewlet: Viewlet = {} as any;
417

418
export class TestViewletService implements IViewletService {
B
Benjamin Pasero 已提交
419
	_serviceBrand: undefined;
420 421 422 423 424 425 426 427 428 429 430

	onDidViewletRegisterEmitter = new Emitter<ViewletDescriptor>();
	onDidViewletDeregisterEmitter = new Emitter<ViewletDescriptor>();
	onDidViewletOpenEmitter = new Emitter<IViewlet>();
	onDidViewletCloseEmitter = new Emitter<IViewlet>();

	onDidViewletRegister = this.onDidViewletRegisterEmitter.event;
	onDidViewletDeregister = this.onDidViewletDeregisterEmitter.event;
	onDidViewletOpen = this.onDidViewletOpenEmitter.event;
	onDidViewletClose = this.onDidViewletCloseEmitter.event;

431 432 433 434 435 436 437
	openViewlet(id: string, focus?: boolean): Promise<IViewlet | undefined> { return Promise.resolve(undefined); }
	getViewlets(): ViewletDescriptor[] { return []; }
	getAllViewlets(): ViewletDescriptor[] { return []; }
	getActiveViewlet(): IViewlet { return activeViewlet; }
	getDefaultViewletId(): string { return 'workbench.view.explorer'; }
	getViewlet(id: string): ViewletDescriptor | undefined { return undefined; }
	getProgressIndicator(id: string) { return undefined; }
B
Benjamin Pasero 已提交
438
	hideActiveViewlet(): void { }
439 440
	getLastActiveViewletId(): string { return undefined!; }
	dispose() { }
441 442 443
}

export class TestPanelService implements IPanelService {
B
Benjamin Pasero 已提交
444
	_serviceBrand: undefined;
445 446 447 448

	onDidPanelOpen = new Emitter<{ panel: IPanel, focus: boolean }>().event;
	onDidPanelClose = new Emitter<IPanel>().event;

449 450 451 452 453
	async openPanel(id?: string, focus?: boolean): Promise<undefined> { return undefined; }
	getPanel(id: string): any { return activeViewlet; }
	getPanels() { return []; }
	getPinnedPanels() { return []; }
	getActivePanel(): IViewlet { return activeViewlet; }
B
Benjamin Pasero 已提交
454
	setPanelEnablement(id: string, enabled: boolean): void { }
455 456 457
	dispose() { }
	showActivity(panelId: string, badge: IBadge, clazz?: string): IDisposable { throw new Error('Method not implemented.'); }
	getProgressIndicator(id: string) { return null!; }
B
Benjamin Pasero 已提交
458
	hideActivePanel(): void { }
459
	getLastActivePanelId(): string { return undefined!; }
460 461
}

462 463
export class TestEditorGroupsService implements IEditorGroupsService {

464
	_serviceBrand: undefined;
465

466
	constructor(public groups: TestEditorGroupView[] = []) { }
467

468
	onDidActiveGroupChange: Event<IEditorGroup> = Event.None;
B
Benjamin Pasero 已提交
469
	onDidActivateGroup: Event<IEditorGroup> = Event.None;
470 471 472
	onDidAddGroup: Event<IEditorGroup> = Event.None;
	onDidRemoveGroup: Event<IEditorGroup> = Event.None;
	onDidMoveGroup: Event<IEditorGroup> = Event.None;
473
	onDidGroupIndexChange: Event<IEditorGroup> = Event.None;
474
	onDidLayout: Event<IDimension> = Event.None;
475
	onDidEditorPartOptionsChange = Event.None;
476 477

	orientation: any;
R
Rob Lourens 已提交
478
	whenRestored: Promise<void> = Promise.resolve(undefined);
B
Benjamin Pasero 已提交
479
	willRestoreEditors = false;
480

J
Joao Moreno 已提交
481
	contentDimension = { width: 800, height: 600 };
482

483 484
	get activeGroup(): IEditorGroup { return this.groups[0]; }
	get count(): number { return this.groups.length; }
485

486 487 488 489 490 491 492
	getGroups(_order?: GroupsOrder): ReadonlyArray<IEditorGroup> { return this.groups; }
	getGroup(identifier: number): IEditorGroup | undefined { return find(this.groups, group => group.id === identifier); }
	getLabel(_identifier: number): string { return 'Group 1'; }
	findGroup(_scope: IFindGroupScope, _source?: number | IEditorGroup, _wrap?: boolean): IEditorGroup { throw new Error('not implemented'); }
	activateGroup(_group: number | IEditorGroup): IEditorGroup { throw new Error('not implemented'); }
	restoreGroup(_group: number | IEditorGroup): IEditorGroup { throw new Error('not implemented'); }
	getSize(_group: number | IEditorGroup): { width: number, height: number } { return { width: 100, height: 100 }; }
493
	setSize(_group: number | IEditorGroup, _size: { width: number, height: number }): void { }
494 495 496
	arrangeGroups(_arrangement: GroupsArrangement): void { }
	applyLayout(_layout: EditorGroupLayout): void { }
	setGroupOrientation(_orientation: any): void { }
497
	addGroup(_location: number | IEditorGroup, _direction: GroupDirection, _options?: IAddGroupOptions): IEditorGroup { throw new Error('not implemented'); }
498
	removeGroup(_group: number | IEditorGroup): void { }
499 500 501
	moveGroup(_group: number | IEditorGroup, _location: number | IEditorGroup, _direction: GroupDirection): IEditorGroup { throw new Error('not implemented'); }
	mergeGroup(_group: number | IEditorGroup, _target: number | IEditorGroup, _options?: IMergeGroupOptions): IEditorGroup { throw new Error('not implemented'); }
	copyGroup(_group: number | IEditorGroup, _location: number | IEditorGroup, _direction: GroupDirection): IEditorGroup { throw new Error('not implemented'); }
502
	centerLayout(active: boolean): void { }
503
	isLayoutCentered(): boolean { return false; }
504

505
	partOptions!: IEditorPartOptions;
506
	enforcePartOptions(options: IEditorPartOptions): IDisposable { return Disposable.None; }
507 508
}

509
export class TestEditorGroupView implements IEditorGroupView {
510 511 512

	constructor(public id: number) { }

513
	get group(): EditorGroup { throw new Error('not implemented'); }
514 515 516 517 518
	activeControl!: IVisibleEditor;
	activeEditor!: IEditorInput;
	previewEditor!: IEditorInput;
	count!: number;
	disposed!: boolean;
B
Benjamin Pasero 已提交
519
	editors: ReadonlyArray<IEditorInput> = [];
520
	label!: string;
521
	ariaLabel!: string;
522
	index!: number;
R
Rob Lourens 已提交
523
	whenRestored: Promise<void> = Promise.resolve(undefined);
524 525 526 527 528
	element!: HTMLElement;
	minimumWidth!: number;
	maximumWidth!: number;
	minimumHeight!: number;
	maximumHeight!: number;
529

530 531 532
	isEmpty = true;
	isMinimized = false;

533
	onWillDispose: Event<void> = Event.None;
534
	onDidGroupChange: Event<IGroupChangeEvent> = Event.None;
B
Benjamin Pasero 已提交
535 536
	onWillCloseEditor: Event<IEditorCloseEvent> = Event.None;
	onDidCloseEditor: Event<IEditorCloseEvent> = Event.None;
537 538
	onWillOpenEditor: Event<IEditorOpeningEvent> = Event.None;
	onDidOpenEditorFail: Event<IEditorInput> = Event.None;
B
Benjamin Pasero 已提交
539 540
	onDidFocus: Event<void> = Event.None;
	onDidChange: Event<{ width: number; height: number; }> = Event.None;
541

542 543 544 545 546 547 548 549
	getEditors(_order?: EditorsOrder): ReadonlyArray<IEditorInput> { return []; }
	getEditorByIndex(_index: number): IEditorInput { throw new Error('not implemented'); }
	getIndexOfEditor(_editor: IEditorInput): number { return -1; }
	openEditor(_editor: IEditorInput, _options?: IEditorOptions): Promise<IEditor> { throw new Error('not implemented'); }
	openEditors(_editors: IEditorInputWithOptions[]): Promise<IEditor> { throw new Error('not implemented'); }
	isOpened(_editor: IEditorInput | IResourceInput): boolean { return false; }
	isPinned(_editor: IEditorInput): boolean { return false; }
	isActive(_editor: IEditorInput): boolean { return false; }
550 551
	moveEditor(_editor: IEditorInput, _target: IEditorGroup, _options?: IMoveEditorOptions): void { }
	copyEditor(_editor: IEditorInput, _target: IEditorGroup, _options?: ICopyEditorOptions): void { }
552 553 554 555
	closeEditor(_editor?: IEditorInput, options?: ICloseEditorOptions): Promise<void> { return Promise.resolve(); }
	closeEditors(_editors: IEditorInput[] | { except?: IEditorInput; direction?: CloseDirection; savedOnly?: boolean; }, options?: ICloseEditorOptions): Promise<void> { return Promise.resolve(); }
	closeAllEditors(): Promise<void> { return Promise.resolve(); }
	replaceEditors(_editors: IEditorReplacement[]): Promise<void> { return Promise.resolve(); }
556
	pinEditor(_editor?: IEditorInput): void { }
557
	focus(): void { }
558
	invokeWithinContext<T>(fn: (accessor: ServicesAccessor) => T): T { throw new Error('not implemented'); }
559
	setActive(_isActive: boolean): void { }
B
Benjamin Pasero 已提交
560
	notifyIndexChanged(_index: number): void { }
B
Benjamin Pasero 已提交
561 562
	dispose(): void { }
	toJSON(): object { return Object.create(null); }
563
	layout(_width: number, _height: number): void { }
564
	relayout() { }
565 566
}

567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588
export class TestEditorGroupAccessor implements IEditorGroupsAccessor {

	groups: IEditorGroupView[] = [];
	activeGroup!: IEditorGroupView;

	partOptions: IEditorPartOptions = {};

	onDidEditorPartOptionsChange = Event.None;
	onDidVisibilityChange = Event.None;

	getGroup(identifier: number): IEditorGroupView | undefined { throw new Error('Method not implemented.'); }
	getGroups(order: GroupsOrder): IEditorGroupView[] { throw new Error('Method not implemented.'); }
	activateGroup(identifier: number | IEditorGroupView): IEditorGroupView { throw new Error('Method not implemented.'); }
	restoreGroup(identifier: number | IEditorGroupView): IEditorGroupView { throw new Error('Method not implemented.'); }
	addGroup(location: number | IEditorGroupView, direction: GroupDirection, options?: IAddGroupOptions | undefined): IEditorGroupView { throw new Error('Method not implemented.'); }
	mergeGroup(group: number | IEditorGroupView, target: number | IEditorGroupView, options?: IMergeGroupOptions | undefined): IEditorGroupView { throw new Error('Method not implemented.'); }
	moveGroup(group: number | IEditorGroupView, location: number | IEditorGroupView, direction: GroupDirection): IEditorGroupView { throw new Error('Method not implemented.'); }
	copyGroup(group: number | IEditorGroupView, location: number | IEditorGroupView, direction: GroupDirection): IEditorGroupView { throw new Error('Method not implemented.'); }
	removeGroup(group: number | IEditorGroupView): void { throw new Error('Method not implemented.'); }
	arrangeGroups(arrangement: GroupsArrangement, target?: number | IEditorGroupView | undefined): void { throw new Error('Method not implemented.'); }
}

B
Benjamin Pasero 已提交
589
export class TestEditorService implements EditorServiceImpl {
590

591
	_serviceBrand: undefined;
592 593 594

	onDidActiveEditorChange: Event<void> = Event.None;
	onDidVisibleEditorsChange: Event<void> = Event.None;
B
Benjamin Pasero 已提交
595
	onDidCloseEditor: Event<IEditorCloseEvent> = Event.None;
596
	onDidOpenEditorFail: Event<IEditorIdentifier> = Event.None;
597
	onDidMostRecentlyActiveEditorsChange: Event<void> = Event.None;
598

599
	activeControl!: IVisibleEditor;
600
	activeTextEditorWidget: any;
601
	activeTextEditorMode: any;
602
	activeEditor!: IEditorInput;
603
	editors: ReadonlyArray<IEditorInput> = [];
604
	mostRecentlyActiveEditors: ReadonlyArray<IEditorIdentifier> = [];
M
Matt Bierner 已提交
605
	visibleControls: ReadonlyArray<IVisibleEditor> = [];
606
	visibleTextEditorWidgets = [];
B
Benjamin Pasero 已提交
607
	visibleEditors: ReadonlyArray<IEditorInput> = [];
B
Benjamin Pasero 已提交
608
	count = this.editors.length;
609

B
Benjamin Pasero 已提交
610
	constructor(private editorGroupService?: IEditorGroupsService) { }
611

B
Benjamin Pasero 已提交
612
	getEditors() { return []; }
613 614
	overrideOpenEditor(_handler: IOpenEditorOverrideHandler): IDisposable { return toDisposable(() => undefined); }
	openEditor(_editor: any, _options?: any, _group?: any): Promise<any> { throw new Error('not implemented'); }
615
	doResolveEditorOpenRequest(editor: IEditorInput | IResourceEditor): [IEditorGroup, EditorInput, EditorOptions | undefined] | undefined {
B
Benjamin Pasero 已提交
616 617 618 619
		if (!this.editorGroupService) {
			return undefined;
		}

620 621
		return [this.editorGroupService.activeGroup, editor as EditorInput, undefined];
	}
622 623 624 625 626
	openEditors(_editors: any, _group?: any): Promise<IEditor[]> { throw new Error('not implemented'); }
	isOpen(_editor: IEditorInput | IResourceInput | IUntitledTextResourceInput): boolean { return false; }
	getOpened(_editor: IEditorInput | IResourceInput | IUntitledTextResourceInput): IEditorInput { throw new Error('not implemented'); }
	replaceEditors(_editors: any, _group: any) { return Promise.resolve(undefined); }
	invokeWithinEditorContext<T>(fn: (accessor: ServicesAccessor) => T): T { throw new Error('not implemented'); }
627
	createInput(_input: IResourceInput | IUntitledTextResourceInput | IResourceDiffInput | IResourceSideBySideInput): EditorInput { throw new Error('not implemented'); }
628 629 630 631
	save(editors: IEditorIdentifier[], options?: ISaveEditorsOptions): Promise<boolean> { throw new Error('Method not implemented.'); }
	saveAll(options?: ISaveEditorsOptions): Promise<boolean> { throw new Error('Method not implemented.'); }
	revert(editors: IEditorIdentifier[], options?: IRevertOptions): Promise<boolean> { throw new Error('Method not implemented.'); }
	revertAll(options?: IRevertAllEditorsOptions): Promise<boolean> { throw new Error('Method not implemented.'); }
632 633
}

634 635
export class TestFileService implements IFileService {

B
Benjamin Pasero 已提交
636
	_serviceBrand: undefined;
637

638 639
	private readonly _onDidFilesChange = new Emitter<FileChangesEvent>();
	private readonly _onDidRunOperation = new Emitter<FileOperationEvent>();
640

641
	readonly onWillActivateFileSystemProvider = Event.None;
642
	readonly onDidChangeFileSystemProviderCapabilities = Event.None;
643
	readonly onError: Event<Error> = Event.None;
644

645
	private content = 'Hello Html';
646
	private lastReadFileUri!: URI;
647

648 649 650
	setContent(content: string): void { this.content = content; }
	getContent(): string { return this.content; }
	getLastReadFileUri(): URI { return this.lastReadFileUri; }
651 652 653 654
	get onDidFilesChange(): Event<FileChangesEvent> { return this._onDidFilesChange.event; }
	fireFileChanges(event: FileChangesEvent): void { this._onDidFilesChange.fire(event); }
	get onDidRunOperation(): Event<FileOperationEvent> { return this._onDidRunOperation.event; }
	fireAfterOperation(event: FileOperationEvent): void { this._onDidRunOperation.fire(event); }
B
Benjamin Pasero 已提交
655 656 657
	resolve(resource: URI, _options?: IResolveFileOptions): Promise<IFileStat>;
	resolve(resource: URI, _options: IResolveMetadataFileOptions): Promise<IFileStatWithMetadata>;
	resolve(resource: URI, _options?: IResolveFileOptions): Promise<IFileStat> {
B
Benjamin Pasero 已提交
658
		return Promise.resolve({
659 660
			resource,
			etag: Date.now().toString(),
B
Benjamin Pasero 已提交
661
			encoding: 'utf8',
B
Benjamin Pasero 已提交
662
			mtime: Date.now(),
663
			size: 42,
664
			isFile: true,
665
			isDirectory: false,
666
			isSymbolicLink: false,
B
Benjamin Pasero 已提交
667
			name: resources.basename(resource)
B
Benjamin Pasero 已提交
668
		});
669
	}
B
Benjamin Pasero 已提交
670

B
Benjamin Pasero 已提交
671 672 673 674
	async resolveAll(toResolve: { resource: URI, options?: IResolveFileOptions }[]): Promise<IResolveFileResult[]> {
		const stats = await Promise.all(toResolve.map(resourceAndOption => this.resolve(resourceAndOption.resource, resourceAndOption.options)));

		return stats.map(stat => ({ stat, success: true }));
I
isidor 已提交
675 676
	}

677
	async exists(_resource: URI): Promise<boolean> { return true; }
B
Benjamin Pasero 已提交
678

679
	readFile(resource: URI, options?: IReadFileOptions | undefined): Promise<IFileContent> {
680 681
		this.lastReadFileUri = resource;

682
		return Promise.resolve({
B
Benjamin Pasero 已提交
683
			resource: resource,
684
			value: VSBuffer.fromString(this.content),
685
			etag: 'index.txt',
B
Benjamin Pasero 已提交
686 687
			encoding: 'utf8',
			mtime: Date.now(),
688
			ctime: Date.now(),
689 690
			name: resources.basename(resource),
			size: 1
E
Erich Gamma 已提交
691
		});
692
	}
E
Erich Gamma 已提交
693

694
	readFileStream(resource: URI, options?: IReadFileOptions | undefined): Promise<IFileStreamContent> {
695 696
		this.lastReadFileUri = resource;

697
		return Promise.resolve({
A
Alex Dima 已提交
698 699
			resource: resource,
			value: {
700
				on: (event: string, callback: Function): void => {
A
Alex Dima 已提交
701
					if (event === 'data') {
702
						callback(this.content);
A
Alex Dima 已提交
703 704 705 706
					}
					if (event === 'end') {
						callback();
					}
B
Benjamin Pasero 已提交
707 708 709 710
				},
				resume: () => { },
				pause: () => { },
				destroy: () => { }
A
Alex Dima 已提交
711 712 713
			},
			etag: 'index.txt',
			encoding: 'utf8',
B
Benjamin Pasero 已提交
714
			mtime: Date.now(),
715
			ctime: Date.now(),
716 717
			size: 1,
			name: resources.basename(resource)
A
Alex Dima 已提交
718
		});
719 720
	}

721 722
	writeShouldThrowError: Error | undefined = undefined;

B
Benjamin Pasero 已提交
723 724 725
	async writeFile(resource: URI, bufferOrReadable: VSBuffer | VSBufferReadable, options?: IWriteFileOptions): Promise<IFileStatWithMetadata> {
		await timeout(0);

726 727 728 729
		if (this.writeShouldThrowError) {
			throw this.writeShouldThrowError;
		}

B
Benjamin Pasero 已提交
730
		return ({
731 732 733
			resource,
			etag: 'index.txt',
			mtime: Date.now(),
734
			ctime: Date.now(),
735
			size: 42,
736
			isFile: true,
737
			isDirectory: false,
738
			isSymbolicLink: false,
B
Benjamin Pasero 已提交
739
			name: resources.basename(resource)
B
Benjamin Pasero 已提交
740
		});
741
	}
D
Daniel Imms 已提交
742

743 744 745 746
	move(_source: URI, _target: URI, _overwrite?: boolean): Promise<IFileStatWithMetadata> { return Promise.resolve(null!); }
	copy(_source: URI, _target: URI, _overwrite?: boolean): Promise<IFileStatWithMetadata> { return Promise.resolve(null!); }
	createFile(_resource: URI, _content?: VSBuffer | VSBufferReadable, _options?: ICreateFileOptions): Promise<IFileStatWithMetadata> { return Promise.resolve(null!); }
	createFolder(_resource: URI): Promise<IFileStatWithMetadata> { throw new Error('not implemented'); }
747

748 749
	onDidChangeFileSystemProviderRegistrations = Event.None;

750 751 752 753 754 755
	private providers = new Map<string, IFileSystemProvider>();

	registerProvider(scheme: string, provider: IFileSystemProvider) {
		this.providers.set(scheme, provider);

		return toDisposable(() => this.providers.delete(scheme));
756 757
	}

758 759
	activateProvider(_scheme: string): Promise<void> { throw new Error('not implemented'); }
	canHandleResource(resource: URI): boolean { return resource.scheme === 'file' || this.providers.has(resource.scheme); }
760 761 762 763 764 765 766
	hasCapability(resource: URI, capability: FileSystemProviderCapabilities): boolean {
		if (capability === FileSystemProviderCapabilities.PathCaseSensitive && isLinux) {
			return true;
		}

		return false;
	}
767

768
	del(_resource: URI, _options?: { useTrash?: boolean, recursive?: boolean }): Promise<void> { return Promise.resolve(); }
769 770 771 772 773 774 775 776

	readonly watches: URI[] = [];
	watch(_resource: URI): IDisposable {
		this.watches.push(_resource);

		return toDisposable(() => this.watches.splice(this.watches.indexOf(_resource), 1));
	}

777 778
	getWriteEncoding(_resource: URI): IResourceEncoding { return { encoding: 'utf8', hasBOM: false }; }
	dispose(): void { }
779
}
780

781
export class TestBackupFileService implements IBackupFileService {
B
Benjamin Pasero 已提交
782
	_serviceBrand: undefined;
783

784 785 786 787 788 789 790 791 792
	hasBackups(): Promise<boolean> { return Promise.resolve(false); }
	hasBackup(_resource: URI): Promise<boolean> { return Promise.resolve(false); }
	hasBackupSync(resource: URI, versionId?: number): boolean { return false; }
	registerResourceForBackup(_resource: URI): Promise<void> { return Promise.resolve(); }
	deregisterResourceForBackup(_resource: URI): Promise<void> { return Promise.resolve(); }
	backup<T extends object>(_resource: URI, _content?: ITextSnapshot, versionId?: number, meta?: T): Promise<void> { return Promise.resolve(); }
	getBackups(): Promise<URI[]> { return Promise.resolve([]); }
	resolve<T extends object>(_backup: URI): Promise<IResolvedBackup<T> | undefined> { return Promise.resolve(undefined); }
	discardBackup(_resource: URI): Promise<void> { return Promise.resolve(); }
B
Benjamin Pasero 已提交
793
	parseBackupContent(textBufferFactory: ITextBufferFactory): string {
794 795 796 797
		const textBuffer = textBufferFactory.create(DefaultEndOfLine.LF);
		const lineCount = textBuffer.getLineCount();
		const range = new Range(1, 1, lineCount, textBuffer.getLineLength(lineCount) + 1);
		return textBuffer.getValueInRange(range, EndOfLinePreference.TextDefined);
798
	}
799
}
D
Daniel Imms 已提交
800

B
Benjamin Pasero 已提交
801
export class TestCodeEditorService implements ICodeEditorService {
802
	_serviceBrand: undefined;
B
Benjamin Pasero 已提交
803 804 805 806 807

	onCodeEditorAdd: Event<ICodeEditor> = Event.None;
	onCodeEditorRemove: Event<ICodeEditor> = Event.None;
	onDiffEditorAdd: Event<IDiffEditor> = Event.None;
	onDiffEditorRemove: Event<IDiffEditor> = Event.None;
A
Alex Dima 已提交
808
	onDidChangeTransientModelProperty: Event<ITextModel> = Event.None;
B
Benjamin Pasero 已提交
809

810 811
	addCodeEditor(_editor: ICodeEditor): void { }
	removeCodeEditor(_editor: ICodeEditor): void { }
B
Benjamin Pasero 已提交
812
	listCodeEditors(): ICodeEditor[] { return []; }
813 814
	addDiffEditor(_editor: IDiffEditor): void { }
	removeDiffEditor(_editor: IDiffEditor): void { }
B
Benjamin Pasero 已提交
815
	listDiffEditors(): IDiffEditor[] { return []; }
816
	getFocusedCodeEditor(): ICodeEditor | null { return null; }
817 818 819 820 821
	registerDecorationType(_key: string, _options: IDecorationRenderOptions, _parentTypeKey?: string): void { }
	removeDecorationType(_key: string): void { }
	resolveDecorationOptions(_typeKey: string, _writable: boolean): IModelDecorationOptions { return Object.create(null); }
	setTransientModelProperty(_model: ITextModel, _key: string, _value: any): void { }
	getTransientModelProperty(_model: ITextModel, _key: string) { }
822
	getTransientModelProperties(_model: ITextModel) { return undefined; }
823 824
	getActiveCodeEditor(): ICodeEditor | null { return null; }
	openCodeEditor(_input: IResourceInput, _source: ICodeEditor, _sideBySide?: boolean): Promise<ICodeEditor | null> { return Promise.resolve(null); }
B
Benjamin Pasero 已提交
825 826
}

827 828
export class TestLifecycleService implements ILifecycleService {

B
Benjamin Pasero 已提交
829
	_serviceBrand: undefined;
830

B
Benjamin Pasero 已提交
831 832
	phase!: LifecyclePhase;
	startupKind!: StartupKind;
833

834
	private readonly _onBeforeShutdown = new Emitter<BeforeShutdownEvent>();
835 836
	get onBeforeShutdown(): Event<BeforeShutdownEvent> { return this._onBeforeShutdown.event; }

837
	private readonly _onWillShutdown = new Emitter<WillShutdownEvent>();
838 839
	get onWillShutdown(): Event<WillShutdownEvent> { return this._onWillShutdown.event; }

840
	private readonly _onShutdown = new Emitter<void>();
841
	get onShutdown(): Event<void> { return this._onShutdown.event; }
842

843
	when(): Promise<void> { return Promise.resolve(); }
844

B
Benjamin Pasero 已提交
845
	fireShutdown(reason = ShutdownReason.QUIT): void {
846
		this._onWillShutdown.fire({
847 848 849
			join: () => { },
			reason
		});
850 851
	}

852
	fireWillShutdown(event: BeforeShutdownEvent): void { this._onBeforeShutdown.fire(event); }
853 854
}

S
rename  
Sandeep Somavarapu 已提交
855
export class TestTextResourceConfigurationService implements ITextResourceConfigurationService {
856

857
	_serviceBrand: undefined;
858

859
	constructor(private configurationService = new TestConfigurationService()) { }
860

B
Benjamin Pasero 已提交
861
	onDidChangeConfiguration() {
862 863 864
		return { dispose() { } };
	}

865
	getValue<T>(resource: URI, arg2?: any, arg3?: any): T {
866 867
		const position: IPosition | null = EditorPosition.isIPosition(arg2) ? arg2 : null;
		const section: string | undefined = position ? (typeof arg3 === 'string' ? arg3 : undefined) : (typeof arg2 === 'string' ? arg2 : undefined);
868
		return this.configurationService.getValue(section, { resource });
869
	}
870 871 872 873

	updateValue(resource: URI, key: string, value: any, configurationTarget?: ConfigurationTarget): Promise<void> {
		return this.configurationService.updateValue(key, value);
	}
B
Benjamin Pasero 已提交
874 875
}

876 877 878 879 880 881 882
export class RemoteFileSystemProvider implements IFileSystemProvider {

	constructor(private readonly diskFileSystemProvider: IFileSystemProvider, private readonly remoteAuthority: string) { }

	readonly capabilities: FileSystemProviderCapabilities = this.diskFileSystemProvider.capabilities;
	readonly onDidChangeCapabilities: Event<void> = this.diskFileSystemProvider.onDidChangeCapabilities;

M
Matt Bierner 已提交
883 884 885 886 887 888
	readonly onDidChangeFile: Event<readonly IFileChange[]> = Event.map(this.diskFileSystemProvider.onDidChangeFile, changes => changes.map((c): IFileChange => {
		return {
			type: c.type,
			resource: c.resource.with({ scheme: Schemas.vscodeRemote, authority: this.remoteAuthority }),
		};
	}));
889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907
	watch(resource: URI, opts: IWatchOptions): IDisposable { return this.diskFileSystemProvider.watch(this.toFileResource(resource), opts); }

	stat(resource: URI): Promise<IStat> { return this.diskFileSystemProvider.stat(this.toFileResource(resource)); }
	mkdir(resource: URI): Promise<void> { return this.diskFileSystemProvider.mkdir(this.toFileResource(resource)); }
	readdir(resource: URI): Promise<[string, FileType][]> { return this.diskFileSystemProvider.readdir(this.toFileResource(resource)); }
	delete(resource: URI, opts: FileDeleteOptions): Promise<void> { return this.diskFileSystemProvider.delete(this.toFileResource(resource), opts); }

	rename(from: URI, to: URI, opts: FileOverwriteOptions): Promise<void> { return this.diskFileSystemProvider.rename(this.toFileResource(from), this.toFileResource(to), opts); }
	copy(from: URI, to: URI, opts: FileOverwriteOptions): Promise<void> { return this.diskFileSystemProvider.copy!(this.toFileResource(from), this.toFileResource(to), opts); }

	readFile(resource: URI): Promise<Uint8Array> { return this.diskFileSystemProvider.readFile!(this.toFileResource(resource)); }
	writeFile(resource: URI, content: Uint8Array, opts: FileWriteOptions): Promise<void> { return this.diskFileSystemProvider.writeFile!(this.toFileResource(resource), content, opts); }

	open(resource: URI, opts: FileOpenOptions): Promise<number> { return this.diskFileSystemProvider.open!(this.toFileResource(resource), opts); }
	close(fd: number): Promise<void> { return this.diskFileSystemProvider.close!(fd); }
	read(fd: number, pos: number, data: Uint8Array, offset: number, length: number): Promise<number> { return this.diskFileSystemProvider.read!(fd, pos, data, offset, length); }
	write(fd: number, pos: number, data: Uint8Array, offset: number, length: number): Promise<number> { return this.diskFileSystemProvider.write!(fd, pos, data, offset, length); }

	private toFileResource(resource: URI): URI { return resource.with({ scheme: Schemas.file, authority: '' }); }
J
Joao Moreno 已提交
908
}
909 910

export const productService: IProductService = { _serviceBrand: undefined, ...product };
911 912 913 914 915

export class TestHostService implements IHostService {

	_serviceBrand: undefined;

916
	readonly hasFocus: boolean = true;
J
João Moreno 已提交
917
	async hadLastFocus(): Promise<boolean> { return true; }
918 919
	readonly onDidChangeFocus: Event<boolean> = Event.None;

920 921
	async restart(): Promise<void> { }
	async reload(): Promise<void> { }
922

923 924
	async focus(): Promise<void> { }

925 926 927 928 929
	async openWindow(arg1?: IOpenEmptyWindowOptions | IWindowOpenable[], arg2?: IOpenWindowOptions): Promise<void> { }

	async toggleFullScreen(): Promise<void> { }
}

930 931 932 933 934 935
export class TestFilesConfigurationService extends FilesConfigurationService {

	onFilesConfigurationChange(configuration: any): void {
		super.onFilesConfigurationChange(configuration);
	}
}
936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068

export class TestReadonlyTextFileEditorModel extends TextFileEditorModel {

	isReadonly(): boolean {
		return true;
	}
}

export class TestEditorInput extends EditorInput {

	constructor(public resource: URI, private typeId: string) {
		super();
	}

	getTypeId(): string {
		return this.typeId;
	}

	resolve(): Promise<IEditorModel | null> {
		return Promise.resolve(null);
	}
}

export function registerTestEditor(id: string, inputs: SyncDescriptor<EditorInput>[], factoryInputId?: string): IDisposable {
	class TestEditorControl extends BaseEditor {

		constructor() { super(id, NullTelemetryService, new TestThemeService(), new TestStorageService()); }

		async setInput(input: EditorInput, options: EditorOptions | undefined, token: CancellationToken): Promise<void> {
			super.setInput(input, options, token);

			await input.resolve();
		}

		getId(): string { return id; }
		layout(): void { }
		createEditor(): any { }
	}

	const disposables = new DisposableStore();

	disposables.add(Registry.as<IEditorRegistry>(Extensions.Editors).registerEditor(EditorDescriptor.create(TestEditorControl, id, 'Test Editor Control'), inputs));

	if (factoryInputId) {

		interface ISerializedTestInput {
			resource: string;
		}

		class EditorsObserverTestEditorInputFactory implements IEditorInputFactory {

			canSerialize(editorInput: EditorInput): boolean {
				return true;
			}

			serialize(editorInput: EditorInput): string {
				let testEditorInput = <TestFileEditorInput>editorInput;
				let testInput: ISerializedTestInput = {
					resource: testEditorInput.resource.toString()
				};

				return JSON.stringify(testInput);
			}

			deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): EditorInput {
				let testInput: ISerializedTestInput = JSON.parse(serializedEditorInput);

				return new TestFileEditorInput(URI.parse(testInput.resource), factoryInputId!);
			}
		}

		disposables.add(Registry.as<IEditorInputFactoryRegistry>(EditorExtensions.EditorInputFactories).registerEditorInputFactory(factoryInputId, EditorsObserverTestEditorInputFactory));
	}

	return disposables;
}

export class TestFileEditorInput extends EditorInput implements IFileEditorInput {
	gotDisposed = false;
	gotSaved = false;
	gotSavedAs = false;
	gotReverted = false;
	dirty = false;
	private fails = false;

	constructor(
		public resource: URI,
		private typeId: string
	) {
		super();
	}

	getTypeId() { return this.typeId; }
	resolve(): Promise<IEditorModel | null> { return !this.fails ? Promise.resolve(null) : Promise.reject(new Error('fails')); }
	matches(other: TestEditorInput): boolean { return other && other.resource && this.resource.toString() === other.resource.toString() && other instanceof TestFileEditorInput && other.getTypeId() === this.typeId; }
	setEncoding(encoding: string) { }
	getEncoding() { return undefined; }
	setPreferredEncoding(encoding: string) { }
	setMode(mode: string) { }
	setPreferredMode(mode: string) { }
	setForceOpenAsBinary(): void { }
	setFailToOpen(): void {
		this.fails = true;
	}
	async save(groupId: GroupIdentifier, options?: ISaveOptions): Promise<IEditorInput | undefined> {
		this.gotSaved = true;
		return this;
	}
	async saveAs(groupId: GroupIdentifier, options?: ISaveOptions): Promise<IEditorInput | undefined> {
		this.gotSavedAs = true;
		return this;
	}
	async revert(group: GroupIdentifier, options?: IRevertOptions): Promise<boolean> {
		this.gotReverted = true;
		this.gotSaved = false;
		this.gotSavedAs = false;
		return true;
	}
	setDirty(): void { this.dirty = true; }
	isDirty(): boolean {
		return this.dirty;
	}
	isReadonly(): boolean {
		return false;
	}
	isResolved(): boolean { return false; }
	dispose(): void {
		super.dispose();
		this.gotDisposed = true;
	}
	movedEditor: IMoveResult | undefined = undefined;
	move(): IMoveResult | undefined { return this.movedEditor; }
}