44namespace StyleCop . Analyzers . Test . MaintainabilityRules
55{
66 using System . Collections . Generic ;
7- using System . Collections . Immutable ;
8- using System . Linq ;
97 using System . Text ;
108 using System . Threading ;
119 using System . Threading . Tasks ;
12- using Microsoft . CodeAnalysis ;
13- using Microsoft . CodeAnalysis . CodeActions ;
1410 using Microsoft . CodeAnalysis . CodeFixes ;
15- using Microsoft . CodeAnalysis . Diagnostics ;
1611 using Microsoft . CodeAnalysis . Text ;
17- using StyleCop . Analyzers . MaintainabilityRules ;
18- using StyleCop . Analyzers . Test . Helpers ;
19- using TestHelper ;
2012 using Xunit ;
13+ using static StyleCop . Analyzers . Test . Verifiers . StyleCopCodeFixVerifier <
14+ StyleCop . Analyzers . MaintainabilityRules . SA1412StoreFilesAsUtf8 ,
15+ StyleCop . Analyzers . MaintainabilityRules . SA1412CodeFixProvider > ;
2116
22- public class SA1412UnitTests : CodeFixVerifier
17+ public class SA1412UnitTests
2318 {
24- private Encoding fileEncoding ;
25-
2619 public static IEnumerable < object [ ] > NonUtf8Encodings
2720 {
2821 get
@@ -40,77 +33,33 @@ public static IEnumerable<object[]> NonUtf8Encodings
4033 [ MemberData ( nameof ( NonUtf8Encodings ) ) ]
4134 public async Task TestFileWithWrongEncodingAsync ( int codepage )
4235 {
43- string testCode = "class TypeName { }" ;
44-
45- this . fileEncoding = Encoding . GetEncoding ( codepage ) ;
36+ var testCode = SourceText . From ( "class TypeName { }" , Encoding . GetEncoding ( codepage ) ) ;
37+ var fixedCode = SourceText . From ( testCode . ToString ( ) , Encoding . UTF8 ) ;
4638
47- var expected = this . CSharpDiagnostic ( ) . WithLocation ( 1 , 1 ) ;
39+ var expected = Diagnostic ( ) . WithLocation ( 1 , 1 ) ;
4840
49- await this . VerifyCSharpDiagnosticAsync ( testCode , expected , CancellationToken . None ) . ConfigureAwait ( false ) ;
41+ await new CSharpTest
42+ {
43+ TestSources = { testCode } ,
44+ ExpectedDiagnostics = { expected } ,
45+ FixedSources = { fixedCode } ,
46+ } . RunAsync ( CancellationToken . None ) . ConfigureAwait ( false ) ;
5047 }
5148
5249 [ Fact ]
5350 public async Task TestFileWithUtf8EncodingWithoutBOMAsync ( )
5451 {
55- string testCode = "class TypeName { }" ;
56-
57- this . fileEncoding = new UTF8Encoding ( false ) ;
58-
59- var expected = this . CSharpDiagnostic ( ) . WithLocation ( 1 , 1 ) ;
60-
61- await this . VerifyCSharpDiagnosticAsync ( testCode , expected , CancellationToken . None ) . ConfigureAwait ( false ) ;
62- }
63-
64- [ Theory ]
65- [ MemberData ( nameof ( NonUtf8Encodings ) ) ]
66- public async Task TestCodeFixAsync ( int codepage )
67- {
68- string testCode = "class TypeName { }" ;
69-
70- this . fileEncoding = Encoding . GetEncoding ( codepage ) ;
71-
72- // Create a project using the specified encoding
73- Project project = this . CreateProject ( new [ ] { testCode } ) ;
74- Project oldProject = project ;
75-
76- Workspace workspace = project . Solution . Workspace ;
77-
78- var codeFixer = this . GetCSharpCodeFixProvider ( ) ;
79-
80- var document = project . Documents . First ( ) ;
81-
82- // Create a diagnostic for the document to fix
83- var properties = ImmutableDictionary < string , string > . Empty . SetItem ( SA1412StoreFilesAsUtf8 . EncodingProperty , this . fileEncoding . WebName ) ;
84- var diagnostic = Diagnostic . Create (
85- this . GetCSharpDiagnosticAnalyzers ( ) . First ( ) . SupportedDiagnostics . First ( ) ,
86- Location . Create ( await document . GetSyntaxTreeAsync ( ) . ConfigureAwait ( false ) , TextSpan . FromBounds ( 0 , 0 ) ) ,
87- properties ) ;
88-
89- await codeFixer . RegisterCodeFixesAsync (
90- new CodeFixContext (
91- document ,
92- diagnostic ,
93- ( ca , d ) =>
94- {
95- var operation = ca . GetOperationsAsync ( CancellationToken . None ) . ConfigureAwait ( false ) . GetAwaiter ( ) . GetResult ( ) [ 0 ] ;
96-
97- operation . Apply ( workspace , CancellationToken . None ) ;
98- } ,
99- CancellationToken . None ) ) . ConfigureAwait ( false ) ;
52+ var testCode = SourceText . From ( "class TypeName { }" , new UTF8Encoding ( false ) ) ;
53+ var fixedCode = SourceText . From ( testCode . ToString ( ) , Encoding . UTF8 ) ;
10054
101- // project should now have the "fixed document" in it.
102- // Because of limitations in Roslyn the fixed document should
103- // have a different DocumentId then the broken document
104- project = workspace . CurrentSolution . Projects . First ( ) ;
55+ var expected = Diagnostic ( ) . WithLocation ( 1 , 1 ) ;
10556
106- Assert . Equal ( 1 , project . DocumentIds . Count ) ;
107-
108- SourceText sourceText = await project . Documents . First ( ) . GetTextAsync ( ) . ConfigureAwait ( false ) ;
109-
110- Assert . Equal ( testCode , sourceText . ToString ( ) ) ;
111-
112- Assert . Equal ( Encoding . UTF8 , sourceText . Encoding ) ;
113- Assert . NotEqual ( oldProject . DocumentIds [ 0 ] , project . DocumentIds [ 0 ] ) ;
57+ await new CSharpTest
58+ {
59+ TestSources = { testCode } ,
60+ ExpectedDiagnostics = { expected } ,
61+ FixedSources = { fixedCode } ,
62+ } . RunAsync ( CancellationToken . None ) . ConfigureAwait ( false ) ;
11463 }
11564
11665 [ Theory ]
@@ -121,175 +70,56 @@ public async Task TestFixAllAsync(int codepage)
12170 await this . TestFixAllExecuterAsync ( codepage , FixAllScope . Solution ) . ConfigureAwait ( false ) ;
12271 }
12372
124- protected override IEnumerable < DiagnosticAnalyzer > GetCSharpDiagnosticAnalyzers ( )
125- {
126- yield return new SA1412StoreFilesAsUtf8 ( ) ;
127- }
128-
129- protected override CodeFixProvider GetCSharpCodeFixProvider ( )
130- {
131- return new SA1412CodeFixProvider ( ) ;
132- }
133-
134- protected override Project CreateProjectImpl ( string [ ] sources , string language , string [ ] filenames )
73+ [ Fact ]
74+ public async Task TestFixAllWithMultipleEncodingsAsync ( )
13575 {
136- string fileNamePrefix = "Test" ;
137- string fileExt = "cs" ;
138-
139- var projectId = ProjectId . CreateNewId ( debugName : "TestProject" ) ;
140- var solution = this . CreateSolution ( projectId , language ) ;
141-
142- int count = 0 ;
143- for ( int i = 0 ; i < sources . Length ; i ++ )
76+ await new CSharpTest
14477 {
145- string source = sources [ i ] ;
146- var newFileName = filenames ? [ i ] ?? fileNamePrefix + count + "." + fileExt ;
147- var documentId = DocumentId . CreateNewId ( projectId , debugName : newFileName ) ;
148- solution = solution . AddDocument ( documentId , newFileName , SourceText . From ( source , encoding : this . fileEncoding ) ) ;
149- count ++ ;
150- }
151-
152- return solution . GetProject ( projectId ) ;
78+ TestSources =
79+ {
80+ SourceText . From ( "class Foo { }" , Encoding . Unicode ) ,
81+ SourceText . From ( "class Bar { }" , Encoding . Unicode ) ,
82+ SourceText . From ( "class FooBar { }" , Encoding . UTF7 ) ,
83+ } ,
84+ ExpectedDiagnostics =
85+ {
86+ Diagnostic ( ) . WithLocation ( "Test0.cs" , 1 , 1 ) ,
87+ Diagnostic ( ) . WithLocation ( "Test1.cs" , 1 , 1 ) ,
88+ Diagnostic ( ) . WithLocation ( "Test2.cs" , 1 , 1 ) ,
89+ } ,
90+ FixedSources =
91+ {
92+ SourceText . From ( "class Foo { }" , Encoding . UTF8 ) ,
93+ SourceText . From ( "class Bar { }" , Encoding . UTF8 ) ,
94+ SourceText . From ( "class FooBar { }" , Encoding . UTF8 ) ,
95+ } ,
96+ NumberOfFixAllIterations = 2 ,
97+ NumberOfFixAllInDocumentIterations = 3 ,
98+ } . RunAsync ( CancellationToken . None ) . ConfigureAwait ( false ) ;
15399 }
154100
155101 private async Task TestFixAllExecuterAsync ( int codepage , FixAllScope scope )
156102 {
157- string [ ] testCode = new [ ] { "class Foo { }" , "class Bar { }" } ;
158-
159- this . fileEncoding = Encoding . GetEncoding ( codepage ) ;
160-
161- // Create a project using the specified encoding
162- Project project = this . CreateProject ( testCode ) ;
163- Project oldProject = project ;
164-
165- Workspace workspace = project . Solution . Workspace ;
166-
167- var codeFixer = this . GetCSharpCodeFixProvider ( ) ;
168- var fixAllProvider = codeFixer . GetFixAllProvider ( ) ;
169- var diagnostics = new List < Diagnostic > ( ) ;
170- var descriptor = this . GetCSharpDiagnosticAnalyzers ( ) . First ( ) . SupportedDiagnostics . First ( ) ;
171- foreach ( var document in project . Documents )
172- {
173- // Create a diagnostic for the document to fix
174- var properties = ImmutableDictionary < string , string > . Empty . SetItem ( SA1412StoreFilesAsUtf8 . EncodingProperty , ( await document . GetTextAsync ( ) . ConfigureAwait ( false ) ) . Encoding . WebName ) ;
175- var diagnostic = Diagnostic . Create (
176- descriptor ,
177- Location . Create ( await document . GetSyntaxTreeAsync ( ) . ConfigureAwait ( false ) , TextSpan . FromBounds ( 0 , 0 ) ) ,
178- properties ) ;
179- diagnostics . Add ( diagnostic ) ;
180- }
181-
182- FixAllContext fixAllContext = new FixAllContext (
183- project . Documents . First ( ) ,
184- codeFixer ,
185- scope ,
186- nameof ( SA1412CodeFixProvider ) + "." + this . fileEncoding . WebName ,
187- new [ ] { SA1412StoreFilesAsUtf8 . DiagnosticId } ,
188- TestDiagnosticProvider . Create ( diagnostics . ToImmutableArray ( ) ) ,
189- CancellationToken . None ) ;
190-
191- CodeAction codeAction = await fixAllProvider . GetFixAsync ( fixAllContext ) . ConfigureAwait ( false ) ;
192- var operation = codeAction . GetOperationsAsync ( CancellationToken . None ) . ConfigureAwait ( false ) . GetAwaiter ( ) . GetResult ( ) [ 0 ] ;
193-
194- operation . Apply ( workspace , CancellationToken . None ) ;
195-
196- // project should now have the "fixed document" in it.
197- // Because of limitations in roslyn the fixed document should
198- // have a different DocumentId then the broken document
199- project = workspace . CurrentSolution . Projects . First ( ) ;
200-
201- Assert . Equal ( 2 , project . DocumentIds . Count ) ;
202-
203- for ( int i = 0 ; i < project . DocumentIds . Count ; i ++ )
204- {
205- DocumentId documentId = project . DocumentIds [ i ] ;
206- SourceText sourceText = await project . GetDocument ( documentId ) . GetTextAsync ( ) . ConfigureAwait ( false ) ;
207-
208- Assert . Equal ( testCode [ i ] , sourceText . ToString ( ) ) ;
209-
210- Assert . Equal ( Encoding . UTF8 , sourceText . Encoding ) ;
211- Assert . NotEqual ( oldProject . DocumentIds [ i ] , project . DocumentIds [ i ] ) ;
212- }
213- }
214-
215- [ Theory ]
216- [ InlineData ( FixAllScope . Solution ) ]
217- [ InlineData ( FixAllScope . Project ) ]
218- private async Task TestFixAllWithMultipleEncodingsAsync ( FixAllScope scope )
219- {
220- string [ ] testCode = new [ ] { "class Foo { }" , "class Bar { }" } ;
221-
222- this . fileEncoding = Encoding . Unicode ;
223-
224- // Create a project using the specified encoding
225- Project project = this . CreateProject ( testCode ) ;
226-
227- project = project . AddDocument ( "Test2.cs" , SourceText . From ( "class FooBar { }" , Encoding . UTF7 ) ) . Project ;
228-
229- Project oldProject = project ;
230-
231- Workspace workspace = project . Solution . Workspace ;
232-
233- var codeFixer = this . GetCSharpCodeFixProvider ( ) ;
234- var fixAllProvider = codeFixer . GetFixAllProvider ( ) ;
235- var diagnostics = new List < Diagnostic > ( ) ;
236- var descriptor = this . GetCSharpDiagnosticAnalyzers ( ) . First ( ) . SupportedDiagnostics . First ( ) ;
237- foreach ( var document in project . Documents )
103+ await new CSharpTest
238104 {
239- // Create a diagnostic for the document to fix
240- var properties = ImmutableDictionary < string , string > . Empty . SetItem ( SA1412StoreFilesAsUtf8 . EncodingProperty , ( await document . GetTextAsync ( ) . ConfigureAwait ( false ) ) . Encoding . WebName ) ;
241- var diagnostic = Diagnostic . Create (
242- descriptor ,
243- Location . Create ( await document . GetSyntaxTreeAsync ( ) . ConfigureAwait ( false ) , TextSpan . FromBounds ( 0 , 0 ) ) ,
244- properties ) ;
245- diagnostics . Add ( diagnostic ) ;
246- }
247-
248- FixAllContext fixAllContext = new FixAllContext (
249- project . Documents . First ( ) ,
250- codeFixer ,
251- scope ,
252- nameof ( SA1412CodeFixProvider ) + "." + this . fileEncoding . WebName ,
253- new [ ] { SA1412StoreFilesAsUtf8 . DiagnosticId } ,
254- TestDiagnosticProvider . Create ( diagnostics . ToImmutableArray ( ) ) ,
255- CancellationToken . None ) ;
256-
257- CodeAction codeAction = await fixAllProvider . GetFixAsync ( fixAllContext ) . ConfigureAwait ( false ) ;
258- var operation = codeAction . GetOperationsAsync ( CancellationToken . None ) . ConfigureAwait ( false ) . GetAwaiter ( ) . GetResult ( ) [ 0 ] ;
259-
260- operation . Apply ( workspace , CancellationToken . None ) ;
261-
262- // project should now have the "fixed document" in it.
263- // Because of limitations in Roslyn the fixed document should
264- // have a different DocumentId then the broken document
265- project = workspace . CurrentSolution . Projects . First ( ) ;
266-
267- Assert . Equal ( 3 , project . DocumentIds . Count ) ;
268-
269- // The order of the document ids is now different from the order before.
270- for ( int i = 1 ; i < 3 ; i ++ )
271- {
272- DocumentId documentId = project . DocumentIds [ i ] ;
273- SourceText sourceText = await project . GetDocument ( documentId ) . GetTextAsync ( ) . ConfigureAwait ( false ) ;
274-
275- Assert . Equal ( testCode [ i - 1 ] , sourceText . ToString ( ) ) ;
276-
277- Assert . Equal ( Encoding . UTF8 , sourceText . Encoding ) ;
278- Assert . NotEqual ( oldProject . DocumentIds [ i - 1 ] , project . DocumentIds [ i ] ) ;
279- }
280-
281- // Check that Test2.cs was not changed
282- DocumentId otherDocumentId = project . DocumentIds [ 0 ] ;
283- var otherDocument = project . GetDocument ( otherDocumentId ) ;
284-
285- Assert . Equal ( "Test2.cs" , otherDocument . Name ) ;
286-
287- SourceText otherDocumentText = await otherDocument . GetTextAsync ( ) . ConfigureAwait ( false ) ;
288-
289- Assert . Equal ( "class FooBar { }" , otherDocumentText . ToString ( ) ) ;
290-
291- Assert . Equal ( Encoding . UTF7 , otherDocumentText . Encoding ) ;
292- Assert . Equal ( oldProject . DocumentIds [ 2 ] , project . DocumentIds [ 0 ] ) ;
105+ TestSources =
106+ {
107+ SourceText . From ( "class Foo { }" , Encoding . GetEncoding ( codepage ) ) ,
108+ SourceText . From ( "class Bar { }" , Encoding . GetEncoding ( codepage ) ) ,
109+ } ,
110+ ExpectedDiagnostics =
111+ {
112+ Diagnostic ( ) . WithLocation ( "Test0.cs" , 1 , 1 ) ,
113+ Diagnostic ( ) . WithLocation ( "Test1.cs" , 1 , 1 ) ,
114+ } ,
115+ FixedSources =
116+ {
117+ SourceText . From ( "class Foo { }" , Encoding . UTF8 ) ,
118+ SourceText . From ( "class Bar { }" , Encoding . UTF8 ) ,
119+ } ,
120+ NumberOfFixAllIterations = 1 ,
121+ NumberOfFixAllInDocumentIterations = 2 ,
122+ } . RunAsync ( CancellationToken . None ) . ConfigureAwait ( false ) ;
293123 }
294124 }
295125}
0 commit comments