Path: blob/main/src/vs/workbench/api/test/browser/extHostMessagerService.test.ts
3296 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 { MainThreadMessageService } from '../../browser/mainThreadMessageService.js';7import { IDialogService, IPrompt, IPromptButton } from '../../../../platform/dialogs/common/dialogs.js';8import { INotificationService, INotification, NoOpNotification, INotificationHandle, Severity, IPromptChoice, IPromptOptions, IStatusMessageOptions, INotificationSource, INotificationSourceFilter, NotificationsFilter, IStatusHandle } from '../../../../platform/notification/common/notification.js';9import { ICommandService } from '../../../../platform/commands/common/commands.js';10import { mock } from '../../../../base/test/common/mock.js';11import { Disposable } from '../../../../base/common/lifecycle.js';12import { Event } from '../../../../base/common/event.js';13import { TestDialogService } from '../../../../platform/dialogs/test/common/testDialogService.js';14import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../base/test/common/utils.js';15import { TestExtensionService } from '../../../test/common/workbenchTestServices.js';1617const emptyCommandService: ICommandService = {18_serviceBrand: undefined,19onWillExecuteCommand: () => Disposable.None,20onDidExecuteCommand: () => Disposable.None,21executeCommand: (commandId: string, ...args: any[]): Promise<any> => {22return Promise.resolve(undefined);23}24};2526const emptyNotificationService = new class implements INotificationService {27declare readonly _serviceBrand: undefined;28onDidChangeFilter: Event<void> = Event.None;29notify(...args: any[]): never {30throw new Error('not implemented');31}32info(...args: any[]): never {33throw new Error('not implemented');34}35warn(...args: any[]): never {36throw new Error('not implemented');37}38error(...args: any[]): never {39throw new Error('not implemented');40}41prompt(severity: Severity, message: string, choices: IPromptChoice[], options?: IPromptOptions): INotificationHandle {42throw new Error('not implemented');43}44status(message: string | Error, options?: IStatusMessageOptions): IStatusHandle {45return { close: () => { } };46}47setFilter(): void {48throw new Error('not implemented');49}50getFilter(source?: INotificationSource | undefined): NotificationsFilter {51throw new Error('not implemented');52}53getFilters(): INotificationSourceFilter[] {54throw new Error('not implemented');55}56removeFilter(sourceId: string): void {57throw new Error('not implemented');58}59};6061class EmptyNotificationService implements INotificationService {62declare readonly _serviceBrand: undefined;63filter: boolean = false;64constructor(private withNotify: (notification: INotification) => void) {65}6667onDidChangeFilter: Event<void> = Event.None;68notify(notification: INotification): INotificationHandle {69this.withNotify(notification);7071return new NoOpNotification();72}73info(message: any): void {74throw new Error('Method not implemented.');75}76warn(message: any): void {77throw new Error('Method not implemented.');78}79error(message: any): void {80throw new Error('Method not implemented.');81}82prompt(severity: Severity, message: string, choices: IPromptChoice[], options?: IPromptOptions): INotificationHandle {83throw new Error('Method not implemented');84}85status(message: string, options?: IStatusMessageOptions): IStatusHandle {86return { close: () => { } };87}88setFilter(): void {89throw new Error('Method not implemented.');90}91getFilter(source?: INotificationSource | undefined): NotificationsFilter {92throw new Error('Method not implemented.');93}94getFilters(): INotificationSourceFilter[] {95throw new Error('Method not implemented.');96}97removeFilter(sourceId: string): void {98throw new Error('Method not implemented.');99}100}101102suite('ExtHostMessageService', function () {103104test('propagte handle on select', async function () {105106const service = new MainThreadMessageService(null!, new EmptyNotificationService(notification => {107assert.strictEqual(notification.actions!.primary!.length, 1);108queueMicrotask(() => notification.actions!.primary![0].run());109}), emptyCommandService, new TestDialogService(), new TestExtensionService());110111const handle = await service.$showMessage(1, 'h', {}, [{ handle: 42, title: 'a thing', isCloseAffordance: true }]);112assert.strictEqual(handle, 42);113114service.dispose();115});116117suite('modal', () => {118test('calls dialog service', async () => {119const service = new MainThreadMessageService(null!, emptyNotificationService, emptyCommandService, new class extends mock<IDialogService>() {120override prompt({ type, message, buttons, cancelButton }: IPrompt<any>) {121assert.strictEqual(type, 1);122assert.strictEqual(message, 'h');123assert.strictEqual(buttons!.length, 1);124assert.strictEqual((cancelButton as IPromptButton<unknown>)!.label, 'Cancel');125return Promise.resolve({ result: buttons![0].run({ checkboxChecked: false }) });126}127} as IDialogService, new TestExtensionService());128129const handle = await service.$showMessage(1, 'h', { modal: true }, [{ handle: 42, title: 'a thing', isCloseAffordance: false }]);130assert.strictEqual(handle, 42);131132service.dispose();133});134135test('returns undefined when cancelled', async () => {136const service = new MainThreadMessageService(null!, emptyNotificationService, emptyCommandService, new class extends mock<IDialogService>() {137override prompt(prompt: IPrompt<any>) {138return Promise.resolve({ result: (prompt.cancelButton as IPromptButton<unknown>)!.run({ checkboxChecked: false }) });139}140} as IDialogService, new TestExtensionService());141142const handle = await service.$showMessage(1, 'h', { modal: true }, [{ handle: 42, title: 'a thing', isCloseAffordance: false }]);143assert.strictEqual(handle, undefined);144145service.dispose();146});147148test('hides Cancel button when not needed', async () => {149const service = new MainThreadMessageService(null!, emptyNotificationService, emptyCommandService, new class extends mock<IDialogService>() {150override prompt({ type, message, buttons, cancelButton }: IPrompt<any>) {151assert.strictEqual(buttons!.length, 0);152assert.ok(cancelButton);153return Promise.resolve({ result: (cancelButton as IPromptButton<unknown>).run({ checkboxChecked: false }) });154}155} as IDialogService, new TestExtensionService());156157const handle = await service.$showMessage(1, 'h', { modal: true }, [{ handle: 42, title: 'a thing', isCloseAffordance: true }]);158assert.strictEqual(handle, 42);159160service.dispose();161});162});163164ensureNoDisposablesAreLeakedInTestSuite();165});166167168