)> Setup(string viewportCodeMarkup) { MarkupTestFile.GetNamedSpans(viewportCodeMarkup, out var viewportCode, out var textSpans); var code = $@" using System; using System.Linq; namespace RoslynRecorder {{ class Program {{ static void Main(string[] args) {{ int thisShouldBeIgnored = 1; #region test {viewportCode} #endregion }} }} }} "; var linePositionSpans = textSpans.ToDictionary( kv => kv.Key, kv => kv.Value.Select(span => span.ToLinePositionSpan(SourceText.From(viewportCode)) ) ); var withLF = code.EnforceLF(); var document = Sources.GetDocument(withLF); var workspace = new Workspace(files: new[] { new File("test.cs", withLF) }); var visitor = new InstrumentationSyntaxVisitor(document, await document.GetSemanticModelAsync()); var viewport = workspace.ExtractViewPorts().DefaultIfEmpty(null).First(); return(visitor.Augmentations, visitor.VariableLocations, document, viewport, linePositionSpans); }
public void Language_can_be_determined_for_a_given_position( string markupCode, string defaultLanguage) { MarkupTestFile.GetNamedSpans(markupCode, out var code, out var spansByName); var parser = CreateSubmissionParser(defaultLanguage); var tree = parser.Parse(code); using var _ = new AssertionScope(); foreach (var pair in spansByName) { var expectedLanguage = pair.Key; var spans = pair.Value; foreach (var position in spans.SelectMany(s => Enumerable.Range(s.Start, s.Length))) { var language = tree.GetLanguageAtPosition(position); language .Should() .Be(expectedLanguage, because: $"position {position} should be {expectedLanguage}"); } } }
public void FilterActiveViewport_Should_Return_Viewport_In_ActiveBufferId() { var text = @" using System; namespace RoslynRecorder { class Program { static void Main(string[] args) { {|regionStart:#region test|} int a = 0; Console.WriteLine(""Entry Point""); {|regionEnd:#endregion|} } #region notthis } #endregion }".EnforceLF(); MarkupTestFile.GetNamedSpans(text, out var code, out var spans); var workspace = new Workspace(files: new[] { new File("testFile.cs", code) }); var viewports = workspace.ExtractViewPorts(); var activeViewport = InstrumentationLineMapper.FilterActiveViewport(viewports, BufferId.Parse("testFile.cs@test")).First(); activeViewport.Region.Start.Should().Be(spans["regionStart"].First().End); activeViewport.Region.End.Should().Be(spans["regionEnd"].First().Start); }
public void GetNamedSpans_Should_Return_Correct_Named_Spans() { var input = "{|first:input span|}other"; MarkupTestFile.GetNamedSpans(input, out string output, out IDictionary <string, ImmutableArray <TextSpan> > spans); var expected = ImmutableArray.Create(new TextSpan(0, 10)); Assert.Equal(expected.ToArray(), spans["first"].ToArray()); }
public async Task When_Run_is_called_with_instrumentation_and_regions_variable_locations_are_mapped() { var code = @" using System; namespace ConsoleProgram { public class Program { public static void Main(string[] args) { Console.WriteLine(); #region reg #endregion Console.WriteLine(a); } } }"; var regionCodeWithMarkup = "{|a:var a = 10;|}"; MarkupTestFile.GetNamedSpans(regionCodeWithMarkup, out var regionCode, out var spans); var linePositionSpans = ToLinePositionSpan(spans, regionCode); var server = GetCodeRunner(); var workspace = new Workspace( workspaceType: "console", buffers: new[] { new Buffer("Program.cs@reg", regionCode) }, files: new[] { new File("Program.cs", code) }, includeInstrumentation: true ); var result = await server.Run(new WorkspaceRequest(workspace)); var locations = result.Features[nameof(ProgramDescriptor)].As <ProgramDescriptor>() .VariableLocations .Where(variable => variable.Name == "a") .SelectMany(variable => variable.Locations) .Select(location => location.StartLine); var expectedLocations = linePositionSpans["a"].Select(loc => loc.Start.Line); locations.Should().BeEquivalentTo(expectedLocations); }
public async Task When_Run_is_called_with_instrumentation_and_regions_lines_are_mapped() { var code = @" using System; namespace ConsoleProgram { public class Program { public static void Main(string[] args) { #region reg #endregion } } }"; var regionCodeWithMarkup = @" {|line:Console.WriteLine();|} {|line:Console.WriteLine();|}"; MarkupTestFile.GetNamedSpans(regionCodeWithMarkup, out var regionCode, out var spans); var linePositionSpans = ToLinePositionSpan(spans, regionCode); var server = GetCodeRunner(); var workspace = new Workspace( workspaceType: "console", buffers: new[] { new Buffer("Program.cs@reg", regionCode) }, files: new[] { new File("Program.cs", code) }, includeInstrumentation: true ); var result = await server.Run(new WorkspaceRequest(workspace)); var filePositions = result.Features[nameof(ProgramStateAtPositionArray)].As <ProgramStateAtPositionArray>() .ProgramStates .Where(state => state.FilePosition != null) .Select(state => state.FilePosition.Line); var expectedLines = linePositionSpans["line"].Select(loc => loc.Start.Line); filePositions.Should().BeEquivalentTo(expectedLines); }
public async Task When_Run_is_called_with_instrumentation_and_no_regions_variable_locations_are_not_mapped() { var markedUpCode = @" using System; namespace ConsoleProgram { public class Program { public static void Main(string[] args) { {|a:var a = 10;|} Console.WriteLine({|a:a|}); } } }"; MarkupTestFile.GetNamedSpans(markedUpCode, out var code, out var spans); var linePositionSpans = ToLinePositionSpan(spans, code); var(server, build) = await GetRunnerAndWorkspaceBuild(); var workspace = new Workspace( workspaceType: build.Name, buffers: new[] { new Buffer("Program.cs", code) }, includeInstrumentation: true ); var result = await server.Run(new WorkspaceRequest(workspace)); var locations = result.Features[nameof(ProgramDescriptor)].As <ProgramDescriptor>() .VariableLocations .Where(variable => variable.Name == "a") .SelectMany(variable => variable.Locations) .Select(location => location.StartLine); var expectedLocations = linePositionSpans["a"].Select(loc => loc.Start.Line); locations.Should().BeEquivalentTo(expectedLocations); }
private async Task FindAndValidateVariablesAsync(string markup) { MarkupTestFile.GetNamedSpans( markup, out var text, out IDictionary <string, ImmutableArray <TextSpan> > spans); var document = Sources.GetDocument(text); var fileLineLocationSpans = ConvertSpans(spans, await document.GetTextAsync()); var visitor = new InstrumentationSyntaxVisitor(document, await document.GetSemanticModelAsync()); var locations = visitor.VariableLocations.Data.ToDictionary( key => key.Key.Name, values => values.Value.Select(location => location.ToLinePositionSpan())); foreach (var kv in locations) { var expected = new HashSet <LinePositionSpan>(fileLineLocationSpans[kv.Key]); var actual = new HashSet <LinePositionSpan>(kv.Value); Assert.Equal(expected, actual); } }
public async Task When_Run_is_called_with_instrumentation_and_no_regions_lines_are_not_mapped() { var markedUpCode = @" using System; namespace ConsoleProgram { public class Program { public static void Main(string[] args) { {|line:Console.WriteLine(""test"");|} {|line:var a = 10;|} } } }"; MarkupTestFile.GetNamedSpans(markedUpCode, out var code, out var spans); var linePositionSpans = ToLinePositionSpan(spans, code); var(server, build) = await GetRunnerAndWorkspaceBuild(); var workspace = new Workspace( workspaceType: build.Name, buffers: new[] { new Buffer("Program.cs", code) }, includeInstrumentation: true); var result = await server.Run(new WorkspaceRequest(workspace)); var filePositions = result.Features[nameof(ProgramStateAtPositionArray)].As <ProgramStateAtPositionArray>() .ProgramStates .Where(state => state.FilePosition != null) .Select(state => state.FilePosition.Line); var expectedLines = linePositionSpans["line"].Select(loc => loc.Start.Line); filePositions.Should().BeEquivalentTo(expectedLines); }
public void Directive_node_indicates_parent_language( string markupCode, string defaultLanguage) { MarkupTestFile.GetNamedSpans(markupCode, out var code, out var spansByName); var parser = CreateSubmissionParser(defaultLanguage); var tree = parser.Parse(code); using var _ = new AssertionScope(); foreach (var pair in spansByName) { var expectedParentLanguage = pair.Key; var spans = pair.Value; foreach (var position in spans.SelectMany(s => Enumerable.Range(s.Start, s.Length))) { var node = tree.GetRoot().FindNode(position); switch (node) { case KernelNameDirectiveNode _: expectedParentLanguage.Should().Be("none"); break; case ActionDirectiveNode adn: adn.ParentLanguage.Should().Be(expectedParentLanguage); break; default: throw new AssertionFailedException($"Expected a {nameof(DirectiveNode)} but found: {node}"); } } } }