public void CanSetNextStatementMatchingPc() { const ulong ADDRESS = 0xdeadbeef; const string NAME = "test"; var threadId = 1u; var mockThread = Substitute.For <RemoteThread>(); mockThread.GetThreadId().Returns(threadId); var mockStackFrame = Substitute.For <IDebugStackFrame2>(); string name; mockStackFrame.GetName(out name).Returns(x => { x[0] = NAME; return(VSConstants.S_OK); }); IDebugThread2 outThread; IDebugThread thread = CreateDebugThread <IDebugThread>(mockThread); mockStackFrame.GetThread(out outThread).Returns(x => { x[0] = thread; return(VSConstants.S_OK); }); var mockCodeContext = Substitute.For <IDebugCodeContext2>(); mockCodeContext .GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS | enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION, Arg.Do <CONTEXT_INFO[]>(infos => { infos[0].bstrAddress = "0x" + ADDRESS.ToString("x16"); infos[0].bstrFunction = NAME; })) .Returns(VSConstants.S_OK); var mockFrame = Substitute.For <RemoteFrame>(); mockFrame.GetPC().Returns(ADDRESS); mockThread.GetFrameAtIndex(0).Returns(mockFrame); Assert.AreEqual(VSConstants.S_OK, thread.CanSetNextStatement(mockStackFrame, mockCodeContext)); }
public void SetNextStatementNoDocumentContext() { // We need CanSetNextStatement() to pass in order to execute SetNexStatement(). const string NAME = "test"; const ulong ADDRESS = 0xabcd; var threadId = 1u; var mockThread = Substitute.For <RemoteThread>(); mockThread.GetThreadId().Returns(threadId); var mockStackFrame = Substitute.For <IDebugStackFrame2>(); string name; mockStackFrame.GetName(out name).Returns(x => { x[0] = NAME; return(VSConstants.S_OK); }); IDebugThread2 outThread; IDebugThread thread = CreateDebugThread <IDebugThread>(mockThread); mockStackFrame.GetThread(out outThread).Returns(x => { x[0] = thread; return(VSConstants.S_OK); }); var mockCodeContext = Substitute.For <IDebugCodeContext2>(); System.Action <CONTEXT_INFO[]> setContextInfo = infos => { infos[0].bstrFunction = NAME; infos[0].bstrAddress = "0x" + ADDRESS.ToString("x16"); infos[0].dwFields = enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS | enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION; }; mockCodeContext .GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS | enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION, Arg.Do(setContextInfo)) .Returns(VSConstants.S_OK); ((IDebugMemoryContext2)mockCodeContext) .GetInfo(Arg.Any <enum_CONTEXT_INFO_FIELDS>(), Arg.Do(setContextInfo)) .Returns(VSConstants.S_OK); IDebugDocumentContext2 documentContext; mockCodeContext.GetDocumentContext(out documentContext).Returns(x => { x[0] = null; return(VSConstants.S_OK); }); const string DIR = "path\\to"; const string FILE_NAME = "file"; const uint LINE = 2; var mockProcess = Substitute.For <SbProcess>(); mockThread.GetProcess().Returns(mockProcess); var mockTarget = Substitute.For <RemoteTarget>(); mockProcess.GetTarget().Returns(mockTarget); var mockAddress = Substitute.For <SbAddress>(); var mockLineEntry = new LineEntryInfo(); mockLineEntry.Directory = DIR; mockLineEntry.FileName = FILE_NAME; mockLineEntry.Line = LINE; var mockError = Substitute.For <SbError>(); mockError.Fail().Returns(false); mockThread.JumpToLine(Path.Combine(DIR, FILE_NAME), LINE).Returns(mockError); mockAddress.GetLineEntry().Returns(mockLineEntry); mockTarget.ResolveLoadAddress(ADDRESS).Returns(mockAddress); Assert.AreEqual(VSConstants.S_OK, thread.SetNextStatement(mockStackFrame, mockCodeContext)); mockThread.Received(1).JumpToLine(Path.Combine(DIR, FILE_NAME), LINE); }
public void SetNextStatement() { // We need CanSetNextStatement() to pass in order to execute SetNexStatement(). const string NAME = "test"; const ulong ADDRESS = 0xabcd; var threadId = 1u; var mockThread = Substitute.For <RemoteThread>(); mockThread.GetThreadId().Returns(threadId); var mockStackFrame = Substitute.For <IDebugStackFrame2>(); string name; mockStackFrame.GetName(out name).Returns(x => { x[0] = NAME; return(VSConstants.S_OK); }); IDebugThread2 outThread; IDebugThread thread = CreateDebugThread <IDebugThread>(mockThread); mockStackFrame.GetThread(out outThread).Returns(x => { x[0] = thread; return(VSConstants.S_OK); }); var mockCodeContext = Substitute.For <IDebugCodeContext2>(); var contextInfosDestination = Arg.Any <CONTEXT_INFO[]>(); mockCodeContext.GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS | enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION, contextInfosDestination).Returns(x => { var infos = x[1] as CONTEXT_INFO[]; infos[0] = new CONTEXT_INFO { bstrFunction = NAME, bstrAddress = "0x" + ADDRESS.ToString("x16"), }; return(VSConstants.S_OK); }); IDebugDocumentContext2 documentContext; var mockDocumentContext = Substitute.For <IDebugDocumentContext2>(); mockCodeContext.GetDocumentContext(out documentContext).Returns(x => { x[0] = mockDocumentContext; return(VSConstants.S_OK); }); const uint LINE = 2; const string PATH = "path\\to\\file"; string path; mockDocumentContext.GetName(enum_GETNAME_TYPE.GN_FILENAME, out path).Returns(x => { x[1] = PATH; return(VSConstants.S_OK); }); mockDocumentContext.GetStatementRange( Arg.Any <TEXT_POSITION[]>(), Arg.Any <TEXT_POSITION[]>()).Returns(x => { var startPosition = x[0] as TEXT_POSITION[]; startPosition[0].dwLine = LINE; return(VSConstants.S_OK); }); var mockError = Substitute.For <SbError>(); mockError.Fail().Returns(false); mockThread.JumpToLine(PATH, LINE).Returns(mockError); Assert.AreEqual(VSConstants.S_OK, thread.SetNextStatement(mockStackFrame, mockCodeContext)); mockThread.Received(1).JumpToLine(PATH, LINE + 1); }