Skip to content
This repository was archived by the owner on Nov 8, 2018. It is now read-only.

Commit be34022

Browse files
committed
Update test framework to include improvements from StyleCopAnalyzers
1 parent c1ded89 commit be34022

File tree

8 files changed

+448
-245
lines changed

8 files changed

+448
-245
lines changed

AsyncUsageAnalyzers/AsyncUsageAnalyzers.Test/AsyncUsageAnalyzers.Test.csproj

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<Import Project="..\..\packages\xunit.core.2.0.0\build\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.core.props" Condition="Exists('..\..\packages\xunit.core.2.0.0\build\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.core.props')" />
4+
<Import Project="..\..\packages\xunit.runner.visualstudio.2.0.0\build\net20\xunit.runner.visualstudio.props" Condition="Exists('..\..\packages\xunit.runner.visualstudio.2.0.0\build\net20\xunit.runner.visualstudio.props')" />
35
<PropertyGroup>
46
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
57
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
68
<ProductVersion>8.0.30703</ProductVersion>
79
<SchemaVersion>2.0</SchemaVersion>
810
<ProjectGuid>{658C2A87-E2A9-494D-93D7-CB60EFE3D02B}</ProjectGuid>
11+
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
912
<OutputType>Library</OutputType>
1013
<AppDesignerFolder>Properties</AppDesignerFolder>
1114
<RootNamespace>AsyncUsageAnalyzers.Test</RootNamespace>
@@ -101,7 +104,18 @@
101104
<Reference Include="Microsoft.CSharp" />
102105
<Reference Include="System.Data" />
103106
<Reference Include="System.Xml" />
104-
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework" />
107+
<Reference Include="xunit.abstractions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
108+
<HintPath>..\..\packages\xunit.abstractions.2.0.0\lib\net35\xunit.abstractions.dll</HintPath>
109+
<Private>True</Private>
110+
</Reference>
111+
<Reference Include="xunit.assert, Version=2.0.0.2929, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
112+
<HintPath>..\..\packages\xunit.assert.2.0.0\lib\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.assert.dll</HintPath>
113+
<Private>True</Private>
114+
</Reference>
115+
<Reference Include="xunit.core, Version=2.0.0.2929, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
116+
<HintPath>..\..\packages\xunit.extensibility.core.2.0.0\lib\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.core.dll</HintPath>
117+
<Private>True</Private>
118+
</Reference>
105119
</ItemGroup>
106120
<ItemGroup>
107121
<Compile Include="Verifiers\CodeFixVerifier.cs" />
@@ -121,7 +135,18 @@
121135
<Name>AsyncUsageAnalyzers</Name>
122136
</ProjectReference>
123137
</ItemGroup>
138+
<ItemGroup>
139+
<Analyzer Include="..\..\packages\Microsoft.CodeAnalysis.Analyzers.1.0.0-rc2\tools\analyzers\C#\Microsoft.CodeAnalysis.Analyzers.dll" />
140+
<Analyzer Include="..\..\packages\Microsoft.CodeAnalysis.Analyzers.1.0.0-rc2\tools\analyzers\C#\Microsoft.CodeAnalysis.CSharp.Analyzers.dll" />
141+
</ItemGroup>
124142
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
143+
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
144+
<PropertyGroup>
145+
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
146+
</PropertyGroup>
147+
<Error Condition="!Exists('..\..\packages\xunit.runner.visualstudio.2.0.0\build\net20\xunit.runner.visualstudio.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\xunit.runner.visualstudio.2.0.0\build\net20\xunit.runner.visualstudio.props'))" />
148+
<Error Condition="!Exists('..\..\packages\xunit.core.2.0.0\build\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.core.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\xunit.core.2.0.0\build\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.core.props'))" />
149+
</Target>
125150
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
126151
Other similar extension points exist, see Microsoft.Common.targets.
127152
<Target Name="BeforeBuild">

AsyncUsageAnalyzers/AsyncUsageAnalyzers.Test/Helpers/CodeFixVerifier.Helper.cs

Lines changed: 41 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,37 +5,48 @@
55
using System.Collections.Generic;
66
using System.Linq;
77
using System.Threading;
8+
using System.Threading.Tasks;
9+
using System.Collections.Immutable;
810

