|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable disable
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp.CodeFixes.GenerateType;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.GenerateVariable;
public sealed partial class GenerateVariableTests
{
private async Task TestGeneratingTypeInRazorSourceGeneratedDocumentAsync(
string workspaceMarkup,
string generatedCode,
string expectedGeneratedCode,
bool requestFromSourceGeneratedDocument)
{
using var workspace = CreateWorkspaceFromOptions(workspaceMarkup, WithRazorGeneratedDocument(generatedCode));
var project = workspace.CurrentSolution.Projects.Single();
var sourceGeneratedDocument = Assert.Single(await project.GetSourceGeneratedDocumentsAsync(CancellationToken.None));
Assert.Contains("Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator", sourceGeneratedDocument.FilePath);
Assert.StartsWith(
"// <auto-generated />",
(await sourceGeneratedDocument.GetTextAsync(CancellationToken.None)).ToString());
var requestDocument = requestFromSourceGeneratedDocument
? sourceGeneratedDocument
: project.Documents.Single();
var requestTree = await requestDocument.GetSyntaxTreeAsync(CancellationToken.None);
var compilation = await project.GetCompilationAsync(CancellationToken.None);
Assert.NotNull(requestTree);
Assert.NotNull(compilation);
var diagnostic = Assert.Single(
compilation!.GetDiagnostics(CancellationToken.None).Where(
diagnostic => diagnostic.Severity == DiagnosticSeverity.Error && diagnostic.Location.SourceTree == requestTree));
var codeActions = new List<CodeAction>();
var context = new CodeFixContext(
requestDocument,
diagnostic.Location.SourceSpan,
[diagnostic],
(action, _) => codeActions.Add(action),
CancellationToken.None);
var provider = new GenerateTypeCodeFixProvider();
await provider.RegisterCodeFixesAsync(context);
var flattenedActions = FlattenActions([.. codeActions]);
var codeAction = Assert.Single(
flattenedActions.Where(action => action.Title == string.Format(FeaturesResources.Generate_nested_0_1, "class", "MissingType")));
var operations = await codeAction.GetOperationsAsync(CancellationToken.None);
var changedSolutions = await ApplyOperationsAndGetSolutionAsync(workspace, operations);
var newSourceGeneratedDocument = await changedSolutions.Item2.GetSourceGeneratedDocumentAsync(sourceGeneratedDocument.Id, CancellationToken.None);
Assert.NotNull(newSourceGeneratedDocument);
AssertEx.EqualOrDiff(
expectedGeneratedCode,
(await newSourceGeneratedDocument!.GetTextAsync(CancellationToken.None)).ToString());
}
[Fact]
public Task TestGeneratingTypeIntoRazorSourceGeneratedDocumentFromRegularDocument()
=> TestGeneratingTypeInRazorSourceGeneratedDocumentAsync(
"""
<Workspace>
<Project Language="C#" AssemblyName="ClassLibrary1" CommonReferences="true">
<Document>
public class C
{
public object M()
{
Component.Miss$$ingType value = null;
return value;
}
}
</Document>
</Project>
</Workspace>
""",
"""
// <auto-generated />
using System;
public partial class Component
{
}
""",
"""
// <auto-generated />
using System;
public partial class Component
{
internal class MissingType
{
}
}
""",
requestFromSourceGeneratedDocument: false);
[Fact]
public Task TestGeneratingTypeInRazorSourceGeneratedDocument()
=> TestGeneratingTypeInRazorSourceGeneratedDocumentAsync(
"""
<Workspace>
<Project Language="C#" AssemblyName="ClassLibrary1" CommonReferences="true">
<Document>
public class Placeholder
{
}
</Document>
</Project>
</Workspace>
""",
"""
// <auto-generated />
using System;
public partial class Component
{
public object M()
{
return new MissingType();
}
}
""",
"""
// <auto-generated />
using System;
public partial class Component
{
public object M()
{
return new MissingType();
}
private class MissingType
{
public MissingType()
{
}
}
}
""",
requestFromSourceGeneratedDocument: true);
[Fact]
public Task TestGeneratingTypeIntoHiddenRazorSourceGeneratedDocumentFromRegularDocument()
=> TestGeneratingTypeInRazorSourceGeneratedDocumentAsync(
"""
<Workspace>
<Project Language="C#" AssemblyName="ClassLibrary1" CommonReferences="true">
<Document>
public class C
{
public object M()
{
Component.Miss$$ingType value = null;
return value;
}
}
</Document>
</Project>
</Workspace>
""",
"""
// <auto-generated />
using System;
#line hidden
public partial class Component
{
}
#line default
""",
"""
// <auto-generated />
using System;
#line hidden
public partial class Component
{
internal class MissingType
{
}
}
#line default
""",
requestFromSourceGeneratedDocument: false);
[Fact]
public Task TestGeneratingTypeInHiddenRazorSourceGeneratedDocument()
=> TestGeneratingTypeInRazorSourceGeneratedDocumentAsync(
"""
<Workspace>
<Project Language="C#" AssemblyName="ClassLibrary1" CommonReferences="true">
<Document>
public class Placeholder
{
}
</Document>
</Project>
</Workspace>
""",
"""
// <auto-generated />
using System;
#line hidden
public partial class Component
{
public object M()
{
return new MissingType();
}
}
#line default
""",
"""
// <auto-generated />
using System;
#line hidden
public partial class Component
{
public object M()
{
return new MissingType();
}
private class MissingType
{
public MissingType()
{
}
}
}
#line default
""",
requestFromSourceGeneratedDocument: true);
}
|