|
// 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.
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp.ConvertCast;
using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.Testing;
using Roslyn.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ConvertConversionOperators;
using VerifyCS = CSharpCodeRefactoringVerifier<CSharpConvertTryCastToDirectCastCodeRefactoringProvider>;
[UseExportProvider]
[Trait(Traits.Feature, Traits.Features.ConvertCast)]
public class ConvertTryCastToDirectCastTests
{
[Fact]
public async Task ConvertFromAsToExplicit()
{
const string InitialMarkup = """
class Program
{
public static void Main()
{
var x = 1 as[||] object;
}
}
""";
const string ExpectedMarkup = """
class Program
{
public static void Main()
{
var x = (object)1;
}
}
""";
await new VerifyCS.Test
{
TestCode = InitialMarkup,
FixedCode = ExpectedMarkup,
CodeActionValidationMode = CodeActionValidationMode.SemanticStructure
}.RunAsync();
}
[Fact]
public async Task ConvertFromAsToExplicit_ValueType()
{
const string InitialMarkup = """
class Program
{
public static void Main()
{
var x = 1 as[||] byte;
}
}
""";
await new VerifyCS.Test
{
TestCode = InitialMarkup,
CompilerDiagnostics = CompilerDiagnostics.None, // CS0077 is present, but we present the refactoring anyway (this may overlap with a diagnostic fixer)
OffersEmptyRefactoring = false,
CodeActionValidationMode = CodeActionValidationMode.Full,
}.RunAsync();
}
[Fact]
public async Task ConvertFromAsToExplicit_NoTypeSyntaxRightOfAs()
{
const string InitialMarkup = """
class Program
{
public static void Main()
{
var x = 1 as[||] 1;
}
}
""";
await new VerifyCS.Test
{
TestCode = InitialMarkup,
CompilerDiagnostics = CompilerDiagnostics.None,
OffersEmptyRefactoring = false,
CodeActionValidationMode = CodeActionValidationMode.None,
}.RunAsync();
}
[Theory]
[InlineData("(1 as object) as $$C",
"(C)(1 as object)")]
[InlineData("(1 as$$ object) as C",
"((object)1) as C")]
public async Task ConvertFromAsToExplicit_Nested(string asExpression, string cast)
{
var initialMarkup = @$"
class C {{ }}
class Program
{{
public static void Main()
{{
var x = {asExpression};
}}
}}
";
var expectedMarkup = @$"
class C {{ }}
class Program
{{
public static void Main()
{{
var x = {cast};
}}
}}
";
await new VerifyCS.Test
{
TestCode = initialMarkup,
FixedCode = expectedMarkup,
CodeActionValidationMode = CodeActionValidationMode.None,
}.RunAsync();
}
[Theory]
[InlineData("(1 + 1) as $$object",
"(object)(1 + 1)")]
[InlineData("(1 $$+ 1) as object",
"(object)(1 + 1)")]
public async Task ConvertFromAsToExplicit_OtherBinaryExpressions(string asExpression, string cast)
{
var initialMarkup = @$"
class Program
{{
public static void Main()
{{
var x = {asExpression};
}}
}}
";
var expectedMarkup = @$"
class Program
{{
public static void Main()
{{
var x = {cast};
}}
}}
";
await new VerifyCS.Test
{
TestCode = initialMarkup,
FixedCode = expectedMarkup,
CodeActionValidationMode = CodeActionValidationMode.SemanticStructure,
}.RunAsync();
}
[Theory]
[InlineData("/* Leading */ 1 as $$object",
"/* Leading */ (object)1")]
[InlineData("1 as $$object /* Trailing */",
"(object)1 /* Trailing */")]
[InlineData("1 /* Middle1 */ as $$object",
"(object)1/* Middle1 */ ")]
[InlineData("1 as /* Middle2 */ $$object",
"/* Middle2 */ (object)1")]
[InlineData("/* Leading */ 1 /* Middle1 */ as /* Middle2 */ $$object /* Trailing */",
"/* Leading */ /* Middle2 */ (object)1/* Middle1 */ /* Trailing */")]
public async Task ConvertFromAsToExplicit_TriviaHandling(string asExpression, string cast)
{
var initialMarkup = @$"
class Program
{{
public static void Main()
{{
var x = {asExpression};
}}
}}
";
var expectedMarkup = @$"
class Program
{{
public static void Main()
{{
var x = {cast};
}}
}}
";
await new VerifyCS.Test
{
TestCode = initialMarkup,
FixedCode = expectedMarkup,
CodeActionValidationMode = CodeActionValidationMode.SemanticStructure,
}.RunAsync();
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/64052")]
public async Task ConvertFromAsToExplicit_NullableReferenceType_NullableEnable()
{
var initialMarkup = """
#nullable enable
class Program
{
public static void Main()
{
var x = null as[||] string;
}
}
""";
var expectedMarkup = """
#nullable enable
class Program
{
public static void Main()
{
var x = (string?)null;
}
}
""";
await new VerifyCS.Test
{
TestCode = initialMarkup,
FixedCode = expectedMarkup,
CodeActionValidationMode = CodeActionValidationMode.SemanticStructure,
}.RunAsync();
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/64052")]
public async Task ConvertFromAsToExplicit_NullableReferenceType_NullableDisable()
{
var initialMarkup = """
#nullable disable
class Program
{
public static void Main()
{
var x = null as[||] string;
}
}
""";
var expectedMarkup = """
#nullable disable
class Program
{
public static void Main()
{
var x = (string)null;
}
}
""";
await new VerifyCS.Test
{
TestCode = initialMarkup,
FixedCode = expectedMarkup,
CodeActionValidationMode = CodeActionValidationMode.SemanticStructure,
}.RunAsync();
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/64466")]
public async Task ConvertFromExplicitToAs_NullableValueType()
{
const string InitialMarkup = """
class Program
{
public static void Main()
{
var x = null as[||] byte?;
}
}
""";
const string FixedCode = """
class Program
{
public static void Main()
{
var x = (byte?)null;
}
}
""";
await new VerifyCS.Test
{
TestCode = InitialMarkup,
FixedCode = FixedCode,
CodeActionValidationMode = CodeActionValidationMode.SemanticStructure,
}.RunAsync();
}
}
|