diff --git a/src/vs/workbench/common/editor/editorStacksModel.ts b/src/vs/workbench/common/editor/editorStacksModel.ts index b45c7f158f4a69a36dbb8313ecf9e2972af61c3a..881de660fb9a8cd39a33814aa586a7d8334cb423 100644 --- a/src/vs/workbench/common/editor/editorStacksModel.ts +++ b/src/vs/workbench/common/editor/editorStacksModel.ts @@ -95,12 +95,12 @@ export function setOpenEditorDirection(dir: Direction): void { DEFAULT_OPEN_EDITOR_DIRECTION = dir; } -interface ISerializedEditorInput { +export interface ISerializedEditorInput { id: string; value: string; } -interface ISerializedEditorGroup { +export interface ISerializedEditorGroup { label: string; editors: ISerializedEditorInput[]; mru: number[]; diff --git a/src/vs/workbench/test/common/editor/editorStacksModel.test.ts b/src/vs/workbench/test/common/editor/editorStacksModel.test.ts index 70bb7829d18197414d615d590a114d86c5bddff9..42d69770a93a27a6aae6841fed843893e7968a06 100644 --- a/src/vs/workbench/test/common/editor/editorStacksModel.test.ts +++ b/src/vs/workbench/test/common/editor/editorStacksModel.test.ts @@ -8,16 +8,19 @@ import * as assert from 'assert'; import {EditorStacksModel, IEditorStacksModel, IEditorGroup, setOpenEditorDirection, Direction} from 'vs/workbench/common/editor/editorStacksModel'; import {EditorInput} from 'vs/workbench/common/editor'; -import {TestStorageService} from 'vs/workbench/test/common/servicesTestUtils'; +import {TestStorageService, TestLifecycleService} from 'vs/workbench/test/common/servicesTestUtils'; import {InstantiationService} from 'vs/platform/instantiation/common/instantiationService'; import {ServiceCollection} from 'vs/platform/instantiation/common/serviceCollection'; import {IStorageService} from 'vs/platform/storage/common/storage'; -import {ILifecycleService, NullLifecycleService} from 'vs/platform/lifecycle/common/lifecycle'; +import {ILifecycleService} from 'vs/platform/lifecycle/common/lifecycle'; +import {IEditorRegistry, Extensions as EditorExtensions, IEditorInputFactory} from 'vs/workbench/browser/parts/editor/baseEditor'; +import {Registry} from 'vs/platform/platform'; +import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation'; function create(): IEditorStacksModel { let services = new ServiceCollection(); services.set(IStorageService, new TestStorageService()); - services.set(ILifecycleService, NullLifecycleService); + services.set(ILifecycleService, new TestLifecycleService()); let inst = new InstantiationService(services); @@ -75,14 +78,52 @@ class TestEditorInput extends EditorInput { constructor(public id: string) { super(); } - public getId() { return 'id'; } + public getId() { return 'testEditorInput'; } public resolve() { return null; } + + public matches(other: TestEditorInput): boolean { + return this.id === other.id; + } +} + +class NonSerializableTestEditorInput extends EditorInput { + constructor(public id: string) { + super(); + } + public getId() { return 'testEditorInput-nonSerializable'; } + public resolve() { return null; } +} + +function input(id = String(index++), nonSerializable?: boolean): EditorInput { + return nonSerializable ? new NonSerializableTestEditorInput(id) : new TestEditorInput(id); } -function input(id = String(index++)): EditorInput { - return new TestEditorInput(id); +interface ISerializedTestInput { + id: string; } +class TestEditorInputFactory implements IEditorInputFactory { + + constructor() { } + + public serialize(editorInput: EditorInput): string { + let testEditorInput = editorInput; + let testInput: ISerializedTestInput = { + id: testEditorInput.id + }; + + return JSON.stringify(testInput); + } + + public deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): EditorInput { + let testInput: ISerializedTestInput = JSON.parse(serializedEditorInput); + + return new TestEditorInput(testInput.id); + } +} + +(Registry.as(EditorExtensions.Editors)).registerEditorInputFactory('testEditorInput', TestEditorInputFactory); + suite('Editor Stacks Model', () => { teardown(() => { @@ -642,4 +683,41 @@ suite('Editor Stacks Model', () => { assert.equal(group.activeEditor, null); assert.equal(group.previewEditor, null); }); + + test('Stack - Single Group, Single Editor - persist', function () { + let services = new ServiceCollection(); + + services.set(IStorageService, new TestStorageService()); + const lifecycle = new TestLifecycleService(); + services.set(ILifecycleService, lifecycle); + + let inst = new InstantiationService(services); + + (Registry.as(EditorExtensions.Editors)).setInstantiationService(inst); + + let model:IEditorStacksModel = inst.createInstance(EditorStacksModel); + const group = model.openGroup('group'); + + const input1 = input(); + group.openEditor(input1); + + assert.equal(model.groups.length, 1); + assert.equal(group.count, 1); + assert.equal(group.activeEditor.matches(input1), true); + assert.equal(group.previewEditor.matches(input1), true); + assert.equal(group.label, 'group'); + assert.equal(group.isActive(input1), true); + + lifecycle.fireShutdown(); + + // Create model again - should load from storage + model = inst.createInstance(EditorStacksModel); + + assert.equal(model.groups.length, 1); + assert.equal(group.count, 1); + assert.equal(group.activeEditor.matches(input1), true); + assert.equal(group.previewEditor.matches(input1), true); + assert.equal(group.label, 'group'); + assert.equal(group.isActive(input1), true); + }); }); \ No newline at end of file diff --git a/src/vs/workbench/test/common/servicesTestUtils.ts b/src/vs/workbench/test/common/servicesTestUtils.ts index 1790f47e49c3a665c7b4ed814c61988a0f1bbfad..f7b208582a021cb6518615bd0621b82a13a93832 100644 --- a/src/vs/workbench/test/common/servicesTestUtils.ts +++ b/src/vs/workbench/test/common/servicesTestUtils.ts @@ -12,7 +12,7 @@ import URI from 'vs/base/common/uri'; import {NullTelemetryService} from 'vs/platform/telemetry/common/telemetry'; import Storage = require('vs/workbench/common/storage'); import WorkbenchEditorCommon = require('vs/workbench/common/editor'); -import Event from 'vs/base/common/event'; +import Event, {Emitter} from 'vs/base/common/event'; import Types = require('vs/base/common/types'); import Severity from 'vs/base/common/severity'; import http = require('vs/base/common/http'); @@ -28,6 +28,7 @@ import {IUntitledEditorService} from 'vs/workbench/services/untitled/common/unti import {IMessageService, IConfirmation} from 'vs/platform/message/common/message'; import {BaseRequestService} from 'vs/platform/request/common/baseRequestService'; import {IWorkspace, IConfiguration} from 'vs/platform/workspace/common/workspace'; +import {ILifecycleService, ShutdownEvent} from 'vs/platform/lifecycle/common/lifecycle'; export const TestWorkspace: IWorkspace = { resource: URI.file('C:\\testWorkspace'), @@ -460,4 +461,27 @@ export class TestConfigurationService extends EventEmitter.EventEmitter implemen public onDidUpdateConfiguration() { return { dispose() { } }; } +} + +export class TestLifecycleService implements ILifecycleService { + + public serviceId = ILifecycleService; + + private _onWillShutdown = new Emitter(); + private _onShutdown = new Emitter(); + + constructor() { + } + + public fireShutdown(): void { + this._onShutdown.fire(); + } + + public get onWillShutdown(): Event { + return this._onWillShutdown.event; + } + + public get onShutdown(): Event { + return this._onShutdown.event; + } } \ No newline at end of file