Skip to content

Commit 7d401cf

Browse files
authored
Merge pull request #423 from tonyhallett/fix-blazor-editor-marks
Fix blazor editor marks
2 parents 2071f51 + 6d9a114 commit 7d401cf

File tree

91 files changed

+3018
-1268
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

91 files changed

+3018
-1268
lines changed

FineCodeCoverage/FineCodeCoverage.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,9 @@
189189
<PackageReference Include="Newtonsoft.Json">
190190
<Version>13.0.1</Version>
191191
</PackageReference>
192+
<PackageReference Include="NUnit">
193+
<Version>3.13.1</Version>
194+
</PackageReference>
192195
<PackageReference Include="ReflectObject">
193196
<Version>1.0.0</Version>
194197
</PackageReference>

FineCodeCoverageTests/AppOptionsProvider_Tests.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,8 @@ internal void Should_Use_Deseralized_String_From_Store_For_AppOption_Property(Fu
349349
{nameof(IAppOptions.ShowLineNewHighlighting),true },
350350
{nameof(IAppOptions.ShowLineNotIncludedHighlighting),true },
351351
{nameof(IAppOptions.UseEnterpriseFontsAndColors),true },
352-
{nameof(IAppOptions.EditorCoverageColouringMode), EditorCoverageColouringMode.UseRoslynWhenTextChanges }
352+
{nameof(IAppOptions.EditorCoverageColouringMode), EditorCoverageColouringMode.UseRoslynWhenTextChanges },
353+
{nameof(IAppOptions.BlazorCoverageLinesFromGeneratedSource), true }
353354
};
354355
var mockJsonConvertService = autoMocker.GetMock<IJsonConvertService>();
355356
mockJsonConvertService.Setup(
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
using FineCodeCoverage.Editor.DynamicCoverage.ContentTypes.Blazor;
2+
using FineCodeCoverage.Options;
3+
using Moq;
4+
using NUnit.Framework;
5+
6+
namespace FineCodeCoverageTests.Editor.DynamicCoverage
7+
{
8+
internal class BlazorCoverageContentType_Tests
9+
{
10+
[TestCase("path.razor",false)]
11+
[TestCase("path.cshtml", true)]
12+
[TestCase("path.vbhtml", true)]
13+
public void Should_Include_Razor_Component_Files(string filePath, bool expectedExclude)
14+
{
15+
Assert.That(new BlazorCoverageContentType(null, null).Exclude(filePath), Is.EqualTo(expectedExclude));
16+
}
17+
18+
[Test]
19+
public void Should_Line_Exclude_HtmlTags()
20+
{
21+
var lineExcluder = new BlazorCoverageContentType(null, null).LineExcluder;
22+
Assert.True(lineExcluder.ExcludeIfNotCode("<"));
23+
}
24+
25+
[Test]
26+
public void Should_Line_Exclude_Directives()
27+
{
28+
var lineExcluder = new BlazorCoverageContentType(null, null).LineExcluder;
29+
Assert.True(lineExcluder.ExcludeIfNotCode("@"));
30+
}
31+
32+
[Test]
33+
public void Should_Line_Exclude_Comments()
34+
{
35+
var lineExcluder = new BlazorCoverageContentType(null, null).LineExcluder;
36+
Assert.True(lineExcluder.ExcludeIfNotCode("//"));
37+
}
38+
39+
[Test]
40+
public void Should_Line_Exclude_Compiler_Directives()
41+
{
42+
var lineExcluder = new BlazorCoverageContentType(null, null).LineExcluder;
43+
Assert.True(lineExcluder.ExcludeIfNotCode("#"));
44+
}
45+
46+
[Test]
47+
public void Should_Not_UseFileCodeSpanRangeServiceForChanges()
48+
{
49+
Assert.False(new BlazorCoverageContentType(null, null).UseFileCodeSpanRangeServiceForChanges);
50+
}
51+
52+
[TestCase(true)]
53+
[TestCase(false)]
54+
public void Should_CoverageFromFileCodeSpanRangeService_From_AppOptions(bool blazorCoverageLinesFromGeneratedSource)
55+
{
56+
var mockAppOptionsProvider = new Mock<IAppOptionsProvider>();
57+
mockAppOptionsProvider.Setup(a => a.Get()).Returns(new AppOptions { BlazorCoverageLinesFromGeneratedSource = blazorCoverageLinesFromGeneratedSource });
58+
Assert.That(new BlazorCoverageContentType(null, mockAppOptionsProvider.Object).CoverageOnlyFromFileCodeSpanRangeService, Is.EqualTo(blazorCoverageLinesFromGeneratedSource));
59+
}
60+
61+
[Test]
62+
public void Should_Use_BlazorFileCodeSpanRangeService()
63+
{
64+
var blazorFileCodeSpanRangeService = new Mock<IBlazorFileCodeSpanRangeService>().Object;
65+
Assert.That(blazorFileCodeSpanRangeService, Is.SameAs(new BlazorCoverageContentType(blazorFileCodeSpanRangeService, null).FileCodeSpanRangeService));
66+
}
67+
68+
[Test]
69+
public void Should_Be_For_The_Razor_ContentType()
70+
{
71+
Assert.That("Razor", Is.EqualTo(new BlazorCoverageContentType(null, null).ContentTypeName));
72+
}
73+
74+
}
75+
}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using AutoMoq;
4+
using FineCodeCoverage.Core.Utilities.VsThreading;
5+
using FineCodeCoverage.Editor.DynamicCoverage;
6+
using FineCodeCoverage.Editor.DynamicCoverage.ContentTypes.Blazor;
7+
using FineCodeCoverage.Editor.DynamicCoverage.Utilities;
8+
using FineCodeCoverage.Editor.Roslyn;
9+
using FineCodeCoverageTests.TestHelpers;
10+
using Microsoft.CodeAnalysis;
11+
using Microsoft.CodeAnalysis.CSharp;
12+
using Microsoft.CodeAnalysis.Text;
13+
using Microsoft.VisualStudio.Text;
14+
using Moq;
15+
using NUnit.Framework;
16+
17+
namespace FineCodeCoverageTests.Editor.DynamicCoverage
18+
{
19+
internal class BlazorFileCodeSpanRangeService_Tests
20+
{
21+
[Test]
22+
public void Should_Return_Null_If_Cannot_Find_Syntax_Root_Of_Generated_Document()
23+
{
24+
var mockTextSnapshot = new Mock<ITextSnapshot>();
25+
var mockTextBuffer = new Mock<ITextBuffer>();
26+
mockTextSnapshot.SetupGet(textSnapshot => textSnapshot.TextBuffer).Returns(mockTextBuffer.Object);
27+
28+
var autoMoqer = new AutoMoqer();
29+
var razorGeneratedFilePathMatcher = autoMoqer.GetMock<IBlazorGeneratedFilePathMatcher>().Object;
30+
autoMoqer.SetInstance<IThreadHelper>(new TestThreadHelper());
31+
autoMoqer.GetMock<ITextInfoFactory>().Setup(t => t.GetFilePath(mockTextBuffer.Object)).Returns("path");
32+
33+
var mockRazorGeneratedDocumentRootFinder = autoMoqer.GetMock<IBlazorGeneratedDocumentRootFinder>();
34+
mockRazorGeneratedDocumentRootFinder.Setup(
35+
razorGeneratedDocumentootFinder => razorGeneratedDocumentootFinder.FindSyntaxRootAsync(mockTextBuffer.Object, "path", razorGeneratedFilePathMatcher)
36+
).ReturnsAsync((SyntaxNode)null);
37+
38+
var fileCodeSpanRanges = autoMoqer.Create<BlazorFileCodeSpanRangeService>().GetFileCodeSpanRanges(mockTextSnapshot.Object);
39+
40+
Assert.IsNull(fileCodeSpanRanges);
41+
mockRazorGeneratedDocumentRootFinder.VerifyAll();
42+
}
43+
44+
[Test]
45+
public void Should_Return_Null_If_Generated_Document_Has_No_Code_Nodes()
46+
{
47+
var mockTextSnapshot = new Mock<ITextSnapshot>();
48+
var mockTextBuffer = new Mock<ITextBuffer>();
49+
mockTextSnapshot.SetupGet(textSnapshot => textSnapshot.TextBuffer).Returns(mockTextBuffer.Object);
50+
51+
var autoMoqer = new AutoMoqer();
52+
var mockCSharpCodeCoverageNodeVisitor = autoMoqer.GetMock<ICSharpCodeCoverageNodeVisitor>();
53+
mockCSharpCodeCoverageNodeVisitor.Setup(cSharpCodeCoverageNodeVisitor => cSharpCodeCoverageNodeVisitor.GetNodes(It.IsAny<SyntaxNode>()))
54+
.Returns(new List<SyntaxNode>());
55+
var razorGeneratedFilePathMatcher = autoMoqer.GetMock<IBlazorGeneratedFilePathMatcher>().Object;
56+
autoMoqer.SetInstance<IThreadHelper>(new TestThreadHelper());
57+
autoMoqer.GetMock<ITextInfoFactory>().Setup(t => t.GetFilePath(mockTextBuffer.Object)).Returns("path");
58+
59+
var rootNode = SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration);
60+
var mockRazorGeneratedDocumentRootFinder = autoMoqer.GetMock<IBlazorGeneratedDocumentRootFinder>();
61+
mockRazorGeneratedDocumentRootFinder.Setup(
62+
razorGeneratedDocumentootFinder => razorGeneratedDocumentootFinder.FindSyntaxRootAsync(mockTextBuffer.Object, "path", razorGeneratedFilePathMatcher)
63+
).ReturnsAsync(rootNode);
64+
65+
var fileCodeSpanRanges = autoMoqer.Create<BlazorFileCodeSpanRangeService>().GetFileCodeSpanRanges(mockTextSnapshot.Object);
66+
67+
Assert.IsNull(fileCodeSpanRanges);
68+
69+
mockCSharpCodeCoverageNodeVisitor.VerifyAll();
70+
}
71+
72+
[TestCase(true)]
73+
[TestCase(false)]
74+
public void Should_Use_The_Generated_Coverage_Syntax_Nodes_Mapped_To_Razor_File_For_The_CodeSpanRange(
75+
bool firstMapsBack
76+
)
77+
{
78+
var mockTextSnapshot = new Mock<ITextSnapshot>();
79+
var mockTextBuffer = new Mock<ITextBuffer>();
80+
mockTextSnapshot.SetupGet(textSnapshot => textSnapshot.TextBuffer).Returns(mockTextBuffer.Object);
81+
82+
var autoMoqer = new AutoMoqer();
83+
var razorGeneratedFilePathMatcher = autoMoqer.GetMock<IBlazorGeneratedFilePathMatcher>().Object;
84+
autoMoqer.SetInstance<IThreadHelper>(new TestThreadHelper());
85+
autoMoqer.GetMock<ITextInfoFactory>().Setup(t => t.GetFilePath(mockTextBuffer.Object)).Returns("path");
86+
87+
var mockRazorGeneratedDocumentRootFinder = autoMoqer.GetMock<IBlazorGeneratedDocumentRootFinder>();
88+
SyntaxNode rootSyntaxNode = SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration);
89+
SyntaxNode codeCoverageNode1 = SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration);
90+
SyntaxNode codeCoverageNode2 = SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration);
91+
mockRazorGeneratedDocumentRootFinder.Setup(
92+
razorGeneratedDocumentootFinder => razorGeneratedDocumentootFinder.FindSyntaxRootAsync(mockTextBuffer.Object, "path", razorGeneratedFilePathMatcher)
93+
).ReturnsAsync(rootSyntaxNode);
94+
95+
var mockCSharpCodeCoverageNodeVisitor = autoMoqer.GetMock<ICSharpCodeCoverageNodeVisitor>();
96+
mockCSharpCodeCoverageNodeVisitor.Setup(cSharpCodeCoverageNodeVisitor => cSharpCodeCoverageNodeVisitor.GetNodes(rootSyntaxNode))
97+
.Returns(new List<SyntaxNode> { codeCoverageNode1, codeCoverageNode2 });
98+
var mockSyntaxNodeLocationMapper = autoMoqer.GetMock<ISyntaxNodeLocationMapper>();
99+
100+
var linePositionSpan1 = new LinePositionSpan(new LinePosition(1, 1), new LinePosition(2, 1));
101+
var fileLinePositionSpan1 = new FileLinePositionSpan(firstMapsBack ? "path" : "",linePositionSpan1);
102+
var linePositionSpan2 = new LinePositionSpan(new LinePosition(3, 1), new LinePosition(4, 1));
103+
var fileLinePositionSpan2 = new FileLinePositionSpan(firstMapsBack ? "" : "path", linePositionSpan2);
104+
var expectedCodeSpanRange = firstMapsBack ? new CodeSpanRange(1, 2) : new CodeSpanRange(3, 4);
105+
106+
mockSyntaxNodeLocationMapper.Setup(syntaxNodeLocationMapper => syntaxNodeLocationMapper.Map(codeCoverageNode1))
107+
.Returns(fileLinePositionSpan1);
108+
mockSyntaxNodeLocationMapper.Setup(syntaxNodeLocationMapper => syntaxNodeLocationMapper.Map(codeCoverageNode2))
109+
.Returns(fileLinePositionSpan2);
110+
111+
112+
var fileCodeSpanRanges = autoMoqer.Create<BlazorFileCodeSpanRangeService>().GetFileCodeSpanRanges(mockTextSnapshot.Object);
113+
var fileCodeSpanRange = fileCodeSpanRanges.Single();
114+
115+
Assert.That(expectedCodeSpanRange, Is.EqualTo(fileCodeSpanRange));
116+
}
117+
}
118+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using FineCodeCoverage.Editor.DynamicCoverage.ContentTypes.Blazor;
2+
using NUnit.Framework;
3+
4+
namespace FineCodeCoverageTests.Editor.DynamicCoverage
5+
{
6+
internal class BlazorGeneratedFilePathMatcher_Tests
7+
{
8+
[TestCase("razorpath","razorpath.",true)]
9+
[TestCase("razorpath", "razorpathx.", false)]
10+
public void Should_Be_Generated_If_File_Path_Starts_With_Razor_Path_And_Dot(
11+
string razorFilePath,
12+
string generatedFilePath,
13+
bool expectedIsGenerated
14+
)
15+
{
16+
var isGenerated = new BlazorGeneratedFilePathMatcher().IsBlazorGeneratedFilePath(razorFilePath, generatedFilePath);
17+
18+
Assert.That(expectedIsGenerated, Is.EqualTo(isGenerated));
19+
}
20+
}
21+
}

0 commit comments

Comments
 (0)