forked from UbiquityDotNET/Ubiquity.NET.Utils
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCommandAnalyzerTests.cs
More file actions
214 lines (182 loc) · 9.9 KB
/
CommandAnalyzerTests.cs
File metadata and controls
214 lines (182 loc) · 9.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
// Copyright (c) Ubiquity.NET Contributors. All rights reserved.
// Licensed under the Apache-2.0 WITH LLVM-exception license. See the LICENSE.md file in the project root for full license information.
namespace Ubiquity.NET.CommandLine.SrcGen.UT
{
[TestClass]
public class CommandAnalyzerTests
{
public TestContext TestContext { get; set; }
[TestMethod]
[DataRow( TestRuntime.Net8_0 )]
[DataRow( TestRuntime.Net10_0 )]
public async Task Empty_source_analyzes_clean( TestRuntime testRuntime )
{
var analyzerTest = CreateTestRunner( string.Empty, testRuntime );
await analyzerTest.RunAsync( TestContext.CancellationToken );
}
[TestMethod]
[DataRow( TestRuntime.Net8_0 )]
[DataRow( TestRuntime.Net10_0 )]
public async Task Option_attribute_without_command_triggers_diagnostic( TestRuntime testRuntime )
{
SourceText txt = GetSourceText( nameof(Option_attribute_without_command_triggers_diagnostic), "input.cs" );
var analyzerTest = CreateTestRunner( txt, testRuntime );
// (9,6): warning UNC001: Property attribute OptionAttribute is only allowed on a property in a type attributed with a command attribute. This use will be ignored by the generator.
analyzerTest.ExpectedDiagnostics.AddRange(
[
new DiagnosticResult("UNC001", DiagnosticSeverity.Error)
.WithArguments("OptionAttribute")
.WithSpan(9, 6, 9, 93),
]
);
await analyzerTest.RunAsync( TestContext.CancellationToken );
}
[TestMethod]
[DataRow( TestRuntime.Net8_0 )]
[DataRow( TestRuntime.Net10_0 )]
public async Task FileValidation_attribute_without_command_triggers_diagnostic( TestRuntime testRuntime )
{
SourceText txt = GetSourceText( nameof(FileValidation_attribute_without_command_triggers_diagnostic), "input.cs" );
var analyzerTest = CreateTestRunner( txt, testRuntime );
// (9,6): warning UNC001: Property attribute OptionAttribute is only allowed on a property in a type attributed with a command attribute. This use will be ignored by the generator.
// (10,6): warning UNC001: Property attribute FileValidationAttribute is only allowed on a property in a type attributed with a command attribute. This use will be ignored by the generator.
analyzerTest.ExpectedDiagnostics.AddRange(
[
new DiagnosticResult("UNC001", DiagnosticSeverity.Error)
.WithArguments("OptionAttribute")
.WithSpan(9, 6, 9, 51),
new DiagnosticResult("UNC001", DiagnosticSeverity.Error)
.WithArguments("FileValidationAttribute")
.WithSpan(10, 6, 10, 51),
]
);
await analyzerTest.RunAsync( TestContext.CancellationToken );
}
[TestMethod]
[DataRow( TestRuntime.Net8_0 )]
[DataRow( TestRuntime.Net10_0 )]
public async Task FolderValidation_attribute_without_command_triggers_diagnostic( TestRuntime testRuntime )
{
SourceText txt = GetSourceText( nameof(FolderValidation_attribute_without_command_triggers_diagnostic), "input.cs" );
var analyzerTest = CreateTestRunner( txt, testRuntime );
// (11,6): error UNC001: Property attribute FolderValidationAttribute is only allowed on a property in a type attributed with a command attribute. This use will be ignored by the generator.
// (11,6): error UNC002: Property attribute FolderValidationAttribute is not allowed on a property independent of a qualifying attribute such as OptionAttribute.
analyzerTest.ExpectedDiagnostics.AddRange(
[
new DiagnosticResult("UNC001", DiagnosticSeverity.Error)
.WithArguments("FolderValidationAttribute")
.WithSpan(11, 6, 11, 55),
new DiagnosticResult("UNC002", DiagnosticSeverity.Error)
.WithArguments("FolderValidationAttribute")
.WithSpan(11, 6, 11, 55),
]
);
await analyzerTest.RunAsync( TestContext.CancellationToken );
}
[TestMethod]
[DataRow( TestRuntime.Net8_0 )]
[DataRow( TestRuntime.Net10_0 )]
public async Task GoldenPath_produces_no_diagnostics( TestRuntime testRuntime )
{
SourceText txt = GetSourceText( nameof(GoldenPath_produces_no_diagnostics), "input.cs" );
var analyzerTest = CreateTestRunner( txt, testRuntime );
await analyzerTest.RunAsync( TestContext.CancellationToken );
}
[TestMethod]
[DataRow( TestRuntime.Net8_0 )]
[DataRow( TestRuntime.Net10_0 )]
public async Task FileValidation_with_wrong_type_produces_UNC002( TestRuntime testRuntime )
{
SourceText txt = GetSourceText( nameof(FileValidation_with_wrong_type_produces_UNC002), "input.cs" );
var analyzerTest = CreateTestRunner( txt, testRuntime );
// (9,6): error UNC003: Property attribute '{0}' requires a property of type '{1}'.
analyzerTest.ExpectedDiagnostics.AddRange(
[
new DiagnosticResult("UNC003", DiagnosticSeverity.Error)
.WithArguments("FileValidationAttribute", "System.IO.FileInfo")
.WithSpan(9, 6, 9, 51),
]
);
await analyzerTest.RunAsync( TestContext.CancellationToken );
}
[TestMethod]
[DataRow( TestRuntime.Net8_0 )]
[DataRow( TestRuntime.Net10_0 )]
public async Task Required_nullable_types_produce_diagnostic( TestRuntime testRuntime )
{
SourceText txt = GetSourceText( nameof(Required_nullable_types_produce_diagnostic), "input.cs" );
var analyzerTest = CreateTestRunner( txt, testRuntime );
// (9,6): error UNC003: Property attribute '{0}' requires a property of type '{1}'.
analyzerTest.ExpectedDiagnostics.AddRange(
[
new DiagnosticResult("UNC004", DiagnosticSeverity.Warning)
.WithArguments("bool?", "Thing1")
.WithSpan(9, 6, 9, 127),
]
);
await analyzerTest.RunAsync( TestContext.CancellationToken );
}
[TestMethod]
[DataRow( TestRuntime.Net8_0 )]
[DataRow( TestRuntime.Net10_0 )]
public async Task OptionArity_Not_matching_type_produces_diagnostic( TestRuntime testRuntime )
{
SourceText txt = GetSourceText( nameof(OptionArity_Not_matching_type_produces_diagnostic), "input.cs" );
var analyzerTest = CreateTestRunner( txt, testRuntime );
// (9,6): error UNC005: Property '{0}' has type of '{1}' does not support arity of ({2}, {3}).
analyzerTest.ExpectedDiagnostics.AddRange(
[
new DiagnosticResult("UNC005", DiagnosticSeverity.Error)
.WithArguments("Thing1", "bool", 3, 5)
.WithSpan(10, 6, 10, 138),
]
);
await analyzerTest.RunAsync( TestContext.CancellationToken );
}
private AnalyzerTest<MsTestVerifier> CreateTestRunner( string source, TestRuntime testRuntime )
{
return CreateTestRunner( SourceText.From( source ), testRuntime );
}
private AnalyzerTest<MsTestVerifier> CreateTestRunner( SourceText source, TestRuntime testRuntime )
{
// Use a test analyzer with language and reference assemblies that match the runtime for the test run
return new SourceAnalyzerTest<CommandLineAnalyzer, MsTestVerifier>( testRuntime.DefaultLangVersion )
{
TestState =
{
Sources = { source },
ReferenceAssemblies = testRuntime.ReferenceAssemblies,
AdditionalReferences =
{
TestContext.GetUbiquityNetCommandLineLib( testRuntime )
},
OutputKind = OutputKind.DynamicallyLinkedLibrary, // Don't require a Main() method
},
// Allow ALL diagnostics for testing, input source should contain valid C# code
// but might otherwise trigger the tested analyzer.
CompilerDiagnostics = CompilerDiagnostics.All,
// Add custom verification to handle cases not covered in default verifications
DiagnosticVerifier = DiagnosticVerifier,
};
}
/// <summary>Custom diagnostic verifier</summary>
/// <param name="diagnostic">diagnostic to verify (actual)</param>
/// <param name="result">Diagnostic result containing the expected results</param>
/// <param name="verifier">Implementation of <see cref="IVerifier"/> to use for verification</param>
/// <seealso href="https://github.com/dotnet/roslyn-sdk/issues/1246"/>
private void DiagnosticVerifier( Diagnostic diagnostic, DiagnosticResult result, IVerifier verifier )
{
DiagnosticVerifiers.VerifyMessageArguments( diagnostic, result, verifier );
// verify the help URI matches the expected form
verifier.EqualOrDiff( diagnostic.Descriptor.HelpLinkUri, FormatHelpUri( diagnostic.Id ) );
}
private static string FormatHelpUri( string id )
{
return $"https://ubiquitydotnet.github.io/Ubiquity.NET.Utils/CommandLine/diagnostics/{id}.html";
}
private static SourceText GetSourceText( params string[] nameParts )
{
return TestHelpers.GetTestText( nameof( CommandAnalyzerTests ), nameParts );
}
}
}