using CodePlay.Core.Converters;
using CodePlay.Core.Parsers;
using CodePlay.Core.Common;
using CodePlay.Core.Models;
using Xunit;
namespace CodePlay.Tests.Converters;
public class CSharpToJavaConverterTests
{
private readonly CSharpToJavaConverter _converter;
private readonly CSharpParser _parser;
public CSharpToJavaConverterTests()
{
_converter = new CSharpToJavaConverter();
_parser = new CSharpParser();
}
#region 基础转换测试
[Fact]
public async Task ConvertAsync_SimpleClass_ShouldConvertSuccessfully()
{
var sourceCode = @"
namespace TestApp
{
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
}";
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);
Assert.Contains("package TestApp;", result.TransformedCode);
Assert.Contains("public class Person", result.TransformedCode);
Assert.Contains("private String name;", result.TransformedCode);
Assert.Contains("private Integer age;", result.TransformedCode);
}
[Fact]
public async Task ConvertAsync_WithMethods_ShouldConvertMethods()
{
var sourceCode = @"
namespace TestApp
{
public class Calculator
{
public int Add(int a, int b)
{
return a + b;
}
}
}";
var syntaxTree = await _parser.ParseAsync(sourceCode);
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
Assert.NotNull(result);
Assert.True(result.Success);
Assert.Contains("Add", result.TransformedCode);
}
[Fact]
public async Task ConvertAsync_WithUsing_ShouldConvertToImport()
{
var sourceCode = @"
using System.Collections.Generic;
namespace TestApp
{
public class MyClass { }
}";
var syntaxTree = await _parser.ParseAsync(sourceCode);
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
Assert.True(result.Success);
Assert.Contains("import System.Collections.Generic;", result.TransformedCode);
}
[Fact]
public async Task ConvertAsync_EmptyClass_ShouldHaveProperBraces()
{
var sourceCode = @"
namespace Test
{
public class Empty { }
}";
var syntaxTree = await _parser.ParseAsync(sourceCode);
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
Assert.True(result.Success);
Assert.Contains("class Empty", result.TransformedCode);
}
[Fact]
public async Task ConvertAsync_WithOptions_ShouldPreserveComments()
{
var sourceCode = @"
///
/// Test class
///
namespace Test
{
public class Test { }
}";
var syntaxTree = await _parser.ParseAsync(sourceCode);
var result = await _converter.ConvertAsync(
syntaxTree,
LanguageType.Java,
new ConversionOptions { KeepComments = true, KeepDocStrings = true });
Assert.NotNull(result);
Assert.True(result.Success);
}
#endregion
#region 类型映射测试
[Fact]
public async Task ConvertAsync_NonNullableTypes_ShouldMapCorrectly()
{
var sourceCode = @"
namespace Test
{
public class Model
{
public string Name { get; set; }
public int Count { get; set; }
public bool Active { get; set; }
}
}";
var syntaxTree = await _parser.ParseAsync(sourceCode);
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
Assert.True(result.Success);
Assert.Contains("private String name;", result.TransformedCode);
Assert.Contains("private Integer count;", result.TransformedCode);
Assert.Contains("private Boolean active;", result.TransformedCode);
}
[Fact]
public async Task ConvertAsync_NullableTypes_ShouldMapToWrapperTypes()
{
var sourceCode = @"
namespace Test
{
public class Model
{
public int? Age { get; set; }
public bool? Active { get; set; }
public long? Count { get; set; }
}
}";
var syntaxTree = await _parser.ParseAsync(sourceCode);
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
Assert.True(result.Success);
Assert.Contains("private Integer age;", result.TransformedCode);
Assert.Contains("private Boolean active;", result.TransformedCode);
Assert.Contains("private Long count;", result.TransformedCode);
Assert.DoesNotContain("?", result.TransformedCode);
}
[Fact]
public async Task ConvertAsync_CollectionTypes_ShouldMapToJavaCollections()
{
var sourceCode = @"
using System.Collections.Generic;
namespace Test
{
public class Model
{
public List Items { get; set; }
public Dictionary Mapping { get; set; }
}
}";
var syntaxTree = await _parser.ParseAsync(sourceCode);
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
Assert.True(result.Success);
Assert.Contains("ArrayList", result.TransformedCode);
Assert.Contains("HashMap", result.TransformedCode);
}
#endregion
#region 修饰符测试
[Fact]
public async Task ConvertAsync_VirtualProperty_ShouldRemoveVirtual()
{
var sourceCode = @"
namespace Test
{
public class Base
{
public virtual string Name { get; set; }
}
}";
var syntaxTree = await _parser.ParseAsync(sourceCode);
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
Assert.True(result.Success);
Assert.DoesNotContain("virtual", result.TransformedCode);
}
[Fact]
public async Task ConvertAsync_OverrideMethod_ShouldRemoveOverride()
{
var sourceCode = @"
namespace Test
{
public class Derived : Base
{
public override string ToString()
{
return ""derived"";
}
}
}";
var syntaxTree = await _parser.ParseAsync(sourceCode);
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
Assert.True(result.Success);
Assert.DoesNotContain("override", result.TransformedCode);
}
[Fact]
public async Task ConvertAsync_StaticProperty_ShouldKeepStatic()
{
var sourceCode = @"
namespace Test
{
public class Model
{
public static string Name { get; set; }
}
}";
var syntaxTree = await _parser.ParseAsync(sourceCode);
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
Assert.True(result.Success);
Assert.Contains("static", result.TransformedCode);
}
#endregion
#region 继承测试
[Fact]
public async Task ConvertAsync_ClassInheritance_ShouldUseExtends()
{
var sourceCode = @"
namespace Test
{
public class Derived : Base
{
}
}";
var syntaxTree = await _parser.ParseAsync(sourceCode);
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
Assert.True(result.Success);
Assert.Contains("extends Base", result.TransformedCode);
}
[Fact]
public async Task ConvertAsync_InterfaceImplementation_ShouldUseImplements()
{
var sourceCode = @"
namespace Test
{
public class Service : IRunnable
{
}
}";
var syntaxTree = await _parser.ParseAsync(sourceCode);
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
Assert.True(result.Success);
Assert.Contains("implements IRunnable", result.TransformedCode);
}
[Fact]
public async Task ConvertAsync_MultipleInheritance_ShouldHandleBoth()
{
var sourceCode = @"
namespace Test
{
public class Service : Base, IRunnable, IDisposable
{
}
}";
var syntaxTree = await _parser.ParseAsync(sourceCode);
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
Assert.True(result.Success);
Assert.Contains("extends Base", result.TransformedCode);
Assert.Contains("implements", result.TransformedCode);
}
#endregion
#region Lambda 和 LINQ 测试
[Fact]
public async Task ConvertAsync_SimpleLambda_ShouldConvertArrow()
{
var sourceCode = @"
var result = list.Where(x => x > 0);
";
var syntaxTree = await _parser.ParseAsync(sourceCode);
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
Assert.True(result.Success);
Assert.Contains("->", result.TransformedCode);
}
[Fact]
public async Task ConvertAsync_LambdaWithBlock_ShouldConvert()
{
var sourceCode = @"
var result = list.Where(x => { return x > 0; });
";
var syntaxTree = await _parser.ParseAsync(sourceCode);
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
Assert.True(result.Success);
Assert.Contains("->", result.TransformedCode);
}
[Fact]
public async Task ConvertAsync_LinqChain_ShouldConvertToStream()
{
var sourceCode = @"
var result = list.Where(x => x > 0).Select(x => x * 2).ToList();
";
var syntaxTree = await _parser.ParseAsync(sourceCode);
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
Assert.True(result.Success);
Assert.Contains(".filter(", result.TransformedCode);
Assert.Contains(".collect(Collectors.toList())", result.TransformedCode);
}
#endregion
#region Async 测试
[Fact]
public async Task ConvertAsync_AsyncMethod_ShouldConvertToCompletableFuture()
{
var sourceCode = @"
public async Task GetDataAsync()
{
return await Task.FromResult(""test"");
}
";
var syntaxTree = await _parser.ParseAsync(sourceCode);
var result = await _converter.ConvertAsync(syntaxTree, LanguageType.Java);
Assert.True(result.Success);
Assert.Contains("CompletableFuture", result.TransformedCode);
}
#endregion
}