diff --git a/source/Runtime/Internal/Flow.cs b/source/Runtime/Internal/Flow.cs index 3b869e5..0d42df9 100644 --- a/source/Runtime/Internal/Flow.cs +++ b/source/Runtime/Internal/Flow.cs @@ -2,14 +2,14 @@ using System.Collections; using System.Collections.Generic; using System.Linq; -using System.Runtime.InteropServices; using System.Text; namespace SharpLab.Runtime.Internal { public static class Flow { private const int MaxReportLength = 20; - private const int MaxReportItemCount = 3; + private const int MaxReportEnumerableItemCount = 3; private const int MaxReportStepNotesPerLineCount = 3; + private const int MaxReportVariablesPerStepCount = 3; private static readonly IDictionary _stepNotesCountPerLine = new Dictionary(); private static readonly List _steps = new List(); @@ -23,18 +23,23 @@ namespace SharpLab.Runtime.Internal { var step = _steps[_steps.Count - 1]; if (!_stepNotesCountPerLine.TryGetValue(step.LineNumber, out int countPerLine)) countPerLine = 0; - countPerLine += 1; - _stepNotesCountPerLine[step.LineNumber] = countPerLine; - if (countPerLine == MaxReportStepNotesPerLineCount + 1) { - if (step.Notes != null) // already has "…" + if (step.Notes == null) { + countPerLine += 1; + _stepNotesCountPerLine[step.LineNumber] = countPerLine; + + if (countPerLine == MaxReportStepNotesPerLineCount + 1) { + step.Notes = new StringBuilder("…"); + _steps[_steps.Count - 1] = step; return; - step.Notes = new StringBuilder("…"); - _steps[_steps.Count - 1] = step; - return; + } } - if (countPerLine > MaxReportStepNotesPerLineCount + 1) + if (countPerLine >= MaxReportStepNotesPerLineCount + 1) + return; + + step.VariableCount += 1; + if (step.VariableCount > MaxReportVariablesPerStepCount + 1) return; var notes = step.Notes; @@ -45,6 +50,12 @@ namespace SharpLab.Runtime.Internal { if (notes.Length > 0) notes.Append(", "); + + if (step.VariableCount == MaxReportVariablesPerStepCount + 1) { + notes.Append("…"); + return; + } + notes.Append(name).Append(": "); AppendValue(notes, value); // Have to reassign in case we set Notes @@ -75,7 +86,7 @@ namespace SharpLab.Runtime.Internal { if (index > 0) builder.Append(", "); - if (index > MaxReportItemCount) { + if (index > MaxReportEnumerableItemCount) { builder.Append("…"); break; } @@ -109,11 +120,14 @@ namespace SharpLab.Runtime.Internal { LineNumber = lineNumber; Notes = null; Exception = null; + VariableCount = 0; } public int LineNumber { get; } public object Exception { get; internal set; } public StringBuilder Notes { get; internal set; } + + internal int VariableCount { get; set; } } } } diff --git a/source/Tests/ExecutionTests.cs b/source/Tests/ExecutionTests.cs index 383257b..dc372a5 100644 --- a/source/Tests/ExecutionTests.cs +++ b/source/Tests/ExecutionTests.cs @@ -11,18 +11,17 @@ using SharpLab.Server; using SharpLab.Server.MirrorSharp.Internal; using Newtonsoft.Json; using Newtonsoft.Json.Linq; -using System; namespace SharpLab.Tests { public class ExecutionTests { private static readonly MirrorSharpOptions MirrorSharpOptions = Startup.CreateMirrorSharpOptions(); [Theory] - [InlineData("Exceptions.DivideByZero.cs", 4, "DivideByZeroException")] - [InlineData("Exceptions.DivideByZero.Catch.cs", 5, "DivideByZeroException")] - [InlineData("Exceptions.DivideByZero.Catch.When.True.cs", 5, "DivideByZeroException")] - [InlineData("Exceptions.DivideByZero.Catch.When.False.cs", 5, "DivideByZeroException")] - [InlineData("Exceptions.DivideByZero.Finally.cs", 5, "DivideByZeroException")] + [InlineData("Exception.DivideByZero.cs", 4, "DivideByZeroException")] + [InlineData("Exception.DivideByZero.Catch.cs", 5, "DivideByZeroException")] + [InlineData("Exception.DivideByZero.Catch.When.True.cs", 5, "DivideByZeroException")] + [InlineData("Exception.DivideByZero.Catch.When.False.cs", 5, "DivideByZeroException")] + [InlineData("Exception.DivideByZero.Finally.cs", 5, "DivideByZeroException")] public async Task SlowUpdate_ReportsExceptionInFlow(string resourceName, int expectedLineNumber, string expectedExceptionTypeName) { var driver = await NewTestDriverAsync(LoadCodeFromResource(resourceName)); @@ -36,22 +35,24 @@ namespace SharpLab.Tests { Assert.Contains(new { Line = expectedLineNumber, Exception = expectedExceptionTypeName }, steps); } - [Fact] - public async Task SlowUpdate_ReportsLimitedNumberOfNotesPerLine() { - var driver = await NewTestDriverAsync(LoadCodeFromResource("Loops.For.10Iterations.cs")); + [Theory] + [InlineData("Loop.For.10Iterations.cs", 3, "i: 0; i: 1; i: 2; …")] + [InlineData("Variable.MultipleDeclarationsOnTheSameLine.cs", 3, "a: 0, b: 0, c: 0, …")] + public async Task SlowUpdate_ReportsLimitedNumberOfNotesPerLine(string resourceName, int lineNumber, string expectedNotes) { + var driver = await NewTestDriverAsync(LoadCodeFromResource(resourceName)); var result = await driver.SendSlowUpdateAsync(); var errors = result.JoinErrors(); var notes = string.Join( - ", ", + "; ", result.ExtensionResult.Flow - .Where(s => s.Line == 3 && s.Notes != null) + .Where(s => s.Line == lineNumber && s.Notes != null) .Select(s => s.Notes) ); Assert.True(errors.IsNullOrEmpty(), errors); - Assert.Equal("i: 0, i: 1, i: 2, …", notes); + Assert.Equal(expectedNotes, notes); } private static int LineNumberFromFlowStep(JToken step) { diff --git a/source/Tests/TestCode/Execution/Exceptions.DivideByZero.Catch.When.False.cs b/source/Tests/TestCode/Execution/Exception.DivideByZero.Catch.When.False.cs similarity index 100% rename from source/Tests/TestCode/Execution/Exceptions.DivideByZero.Catch.When.False.cs rename to source/Tests/TestCode/Execution/Exception.DivideByZero.Catch.When.False.cs diff --git a/source/Tests/TestCode/Execution/Exceptions.DivideByZero.Catch.When.True.cs b/source/Tests/TestCode/Execution/Exception.DivideByZero.Catch.When.True.cs similarity index 100% rename from source/Tests/TestCode/Execution/Exceptions.DivideByZero.Catch.When.True.cs rename to source/Tests/TestCode/Execution/Exception.DivideByZero.Catch.When.True.cs diff --git a/source/Tests/TestCode/Execution/Exceptions.DivideByZero.Catch.cs b/source/Tests/TestCode/Execution/Exception.DivideByZero.Catch.cs similarity index 100% rename from source/Tests/TestCode/Execution/Exceptions.DivideByZero.Catch.cs rename to source/Tests/TestCode/Execution/Exception.DivideByZero.Catch.cs diff --git a/source/Tests/TestCode/Execution/Exceptions.DivideByZero.Finally.cs b/source/Tests/TestCode/Execution/Exception.DivideByZero.Finally.cs similarity index 100% rename from source/Tests/TestCode/Execution/Exceptions.DivideByZero.Finally.cs rename to source/Tests/TestCode/Execution/Exception.DivideByZero.Finally.cs diff --git a/source/Tests/TestCode/Execution/Exceptions.DivideByZero.cs b/source/Tests/TestCode/Execution/Exception.DivideByZero.cs similarity index 100% rename from source/Tests/TestCode/Execution/Exceptions.DivideByZero.cs rename to source/Tests/TestCode/Execution/Exception.DivideByZero.cs diff --git a/source/Tests/TestCode/Execution/Loops.For.10Iterations.cs b/source/Tests/TestCode/Execution/Loop.For.10Iterations.cs similarity index 100% rename from source/Tests/TestCode/Execution/Loops.For.10Iterations.cs rename to source/Tests/TestCode/Execution/Loop.For.10Iterations.cs diff --git a/source/Tests/TestCode/Execution/Variable.MultipleDeclarationsOnTheSameLine.cs b/source/Tests/TestCode/Execution/Variable.MultipleDeclarationsOnTheSameLine.cs new file mode 100644 index 0000000..93dc835 --- /dev/null +++ b/source/Tests/TestCode/Execution/Variable.MultipleDeclarationsOnTheSameLine.cs @@ -0,0 +1,5 @@ +public class C { + public void M() { + int a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0, i = 0; + } +} \ No newline at end of file