Files
vscode/src/vs/workbench/api/test/browser/extHostEditorTabs.test.ts
2022-03-14 14:55:08 -04:00

270 lines
8.6 KiB
TypeScript

/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import assert = require('assert');
import { URI } from 'vs/base/common/uri';
import { mock } from 'vs/base/test/common/mock';
import { IEditorTabDto, MainThreadEditorTabsShape, TabKind } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostEditorTabs, IEditorTabGroup } from 'vs/workbench/api/common/extHostEditorTabs';
import { SingleProxyRPCProtocol } from 'vs/workbench/api/test/common/testRPCProtocol';
suite('ExtHostEditorTabs', function () {
test('empty', function () {
const extHostEditorTabs = new ExtHostEditorTabs(
SingleProxyRPCProtocol(new class extends mock<MainThreadEditorTabsShape>() {
// override/implement $moveTab or $closeTab
})
);
assert.strictEqual(extHostEditorTabs.tabGroups.groups.length, 0);
assert.strictEqual(extHostEditorTabs.tabGroups.activeTabGroup, undefined);
});
test('single tab', function () {
const extHostEditorTabs = new ExtHostEditorTabs(
SingleProxyRPCProtocol(new class extends mock<MainThreadEditorTabsShape>() {
// override/implement $moveTab or $closeTab
})
);
const tab: IEditorTabDto = {
isActive: true,
isDirty: true,
isPinned: true,
label: 'label1',
viewColumn: 0,
additionalResourcesAndViewTypes: [],
kind: TabKind.Singular
};
extHostEditorTabs.$acceptEditorTabModel([{
isActive: true,
viewColumn: 0,
groupId: 12,
tabs: [tab],
activeTab: { ...tab }
}]);
assert.strictEqual(extHostEditorTabs.tabGroups.groups.length, 1);
const [first] = extHostEditorTabs.tabGroups.groups;
assert.ok(first.activeTab);
assert.strictEqual(first.tabs.indexOf(first.activeTab), 0);
{
extHostEditorTabs.$acceptEditorTabModel([{
isActive: true,
viewColumn: 0,
groupId: 12,
tabs: [tab],
activeTab: undefined! // TODO@lramos15 unused
}]);
assert.strictEqual(extHostEditorTabs.tabGroups.groups.length, 1);
const [first] = extHostEditorTabs.tabGroups.groups;
assert.ok(first.activeTab);
assert.strictEqual(first.tabs.indexOf(first.activeTab), 0);
}
});
test('Empty tab group', function () {
const extHostEditorTabs = new ExtHostEditorTabs(
SingleProxyRPCProtocol(new class extends mock<MainThreadEditorTabsShape>() {
// override/implement $moveTab or $closeTab
})
);
extHostEditorTabs.$acceptEditorTabModel([{
isActive: true,
viewColumn: 0,
groupId: 12,
tabs: [],
activeTab: undefined
}]);
assert.strictEqual(extHostEditorTabs.tabGroups.groups.length, 1);
const [first] = extHostEditorTabs.tabGroups.groups;
assert.strictEqual(first.activeTab, undefined);
assert.strictEqual(first.tabs.length, 0);
});
test('Ensure tabGroup change events fires', function () {
const extHostEditorTabs = new ExtHostEditorTabs(
SingleProxyRPCProtocol(new class extends mock<MainThreadEditorTabsShape>() {
// override/implement $moveTab or $closeTab
})
);
let count = 0;
extHostEditorTabs.tabGroups.onDidChangeTabGroup(() => count++);
assert.strictEqual(extHostEditorTabs.tabGroups.groups.length, 0);
assert.strictEqual(extHostEditorTabs.tabGroups.activeTabGroup, undefined);
assert.strictEqual(count, 0);
extHostEditorTabs.$acceptEditorTabModel([{
isActive: true,
viewColumn: 0,
groupId: 12,
tabs: [],
activeTab: undefined
}]);
assert.ok(extHostEditorTabs.tabGroups.activeTabGroup);
const activeTabGroup: IEditorTabGroup = extHostEditorTabs.tabGroups.activeTabGroup;
assert.strictEqual(extHostEditorTabs.tabGroups.groups.length, 1);
assert.strictEqual(activeTabGroup.tabs.length, 0);
assert.strictEqual(count, 1);
});
test('Ensure reference equality for activeTab and activeGroup', function () {
const extHostEditorTabs = new ExtHostEditorTabs(
SingleProxyRPCProtocol(new class extends mock<MainThreadEditorTabsShape>() {
// override/implement $moveTab or $closeTab
})
);
const tab: IEditorTabDto = {
isActive: true,
isDirty: true,
isPinned: true,
label: 'label1',
resource: URI.parse('file://abc/def.txt'),
editorId: 'default',
viewColumn: 0,
additionalResourcesAndViewTypes: [],
kind: TabKind.Singular
};
extHostEditorTabs.$acceptEditorTabModel([{
isActive: true,
viewColumn: 0,
groupId: 12,
tabs: [tab],
activeTab: { ...tab }
}]);
assert.strictEqual(extHostEditorTabs.tabGroups.groups.length, 1);
const [first] = extHostEditorTabs.tabGroups.groups;
assert.ok(first.activeTab);
assert.strictEqual(first.tabs.indexOf(first.activeTab), 0);
assert.strictEqual(first.activeTab, first.tabs[0]);
assert.strictEqual(extHostEditorTabs.tabGroups.activeTabGroup, first);
});
test('onDidChangeActiveTabGroup fires properly', function () {
const extHostEditorTabs = new ExtHostEditorTabs(
SingleProxyRPCProtocol(new class extends mock<MainThreadEditorTabsShape>() {
// override/implement $moveTab or $closeTab
})
);
let count = 0;
let activeTabGroupFromEvent: IEditorTabGroup | undefined = undefined;
extHostEditorTabs.tabGroups.onDidChangeActiveTabGroup((tabGroup) => {
count++;
activeTabGroupFromEvent = tabGroup;
});
assert.strictEqual(extHostEditorTabs.tabGroups.groups.length, 0);
assert.strictEqual(extHostEditorTabs.tabGroups.activeTabGroup, undefined);
assert.strictEqual(count, 0);
const tabModel = [{
isActive: true,
viewColumn: 0,
groupId: 12,
tabs: [],
activeTab: undefined
}];
extHostEditorTabs.$acceptEditorTabModel(tabModel);
assert.ok(extHostEditorTabs.tabGroups.activeTabGroup);
let activeTabGroup: IEditorTabGroup = extHostEditorTabs.tabGroups.activeTabGroup;
assert.strictEqual(count, 1);
assert.strictEqual(activeTabGroup, activeTabGroupFromEvent);
// Firing again with same model shouldn't cause a change
extHostEditorTabs.$acceptEditorTabModel(tabModel);
assert.strictEqual(count, 1);
// Changing a property should fire a change
tabModel[0].viewColumn = 1;
extHostEditorTabs.$acceptEditorTabModel(tabModel);
assert.strictEqual(count, 2);
activeTabGroup = extHostEditorTabs.tabGroups.activeTabGroup;
assert.strictEqual(activeTabGroup, activeTabGroupFromEvent);
// Changing the active tab group should fire a change
tabModel[0].isActive = false;
tabModel.push({
isActive: true,
viewColumn: 0,
groupId: 13,
tabs: [],
activeTab: undefined
});
extHostEditorTabs.$acceptEditorTabModel(tabModel);
assert.strictEqual(count, 3);
activeTabGroup = extHostEditorTabs.tabGroups.activeTabGroup;
assert.strictEqual(activeTabGroup, activeTabGroupFromEvent);
// Empty tab model should fire a change and return undefined
extHostEditorTabs.$acceptEditorTabModel([]);
assert.strictEqual(count, 4);
activeTabGroup = extHostEditorTabs.tabGroups.activeTabGroup;
assert.strictEqual(activeTabGroup, undefined);
assert.strictEqual(activeTabGroup, activeTabGroupFromEvent);
});
test.skip('Ensure reference stability', function () {
const extHostEditorTabs = new ExtHostEditorTabs(
SingleProxyRPCProtocol(new class extends mock<MainThreadEditorTabsShape>() {
// override/implement $moveTab or $closeTab
})
);
const tabDto: IEditorTabDto = {
isActive: true,
isDirty: true,
isPinned: true,
label: 'label1',
resource: URI.parse('file://abc/def.txt'),
editorId: 'default',
viewColumn: 0,
additionalResourcesAndViewTypes: [],
kind: TabKind.Singular
};
// single dirty tab
extHostEditorTabs.$acceptEditorTabModel([{
isActive: true,
viewColumn: 0,
groupId: 12,
tabs: [tabDto],
activeTab: undefined // NOT needed
}]);
let all = extHostEditorTabs.tabGroups.groups.map(group => group.tabs).flat();
assert.strictEqual(all.length, 1);
const apiTab1 = all[0];
assert.strictEqual(apiTab1.resource?.toString(), URI.revive(tabDto.resource)?.toString());
assert.strictEqual(apiTab1.isDirty, true);
// NOT DIRTY anymore
const tabDto2: IEditorTabDto = { ...tabDto, isDirty: false };
extHostEditorTabs.$acceptEditorTabModel([{
isActive: true,
viewColumn: 0,
groupId: 12,
tabs: [tabDto2],
activeTab: undefined // NOT needed
}]);
all = extHostEditorTabs.tabGroups.groups.map(group => group.tabs).flat();
assert.strictEqual(all.length, 1);
const apiTab2 = all[0];
assert.strictEqual(apiTab2.resource?.toString(), URI.revive(tabDto.resource)?.toString());
assert.strictEqual(apiTab2.isDirty, false);
assert.strictEqual(apiTab1 === apiTab2, true);
});
});