Path: blob/main/src/vs/workbench/contrib/debug/test/common/debugModel.test.ts
5241 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 { DeferredPromise } from '../../../../../base/common/async.js';7import { DisposableStore } from '../../../../../base/common/lifecycle.js';8import { mockObject, upcastDeepPartial, upcastPartial } from '../../../../../base/test/common/mock.js';9import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../base/test/common/utils.js';10import { NullLogService } from '../../../../../platform/log/common/log.js';11import { ITextFileService } from '../../../../services/textfile/common/textfiles.js';12import { TestStorageService } from '../../../../test/common/workbenchTestServices.js';13import { IDebugSession } from '../../common/debug.js';14import { DebugModel, ExceptionBreakpoint, FunctionBreakpoint, Thread } from '../../common/debugModel.js';15import { MockDebugStorage } from './mockDebug.js';16import { runWithFakedTimers } from '../../../../../base/test/common/timeTravelScheduler.js';1718suite('DebugModel', () => {19ensureNoDisposablesAreLeakedInTestSuite();2021suite('FunctionBreakpoint', () => {22test('Id is saved', () => {23const fbp = new FunctionBreakpoint({ name: 'function', enabled: true, hitCondition: 'hit condition', condition: 'condition', logMessage: 'log message' });24const strigified = JSON.stringify(fbp);25const parsed = JSON.parse(strigified);26assert.equal(parsed.id, fbp.getId());27});28});2930suite('ExceptionBreakpoint', () => {31test('Restored matches new', () => {32const ebp = new ExceptionBreakpoint({33conditionDescription: 'condition description',34description: 'description',35filter: 'condition',36label: 'label',37supportsCondition: true,38enabled: true,39}, 'id');40const strigified = JSON.stringify(ebp);41const parsed = JSON.parse(strigified);42const newEbp = new ExceptionBreakpoint(parsed);43assert.ok(ebp.matches(newEbp));44});45});4647suite('DebugModel', () => {48test('refreshTopOfCallstack resolves all returned promises when called multiple times', async () => {49return runWithFakedTimers({}, async () => {50const topFrameDeferred = new DeferredPromise<void>();51const wholeStackDeferred = new DeferredPromise<void>();52const fakeThread = mockObject<Thread>()({53session: upcastDeepPartial<IDebugSession>({ capabilities: { supportsDelayedStackTraceLoading: true } }),54getCallStack: () => [],55getStaleCallStack: () => [],56});57fakeThread.fetchCallStack.callsFake((levels: number) => {58return levels === 1 ? topFrameDeferred.p : wholeStackDeferred.p;59});60fakeThread.getId.returns(1);6162const disposable = new DisposableStore();63const storage = disposable.add(new TestStorageService());64const model = new DebugModel(disposable.add(new MockDebugStorage(storage)), upcastPartial<ITextFileService>({ isDirty: (e: unknown) => false }), undefined!, new NullLogService());65disposable.add(model);6667let top1Resolved = false;68let whole1Resolved = false;69let top2Resolved = false;70let whole2Resolved = false;71// eslint-disable-next-line local/code-no-any-casts72const result1 = model.refreshTopOfCallstack(fakeThread as any);73result1.topCallStack.then(() => top1Resolved = true);74result1.wholeCallStack.then(() => whole1Resolved = true);7576// eslint-disable-next-line local/code-no-any-casts77const result2 = model.refreshTopOfCallstack(fakeThread as any);78result2.topCallStack.then(() => top2Resolved = true);79result2.wholeCallStack.then(() => whole2Resolved = true);8081assert.ok(!top1Resolved);82assert.ok(!whole1Resolved);83assert.ok(!top2Resolved);84assert.ok(!whole2Resolved);8586await topFrameDeferred.complete();87await result1.topCallStack;88await result2.topCallStack;89assert.ok(!whole1Resolved);90assert.ok(!whole2Resolved);9192await wholeStackDeferred.complete();93await result1.wholeCallStack;94await result2.wholeCallStack;9596disposable.dispose();97});98});99});100});101102103