From f36fff45bc28bf50cc961a014ac7a10b814f0646 Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 19 Oct 2016 11:08:13 +0200 Subject: [PATCH] debug model: introduce process, limit pointers to session --- src/vs/workbench/parts/debug/common/debug.ts | 22 +-- .../parts/debug/common/debugModel.ts | 133 +++++++++--------- .../debug/electron-browser/debugHover.ts | 2 +- .../debug/electron-browser/debugService.ts | 13 +- .../debug/electron-browser/debugViewer.ts | 2 +- .../debug/test/common/debugViewModel.test.ts | 9 +- .../{mockDebugService.ts => mockDebug.ts} | 44 +++--- .../parts/debug/test/node/debugModel.test.ts | 48 ++++--- 8 files changed, 144 insertions(+), 129 deletions(-) rename src/vs/workbench/parts/debug/test/common/{mockDebugService.ts => mockDebug.ts} (97%) diff --git a/src/vs/workbench/parts/debug/common/debug.ts b/src/vs/workbench/parts/debug/common/debug.ts index 70accd681fa..4e3273f73ec 100644 --- a/src/vs/workbench/parts/debug/common/debug.ts +++ b/src/vs/workbench/parts/debug/common/debug.ts @@ -54,6 +54,7 @@ export interface ITreeElement { export interface IExpressionContainer extends ITreeElement { reference: number; + stackFrame: IStackFrame; getChildren(debugService: IDebugService): TPromise; } @@ -64,12 +65,19 @@ export interface IExpression extends ITreeElement, IExpressionContainer { type?: string; } +export interface IProcess extends ITreeElement { + stackTrace(args: DebugProtocol.StackTraceArguments): TPromise; + scopes(args: DebugProtocol.ScopesArguments): TPromise; + variables(args: DebugProtocol.VariablesArguments): TPromise; + evaluate(args: DebugProtocol.EvaluateArguments): TPromise; +} + export interface IThread extends ITreeElement { /** - * Id of the debug session the thread belongs to + * Process the thread belongs to */ - sessionId: string; + process: IProcess; /** * Id of the thread generated by the debug adapter backend. @@ -119,8 +127,7 @@ export interface IScope extends IExpressionContainer { } export interface IStackFrame extends ITreeElement { - threadId: number; - sessionId: string; + thread: IThread; name: string; lineNumber: number; column: number; @@ -274,17 +281,12 @@ export interface IRawBreakpointContribution { language: string; } -export interface IRawDebugSession { +export interface IRawDebugSession extends IProcess { configuration: { type: string, capabilities: DebugProtocol.Capabilities }; getId(): string; disconnect(restart?: boolean, force?: boolean): TPromise; - stackTrace(args: DebugProtocol.StackTraceArguments): TPromise; - scopes(args: DebugProtocol.ScopesArguments): TPromise; - variables(args: DebugProtocol.VariablesArguments): TPromise; - evaluate(args: DebugProtocol.EvaluateArguments): TPromise; - custom(request: string, args: any): TPromise; onDidEvent: Event; diff --git a/src/vs/workbench/parts/debug/common/debugModel.ts b/src/vs/workbench/parts/debug/common/debugModel.ts index 79c21c4b5ea..392fe5a6ab7 100644 --- a/src/vs/workbench/parts/debug/common/debugModel.ts +++ b/src/vs/workbench/parts/debug/common/debugModel.ts @@ -22,16 +22,16 @@ function massageValue(value: string): string { return value ? value.replace(/\n/g, '\\n').replace(/\r/g, '\\r').replace(/\t/g, '\\t') : value; } -export function evaluateExpression(session: debug.IRawDebugSession, stackFrame: debug.IStackFrame, expression: Expression, context: string): TPromise { - if (!session) { +export function evaluateExpression(stackFrame: debug.IStackFrame, expression: Expression, context: string): TPromise { + if (!stackFrame || !stackFrame.thread.process) { expression.value = context === 'repl' ? nls.localize('startDebugFirst', "Please start a debug session to evaluate") : Expression.DEFAULT_VALUE; expression.available = false; expression.reference = 0; return TPromise.as(expression); } - expression.setSession(session); + expression.stackFrame = stackFrame; - return session.evaluate({ + return stackFrame.thread.process.evaluate({ expression: expression.name, frameId: stackFrame ? stackFrame.frameId : undefined, context @@ -169,7 +169,7 @@ export abstract class ExpressionContainer implements debug.IExpressionContainer private _value: string; constructor( - protected session: debug.IRawDebugSession, + public stackFrame: debug.IStackFrame, public reference: number, private id: string, private cacheChildren: boolean, @@ -201,7 +201,7 @@ export abstract class ExpressionContainer implements debug.IExpressionContainer for (let i = 0; i < numberOfChunks; i++) { const start = this.startOfVariables + i * chunkSize; const count = Math.min(chunkSize, this.indexedVariables - i * chunkSize); - childrenArray.push(new Variable(this.session, this, this.reference, `[${start}..${start + count - 1}]`, '', null, count, null, true, start)); + childrenArray.push(new Variable(this.stackFrame, this, this.reference, `[${start}..${start + count - 1}]`, '', null, count, null, true, start)); } return childrenArray; @@ -227,16 +227,16 @@ export abstract class ExpressionContainer implements debug.IExpressionContainer } private fetchVariables(start: number, count: number, filter: 'indexed' | 'named'): TPromise { - return this.session.variables({ + return this.stackFrame.thread.process.variables({ variablesReference: this.reference, start, count, filter }).then(response => { return response && response.body && response.body.variables ? arrays.distinct(response.body.variables.filter(v => !!v), v => v.name).map( - v => new Variable(this.session, this, v.variablesReference, v.name, v.value, v.namedVariables, v.indexedVariables, v.type) + v => new Variable(this.stackFrame, this, v.variablesReference, v.name, v.value, v.namedVariables, v.indexedVariables, v.type) ) : []; - }, (e: Error) => [new Variable(this.session, this, 0, null, e.message, 0, 0, null, false)]); + }, (e: Error) => [new Variable(this.stackFrame, this, 0, null, e.message, 0, 0, null, false)]); } // The adapter explicitly sents the children count of an expression only if there are lots of children which should be chunked. @@ -263,10 +263,6 @@ export class Expression extends ExpressionContainer implements debug.IExpression this.value = Expression.DEFAULT_VALUE; this.available = false; } - - public setSession(session: debug.IRawDebugSession) { - this.session = session; - } } export class Variable extends ExpressionContainer implements debug.IExpression { @@ -275,7 +271,7 @@ export class Variable extends ExpressionContainer implements debug.IExpression { public errorMessage: string; constructor( - session: debug.IRawDebugSession, + stackFrame: debug.IStackFrame, public parent: debug.IExpressionContainer, reference: number, public name: string, @@ -286,7 +282,7 @@ export class Variable extends ExpressionContainer implements debug.IExpression { public available = true, startOfVariables = 0 ) { - super(session, reference, `variable:${parent.getId()}:${name}:${reference}`, true, namedVariables, indexedVariables, startOfVariables); + super(stackFrame, reference, `variable:${stackFrame.getId()}:${parent.getId()}:${name}:${reference}`, true, namedVariables, indexedVariables, startOfVariables); this.value = massageValue(value); } } @@ -294,15 +290,14 @@ export class Variable extends ExpressionContainer implements debug.IExpression { export class Scope extends ExpressionContainer implements debug.IScope { constructor( - session: debug.IRawDebugSession, - threadId: number, + stackFrame: debug.IStackFrame, public name: string, reference: number, public expensive: boolean, namedVariables: number, indexedVariables: number ) { - super(session, reference, `scope:${threadId}:${name}:${reference}`, true, namedVariables, indexedVariables); + super(stackFrame, reference, `scope:${stackFrame.getId()}:${name}:${reference}`, true, namedVariables, indexedVariables); } } @@ -311,8 +306,7 @@ export class StackFrame implements debug.IStackFrame { private scopes: TPromise; constructor( - private session: debug.IRawDebugSession, - public threadId: number, + public thread: debug.IThread, public frameId: number, public source: Source, public name: string, @@ -322,19 +316,15 @@ export class StackFrame implements debug.IStackFrame { this.scopes = null; } - public get sessionId() { - return this.session.getId(); - } - public getId(): string { - return `stackframe:${this.sessionId}:${this.threadId}:${this.frameId}`; + return `stackframe:${this.thread.getId()}:${this.frameId}`; } public getScopes(): TPromise { if (!this.scopes) { - this.scopes = this.session.scopes({ frameId: this.frameId }).then(response => { + this.scopes = this.thread.process.scopes({ frameId: this.frameId }).then(response => { return response && response.body && response.body.scopes ? - response.body.scopes.map(rs => new Scope(this.session, this.threadId, rs.name, rs.variablesReference, rs.expensive, rs.namedVariables, rs.indexedVariables)) : []; + response.body.scopes.map(rs => new Scope(this, rs.name, rs.variablesReference, rs.expensive, rs.namedVariables, rs.indexedVariables)) : []; }, err => []); } @@ -348,7 +338,7 @@ export class Thread implements debug.IThread { public stoppedDetails: debug.IRawStoppedDetails; public stopped: boolean; - constructor(private session: debug.IRawDebugSession, public name: string, public threadId: number) { + constructor(public process: debug.IProcess, public name: string, public threadId: number) { this.promisedCallStack = undefined; this.stoppedDetails = undefined; this.cachedCallStack = undefined; @@ -356,11 +346,7 @@ export class Thread implements debug.IThread { } public getId(): string { - return `thread:${this.sessionId}:${this.name}:${this.threadId}`; - } - - public get sessionId(): string { - return this.session.getId(); + return `thread:${this.process.getId()}:${this.name}:${this.threadId}`; } public clearCallStack(): void { @@ -393,7 +379,7 @@ export class Thread implements debug.IThread { } private getCallStackImpl(startFrame: number): TPromise { - return this.session.stackTrace({ threadId: this.threadId, startFrame, levels: 20 }).then(response => { + return this.process.stackTrace({ threadId: this.threadId, startFrame, levels: 20 }).then(response => { if (!response || !response.body) { return []; } @@ -401,10 +387,10 @@ export class Thread implements debug.IThread { this.stoppedDetails.totalFrames = response.body.totalFrames; return response.body.stackFrames.map((rsf, level) => { if (!rsf) { - return new StackFrame(this.session, this.threadId, 0, new Source({ name: UNKNOWN_SOURCE_LABEL }, false), nls.localize('unknownStack', "Unknown stack location"), undefined, undefined); + return new StackFrame(this, 0, new Source({ name: UNKNOWN_SOURCE_LABEL }, false), nls.localize('unknownStack', "Unknown stack location"), undefined, undefined); } - return new StackFrame(this.session, this.threadId, rsf.id, rsf.source ? new Source(rsf.source) : new Source({ name: UNKNOWN_SOURCE_LABEL }, false), rsf.name, rsf.line, rsf.column); + return new StackFrame(this, rsf.id, rsf.source ? new Source(rsf.source) : new Source({ name: UNKNOWN_SOURCE_LABEL }, false), rsf.name, rsf.line, rsf.column); }); }, (err: Error) => { this.stoppedDetails.framesErrorMessage = err.message; @@ -413,22 +399,39 @@ export class Thread implements debug.IThread { } } -class DebugSession { +class Process implements debug.IProcess { + public threads: { [reference: number]: debug.IThread; }; - constructor(public raw: debug.IRawDebugSession) { + constructor(public rawSession: debug.IRawDebugSession) { this.threads = {}; } public getId(): string { - return this.raw.getId(); + return this.rawSession.getId(); + } + + public stackTrace(args: DebugProtocol.StackTraceArguments): TPromise { + return this.rawSession.stackTrace(args); + } + + public scopes(args: DebugProtocol.ScopesArguments): TPromise { + return this.rawSession.scopes(args); + } + + public variables(args: DebugProtocol.VariablesArguments): TPromise { + return this.rawSession.variables(args); + } + + public evaluate(args: DebugProtocol.EvaluateArguments): TPromise { + return this.rawSession.evaluate(args); } public rawUpdate(data: debug.IRawModelUpdate): void { if (data.thread && !this.threads[data.threadId]) { // A new thread came in, initialize it. - this.threads[data.threadId] = new Thread(this.raw, data.thread.name, data.thread.id); + this.threads[data.threadId] = new Thread(this.rawSession, data.thread.name, data.thread.id); } if (data.stoppedDetails) { @@ -549,7 +552,7 @@ export class ExceptionBreakpoint implements debug.IExceptionBreakpoint { export class Model implements debug.IModel { - private sessions: DebugSession[]; + private processes: Process[]; private toDispose: lifecycle.IDisposable[]; private replElements: debug.ITreeElement[]; private _onDidChangeBreakpoints: Emitter; @@ -564,7 +567,7 @@ export class Model implements debug.IModel { private exceptionBreakpoints: debug.IExceptionBreakpoint[], private watchExpressions: Expression[] ) { - this.sessions = []; + this.processes = []; this.replElements = []; this.toDispose = []; this._onDidChangeBreakpoints = new Emitter(); @@ -578,11 +581,11 @@ export class Model implements debug.IModel { } public getSessions(): debug.IRawDebugSession[] { - return this.sessions.map(s => s.raw); + return this.processes.map(p => p.rawSession); } public removeSession(id: string): void { - this.sessions = this.sessions.filter(s => s.getId() !== id); + this.processes = this.processes.filter(p => p.getId() !== id); this._onDidChangeCallStack.fire(); } @@ -603,29 +606,29 @@ export class Model implements debug.IModel { } public getThreads(sessionId: string): { [reference: number]: debug.IThread; } { - const session = this.sessions.filter(s => s.getId() === sessionId).pop(); - if (!session) { + const process = this.processes.filter(p => p.getId() === sessionId).pop(); + if (!process) { return {}; } - return session.threads; + return process.threads; } public rawUpdate(data: debug.IRawModelUpdate): void { - let session = this.sessions.filter(s => s.getId() === data.rawSession.getId()).pop(); - if (!session) { - session = new DebugSession(data.rawSession); - this.sessions.push(session); + let process = this.processes.filter(p => p.getId() === data.rawSession.getId()).pop(); + if (!process) { + process = new Process(data.rawSession); + this.processes.push(process); } - session.rawUpdate(data); + process.rawUpdate(data); this._onDidChangeCallStack.fire(); } public clearThreads(sessionId: string, removeThreads: boolean, reference: number = undefined): void { - const session = this.sessions.filter(s => s.getId() === sessionId).pop(); - if (session) { - session.clearThreads(removeThreads, reference); + const process = this.processes.filter(p => p.getId() === sessionId).pop(); + if (process) { + process.clearThreads(removeThreads, reference); this._onDidChangeCallStack.fire(); } } @@ -738,10 +741,10 @@ export class Model implements debug.IModel { return this.replElements; } - public addReplExpression(session: debug.IRawDebugSession, stackFrame: debug.IStackFrame, name: string): TPromise { + public addReplExpression(stackFrame: debug.IStackFrame, name: string): TPromise { const expression = new Expression(name, true); this.addReplElements([expression]); - return evaluateExpression(session, stackFrame, expression, 'repl') + return evaluateExpression(stackFrame, expression, 'repl') .then(() => this._onDidChangeREPLElements.fire()); } @@ -813,7 +816,7 @@ export class Model implements debug.IModel { return this.watchExpressions; } - public addWatchExpression(session: debug.IRawDebugSession, stackFrame: debug.IStackFrame, name: string): TPromise { + public addWatchExpression(stackFrame: debug.IStackFrame, name: string): TPromise { const we = new Expression(name, false); this.watchExpressions.push(we); if (!name) { @@ -821,14 +824,14 @@ export class Model implements debug.IModel { return TPromise.as(null); } - return this.evaluateWatchExpressions(session, stackFrame, we.getId()); + return this.evaluateWatchExpressions(stackFrame, we.getId()); } - public renameWatchExpression(session: debug.IRawDebugSession, stackFrame: debug.IStackFrame, id: string, newName: string): TPromise { + public renameWatchExpression(stackFrame: debug.IStackFrame, id: string, newName: string): TPromise { const filtered = this.watchExpressions.filter(we => we.getId() === id); if (filtered.length === 1) { filtered[0].name = newName; - return evaluateExpression(session, stackFrame, filtered[0], 'watch').then(() => { + return evaluateExpression(stackFrame, filtered[0], 'watch').then(() => { this._onDidChangeWatchExpressions.fire(filtered[0]); }); } @@ -836,19 +839,19 @@ export class Model implements debug.IModel { return TPromise.as(null); } - public evaluateWatchExpressions(session: debug.IRawDebugSession, stackFrame: debug.IStackFrame, id: string = null): TPromise { + public evaluateWatchExpressions(stackFrame: debug.IStackFrame, id: string = null): TPromise { if (id) { const filtered = this.watchExpressions.filter(we => we.getId() === id); if (filtered.length !== 1) { return TPromise.as(null); } - return evaluateExpression(session, stackFrame, filtered[0], 'watch').then(() => { + return evaluateExpression(stackFrame, filtered[0], 'watch').then(() => { this._onDidChangeWatchExpressions.fire(filtered[0]); }); } - return TPromise.join(this.watchExpressions.map(we => evaluateExpression(session, stackFrame, we, 'watch'))).then(() => { + return TPromise.join(this.watchExpressions.map(we => evaluateExpression(stackFrame, we, 'watch'))).then(() => { this._onDidChangeWatchExpressions.fire(); }); } @@ -869,7 +872,7 @@ export class Model implements debug.IModel { } public sourceIsUnavailable(source: Source): void { - this.sessions.forEach(s => s.sourceIsUnavailable(source)); + this.processes.forEach(p => p.sourceIsUnavailable(source)); this._onDidChangeCallStack.fire(); } diff --git a/src/vs/workbench/parts/debug/electron-browser/debugHover.ts b/src/vs/workbench/parts/debug/electron-browser/debugHover.ts index 9bb255d47c9..723b4bd0150 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugHover.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugHover.ts @@ -160,7 +160,7 @@ export class DebugHoverWidget implements editorbrowser.IContentWidget { const matchingExpression = lineContent.substring(expressionRange.startColumn - 1, expressionRange.endColumn); const evaluatedExpression = session.configuration.capabilities.supportsEvaluateForHovers ? - evaluateExpression(session, focusedStackFrame, new Expression(matchingExpression, true), 'hover') : + evaluateExpression(focusedStackFrame, new Expression(matchingExpression, true), 'hover') : this.findExpressionInStackFrame(matchingExpression.split('.').map(word => word.trim()).filter(word => !!word)); return evaluatedExpression.then(expression => { diff --git a/src/vs/workbench/parts/debug/electron-browser/debugService.ts b/src/vs/workbench/parts/debug/electron-browser/debugService.ts index f5a4efe72b1..7dd4978d7df 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugService.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugService.ts @@ -423,13 +423,14 @@ export class DebugService implements debug.IDebugService { let thread: debug.IThread = null; let session: debug.IRawDebugSession = null; if (focusedStackFrame) { - session = this.model.getSessions().filter(s => s.getId() === focusedStackFrame.sessionId).pop(); - thread = this.model.getThreads(focusedStackFrame.sessionId)[focusedStackFrame.threadId]; + const processId = focusedStackFrame.thread.process.getId(); + session = this.model.getSessions().filter(s => s.getId() === processId).pop(); + thread = this.model.getThreads(processId)[focusedStackFrame.thread.threadId]; } this.viewModel.setFocusedStackFrame(focusedStackFrame, thread, session); if (focusedStackFrame) { - return this.model.evaluateWatchExpressions(this.session, focusedStackFrame); + return this.model.evaluateWatchExpressions(focusedStackFrame); } else { this.model.clearWatchExpressionValues(); return TPromise.as(null); @@ -491,7 +492,7 @@ export class DebugService implements debug.IDebugService { public addReplExpression(name: string): TPromise { this.telemetryService.publicLog('debugService/addReplExpression'); const focussedStackFrame = this.viewModel.getFocusedStackFrame(); - return this.model.addReplExpression(this.session, focussedStackFrame, name) + return this.model.addReplExpression(focussedStackFrame, name) // Evaluate all watch expressions again since repl evaluation might have changed some. .then(() => this.setFocusedStackFrameAndEvaluate(focussedStackFrame)); } @@ -529,11 +530,11 @@ export class DebugService implements debug.IDebugService { } public addWatchExpression(name: string): TPromise { - return this.model.addWatchExpression(this.session, this.viewModel.getFocusedStackFrame(), name); + return this.model.addWatchExpression(this.viewModel.getFocusedStackFrame(), name); } public renameWatchExpression(id: string, newName: string): TPromise { - return this.model.renameWatchExpression(this.session, this.viewModel.getFocusedStackFrame(), id, newName); + return this.model.renameWatchExpression(this.viewModel.getFocusedStackFrame(), id, newName); } public removeWatchExpressions(id?: string): void { diff --git a/src/vs/workbench/parts/debug/electron-browser/debugViewer.ts b/src/vs/workbench/parts/debug/electron-browser/debugViewer.ts index e1ba199ebd6..ed182b106ec 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugViewer.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugViewer.ts @@ -377,7 +377,7 @@ export class CallStackDataSource implements tree.IDataSource { return callStack.concat([thread.stoppedDetails.framesErrorMessage]); } if (thread.stoppedDetails && thread.stoppedDetails.totalFrames > callStack.length) { - return callStack.concat([new ThreadAndSessionId(thread.sessionId, thread.threadId)]); + return callStack.concat([new ThreadAndSessionId(thread.process.getId(), thread.threadId)]); } return callStack; diff --git a/src/vs/workbench/parts/debug/test/common/debugViewModel.test.ts b/src/vs/workbench/parts/debug/test/common/debugViewModel.test.ts index 30b5c0254cf..7cbddc8b663 100644 --- a/src/vs/workbench/parts/debug/test/common/debugViewModel.test.ts +++ b/src/vs/workbench/parts/debug/test/common/debugViewModel.test.ts @@ -6,7 +6,7 @@ import assert = require('assert'); import { ViewModel } from 'vs/workbench/parts/debug/common/debugViewModel'; import { StackFrame, Expression, Thread } from 'vs/workbench/parts/debug/common/debugModel'; -import { MockRawSession } from 'vs/workbench/parts/debug/test/common/mockDebugService'; +import { MockProcess } from 'vs/workbench/parts/debug/test/common/mockDebug'; suite('Debug - View Model', () => { var model: ViewModel; @@ -22,9 +22,10 @@ suite('Debug - View Model', () => { test('focused stack frame', () => { assert.equal(model.getFocusedStackFrame(), null); assert.equal(model.getFocusedThread(), null); - const rawSession = new MockRawSession; - const frame = new StackFrame(rawSession, 1, 1, null, 'app.js', 1, 1); - model.setFocusedStackFrame(frame, new Thread(rawSession, 'myThread', 1), null); + const process = new MockProcess(); + const thread = new Thread(process, 'myThread', 1); + const frame = new StackFrame(thread, 1, null, 'app.js', 1, 1); + model.setFocusedStackFrame(frame, thread, null); assert.equal(model.getFocusedStackFrame(), frame); assert.equal(model.getFocusedThread().threadId, 1); diff --git a/src/vs/workbench/parts/debug/test/common/mockDebugService.ts b/src/vs/workbench/parts/debug/test/common/mockDebug.ts similarity index 97% rename from src/vs/workbench/parts/debug/test/common/mockDebugService.ts rename to src/vs/workbench/parts/debug/test/common/mockDebug.ts index a192e8af0b1..40ed08e4a4a 100644 --- a/src/vs/workbench/parts/debug/test/common/mockDebugService.ts +++ b/src/vs/workbench/parts/debug/test/common/mockDebug.ts @@ -142,32 +142,12 @@ export class MockDebugService implements debug.IDebugService { } } - -export class MockRawSession implements debug.IRawDebugSession { - - public get configuration(): { type: string, capabilities: DebugProtocol.Capabilities } { - return { - type: 'mock', - capabilities: {} - }; - } +export class MockProcess implements debug.IProcess { public getId() { return 'mockrawsession'; } - public get onDidEvent(): Event { - return null; - } - - public custom(request: string, args: any): TPromise { - return TPromise.as(null); - } - - public disconnect(restart?: boolean, force?: boolean): TPromise { - return TPromise.as(null); - } - public stackTrace(args: DebugProtocol.StackTraceArguments): TPromise { return TPromise.as({ body: { @@ -188,3 +168,25 @@ export class MockRawSession implements debug.IRawDebugSession { return TPromise.as(null); } } + +export class MockRawSession extends MockProcess implements debug.IRawDebugSession { + + public get configuration(): { type: string, capabilities: DebugProtocol.Capabilities } { + return { + type: 'mock', + capabilities: {} + }; + } + + public get onDidEvent(): Event { + return null; + } + + public custom(request: string, args: any): TPromise { + return TPromise.as(null); + } + + public disconnect(restart?: boolean, force?: boolean): TPromise { + return TPromise.as(null); + } +} diff --git a/src/vs/workbench/parts/debug/test/node/debugModel.test.ts b/src/vs/workbench/parts/debug/test/node/debugModel.test.ts index d206864a5b2..666c25cb9b0 100644 --- a/src/vs/workbench/parts/debug/test/node/debugModel.test.ts +++ b/src/vs/workbench/parts/debug/test/node/debugModel.test.ts @@ -8,14 +8,16 @@ import uri from 'vs/base/common/uri'; import severity from 'vs/base/common/severity'; import debugmodel = require('vs/workbench/parts/debug/common/debugModel'); import * as sinon from 'sinon'; -import { MockRawSession } from 'vs/workbench/parts/debug/test/common/mockDebugService'; +import { MockProcess, MockRawSession } from 'vs/workbench/parts/debug/test/common/mockDebug'; suite('Debug - Model', () => { let model: debugmodel.Model; + let process: MockProcess; let rawSession: MockRawSession; setup(() => { model = new debugmodel.Model([], true, [], [], []); + process = new MockProcess(); rawSession = new MockRawSession(); }); @@ -90,10 +92,10 @@ suite('Debug - Model', () => { } }); - var threads = model.getThreads(rawSession.getId()); + var threads = model.getThreads(process.getId()); assert.equal(threads[threadId].name, threadName); - model.clearThreads(rawSession.getId(),true); + model.clearThreads(process.getId(),true); assert.equal(model.getThreads[threadId], null); }); @@ -136,8 +138,8 @@ suite('Debug - Model', () => { allThreadsStopped: true }); - const thread1 = model.getThreads(rawSession.getId())[threadId1]; - const thread2 = model.getThreads(rawSession.getId())[threadId2]; + const thread1 = model.getThreads(process.getId())[threadId1]; + const thread2 = model.getThreads(process.getId())[threadId2]; // at the beginning, callstacks are obtainable but not available assert.equal(thread1.name, threadName1); @@ -180,7 +182,7 @@ suite('Debug - Model', () => { assert.equal(thread2.stopped, true); assert.equal(thread2.getCachedCallStack(), undefined); - model.clearThreads(rawSession.getId(), true); + model.clearThreads(process.getId(), true); assert.equal(model.getThreads[threadId1], null); assert.equal(model.getThreads[threadId2], null); }); @@ -224,8 +226,8 @@ suite('Debug - Model', () => { allThreadsStopped: false }); - const stoppedThread = model.getThreads(rawSession.getId())[stoppedThreadId]; - const runningThread = model.getThreads(rawSession.getId())[runningThreadId]; + const stoppedThread = model.getThreads(process.getId())[stoppedThreadId]; + const runningThread = model.getThreads(process.getId())[runningThreadId]; // the callstack for the stopped thread is obtainable but not available // the callstack for the running thread is not obtainable nor available @@ -265,7 +267,7 @@ suite('Debug - Model', () => { assert.equal(stoppedThread.stopped, true); assert.equal(stoppedThread.getCachedCallStack(), undefined); - model.clearThreads(rawSession.getId(), true); + model.clearThreads(process.getId(), true); assert.equal(model.getThreads[stoppedThreadId], null); assert.equal(model.getThreads[runningThreadId], null); }); @@ -283,14 +285,15 @@ suite('Debug - Model', () => { test('watch expressions', () => { assert.equal(model.getWatchExpressions().length, 0); - const stackFrame = new debugmodel.StackFrame(rawSession, 1, 1, null, 'app.js', 1, 1); - model.addWatchExpression(null, stackFrame, 'console').done(); - model.addWatchExpression(null, stackFrame, 'console').done(); + const thread = new debugmodel.Thread(process, 'mockthread', 1); + const stackFrame = new debugmodel.StackFrame(thread, 1, null, 'app.js', 1, 1); + model.addWatchExpression(stackFrame, 'console').done(); + model.addWatchExpression(stackFrame, 'console').done(); const watchExpressions = model.getWatchExpressions(); assertWatchExpressions(watchExpressions, 'console'); - model.renameWatchExpression(null, stackFrame, watchExpressions[0].getId(), 'new_name').done(); - model.renameWatchExpression(null, stackFrame, watchExpressions[1].getId(), 'new_name').done(); + model.renameWatchExpression(stackFrame, watchExpressions[0].getId(), 'new_name').done(); + model.renameWatchExpression(stackFrame, watchExpressions[1].getId(), 'new_name').done(); assertWatchExpressions(model.getWatchExpressions(), 'new_name'); model.clearWatchExpressionValues(); @@ -302,10 +305,11 @@ suite('Debug - Model', () => { test('repl expressions', () => { assert.equal(model.getReplElements().length, 0); - const stackFrame = new debugmodel.StackFrame(rawSession, 1, 1, null, 'app.js', 1, 1); - model.addReplExpression(null, stackFrame, 'myVariable').done(); - model.addReplExpression(null, stackFrame, 'myVariable').done(); - model.addReplExpression(null, stackFrame, 'myVariable').done(); + const thread = new debugmodel.Thread(process, 'mockthread', 1); + const stackFrame = new debugmodel.StackFrame(thread, 1, null, 'app.js', 1, 1); + model.addReplExpression(stackFrame, 'myVariable').done(); + model.addReplExpression(stackFrame, 'myVariable').done(); + model.addReplExpression(stackFrame, 'myVariable').done(); assert.equal(model.getReplElements().length, 3); model.getReplElements().forEach(re => { @@ -360,11 +364,13 @@ suite('Debug - Model', () => { assert.equal(debugmodel.getFullExpressionName(new debugmodel.Expression(null, false), type), null); assert.equal(debugmodel.getFullExpressionName(new debugmodel.Expression('son', false), type), 'son'); - const scope = new debugmodel.Scope(rawSession, 1, 'myscope', 1, false, 1, 0); - const son = new debugmodel.Variable(rawSession, new debugmodel.Variable(rawSession, new debugmodel.Variable(rawSession, scope, 0, 'grandfather', '75', 1, 0), 0, 'father', '45', 1, 0), 0, 'son', '20', 1, 0); + const thread = new debugmodel.Thread(process, 'mockthread', 1); + const stackFrame = new debugmodel.StackFrame(thread, 1, null, 'app.js', 1, 1); + const scope = new debugmodel.Scope(stackFrame, 'myscope', 1, false, 1, 0); + const son = new debugmodel.Variable(stackFrame, new debugmodel.Variable(stackFrame, new debugmodel.Variable(stackFrame, scope, 0, 'grandfather', '75', 1, 0), 0, 'father', '45', 1, 0), 0, 'son', '20', 1, 0); assert.equal(debugmodel.getFullExpressionName(son, type), 'grandfather.father.son'); - const grandson = new debugmodel.Variable(rawSession, son, 0, '/weird_name', '1', 0, 0); + const grandson = new debugmodel.Variable(stackFrame, son, 0, '/weird_name', '1', 0, 0); assert.equal(debugmodel.getFullExpressionName(grandson, type), 'grandfather.father.son[\'/weird_name\']'); }); }); -- GitLab