using CodePlay.Core.Parsers; using CodePlay.Core.Converters; using CodePlay.Core.Common; using Xunit; namespace CodePlay.Tests.Converters; public class CSharp13FeatureTests { private readonly CSharpParser _parser; private readonly CSharpToJavaConverter _converter; public CSharp13FeatureTests() { _parser = new CSharpParser(); _converter = new CSharpToJavaConverter(); } #region 1. 参数数组展开运算符 (Spread Operator) - 4 个测试 [Fact] public async Task ConvertAsync_SpreadOperator_IntArraySpread_ShouldConvert() { var sourceCode = @" int[] a = { 1, 2, 3 }; int[] b = { 0, ..a, 4 };"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_SpreadOperator_StringArraySpread_ShouldConvert() { var sourceCode = @" string[] names = { ""Alice"", ""Bob"" }; string[] all = { ..names, ""Charlie"" };"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_SpreadOperator_MultipleSpreads_ShouldConvert() { var sourceCode = @" int[] a = { 1, 2 }; int[] b = { 3, 4 }; int[] combined = { ..a, 0, ..b };"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_SpreadOperator_CollectionExpression_ShouldConvert() { var sourceCode = @" List list = [1, ..existingList, 5];"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } #endregion #region 2. 隐式 Lambda 参数类型 - 4 个测试 [Fact] public async Task ConvertAsync_ImplicitLambda_SingleParameter_ShouldConvert() { var sourceCode = @" var square = x => x * x;"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_ImplicitLambda_TwoParameters_ShouldConvert() { var sourceCode = @" var add = (x, y) => x + y;"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_ImplicitLambda_MultiParameters_ShouldConvert() { var sourceCode = @" Func add = (x, y) => x + y;"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_ImplicitLambda_WithBlockBody_ShouldConvert() { var sourceCode = @" var process = (a, b) => { var sum = a + b; return sum * 2; };"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } #endregion #region 3. 列表模式匹配 - 4 个测试 [Fact] public async Task ConvertAsync_ListPattern_EmptyListMatch_ShouldConvert() { var sourceCode = @" if (values is []) { return true; }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_ListPattern_SingleElementMatch_ShouldConvert() { var sourceCode = @" if (values is [1]) { return true; }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_ListPattern_MultipleElementsMatch_ShouldConvert() { var sourceCode = @" if (values is [1, 2, 3]) { }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_ListPattern_WithDiscard_ShouldConvert() { var sourceCode = @" if (values is [_, _, _]) { }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } #endregion #region 4. 切片模式匹配 - 4 个测试 [Fact] public async Task ConvertAsync_SlicePattern_EndSliceOnly_ShouldConvert() { var sourceCode = @" if (values is [1, 2, ..]) { }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_SlicePattern_StartSliceOnly_ShouldConvert() { var sourceCode = @" if (values is [.., 3, 4]) { }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_SlicePattern_MiddleSlice_ShouldConvert() { var sourceCode = @" if (values is [1, .., 4]) { }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_SlicePattern_OmegaOnly_ShouldConvert() { var sourceCode = @" if (values is [..]) { }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } #endregion #region 5. 关系模式匹配 - 4 个测试 [Fact] public async Task ConvertAsync_RelationalPattern_GreaterThan_ShouldConvert() { var sourceCode = @" if (x is > 0) { }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_RelationalPattern_LessThan_ShouldConvert() { var sourceCode = @" if (x is < 10) { }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_RelationalPattern_AndPattern_ShouldConvert() { var sourceCode = @" if (x is (> 0 and < 10)) { }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_RelationalPattern_OrPattern_ShouldConvert() { var sourceCode = @" if (x is (< 0 or > 100)) { }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } #endregion #region 6. 主构造函数参数 - 4 个测试 [Fact] public async Task ConvertAsync_PrimaryConstructor_SingleParameter_ShouldConvert() { var sourceCode = @" public class Point(int x) { public int X => x; }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_PrimaryConstructor_MultipleParameters_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); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_PrimaryConstructor_ParamsArray_ShouldConvert() { var sourceCode = @" public class Collection(params int[] items) { public int[] Items => items; }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_PrimaryConstructor_WithGenerics_ShouldConvert() { var sourceCode = @" public class Box(T value) { public T Value => value; }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } #endregion #region 7. Lock 语句 - 4 个测试 [Fact] public async Task ConvertAsync_LockStatement_SimpleLock_ShouldConvert() { var sourceCode = @" lock (syncObj) { count++; }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_LockStatement_WithMultipleStatements_ShouldConvert() { var sourceCode = @" lock (this) { balance += amount; NotifyChanged(); }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_LockStatement_NestedLock_ShouldConvert() { var sourceCode = @" lock (outer) { lock (inner) { DoWork(); } }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_LockStatement_WithReturn_ShouldConvert() { var sourceCode = @" lock (sync) { if (condition) return value; return null; }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } #endregion #region 8. Params IEnumerable 增强 - 4 个测试 [Fact] public async Task ConvertAsync_Params_EnumerableInt_ShouldConvert() { var sourceCode = @" public void Process(params IEnumerable items) { foreach (var item in items) { } }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_Params_EnumerableString_ShouldConvert() { var sourceCode = @" public void PrintAll(params IEnumerable values) { foreach (var v in values) Console.WriteLine(v); }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_Params_ICollection_ShouldConvert() { var sourceCode = @" public void SumAll(params ICollection numbers) { }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_Params_IList_ShouldConvert() { var sourceCode = @" public void ProcessList(params IList items) { }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } #endregion #region 9. C# 12 集合表达式 - 4 个测试 [Fact] public async Task ConvertAsync_CSharp12Collection_IntListLiteral_ShouldConvert() { var sourceCode = @" List numbers = [1, 2, 3];"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_CSharp12Collection_StringListLiteral_ShouldConvert() { var sourceCode = @" List names = [""Alice"", ""Bob"", ""Charlie""];"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_CSharp12Collection_NestedCollectionLiteral_ShouldConvert() { var sourceCode = @" List> matrix = [[1, 2], [3, 4]];"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_CSharp12Collection_ArrayLiteral_ShouldConvert() { var sourceCode = @" int[] array = [10, 20, 30, 40];"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } #endregion #region 10. 类型别名 (C# 12) - 3 个测试 [Fact] public async Task ConvertAsync_TypeAlias_SimpleAlias_ShouldRemove() { var sourceCode = @" using IntList = System.Collections.Generic.List;"; 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_TypeAlias_NestedTypeAlias_ShouldRemove() { var sourceCode = @" using StringDict = System.Collections.Generic.Dictionary;"; 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_TypeAlias_MultipleAliases_ShouldRemove() { var sourceCode = @" using IntList = System.Collections.Generic.List; using StringList = System.Collections.Generic.List;"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); } #endregion #region 11. 默认 Lambda 参数 (C# 13) - 3 个测试 [Fact] public async Task ConvertAsync_DefaultLambdaParameters_SingleDefault_ShouldConvert() { var sourceCode = @" var method = (int x = 10) => x * 2;"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_DefaultLambdaParameters_MultipleDefaults_ShouldConvert() { var sourceCode = @" var method = (int x = 10, int y = 20) => x + y;"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_DefaultLambdaParameters_MixedDefaults_ShouldConvert() { var sourceCode = @" var method = (int x, int y = 5) => x + y;"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } #endregion #region 12. Switch Type Pattern - 3 个测试 [Fact] public async Task ConvertAsync_TypeSwitchPattern_SingleType_ShouldConvert() { var sourceCode = @" string result = value switch { string s => ""String"", _ => ""Other"" };"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_TypeSwitchPattern_GenericTypes_ShouldConvert() { var sourceCode = @" string result = value switch { IEnumerable seq => ""Int Seq"", IEnumerable seq => ""String Seq"", _ => ""Other"" };"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_TypeSwitchPattern_MultipleConditions_ShouldConvert() { var sourceCode = @" string GetType(object o) => o switch { int i => ""Integer"", string s when s.Length > 0 => ""Non-empty String"", null => ""Null"", _ => ""Unknown"" };"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } #endregion #region 13. 原始字符串字面量 - 3 个测试 [Fact] public async Task ConvertAsync_RawStringLiteral_SingleLine_ShouldConvert() { var sourceCode = @" string xml = $""""""Value"""""";"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_RawStringLiteral_MultiLine_ShouldConvert() { var sourceCode = @" string xml = $"""""" Value """""";"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_RawStringLiteral_WithInterpolation_ShouldConvert() { var sourceCode = @" string html = $""""""

{name}

"""""";"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } #endregion #region 14. 综合测试 - 4 个测试 [Fact] public async Task ConvertAsync_CSharp13_CombinedSpreadAndLambda_ShouldConvert() { var sourceCode = @" int[] a = [1, 2]; int[] b = [0, ..a, 3]; var sum = b.Sum(x => x * 2);"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_CSharp13_CombinedPatternAndSwitch_ShouldConvert() { var sourceCode = @" string Describe(object o) => o switch { (> 0 and < 10) => ""Small positive"", (>= 10 and <= 100) => ""Medium"", _ => ""Other"" };"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_CSharp13_CombinedLockAndParams_ShouldConvert() { var sourceCode = @" public void UpdateAll(params IEnumerable values) { lock (sync) { foreach (var v in values) data.Add(v); } }"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } [Fact] public async Task ConvertAsync_CSharp13_RecordWithCollectionAndSpread_ShouldConvert() { var sourceCode = @" public record Data(int[] Values); var d1 = new Data([1, 2, 3]); int[] base = [0]; var d2 = new Data([..base, 4, 5]);"; var syntaxTree = await _parser.ParseAsync(sourceCode); var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java); Assert.NotNull(result); Assert.True(result.Success); Assert.NotNull(result.TransformedCode); } #endregion }