public async Task ReportDiagnosticForRecursiveMock() { var code = @" using Moq; namespace Recursive { public interface IRecursiveRoot2 { IRecursiveBranch2 Branch { get; } } public interface IRecursiveBranch2 { IRecursiveLeaf2 Leaf { get; } } public interface IRecursiveLeaf2 { string Name { get; set; } } public class RecursiveMocks { public RecursiveMocks() { var mock = Mock.Of<IRecursiveRoot2>(); mock.Setup(m => m.Branch.Leaf.Name).Returns(""foo=""); // mock.Branch.Leaf.Name.Returns(""foo""); } } } "; var(workspace, project) = CreateWorkspaceAndProject(LanguageNames.CSharp, includeMockApi: true); var compilation = await project.GetCompilationAsync(TimeoutToken(5)); AssertCode.NoErrors(compilation); var doc = workspace.AddDocument(project, code); var exports = workspace.Services.HostServices.GetExports <CodeFixProvider, IDictionary <string, object> >() .Where(x => x.Metadata.ContainsKey("Languages") && x.Metadata.ContainsKey("Name") && x.Metadata["Languages"] is string[] languages && languages.Contains(doc.Project.Language) && x.Metadata["Name"] is string name && name == "ImplementInterface") .Select(x => x.Value) .FirstOrDefault(); Assert.NotNull(exports); compilation = await doc.Project.GetCompilationAsync(TimeoutToken(5)); AssertCode.NoErrors(compilation); // First we'll generate the mock from Mock.Of<T> doc = await workspace.ApplyCodeFixAsync <MockGeneratorAnalyzer, GenerateMockCodeFix>(doc, "MOQ001"); await AssertCode.NoErrorsAsync(doc); var analyzer = new RecursiveMockAnalyzer(); compilation = await doc.Project.GetCompilationAsync(TimeoutToken(5)); var withAnalyzers = compilation.WithAnalyzers(ImmutableArray.Create <DiagnosticAnalyzer>(analyzer)); var diagnostics = (await withAnalyzers.GetAnalyzerDiagnosticsAsync()) .Where(d => d.Id == "MOQ001") .OrderBy(d => d.Location.SourceSpan.Start) .ToArray(); Assert.Equal(2, diagnostics.Length); doc = await workspace.ApplyCodeFixAsync <RecursiveMockAnalyzer, GenerateMockCodeFix>(doc, "MOQ001"); doc = await workspace.ApplyCodeFixAsync <RecursiveMockAnalyzer, GenerateMockCodeFix>(doc, "MOQ001"); compilation = await doc.Project.GetCompilationAsync(TimeoutToken(5)); withAnalyzers = compilation.WithAnalyzers(ImmutableArray.Create <DiagnosticAnalyzer>(analyzer)); diagnostics = (await withAnalyzers.GetAnalyzerDiagnosticsAsync()) .Where(d => d.Id == "MOQ001") .OrderBy(d => d.Location.SourceSpan.Start) .ToArray(); Assert.Empty(diagnostics); }
public async Task ReportDiagnosticForRecursiveMock() { var code = @" using Moq; namespace Recursive { public interface IRecursiveRoot { IRecursiveBranch Branch { get; } } public interface IRecursiveBranch { IRecursiveLeaf Leaf { get; } } public interface IRecursiveLeaf { string Name { get; set; } } public class RecursiveMocks { public RecursiveMocks() { var mock = Mock.Of<IRecursiveRoot>(); mock.Branch.Leaf.Name.Returns(""foo""); } } } "; var(workspace, project) = CreateWorkspaceAndProject(LanguageNames.CSharp, includeMockApi: true); var compilation = await project.GetCompilationAsync(TimeoutToken(5)); AssertCode.NoErrors(compilation); //var doc = project.AddDocument("code.cs", SourceText.From(code)); var doc = workspace.AddDocument(DocumentInfo.Create( DocumentId.CreateNewId(project.Id), "code.cs", loader: TextLoader.From(TextAndVersion.Create(SourceText.From(code), VersionStamp.Create())))); compilation = await doc.Project.GetCompilationAsync(TimeoutToken(5)); AssertCode.NoErrors(compilation); var withAnalyzers = compilation.WithAnalyzers(ImmutableArray.Create <DiagnosticAnalyzer>(new MockGeneratorAnalyzer())); var diagnostics = (await withAnalyzers.GetAnalyzerDiagnosticsAsync()) .OrderBy(d => d.Location.SourceSpan.Start) .ToArray(); // Apply first codefix in document order var provider = new GenerateMockCodeFix(); var actions = new List <CodeAction>(); var context = new CodeFixContext(doc, diagnostics[0], (a, d) => actions.Add(a), TimeoutToken(5)); await provider.RegisterCodeFixesAsync(context); var solution = actions .SelectMany(x => x.GetOperationsAsync(TimeoutToken(2)).Result) .OfType <ApplyChangesOperation>() .First() .ChangedSolution; doc = solution.GetDocument(doc.Id); var analyzer = new RecursiveMockAnalyzer(); compilation = await doc.Project.GetCompilationAsync(TimeoutToken(5)); var diag = compilation.GetDiagnostics(TimeoutToken(5)); AssertCode.NoErrors(compilation); withAnalyzers = compilation.WithAnalyzers(ImmutableArray.Create <DiagnosticAnalyzer>(analyzer)); }