using CodePlay.Core.Common; using CodePlay.Core.Converters; using CodePlay.Core.Models; using CodePlay.Core.Parsers; using Xunit; namespace CodePlay.Tests.Semantics; public class CSharpToJavaSemanticEquivalenceTests { private readonly CSharpToJavaStrategy _strategy; private readonly CSharpParser _parser; public CSharpToJavaSemanticEquivalenceTests() { _strategy = new CSharpToJavaStrategy(); _parser = new CSharpParser(); } private async Task ConvertAsync(string source) { var tree = await _parser.ParseAsync(source); var converter = new CSharpToJavaConverter(); return await converter.ConvertAsync(tree, LanguageType.Java); } [Fact] public async Task ConvertClass_ShouldPreserveMethodCount() { var source = @" public class Calculator { public int Add(int a, int b) { return a + b; } public int Subtract(int a, int b) { return a - b; } public int Multiply(int a, int b) { return a * b; } } "; var result = await ConvertAsync(source); Assert.True(result.Success); Assert.Contains("Add(", result.TransformedCode); Assert.Contains("Subtract(", result.TransformedCode); Assert.Contains("Multiply(", result.TransformedCode); } [Fact] public async Task ConvertClass_ShouldPreserveMethodParameters() { var source = @" public class Service { public void Process(string name, int age, double score) { } } "; var result = await ConvertAsync(source); Assert.True(result.Success); Assert.Contains("String", result.TransformedCode); Assert.Contains("Integer", result.TransformedCode); Assert.Contains("Double", result.TransformedCode); Assert.Contains("name", result.TransformedCode); Assert.Contains("age", result.TransformedCode); Assert.Contains("score", result.TransformedCode); } [Fact] public async Task ConvertControlFlow_IfElse_ShouldPreserveStructure() { var source = @" public class Logic { public string Evaluate(int value) { if (value > 0) return ""positive""; else if (value < 0) return ""negative""; else return ""zero""; } } "; var result = await ConvertAsync(source); Assert.True(result.Success); var code = result.TransformedCode; Assert.Contains("if", code); Assert.Contains(">", code); Assert.Contains("else", code); Assert.Contains("return", code); } [Fact] public async Task ConvertControlFlow_ForLoop_ShouldPreserveStructure() { var source = @" public class Counter { public int Sum(int max) { int total = 0; for (int i = 0; i < max; i++) { total += i; } return total; } } "; var result = await ConvertAsync(source); Assert.True(result.Success); var code = result.TransformedCode; Assert.Contains("for", code); Assert.Contains("++", code); } [Fact] public async Task ConvertLambda_ShouldPreserveArrowSyntax() { var source = @" public class LambdaTest { public void Execute() { var list = new List(); list.Where(x => x > 5); } } "; var result = await ConvertAsync(source); Assert.True(result.Success); var code = result.TransformedCode; Assert.Contains("->", code); } [Fact] public async Task ConvertTypeMapping_Primitives_ShouldCorrectlyMap() { var source = @" public class Types { public string Name; public int Count; public double Price; public bool Active; public long Id; public float Weight; public char Code; public byte Flag; } "; var result = await ConvertAsync(source); Assert.True(result.Success); var code = result.TransformedCode; Assert.Contains("String", code); Assert.Contains("Integer", code); Assert.Contains("Double", code); Assert.Contains("Boolean", code); Assert.Contains("Long", code); Assert.Contains("Float", code); Assert.Contains("Character", code); Assert.Contains("Byte", code); } [Fact] public async Task ConvertNullableTypes_ShouldPreserveNullabilitySemantics() { var source = @" public class NullableTest { public string? Name; public int? Count; } "; var result = await ConvertAsync(source); Assert.True(result.Success); var code = result.TransformedCode; Assert.Contains("String", code); Assert.Contains("Integer", code); } [Fact] public async Task ConvertInheritance_ShouldPreserveClassHierarchy() { var source = @" public class Animal { public string Name { get; set; } } public class Dog : Animal { public string Breed { get; set; } } "; var result = await ConvertAsync(source); Assert.True(result.Success); Assert.Contains("extends", result.TransformedCode); } [Fact] public async Task ConvertInterface_ShouldPreserveInterfaceHierarchy() { var source = @" public interface IRepository { } public class UserRepository : IRepository { } "; var result = await ConvertAsync(source); Assert.True(result.Success); Assert.Contains("implements", result.TransformedCode); } [Fact] public async Task ConvertNaming_ShouldConvertPascalCaseToCamelCase() { var source = @" public class NamingTest { public string UserName { get; set; } public int MaxValue { get; set; } } "; var result = await ConvertAsync(source); Assert.True(result.Success); Assert.Contains("userName", result.TransformedCode); Assert.Contains("maxValue", result.TransformedCode); } [Fact] public async Task ConvertNullCoalescing_ShouldPreserveNullHandlingSemantics() { var source = @" public class NullCoalesce { public string GetValue(string input) { return input ?? ""default""; } } "; var result = await ConvertAsync(source); Assert.True(result.Success); var code = result.TransformedCode; Assert.True(code.Contains("null") || code.Contains("default")); } [Fact] public async Task ConvertRecord_ShouldPreserveClassStructure() { var source = @" public record Person(string Name, int Age); "; var result = await ConvertAsync(source); Assert.True(result.Success); Assert.Contains("class", result.TransformedCode); Assert.Contains("Person", result.TransformedCode); } [Fact] public async Task ConvertComplexType_ShouldPreserveGenericStructure() { var source = @" public class Container { public List Items { get; set; } public Dictionary Map { get; set; } } "; var result = await ConvertAsync(source); Assert.True(result.Success); var code = result.TransformedCode; Assert.Contains("", code); Assert.Contains("Items", code); Assert.Contains("Map", code); } [Fact] public async Task ConvertMultipleClasses_ShouldPreserveAllTypes() { var source = @" public class A { public int Value { get; set; } } public class B { public string Name { get; set; } } public class C { public bool Flag { get; set; } } "; var result = await ConvertAsync(source); Assert.True(result.Success); var code = result.TransformedCode; Assert.Contains("class A", code); Assert.Contains("class B", code); Assert.Contains("class C", code); } [Fact] public async Task ConvertMethodChaining_ShouldPreserveCallOrder() { var source = @" public class Chain { public string Process(List numbers) { return numbers.Where(x => x > 0) .Select(x => x.ToString()) .OrderBy(x => x) .ToList() .Count.ToString(); } } "; var result = await ConvertAsync(source); Assert.True(result.Success); var code = result.TransformedCode; Assert.Contains(".filter(", code); Assert.Contains(".map(", code); Assert.Contains(".sorted(", code); Assert.Contains(".collect(", code); } }