Path: blob/main/src/vs/workbench/test/browser/parts/statusbar/statusbarModel.test.ts
4780 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import assert from 'assert';6import { IStatusbarViewModelEntry, StatusbarViewModel } from '../../../../browser/parts/statusbar/statusbarModel.js';7import { TestStorageService } from '../../../common/workbenchTestServices.js';8import { StatusbarAlignment } from '../../../../services/statusbar/browser/statusbar.js';9import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../base/test/common/utils.js';10import { DisposableStore } from '../../../../../base/common/lifecycle.js';1112suite('Workbench status bar model', () => {1314const disposables = new DisposableStore();1516teardown(() => {17disposables.clear();18});1920test('basics', () => {21const container = document.createElement('div');22const model = disposables.add(new StatusbarViewModel(disposables.add(new TestStorageService())));2324assert.strictEqual(model.entries.length, 0);2526const entry1: IStatusbarViewModelEntry = { id: '3', alignment: StatusbarAlignment.LEFT, name: '3', priority: { primary: 3, secondary: 1 }, container, labelContainer: container, hasCommand: false, extensionId: undefined };27model.add(entry1);28const entry2: IStatusbarViewModelEntry = { id: '2', alignment: StatusbarAlignment.LEFT, name: '2', priority: { primary: 2, secondary: 1 }, container, labelContainer: container, hasCommand: false, extensionId: undefined };29model.add(entry2);30const entry3: IStatusbarViewModelEntry = { id: '1', alignment: StatusbarAlignment.LEFT, name: '1', priority: { primary: 1, secondary: 1 }, container, labelContainer: container, hasCommand: false, extensionId: undefined };31model.add(entry3);32const entry4: IStatusbarViewModelEntry = { id: '1-right', alignment: StatusbarAlignment.RIGHT, name: '1-right', priority: { primary: 1, secondary: 1 }, container, labelContainer: container, hasCommand: false, extensionId: undefined };33model.add(entry4);3435assert.strictEqual(model.entries.length, 4);3637const leftEntries = model.getEntries(StatusbarAlignment.LEFT);38assert.strictEqual(leftEntries.length, 3);39assert.strictEqual(model.getEntries(StatusbarAlignment.RIGHT).length, 1);4041assert.strictEqual(leftEntries[0].id, '3');42assert.strictEqual(leftEntries[1].id, '2');43assert.strictEqual(leftEntries[2].id, '1');4445const entries = model.entries;46assert.strictEqual(entries[0].id, '3');47assert.strictEqual(entries[1].id, '2');48assert.strictEqual(entries[2].id, '1');49assert.strictEqual(entries[3].id, '1-right');5051assert.ok(model.findEntry(container));5253let didChangeEntryVisibility: { id: string; visible: boolean } = { id: '', visible: false };54disposables.add(model.onDidChangeEntryVisibility(e => {55didChangeEntryVisibility = e;56}));5758assert.strictEqual(model.isHidden('1'), false);59model.hide('1');60assert.strictEqual(didChangeEntryVisibility.id, '1');61assert.strictEqual(didChangeEntryVisibility.visible, false);62assert.strictEqual(model.isHidden('1'), true);6364didChangeEntryVisibility = { id: '', visible: false };6566model.show('1');67assert.strictEqual(didChangeEntryVisibility.id, '1');68assert.strictEqual(didChangeEntryVisibility.visible, true);69assert.strictEqual(model.isHidden('1'), false);7071model.remove(entry1);72model.remove(entry4);73assert.strictEqual(model.entries.length, 2);7475model.remove(entry2);76model.remove(entry3);77assert.strictEqual(model.entries.length, 0);78});7980test('sorting with infinity and max number', () => {81const container = document.createElement('div');82const model = disposables.add(new StatusbarViewModel(disposables.add(new TestStorageService())));8384assert.strictEqual(model.entries.length, 0);8586model.add({ id: '3', alignment: StatusbarAlignment.LEFT, name: '3', priority: { primary: Number.MAX_VALUE, secondary: 1 }, container, labelContainer: container, hasCommand: false, extensionId: undefined });87model.add({ id: '2', alignment: StatusbarAlignment.LEFT, name: '2', priority: { primary: Number.MIN_VALUE, secondary: 1 }, container, labelContainer: container, hasCommand: false, extensionId: undefined });88model.add({ id: '1', alignment: StatusbarAlignment.LEFT, name: '1', priority: { primary: Number.POSITIVE_INFINITY, secondary: 1 }, container, labelContainer: container, hasCommand: false, extensionId: undefined });89model.add({ id: '0', alignment: StatusbarAlignment.LEFT, name: '0', priority: { primary: Number.NEGATIVE_INFINITY, secondary: 1 }, container, labelContainer: container, hasCommand: false, extensionId: undefined });90model.add({ id: '4', alignment: StatusbarAlignment.LEFT, name: '4', priority: { primary: 100, secondary: 1 }, container, labelContainer: container, hasCommand: false, extensionId: undefined });9192const entries = model.entries;93assert.strictEqual(entries[0].id, '1');94assert.strictEqual(entries[1].id, '3');95assert.strictEqual(entries[2].id, '4');96assert.strictEqual(entries[3].id, '2');97assert.strictEqual(entries[4].id, '0');98});99100test('secondary priority used when primary is same', () => {101const container = document.createElement('div');102const model = disposables.add(new StatusbarViewModel(disposables.add(new TestStorageService())));103104assert.strictEqual(model.entries.length, 0);105106model.add({ id: '1', alignment: StatusbarAlignment.LEFT, name: '1', priority: { primary: 1, secondary: 1 }, container, labelContainer: container, hasCommand: false, extensionId: undefined });107model.add({ id: '2', alignment: StatusbarAlignment.LEFT, name: '2', priority: { primary: 1, secondary: 2 }, container, labelContainer: container, hasCommand: false, extensionId: undefined });108model.add({ id: '3', alignment: StatusbarAlignment.LEFT, name: '3', priority: { primary: 1, secondary: 3 }, container, labelContainer: container, hasCommand: false, extensionId: undefined });109110const entries = model.entries;111assert.strictEqual(entries[0].id, '3');112assert.strictEqual(entries[1].id, '2');113assert.strictEqual(entries[2].id, '1');114});115116test('insertion order preserved when priorites are the same', () => {117const container = document.createElement('div');118const model = disposables.add(new StatusbarViewModel(disposables.add(new TestStorageService())));119120assert.strictEqual(model.entries.length, 0);121122model.add({ id: '1', alignment: StatusbarAlignment.LEFT, name: '1', priority: { primary: 1, secondary: 1 }, container, labelContainer: container, hasCommand: false, extensionId: undefined });123model.add({ id: '2', alignment: StatusbarAlignment.LEFT, name: '2', priority: { primary: 1, secondary: 1 }, container, labelContainer: container, hasCommand: false, extensionId: undefined });124model.add({ id: '3', alignment: StatusbarAlignment.LEFT, name: '3', priority: { primary: 1, secondary: 1 }, container, labelContainer: container, hasCommand: false, extensionId: undefined });125126const entries = model.entries;127assert.strictEqual(entries[0].id, '1');128assert.strictEqual(entries[1].id, '2');129assert.strictEqual(entries[2].id, '3');130});131132test('entry with reference to other entry (existing)', () => {133const container = document.createElement('div');134const model = disposables.add(new StatusbarViewModel(disposables.add(new TestStorageService())));135136// Existing reference, Alignment: left137model.add({ id: 'a', alignment: StatusbarAlignment.LEFT, name: '1', priority: { primary: 2, secondary: 1 }, container, labelContainer: container, hasCommand: false, extensionId: undefined });138model.add({ id: 'b', alignment: StatusbarAlignment.LEFT, name: '2', priority: { primary: 1, secondary: 1 }, container, labelContainer: container, hasCommand: false, extensionId: undefined });139140let entry = { id: 'c', alignment: StatusbarAlignment.LEFT, name: '3', priority: { primary: { location: { id: 'a', priority: 2 }, alignment: StatusbarAlignment.LEFT }, secondary: 1 }, container, labelContainer: container, hasCommand: false, extensionId: undefined };141model.add(entry);142143let entries = model.entries;144assert.strictEqual(entries.length, 3);145assert.strictEqual(entries[0].id, 'c');146assert.strictEqual(entries[1].id, 'a');147assert.strictEqual(entries[2].id, 'b');148149model.remove(entry);150151// Existing reference, Alignment: right152entry = { id: 'c', alignment: StatusbarAlignment.RIGHT, name: '3', priority: { primary: { location: { id: 'a', priority: 2 }, alignment: StatusbarAlignment.RIGHT }, secondary: 1 }, container, labelContainer: container, hasCommand: false, extensionId: undefined };153model.add(entry);154155entries = model.entries;156assert.strictEqual(entries.length, 3);157assert.strictEqual(entries[0].id, 'a');158assert.strictEqual(entries[1].id, 'c');159assert.strictEqual(entries[2].id, 'b');160});161162test('entry with reference to other entry (nonexistent)', () => {163const container = document.createElement('div');164const model = disposables.add(new StatusbarViewModel(disposables.add(new TestStorageService())));165166// Nonexistent reference, Alignment: left167model.add({ id: 'a', alignment: StatusbarAlignment.LEFT, name: '1', priority: { primary: 2, secondary: 1 }, container, labelContainer: container, hasCommand: false, extensionId: undefined });168model.add({ id: 'b', alignment: StatusbarAlignment.LEFT, name: '2', priority: { primary: 1, secondary: 1 }, container, labelContainer: container, hasCommand: false, extensionId: undefined });169170let entry = { id: 'c', alignment: StatusbarAlignment.LEFT, name: '3', priority: { primary: { location: { id: 'not-existing', priority: 0 }, alignment: StatusbarAlignment.LEFT }, secondary: 1 }, container, labelContainer: container, hasCommand: false, extensionId: undefined };171model.add(entry);172173let entries = model.entries;174assert.strictEqual(entries.length, 3);175assert.strictEqual(entries[0].id, 'a');176assert.strictEqual(entries[1].id, 'b');177assert.strictEqual(entries[2].id, 'c');178179model.remove(entry);180181// Nonexistent reference, Alignment: different fallback priority182entry = { id: 'c', alignment: StatusbarAlignment.LEFT, name: '3', priority: { primary: { location: { id: 'not-existing', priority: 3 }, alignment: StatusbarAlignment.LEFT }, secondary: 1 }, container, labelContainer: container, hasCommand: false, extensionId: undefined };183model.add(entry);184185entries = model.entries;186assert.strictEqual(entries.length, 3);187assert.strictEqual(entries[0].id, 'c');188assert.strictEqual(entries[1].id, 'a');189assert.strictEqual(entries[2].id, 'b');190191model.remove(entry);192193// Nonexistent reference, Alignment: right194entry = { id: 'c', alignment: StatusbarAlignment.RIGHT, name: '3', priority: { primary: { location: { id: 'not-existing', priority: 3 }, alignment: StatusbarAlignment.RIGHT }, secondary: 1 }, container, labelContainer: container, hasCommand: false, extensionId: undefined };195model.add(entry);196197entries = model.entries;198assert.strictEqual(entries.length, 3);199assert.strictEqual(entries[0].id, 'a');200assert.strictEqual(entries[1].id, 'b');201assert.strictEqual(entries[2].id, 'c');202});203204test('entry with reference to other entry resorts based on other entry being there or not', () => {205const container = document.createElement('div');206const model = disposables.add(new StatusbarViewModel(disposables.add(new TestStorageService())));207208model.add({ id: 'a', alignment: StatusbarAlignment.LEFT, name: '1', priority: { primary: 2, secondary: 1 }, container, labelContainer: container, hasCommand: false, extensionId: undefined });209model.add({ id: 'b', alignment: StatusbarAlignment.LEFT, name: '2', priority: { primary: 1, secondary: 1 }, container, labelContainer: container, hasCommand: false, extensionId: undefined });210model.add({ id: 'c', alignment: StatusbarAlignment.LEFT, name: '3', priority: { primary: { location: { id: 'not-existing', priority: 0 }, alignment: StatusbarAlignment.LEFT }, secondary: 1 }, container, labelContainer: container, hasCommand: false, extensionId: undefined });211212let entries = model.entries;213assert.strictEqual(entries.length, 3);214assert.strictEqual(entries[0].id, 'a');215assert.strictEqual(entries[1].id, 'b');216assert.strictEqual(entries[2].id, 'c');217218const entry = { id: 'not-existing', alignment: StatusbarAlignment.LEFT, name: 'not-existing', priority: { primary: 3, secondary: 1 }, container, labelContainer: container, hasCommand: false, extensionId: undefined };219model.add(entry);220221entries = model.entries;222assert.strictEqual(entries.length, 4);223assert.strictEqual(entries[0].id, 'c');224assert.strictEqual(entries[1].id, 'not-existing');225assert.strictEqual(entries[2].id, 'a');226assert.strictEqual(entries[3].id, 'b');227228model.remove(entry);229230entries = model.entries;231assert.strictEqual(entries.length, 3);232assert.strictEqual(entries[0].id, 'a');233assert.strictEqual(entries[1].id, 'b');234assert.strictEqual(entries[2].id, 'c');235});236237test('entry with reference to other entry but different alignment does not explode', () => {238const container = document.createElement('div');239const model = disposables.add(new StatusbarViewModel(disposables.add(new TestStorageService())));240241model.add({ id: '1-left', alignment: StatusbarAlignment.LEFT, name: '1-left', priority: { primary: 2, secondary: 1 }, container, labelContainer: container, hasCommand: false, extensionId: undefined });242model.add({ id: '2-left', alignment: StatusbarAlignment.LEFT, name: '2-left', priority: { primary: 1, secondary: 1 }, container, labelContainer: container, hasCommand: false, extensionId: undefined });243244model.add({ id: '1-right', alignment: StatusbarAlignment.RIGHT, name: '1-right', priority: { primary: 2, secondary: 1 }, container, labelContainer: container, hasCommand: false, extensionId: undefined });245model.add({ id: '2-right', alignment: StatusbarAlignment.RIGHT, name: '2-right', priority: { primary: 1, secondary: 1 }, container, labelContainer: container, hasCommand: false, extensionId: undefined });246247assert.strictEqual(model.getEntries(StatusbarAlignment.LEFT).length, 2);248assert.strictEqual(model.getEntries(StatusbarAlignment.RIGHT).length, 2);249250const relativeEntryLeft = { id: 'relative', alignment: StatusbarAlignment.LEFT, name: 'relative', priority: { primary: { location: { id: '1-right', priority: 2 }, alignment: StatusbarAlignment.LEFT }, secondary: 1 }, container, labelContainer: container, hasCommand: false, extensionId: undefined };251model.add(relativeEntryLeft);252253assert.strictEqual(model.getEntries(StatusbarAlignment.LEFT).length, 3);254assert.strictEqual(model.getEntries(StatusbarAlignment.LEFT)[2], relativeEntryLeft);255assert.strictEqual(model.getEntries(StatusbarAlignment.RIGHT).length, 2);256257model.remove(relativeEntryLeft);258259const relativeEntryRight = { id: 'relative', alignment: StatusbarAlignment.RIGHT, name: 'relative', priority: { primary: { location: { id: '1-right', priority: 2 }, alignment: StatusbarAlignment.LEFT }, secondary: 1 }, container, labelContainer: container, hasCommand: false, extensionId: undefined };260model.add(relativeEntryRight);261262assert.strictEqual(model.getEntries(StatusbarAlignment.LEFT).length, 2);263assert.strictEqual(model.getEntries(StatusbarAlignment.RIGHT).length, 3);264});265266test('entry with reference to other entry respects secondary sorting (existent)', () => {267const container = document.createElement('div');268const model = disposables.add(new StatusbarViewModel(disposables.add(new TestStorageService())));269270model.add({ id: 'ref', alignment: StatusbarAlignment.LEFT, name: 'ref', priority: { primary: 0, secondary: 0 }, container, labelContainer: container, hasCommand: false, extensionId: undefined });271model.add({ id: 'entry2', alignment: StatusbarAlignment.RIGHT, name: '2', priority: { primary: { location: { id: 'ref', priority: 0 }, alignment: StatusbarAlignment.RIGHT }, secondary: 2 }, container, labelContainer: container, hasCommand: false, extensionId: undefined });272model.add({ id: 'entry1', alignment: StatusbarAlignment.RIGHT, name: '1', priority: { primary: { location: { id: 'ref', priority: 0 }, alignment: StatusbarAlignment.RIGHT }, secondary: 1 }, container, labelContainer: container, hasCommand: false, extensionId: undefined });273model.add({ id: 'entry3', alignment: StatusbarAlignment.RIGHT, name: '3', priority: { primary: { location: { id: 'ref', priority: 0 }, alignment: StatusbarAlignment.RIGHT }, secondary: 3 }, container, labelContainer: container, hasCommand: false, extensionId: undefined });274275const entries = model.entries;276assert.strictEqual(entries.length, 4);277assert.strictEqual(entries[0].id, 'ref');278assert.strictEqual(entries[1].id, 'entry3');279assert.strictEqual(entries[2].id, 'entry2');280assert.strictEqual(entries[3].id, 'entry1');281});282283test('entry with reference to other entry respects secondary sorting (nonexistent)', () => {284const container = document.createElement('div');285const model = disposables.add(new StatusbarViewModel(disposables.add(new TestStorageService())));286287model.add({ id: 'entry2', alignment: StatusbarAlignment.RIGHT, name: '2', priority: { primary: { location: { id: 'ref', priority: 1 }, alignment: StatusbarAlignment.RIGHT }, secondary: 2 }, container, labelContainer: container, hasCommand: false, extensionId: undefined });288model.add({ id: 'entry1', alignment: StatusbarAlignment.RIGHT, name: '1', priority: { primary: { location: { id: 'ref', priority: 1 }, alignment: StatusbarAlignment.RIGHT }, secondary: 1 }, container, labelContainer: container, hasCommand: false, extensionId: undefined });289model.add({ id: 'entry3', alignment: StatusbarAlignment.RIGHT, name: '3', priority: { primary: { location: { id: 'ref', priority: 1 }, alignment: StatusbarAlignment.RIGHT }, secondary: 3 }, container, labelContainer: container, hasCommand: false, extensionId: undefined });290291const entries = model.entries;292assert.strictEqual(entries.length, 3);293assert.strictEqual(entries[0].id, 'entry3');294assert.strictEqual(entries[1].id, 'entry2');295assert.strictEqual(entries[2].id, 'entry1');296});297298ensureNoDisposablesAreLeakedInTestSuite();299});300301302