Skip to content

Commit

Permalink
[GH-70] - checking menu items generation when source code is not avai…
Browse files Browse the repository at this point in the history
…lable
  • Loading branch information
tpodolak committed Feb 27, 2019
1 parent ccf2d99 commit 4141bcc
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
using System.Collections.Immutable;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using NSubstitute.Analyzers.CSharp.Refactorings;
using NSubstitute.Analyzers.Shared;
using NSubstitute.Analyzers.Shared.CodeFixProviders;

namespace NSubstitute.Analyzers.CSharp.CodeFixProviders
{
[ExportCodeFixProvider(LanguageNames.CSharp)]
internal class InternalSetupSpecificationCodeFixProvider : AbstractInternalSetupSpecificationCodeFixProvider<CompilationUnitSyntax>
{
public override ImmutableArray<string> FixableDiagnosticIds { get; } = ImmutableArray.Create(DiagnosticIdentifiers.InternalSetupSpecification);

protected override string ReplaceModifierCodeFixTitle { get; } = "Replace internal with public modifier";

protected override Task<Document> AddModifierRefactoring(Document document, SyntaxNode node, Accessibility accessibility)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
using System.Threading.Tasks;
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;
Expand Down Expand Up @@ -43,21 +49,27 @@ public void Test()
public async Task DoesNotCreateCodeActions_WhenSymbol_DoesNotBelongToCompilation()
{
var source = @"using NSubstitute;
using ExternalNamespace;
namespace MyNamespace
{
public class FooTests
{
public void Test()
{
var substitute = NSubstitute.Substitute.For<object>();
var x = substitute.ToString().Returns(string.Empty);
var substitute = NSubstitute.Substitute.For<InternalFoo>();
var x = substitute.Bar().Returns(1);
}
}
}";
await VerifyCodeActions(source);
}

protected override IEnumerable<MetadataReference> GetAdditionalMetadataReferences()
{
return new[] { GetInternalLibraryMetadataReference() };
}

protected override DiagnosticAnalyzer GetDiagnosticAnalyzer()
{
return new NonSubstitutableMemberAnalyzer();
Expand All @@ -67,5 +79,40 @@ protected override CodeFixProvider GetCodeFixProvider()
{
return new InternalSetupSpecificationCodeFixProvider();
}

private static PortableExecutableReference GetInternalLibraryMetadataReference()
{
var syntaxTree = CSharpSyntaxTree.ParseText($@"
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo(""{TestProjectName}"")]
namespace ExternalNamespace
{{
public class InternalFoo
{{
internal virtual int Bar()
{{
return 1;
}}
}}
}}");

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);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
using System.Threading.Tasks;
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;
Expand Down Expand Up @@ -38,15 +44,17 @@ End Namespace
public async Task DoesNotCreateCodeActions_WhenSymbol_DoesNotBelongToCompilation()
{
var source = @"Imports NSubstitute
Imports ExternalNamespace
Namespace MyNamespace
Public Class FooTests
Public Sub Test()
Dim substitute = NSubstitute.Substitute.[For](Of Object)()
Dim x = substitute.ToString().Returns(String.Empty)
Dim substitute = NSubstitute.Substitute.[For](Of InternalFoo)()
Dim x = substitute.Bar().Returns(1)
End Sub
End Class
End Namespace";

await VerifyCodeActions(source);
}

Expand All @@ -59,5 +67,43 @@ protected override CodeFixProvider GetCodeFixProvider()
{
return new InternalSetupSpecificationCodeFixProvider();
}

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
Public Class InternalFoo
Friend Overridable Function Bar() As Integer
Return 1
End Function
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);
}
}
}
}

0 comments on commit 4141bcc

Please sign in to comment.