public async Task CallStack() { var tracer = await _session.TraceExecutionAsync(); const string code1 = @"f <- function(n) { if (n > 0) { g(n - 1) } else { return() } }"; const string code2 = @"g <- function(n) { if (n > 0) { f(n - 1) } else { return() } }"; using (var sf1 = new SourceFile(code1)) using (var sf2 = new SourceFile(code2)) { await tracer.EnableBreakpointsAsync(true); await sf1.Source(_session); await sf2.Source(_session); var bp = await tracer.CreateBreakpointAsync(sf1, 5); var bpHit = new BreakpointHitDetector(bp); using (var inter = await _session.BeginInteractionAsync()) { await inter.RespondAsync("f(4)\n"); } await bpHit.ShouldBeHitAtNextPromptAsync(); await _session.ShouldHaveTracebackAsync(new TracebackBuilder { { null, null, "f(4)", "<environment: R_GlobalEnv>" }, { sf1, 3, "g(n - 1)", null }, { sf2, 3, "f(n - 1)", null }, { sf1, 3, "g(n - 1)", null }, { sf2, 3, "f(n - 1)", null }, { sf1, 5, TracebackBuilder.Any, null } }); } }
public async Task StepOver() { const string code = @"f <- function(x) { x + 1 } x <- f(1) print(x)"; var tracer = await _session.TraceExecutionAsync(); using (var sf = new SourceFile(code)) { await tracer.EnableBreakpointsAsync(true); var bp = await tracer.CreateBreakpointAsync(sf, 4); var bpHit = new BreakpointHitDetector(bp); await sf.Source(_session); await bpHit.ShouldBeHitAtNextPromptAsync(); await _session.ShouldHaveTracebackAsync(new TracebackBuilder { { bp.Location } }); (await tracer.StepOverAsync()).Should().Be(true); await _session.ShouldHaveTracebackAsync(new TracebackBuilder { { bp.Location, +1 } }); } }
public async Task StepOntoBreakpoint() { const string code = @"x <- 1 y <- 2"; var tracer = await _session.TraceExecutionAsync(); using (var sf = new SourceFile(code)) { await tracer.EnableBreakpointsAsync(true); var bp1 = await tracer.CreateBreakpointAsync(sf, 1); var bp2 = await tracer.CreateBreakpointAsync(sf, 2); var bp1Hit = new BreakpointHitDetector(bp1); var bp2Hit = new BreakpointHitDetector(bp2); await sf.Source(_session); await bp1Hit.ShouldBeHitAtNextPromptAsync(); (await tracer.StepOverAsync()).Should().Be(false); await bp2Hit.ShouldBeHitAtNextPromptAsync(); } }
public async Task StepOutFromGlobal() { const string code = @"x <- 1 y <- 2"; var tracer = await _session.TraceExecutionAsync(); using (var sf = new SourceFile(code)) { await tracer.EnableBreakpointsAsync(true); var bp1 = await tracer.CreateBreakpointAsync(sf, 1); var bp2 = await tracer.CreateBreakpointAsync(sf, 2); var bp1Hit = new BreakpointHitDetector(bp1); await sf.Source(_session); await bp1Hit.ShouldBeHitAtNextPromptAsync(); await _session.ShouldHaveTracebackAsync(new TracebackBuilder { { bp1.Location } }); (await tracer.StepOutAsync()).Should().Be(false); await _session.ShouldHaveTracebackAsync(new TracebackBuilder { { bp2.Location } }); } }
public async Task StepOutToFunction() { const string code = @"f <- function() { 1 } g <- function() { f() 1 } g()"; var tracer = await _session.TraceExecutionAsync(); using (var sf = new SourceFile(code)) { await tracer.EnableBreakpointsAsync(true); var bp = await tracer.CreateBreakpointAsync(sf, 2); var bpHit = new BreakpointHitDetector(bp); await sf.Source(_session); await bpHit.ShouldBeHitAtNextPromptAsync(); await _session.ShouldHaveTracebackAsync(new TracebackBuilder { { sf, 8, "g()" }, { sf, 5, "f()" }, { bp.Location }, }); (await tracer.StepOutAsync()).Should().Be(true); await _session.ShouldHaveTracebackAsync(new TracebackBuilder { { sf, 8, "g()" }, { sf, 6, TracebackBuilder.Any }, }); } }
public async Task HideSourceFrames(bool debug) { var tracer = await _session.TraceExecutionAsync(); using (var sf = new SourceFile("0")) { await tracer.EnableBreakpointsAsync(true); var bp = await tracer.CreateBreakpointAsync(sf, 1); var bpHit = new BreakpointHitDetector(bp); await sf.Source(_session, debug); await bpHit.ShouldBeHitAtNextPromptAsync(); var frame = (await _session.TracebackAsync()).Single(); frame.IsGlobal.Should().BeTrue(); } }
public async Task SetAndHitBreakpointInsideUnloadedFunction() { const string code = @"f <- function() { 0 } f()"; var tracer = await _session.TraceExecutionAsync(); using (var sf = new SourceFile(code)) { await tracer.EnableBreakpointsAsync(true); var bp = await tracer.CreateBreakpointAsync(new RSourceLocation(sf.FilePath, 2)); var bpHit = new BreakpointHitDetector(bp); await sf.Source(_session); await bpHit.ShouldBeHitAtNextPromptAsync(); } }
public async Task SetAndHitToplevelBreakpoint() { const string code = @"x <- 1 y <- 2 z <- 3"; var tracer = await _session.TraceExecutionAsync(); using (var sf = new SourceFile(code)) { await tracer.EnableBreakpointsAsync(true); var bp = await tracer.CreateBreakpointAsync(new RSourceLocation(sf.FilePath, 2)); var bpHit = new BreakpointHitDetector(bp); await sf.Source(_session); await bpHit.ShouldBeHitAtNextPromptAsync(); } }
public async Task BreakpointsInDifferentFiles() { var tracer = await _session.TraceExecutionAsync(); using (var sf1 = new SourceFile("1")) using (var sf2 = new SourceFile($"eval(parse({sf1.FilePath.ToRStringLiteral()}))")) { await tracer.EnableBreakpointsAsync(true); var bp1Loc = new RSourceLocation(sf1.FilePath, 1); var bp1 = await tracer.CreateBreakpointAsync(bp1Loc); bp1.Location.Should().Be(bp1Loc); var bp2Loc = new RSourceLocation(sf2.FilePath, 1); var bp2 = await tracer.CreateBreakpointAsync(bp2Loc); bp2.Location.Should().Be(bp2Loc); tracer.Breakpoints.Should().HaveCount(2); var bp1Hit = new BreakpointHitDetector(bp1); var bp2Hit = new BreakpointHitDetector(bp2); await sf2.Source(_session); await bp2Hit.ShouldBeHitAtNextPromptAsync(); bp1Hit.WasHit.Should().BeFalse(); bp2Hit.Reset(); await tracer.ContinueAsync(); await bp1Hit.ShouldBeHitAtNextPromptAsync(); bp2Hit.WasHit.Should().BeFalse(); } }
public async Task OverlappingBreakpoints() { const string code = @"f <- function() { 1 }"; var tracer = await _session.TraceExecutionAsync(); using (var sf = new SourceFile(code)) { await tracer.EnableBreakpointsAsync(true); await sf.Source(_session); var bp1 = await tracer.CreateBreakpointAsync(sf, 1); var bp2 = await tracer.CreateBreakpointAsync(sf, 1); bp1.Should().BeSameAs(bp2); tracer.Breakpoints.Should().HaveCount(1); var bp1Hit = new BreakpointHitDetector(bp1); var bp2Hit = new BreakpointHitDetector(bp2); using (var inter = await _session.BeginInteractionAsync()) { await inter.RespondAsync("f()\n"); } await bp1Hit.ShouldBeHitAtNextPromptAsync(); bp2Hit.WasHit.Should().BeTrue(); await bp1.DeleteAsync(); tracer.Breakpoints.Should().HaveCount(1); tracer.Breakpoints.Should().Contain(bp2); await tracer.ContinueAsync(); using (var inter = await _session.BeginInteractionAsync()) { await inter.RespondAsync("f()\n"); } await bp2Hit.ShouldBeHitAtNextPromptAsync(); await bp2.DeleteAsync(); tracer.Breakpoints.Should().BeEmpty(); await tracer.ContinueAsync(); using (var inter = await _session.BeginInteractionAsync()) { await inter.RespondAsync("f()\n"); } using (var inter = await _session.BeginInteractionAsync()) { inter.Contexts.IsBrowser().Should().BeFalse(); } } }
public async Task RemovedBreakpointNotHit() { const string code = @"f <- function() { 0 }"; var tracer = await _session.TraceExecutionAsync(); using (var sf = new SourceFile(code)) { await tracer.EnableBreakpointsAsync(true); await sf.Source(_session); var bp = await tracer.CreateBreakpointAsync(new RSourceLocation(sf.FilePath, 2)); var bpHit = new BreakpointHitDetector(bp); using (var inter = await _session.BeginInteractionAsync()) { await inter.RespondAsync("f()\n"); } await bpHit.ShouldBeHitAtNextPromptAsync(); await bp.DeleteAsync(); await tracer.ContinueAsync(); using (var inter = await _session.BeginInteractionAsync()) { await inter.RespondAsync("f()\n"); } using (var inter = await _session.BeginInteractionAsync()) { inter.Contexts.IsBrowser().Should().BeFalse(); } } }