-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[GH-38] - Adding tests for external sources
- Loading branch information
Showing
5 changed files
with
275 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
134 changes: 134 additions & 0 deletions
134
...teForInternalMemberCodeFixProviderTests/SubstituteForInternalMemberCodeFixActionsTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CodeFixes; | ||
using Microsoft.CodeAnalysis.CSharp; | ||
using Microsoft.CodeAnalysis.Diagnostics; | ||
using NSubstitute.Analyzers.CSharp.CodeFixProviders; | ||
using NSubstitute.Analyzers.CSharp.DiagnosticAnalyzers; | ||
using NSubstitute.Analyzers.Tests.Shared.CodeFixProviders; | ||
using Xunit; | ||
|
||
namespace NSubstitute.Analyzers.Tests.CSharp.CodeFixProviderTests.SubstituteForInternalMemberCodeFixProviderTests | ||
{ | ||
public class SubstituteForInternalMemberCodeFixActionsTests : CSharpCodeFixActionsVerifier, ISubstituteForInternalMemberCodeFixActionsVerifier | ||
{ | ||
[Fact] | ||
public async Task CreatesCorrectCodeFixActions_WhenSourceForInternalType_IsAvailable() | ||
{ | ||
var source = @"using NSubstitute.Core; | ||
namespace MyNamespace | ||
{ | ||
namespace MyInnerNamespace | ||
{ | ||
internal class Foo | ||
{ | ||
} | ||
public class FooTests | ||
{ | ||
public void Test() | ||
{ | ||
var substitute = SubstitutionContext.Current.SubstituteFactory.CreatePartial(new[] {typeof(Foo)}, null); | ||
} | ||
} | ||
} | ||
}"; | ||
await VerifyCodeActions(source, "Append InternalsVisibleTo attribute"); | ||
} | ||
|
||
[Fact] | ||
public async Task Does_Not_CreateCodeFixActions_WhenType_IsNotInternal() | ||
{ | ||
var source = @"using NSubstitute.Core; | ||
namespace MyNamespace | ||
{ | ||
namespace MyInnerNamespace | ||
{ | ||
public class Foo | ||
{ | ||
} | ||
public class FooTests | ||
{ | ||
public void Test() | ||
{ | ||
var substitute = SubstitutionContext.Current.SubstituteFactory.CreatePartial(new[] {typeof(Foo)}, null); | ||
} | ||
} | ||
} | ||
}"; | ||
await VerifyCodeActions(source); | ||
} | ||
|
||
[Fact] | ||
public async Task Does_Not_CreateCodeFixActions_WhenSourceForInternalType_IsNotAvailable() | ||
{ | ||
var source = @"using NSubstitute.Core; | ||
using ExternalNamespace; | ||
namespace MyNamespace | ||
{ | ||
namespace MyInnerNamespace | ||
{ | ||
public class FooTests | ||
{ | ||
public void Test() | ||
{ | ||
var substitute = SubstitutionContext.Current.SubstituteFactory.CreatePartial(new[] {typeof(InternalFoo)}, null); | ||
} | ||
} | ||
} | ||
}"; | ||
await VerifyCodeActions(source); | ||
} | ||
|
||
protected override DiagnosticAnalyzer GetDiagnosticAnalyzer() | ||
{ | ||
return new SubstituteAnalyzer(); | ||
} | ||
|
||
protected override CodeFixProvider GetCodeFixProvider() | ||
{ | ||
return new SubstituteForInternalMemberCodeFixProvider(); | ||
} | ||
|
||
protected override IEnumerable<MetadataReference> GetAdditionalMetadataReferences() | ||
{ | ||
return new[] { GetInternalLibraryMetadataReference() }; | ||
} | ||
|
||
private static PortableExecutableReference GetInternalLibraryMetadataReference() | ||
{ | ||
var syntaxTree = CSharpSyntaxTree.ParseText($@" | ||
using System.Runtime.CompilerServices; | ||
[assembly: InternalsVisibleTo(""{TestProjectName}"")] | ||
namespace ExternalNamespace | ||
{{ | ||
internal class InternalFoo | ||
{{ | ||
}} | ||
}}"); | ||
|
||
var references = new[] { MetadataReference.CreateFromFile(typeof(object).Assembly.Location) }; | ||
var compilationOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary); | ||
var compilation = CSharpCompilation.Create("Internal", new[] { syntaxTree }, references, compilationOptions); | ||
|
||
using (var ms = new MemoryStream()) | ||
{ | ||
var result = compilation.Emit(ms); | ||
|
||
if (result.Success == false) | ||
{ | ||
var errors = result.Diagnostics.Where(diag => diag.IsWarningAsError || diag.Severity == DiagnosticSeverity.Error); | ||
throw new InvalidOperationException($"Internal library compilation failed: {string.Join(",", errors)}"); | ||
} | ||
|
||
ms.Seek(0, SeekOrigin.Begin); | ||
return MetadataReference.CreateFromStream(ms); | ||
} | ||
} | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
...yzers.Tests.Shared/CodeFixProviders/ISubstituteForInternalMemberCodeFixActionsVerifier.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
using System.Threading.Tasks; | ||
|
||
namespace NSubstitute.Analyzers.Tests.Shared.CodeFixProviders | ||
{ | ||
public interface ISubstituteForInternalMemberCodeFixActionsVerifier | ||
{ | ||
Task CreatesCorrectCodeFixActions_WhenSourceForInternalType_IsAvailable(); | ||
|
||
Task Does_Not_CreateCodeFixActions_WhenType_IsNotInternal(); | ||
|
||
Task Does_Not_CreateCodeFixActions_WhenSourceForInternalType_IsNotAvailable(); | ||
} | ||
} |
126 changes: 126 additions & 0 deletions
126
...teForInternalMemberCodeFixProviderTests/SubstituteForInternalMemberCodeFixActionsTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CodeFixes; | ||
using Microsoft.CodeAnalysis.Diagnostics; | ||
using Microsoft.CodeAnalysis.VisualBasic; | ||
using NSubstitute.Analyzers.Tests.Shared.CodeFixProviders; | ||
using NSubstitute.Analyzers.VisualBasic.CodeFixProviders; | ||
using NSubstitute.Analyzers.VisualBasic.DiagnosticAnalyzers; | ||
using Xunit; | ||
|
||
namespace NSubstitute.Analyzers.Tests.VisualBasic.CodeFixProvidersTests.SubstituteForInternalMemberCodeFixProviderTests | ||
{ | ||
public class SubstituteForInternalMemberCodeFixActionsTests : VisualBasicCodeFixActionsVerifier, ISubstituteForInternalMemberCodeFixActionsVerifier | ||
{ | ||
[Fact] | ||
public async Task CreatesCorrectCodeFixActions_WhenSourceForInternalType_IsAvailable() | ||
{ | ||
var source = @"Imports NSubstitute.Core | ||
Namespace MyNamespace | ||
Namespace MyInnerNamespace | ||
Friend Class Foo | ||
End Class | ||
Public Class FooTests | ||
Public Sub Test() | ||
Dim substitute = SubstitutionContext.Current.SubstituteFactory.CreatePartial({GetType(Foo)}, Nothing) | ||
End Sub | ||
End Class | ||
End Namespace | ||
End Namespace | ||
"; | ||
await VerifyCodeActions(source, "Append InternalsVisibleTo attribute"); | ||
} | ||
|
||
[Fact] | ||
public async Task Does_Not_CreateCodeFixActions_WhenType_IsNotInternal() | ||
{ | ||
var source = @"Imports NSubstitute.Core | ||
Namespace MyNamespace | ||
Namespace MyInnerNamespace | ||
Public Class Foo | ||
End Class | ||
Public Class FooTests | ||
Public Sub Test() | ||
Dim substitute = SubstitutionContext.Current.SubstituteFactory.CreatePartial({GetType(Foo)}, Nothing) | ||
End Sub | ||
End Class | ||
End Namespace | ||
End Namespace | ||
"; | ||
await VerifyCodeActions(source); | ||
} | ||
|
||
[Fact] | ||
public async Task Does_Not_CreateCodeFixActions_WhenSourceForInternalType_IsNotAvailable() | ||
{ | ||
var source = @"Imports NSubstitute.Core | ||
Imports ExternalNamespace | ||
Namespace MyNamespace | ||
Namespace MyInnerNamespace | ||
Public Class FooTests | ||
Public Sub Test() | ||
Dim substitute = SubstitutionContext.Current.SubstituteFactory.CreatePartial({GetType(InternalFoo)}, Nothing) | ||
End Sub | ||
End Class | ||
End Namespace | ||
End Namespace | ||
"; | ||
await VerifyCodeActions(source); | ||
} | ||
|
||
protected override DiagnosticAnalyzer GetDiagnosticAnalyzer() | ||
{ | ||
return new SubstituteAnalyzer(); | ||
} | ||
|
||
protected override CodeFixProvider GetCodeFixProvider() | ||
{ | ||
return new SubstituteForInternalMemberCodeFixProvider(); | ||
} | ||
|
||
protected override IEnumerable<MetadataReference> GetAdditionalMetadataReferences() | ||
{ | ||
return new[] { GetInternalLibraryMetadataReference() }; | ||
} | ||
|
||
private static PortableExecutableReference GetInternalLibraryMetadataReference() | ||
{ | ||
var syntaxTree = VisualBasicSyntaxTree.ParseText($@" | ||
Imports System.Runtime.CompilerServices | ||
<Assembly: InternalsVisibleTo(""{TestProjectName}"")> | ||
Namespace ExternalNamespace | ||
Friend Class InternalFoo | ||
End Class | ||
End Namespace | ||
"); | ||
|
||
var references = new[] { MetadataReference.CreateFromFile(typeof(object).Assembly.Location) }; | ||
var compilationOptions = new VisualBasicCompilationOptions(OutputKind.DynamicallyLinkedLibrary); | ||
var compilation = VisualBasicCompilation.Create("Internal", new[] { syntaxTree }, references, compilationOptions); | ||
|
||
using (var ms = new MemoryStream()) | ||
{ | ||
var result = compilation.Emit(ms); | ||
|
||
if (result.Success == false) | ||
{ | ||
var errors = result.Diagnostics.Where(diag => diag.IsWarningAsError || diag.Severity == DiagnosticSeverity.Error); | ||
throw new InvalidOperationException($"Internal library compilation failed: {string.Join(",", errors)}"); | ||
} | ||
|
||
ms.Seek(0, SeekOrigin.Begin); | ||
return MetadataReference.CreateFromStream(ms); | ||
} | ||
} | ||
} | ||
} |