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 BreakContinue() { const string code = @"x <- 0 browser() while (x >= 0) { x <- x + 1 } browser()"; var tracer = await _session.TraceExecutionAsync(); using (var sf = new SourceFile(code)) { await sf.Source(_session); await _session.NextPromptShouldBeBrowseAsync(); await tracer.ContinueAsync(); await Task.Delay(100); await tracer.BreakAsync(); await _session.NextPromptShouldBeBrowseAsync(); var frame = (await _session.TracebackAsync()).Single(); frame.FileName.Should().Be(sf.FilePath); frame.LineNumber.Should().BeInRange(3, 5); await _session.ExecuteAsync("x <- -42"); await tracer.ContinueAsync(); await _session.NextPromptShouldBeBrowseAsync(); await _session.ShouldHaveTracebackAsync(new TracebackBuilder { { sf, 6 } }); } }