using CodePlay.Core.Parsers; using CodePlay.Core.Converters; using CodePlay.Core.Common; using Xunit; namespace CodePlay.Tests.Converters; public class CSharpAdvancedFeaturesTests { private readonly CSharpParser _parser; private readonly CSharpToJavaConverter _converter; public CSharpAdvancedFeaturesTests() { _parser = new CSharpParser(); _converter = new CSharpToJavaConverter(); } #region Record 类型测试 [Fact] public async Task ConvertAsync_RecordType_ShouldConvertToClass() { var sourceCode = @" namespace Test; public record Person(string Name, int Age);"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); } [Fact] public async Task ConvertAsync_RecordWithMethods_ShouldConvertToClass() { var sourceCode = @" public record Product { public string Name { get; init; } public decimal Price { get; init; } public decimal GetTotal(int quantity) => Price * quantity; }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); } #endregion #region 模式匹配测试 [Fact] public async Task ConvertAsync_PatternMatching_TypePattern_ShouldConvert() { var sourceCode = @" public void Check(object obj) { if (obj is string s) { Console.WriteLine(s); } }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); } [Fact] public async Task ConvertAsync_PatternMatching_NullPattern_ShouldConvert() { var sourceCode = @" public void Check(string str) { if (str is null) { throw new ArgumentNullException(); } }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); } [Fact] public async Task ConvertAsync_PatternMatching_PropertyPattern_ShouldConvert() { var sourceCode = @" public void Check(Person p) { if (p is { Age: >= 18, Name: not null }) { Console.WriteLine(p.Name); } }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); } #endregion #region Range 和 Index 测试 [Fact] public async Task ConvertAsync_Range_StringSlice_ShouldConvertToSubstring() { var sourceCode = @" public void Slice() { var str = ""Hello World""; var part = str[1..5]; }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); } [Fact] public async Task ConvertAsync_Index_FromEnd_ShouldConvert() { var sourceCode = @" public void LastChar() { var str = ""Hello""; var last = str[^1]; }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); } [Fact] public async Task ConvertAsync_Range_ArraySlice_ShouldConvert() { var sourceCode = @" public void SliceArray() { var arr = new int[] { 1, 2, 3, 4, 5 }; var part = arr[1..3]; }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); } #endregion #region Switch 表达式测试 [Fact] public async Task ConvertAsync_SwitchExpression_Simple_ShouldConvertToSwitch() { var sourceCode = @" public string GetTypeName(object obj) => obj switch { string s => ""String"", int i => ""Integer"", _ => ""Unknown"" };"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); } [Fact] public async Task ConvertAsync_SwitchExpression_WithGuards_ShouldConvert() { var sourceCode = @" public string Describe(int value) => value switch { > 100 => ""Large"", > 0 => ""Small"", _ => ""Zero or Negative"" };"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); } #endregion #region Init-only 属性测试 [Fact] public async Task ConvertAsync_InitOnlyProperty_ShouldConvertToFinal() { var sourceCode = @" public class Person { public string Name { get; init; } public int Age { get; init; } }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); } [Fact] public async Task ConvertAsync_InitOnlyProperty_WithConstructor_ShouldConvert() { var sourceCode = @" public class Config { public string ConnectionString { get; init; } public int Timeout { get; init; } public Config() { ConnectionString = ""default""; Timeout = 30; } }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); } #endregion #region Nullable 引用类型测试 [Fact] public async Task ConvertAsync_NullableReferenceTypes_ShouldHandle() { var sourceCode = @" public class Model { public string? OptionalName { get; set; } public string RequiredName { get; set; } = ""; }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); } #endregion #region Primary Constructor 测试 [Fact] public async Task ConvertAsync_PrimaryConstructor_ShouldConvert() { var sourceCode = @" public class Point(int x, int y) { public int X => x; public int Y => y; }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); } #endregion #region File-scoped Namespace 测试 [Fact] public async Task ConvertAsync_FileScopedNamespace_ShouldConvertToBraced() { var sourceCode = @" namespace MyApp.Services; public class EmailService { }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.Contains("package MyApp.Services", result.TransformedCode); } #endregion #region Global Using 测试 [Fact] public async Task ConvertAsync_GlobalUsing_ShouldConvert() { var sourceCode = @" global using System; global using System.Collections.Generic; namespace Test { }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); } #endregion }