911
namespace TestHelper
1012
{
1113
/// <summary>
12-
/// Diagnostic Producer class with extra methods dealing with applying codefixes
14+
/// Diagnostic Producer class with extra methods dealing with applying code fixes.
1315
/// All methods are static
1416
/// </summary>
1517
public abstract partial class CodeFixVerifier : DiagnosticVerifier
1618
{
1719
/// <summary>
18-
/// Apply the inputted CodeAction to the inputted document.
19-
/// Meant to be used to apply codefixes.
20+
/// Apply the inputted <see cref="CodeAction"/> to the inputted document.
21+
/// Meant to be used to apply code fixes.
2022
/// </summary>
21-
/// <param name="document">The Document to apply the fix on</param>
22-
/// <param name="codeAction">A CodeAction that will be applied to the Document.</param>
23-
/// <returns>A Document with the changes from the CodeAction</returns>
24-
private static Document ApplyFix(Document document, CodeAction codeAction)
23+
/// <param name="document">The <see cref="Document"/> to apply the fix on</param>
24+
/// <param name="codeAction">A <see cref="CodeAction"/> that will be applied to the
25+
/// <paramref name="document"/>.</param>
26+
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that the task will observe.</param>
27+
/// <returns>A <see cref="Document"/> with the changes from the <see cref="CodeAction"/>.</returns>
28+
private static async Task<Document> ApplyFixAsync(Document document, CodeAction codeAction, CancellationToken cancellationToken)
2529
{
26-
var operations = codeAction.GetOperationsAsync(CancellationToken.None).Result;
30+
var operations = await codeAction.GetOperationsAsync(cancellationToken).ConfigureAwait(false);
2731
var solution = operations.OfType<ApplyChangesOperation>().Single().ChangedSolution;
2832
return solution.GetDocument(document.Id);
2933
}
3034

3135
/// <summary>
32-
/// Compare two collections of Diagnostics,and return a list of any new diagnostics that appear only in the second collection.
33-
/// Note: Considers Diagnostics to be the same if they have the same Ids. In the case of multiple diagnostics with the same Id in a row,
34-
/// this method may not necessarily return the new one.
36+
/// Compare two collections of <see cref="Diagnostic"/>s, and return a list of any new diagnostics that appear
37+
/// only in the second collection.
38+
/// <note type="note">
39+
/// <para>Considers <see cref="Diagnostic"/> to be the same if they have the same <see cref="Diagnostic.Id"/>s.
40+
/// In the case of multiple diagnostics with the same <see cref="Diagnostic.Id"/> in a row, this method may not
41+
/// necessarily return the new one.</para>
42+
/// </note>
3543
/// </summary>
36-
/// <param name="diagnostics">The Diagnostics that existed in the code before the CodeFix was applied</param>
37-
/// <param name="newDiagnostics">The Diagnostics that exist in the code after the CodeFix was applied</param>
38-
/// <returns>A list of Diagnostics that only surfaced in the code after the CodeFix was applied</returns>
44+
/// <param name="diagnostics">The <see cref="Diagnostic"/>s that existed in the code before the code fix was
45+
/// applied.</param>
46+
/// <param name="newDiagnostics">The <see cref="Diagnostic"/>s that exist in the code after the code fix was
47+
/// applied.</param>
48+
/// <returns>A list of <see cref="Diagnostic"/>s that only surfaced in the code after the code fix was
49+
/// applied.</returns>
3950
private static IEnumerable<Diagnostic> GetNewDiagnostics(IEnumerable<Diagnostic> diagnostics, IEnumerable<Diagnostic> newDiagnostics)
4051
{
4152
var oldArray = diagnostics.OrderBy(d => d.Location.SourceSpan.Start).ToArray();
@@ -59,27 +70,29 @@ private static IEnumerable<Diagnostic> GetNewDiagnostics(IEnumerable<Diagnostic>
5970
}
6071

6172
/// <summary>
62-
/// Get the existing compiler diagnostics on the inputted document.
73+
/// Get the existing compiler diagnostics on the input document.
6374
/// </summary>
64-
/// <param name="document">The Document to run the compiler diagnostic analyzers on</param>
65-
/// <returns>The compiler diagnostics that were found in the code</returns>
66-
private static IEnumerable<Diagnostic> GetCompilerDiagnostics(Document document)
75+
/// <param name="document">The <see cref="Document"/> to run the compiler diagnostic analyzers on.</param>
76+
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that the task will observe.</param>
77+
/// <returns>The compiler diagnostics that were found in the code.</returns>
78+
private static async Task<ImmutableArray<Diagnostic>> GetCompilerDiagnosticsAsync(Document document, CancellationToken cancellationToken)
6779
{
68-
return document.GetSemanticModelAsync().Result.GetDiagnostics();
80+
var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
81+
return semanticModel.GetDiagnostics(cancellationToken: cancellationToken);
6982
}
7083

7184
/// <summary>
72-
/// Given a document, turn it into a string based on the syntax root
85+
/// Given a document, turn it into a string based on the syntax root.
7386
/// </summary>
74-
/// <param name="document">The Document to be converted to a string</param>
75-
/// <returns>A string containing the syntax of the Document after formatting</returns>
76-
private static string GetStringFromDocument(Document document)
87+
/// <param name="document">The <see cref="Document"/> to be converted to a string.</param>
88+
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that the task will observe.</param>
89+
/// <returns>A string containing the syntax of the <see cref="Document"/> after formatting.</returns>
90+
private static async Task<string> GetStringFromDocumentAsync(Document document, CancellationToken cancellationToken)
7791
{
78-
var simplifiedDoc = Simplifier.ReduceAsync(document, Simplifier.Annotation).Result;
79-
var root = simplifiedDoc.GetSyntaxRootAsync().Result;
80-
root = Formatter.Format(root, Formatter.Annotation, simplifiedDoc.Project.Solution.Workspace);
81-
return root.GetText().ToString();
92+
var simplifiedDoc = await Simplifier.ReduceAsync(document, Simplifier.Annotation, cancellationToken: cancellationToken).ConfigureAwait(false);
93+
var formatted = await Formatter.FormatAsync(simplifiedDoc, Formatter.Annotation, cancellationToken: cancellationToken).ConfigureAwait(false);
94+
var sourceText = await formatted.GetTextAsync(cancellationToken).ConfigureAwait(false);
95+
return sourceText.ToString();
8296
}
8397
}
8498
}
85-

AsyncUsageAnalyzers/AsyncUsageAnalyzers.Test/Helpers/DiagnosticResult.cs

Lines changed: 70 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,17 @@ namespace TestHelper
88
/// </summary>
99
public struct DiagnosticResultLocation
1010
{
11+
public string Path;
12+
public int Line;
13+
public int Column;
14+
1115
public DiagnosticResultLocation(string path, int line, int column)
1216
{
1317
if (line < 0 && column < 0)
1418
{
1519
throw new ArgumentOutOfRangeException("At least one of line and column must be > 0");
1620
}
21+
1722
if (line < -1 || column < -1)
1823
{
1924
throw new ArgumentOutOfRangeException("Both line and column must be >= -1");
@@ -23,18 +28,25 @@ public DiagnosticResultLocation(string path, int line, int column)
2328
this.Line = line;
2429
this.Column = column;
2530
}
26-
27-
public string Path;
28-
public int Line;
29-
public int Column;
3031
}
3132

3233
/// <summary>
33-
/// Struct that stores information about a Diagnostic appearing in a source
34+
/// Structure that stores information about a <see cref="Diagnostic"/> appearing in a source.
3435
/// </summary>
3536
public struct DiagnosticResult
3637
{
38+
private static readonly object[] EmptyArguments = new object[0];
39+
3740
private DiagnosticResultLocation[] locations;
41+
private string message;
42+
43+
public DiagnosticResult(DiagnosticDescriptor descriptor)
44+
: this()
45+
{
46+
this.Id = descriptor.Id;
47+
this.Severity = descriptor.DefaultSeverity;
48+
this.MessageFormat = descriptor.MessageFormat;
49+
}
3850

3951
public DiagnosticResultLocation[] Locations
4052
{
@@ -44,6 +56,7 @@ public DiagnosticResultLocation[] Locations
4456
{
4557
this.locations = new DiagnosticResultLocation[] { };
4658
}
59+
4760
return this.locations;
4861
}
4962

@@ -65,14 +78,44 @@ public string Id
6578

6679
public string Message
6780
{
68-
get; set;
81+
get
82+
{
83+
if (this.message != null)
84+
{
85+
return this.message;
86+
}
87+
88+
if (this.MessageFormat != null)
89+
{
90+
return string.Format(this.MessageFormat.ToString(), this.MessageArguments ?? EmptyArguments);
91+
}
92+
93+
return null;
94+
}
95+
96+
set
97+
{
98+
this.message = value;
99+
}
100+
}
101+
102+
public LocalizableString MessageFormat
103+
{
104+
get;
105+
set;
106+
}
107+
108+
public object[] MessageArguments
109+
{
110+
get;
111+
set;
69112
}
70113

71114
public string Path
72115
{
73116
get
74117
{
75-
return this.Locations.Length > 0 ? this.Locations[0].Path : "";
118+
return this.Locations.Length > 0 ? this.Locations[0].Path : string.Empty;
76119
}
77120
}
78121

@@ -91,5 +134,25 @@ public int Column
91134
return this.Locations.Length > 0 ? this.Locations[0].Column : -1;
92135
}
93136
}
137+
138+
public DiagnosticResult WithArguments(params object[] arguments)
139+
{
140+
DiagnosticResult result = this;
141+
result.MessageArguments = arguments;
142+
return result;
143+
}
144+
145+
public DiagnosticResult WithLocation(int line, int column)
146+
{
147+
return this.WithLocation("Test0.cs", line, column);
148+
}
149+
150+
public DiagnosticResult WithLocation(string path, int line, int column)
151+
{
152+
DiagnosticResult result = this;
153+
Array.Resize(ref result.locations, (result.locations?.Length ?? 0) + 1);
154+
result.locations[result.locations.Length - 1] = new DiagnosticResultLocation(path, line, column);
155+
return result;
156+
}
94157
}
95158
}

0 commit comments

Comments
 (0)