MarketAlly.AIPlugin.Extensions/Test.Refactoring/EnhancedRefactoringTestServ...

1062 lines
32 KiB
C#
Executable File

using global::MarketAlly.AIPlugin;
using global::MarketAlly.AIPlugin.Refactoring.Plugins;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System.Text.Json;
namespace MarketAlly.AIPlugin.Refactoring.TestConsole;
public class EnhancedRefactoringTestService
{
private readonly AIPluginRegistry _pluginRegistry;
private readonly ILogger<EnhancedRefactoringTestService> _logger;
public EnhancedRefactoringTestService(AIPluginRegistry pluginRegistry, ILogger<EnhancedRefactoringTestService> logger)
{
_pluginRegistry = pluginRegistry;
_logger = logger;
SetupPlugins();
}
private void SetupPlugins()
{
_pluginRegistry.RegisterPlugin(new CodeAnalysisPlugin());
_pluginRegistry.RegisterPlugin(new EnhancedDocumentationGeneratorPlugin());
_pluginRegistry.RegisterPlugin(new CodeFormatterPlugin());
_pluginRegistry.RegisterPlugin(new NamingConventionPlugin());
_pluginRegistry.RegisterPlugin(new BatchRefactorPlugin());
_pluginRegistry.RegisterPlugin(new CodeRefactoringPlugin());
_pluginRegistry.RegisterPlugin(new ReadmeGeneratorPlugin());
_pluginRegistry.RegisterPlugin(new AIReadmeGeneratorPlugin());
_logger.LogInformation("Registered {Count} refactoring plugins including README generators",
_pluginRegistry.GetAllPlugins().Count);
}
public async Task CreateAdvancedSampleFiles()
{
Console.WriteLine("[INFO] Creating advanced sample files with refactoring opportunities...");
var sampleDirectory = Path.Combine(Directory.GetCurrentDirectory(), "advanced_samples");
Directory.CreateDirectory(sampleDirectory);
await CreateComplexClassForExtraction(sampleDirectory);
await CreateGodClassForSplitting(sampleDirectory);
await CreateDuplicateCodeSample(sampleDirectory);
await CreateLongParameterListSample(sampleDirectory);
Console.WriteLine($"[SUCCESS] Created advanced sample files in: {sampleDirectory}");
Console.WriteLine("Advanced sample files for refactoring:");
Console.WriteLine(" - ComplexCalculator.cs (needs method extraction)");
Console.WriteLine(" - UserManagementSystem.cs (god class needing splitting)");
Console.WriteLine(" - DuplicateLogic.cs (contains duplicate code blocks)");
Console.WriteLine(" - ParameterHeavyService.cs (needs parameter objects)");
}
private async Task CreateComplexCalculator(string directory)
{
var content = @"using System;
using System.Collections.Generic;
using System.Linq;
namespace AdvancedSamples
{
public class ComplexCalculator
{
// This method is too long and complex - perfect for method extraction
public double CalculateComplexFormula(double x, double y, double z, bool useAdvanced, string mode)
{
double result = 0;
// Step 1: Basic validation and preprocessing
if (x <= 0 || y <= 0 || z <= 0)
{
throw new ArgumentException(""All values must be positive"");
}
double normalizedX = x / 100.0;
double normalizedY = y / 100.0;
double normalizedZ = z / 100.0;
if (normalizedX > 1.0) normalizedX = 1.0;
if (normalizedY > 1.0) normalizedY = 1.0;
if (normalizedZ > 1.0) normalizedZ = 1.0;
// Step 2: Complex mathematical operations
double baseCalculation = 0;
if (mode == ""linear"")
{
baseCalculation = normalizedX * 2.5 + normalizedY * 1.8 + normalizedZ * 3.2;
baseCalculation = Math.Pow(baseCalculation, 1.2);
baseCalculation = baseCalculation * Math.PI / 4.0;
}
else if (mode == ""exponential"")
{
baseCalculation = Math.Exp(normalizedX * 0.1) + Math.Exp(normalizedY * 0.15) + Math.Exp(normalizedZ * 0.12);
baseCalculation = baseCalculation * Math.Log(x + y + z + 1);
baseCalculation = Math.Sqrt(baseCalculation);
}
else if (mode == ""trigonometric"")
{
baseCalculation = Math.Sin(normalizedX * Math.PI) * Math.Cos(normalizedY * Math.PI) * Math.Tan(normalizedZ * Math.PI / 4);
baseCalculation = Math.Abs(baseCalculation);
baseCalculation = baseCalculation * 100;
}
// Step 3: Advanced processing if enabled
if (useAdvanced)
{
double advancedFactor = 1.0;
// Complex conditional logic
if (baseCalculation > 50)
{
if (x > y && y > z)
{
advancedFactor = 1.25;
}
else if (x < y && y < z)
{
advancedFactor = 1.15;
}
else
{
advancedFactor = 1.05;
}
}
else if (baseCalculation > 25)
{
advancedFactor = 0.95;
}
else
{
advancedFactor = 0.85;
}
baseCalculation *= advancedFactor;
// Additional transformations
if (mode.Contains(""linear""))
{
baseCalculation += Math.Sqrt(x) + Math.Sqrt(y) + Math.Sqrt(z);
}
baseCalculation = Math.Round(baseCalculation, 4);
}
// Step 4: Final result processing
result = baseCalculation;
if (result < 0) result = 0;
if (result > 1000) result = 1000;
// Log the calculation for debugging
Console.WriteLine($""Calculated result: {result} for inputs ({x}, {y}, {z}) with mode '{mode}' and advanced={useAdvanced}"");
return result;
}
public bool ValidateInputRange(double value, double min, double max, string paramName)
{
if (value < min)
{
Console.WriteLine($""Warning: {paramName} value {value} is below minimum {min}"");
return false;
}
if (value > max)
{
Console.WriteLine($""Warning: {paramName} value {value} is above maximum {max}"");
return false;
}
return true;
}
}
}";
await File.WriteAllTextAsync(Path.Combine(directory, "ComplexCalculator.cs"), content);
}
private async Task CreateGodClassForSplitting(string directory)
{
var content = @"using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
namespace AdvancedSamples
{
// This is a ""God Class"" that does too many things - needs splitting
public class UserManagementSystem
{
private List<User> _users = new List<User>();
private readonly HttpClient _httpClient = new HttpClient();
private readonly string _logFile = ""user_operations.log"";
// User CRUD Operations (should be in UserRepository)
public void CreateUser(string name, string email, int age)
{
var user = new User { Id = Guid.NewGuid(), Name = name, Email = email, Age = age };
_users.Add(user);
LogOperation($""User created: {user.Id}"");
}
public User GetUser(Guid id)
{
var user = _users.Find(u => u.Id == id);
LogOperation($""User retrieved: {id}"");
return user;
}
public void UpdateUser(Guid id, string name, string email, int age)
{
var user = _users.Find(u => u.Id == id);
if (user != null)
{
user.Name = name;
user.Email = email;
user.Age = age;
LogOperation($""User updated: {id}"");
}
}
public void DeleteUser(Guid id)
{
var user = _users.Find(u => u.Id == id);
if (user != null)
{
_users.Remove(user);
LogOperation($""User deleted: {id}"");
}
}
// Email Operations (should be in EmailService)
public async Task SendWelcomeEmail(Guid userId)
{
var user = GetUser(userId);
if (user != null)
{
var emailContent = $""Welcome {user.Name}! Your account has been created."";
await SendEmail(user.Email, ""Welcome"", emailContent);
LogOperation($""Welcome email sent to: {user.Email}"");
}
}
public async Task SendPasswordResetEmail(Guid userId)
{
var user = GetUser(userId);
if (user != null)
{
var resetToken = GenerateResetToken();
var emailContent = $""Click here to reset your password: /reset?token={resetToken}"";
await SendEmail(user.Email, ""Password Reset"", emailContent);
LogOperation($""Password reset email sent to: {user.Email}"");
}
}
private async Task SendEmail(string to, string subject, string body)
{
// Simulate email sending
await Task.Delay(100);
Console.WriteLine($""EMAIL: To={to}, Subject={subject}, Body={body}"");
}
// Logging Operations (should be in LoggingService)
public void LogOperation(string message)
{
var logEntry = $""[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] {message}"";
File.AppendAllText(_logFile, logEntry + Environment.NewLine);
}
public string[] GetRecentLogs(int count)
{
if (!File.Exists(_logFile)) return new string[0];
var lines = File.ReadAllLines(_logFile);
if (lines.Length <= count)
return lines;
var recentLines = new string[count];
Array.Copy(lines, lines.Length - count, recentLines, 0, count);
return recentLines;
}
public void ClearLogs()
{
if (File.Exists(_logFile))
{
File.Delete(_logFile);
}
}
// Validation Operations (should be in ValidationService)
public bool ValidateEmail(string email)
{
if (string.IsNullOrEmpty(email)) return false;
if (!email.Contains(""@"")) return false;
if (!email.Contains(""."")) return false;
return true;
}
public bool ValidateAge(int age)
{
return age >= 13 && age <= 120;
}
public bool ValidateName(string name)
{
if (string.IsNullOrEmpty(name)) return false;
if (name.Length < 2) return false;
if (name.Length > 50) return false;
return true;
}
// Utility Operations (should be in separate utility classes)
private string GenerateResetToken()
{
return Guid.NewGuid().ToString(""N"").Substring(0, 16);
}
public void ExportUsersToFile(string fileName)
{
var lines = new List<string>();
lines.Add(""Id,Name,Email,Age"");
foreach (var user in _users)
{
lines.Add($""{user.Id},{user.Name},{user.Email},{user.Age}"");
}
File.WriteAllLines(fileName, lines);
LogOperation($""Users exported to: {fileName}"");
}
public void ImportUsersFromFile(string fileName)
{
if (!File.Exists(fileName)) return;
var lines = File.ReadAllLines(fileName);
for (int i = 1; i < lines.Length; i++) // Skip header
{
var parts = lines[i].Split(',');
if (parts.Length == 4)
{
var user = new User
{
Id = Guid.Parse(parts[0]),
Name = parts[1],
Email = parts[2],
Age = int.Parse(parts[3])
};
_users.Add(user);
}
}
LogOperation($""Users imported from: {fileName}"");
}
}
public class User
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public int Age { get; set; }
}
}";
await File.WriteAllTextAsync(Path.Combine(directory, "UserManagementSystem.cs"), content);
}
private async Task CreateDuplicateCodeSample(string directory)
{
var content = @"using System;
using System.IO;
using System.Text;
namespace AdvancedSamples
{
public class DuplicateLogic
{
private const string ERROR_LOG_FILE = ""errors.log"";
private const string INFO_LOG_FILE = ""info.log"";
private const string DEBUG_LOG_FILE = ""debug.log"";
// These methods have duplicate logging logic
public void LogError(string message)
{
var timestamp = DateTime.Now.ToString(""yyyy-MM-dd HH:mm:ss"");
var logEntry = $""[{timestamp}] ERROR: {message}"";
try
{
if (!File.Exists(ERROR_LOG_FILE))
{
File.Create(ERROR_LOG_FILE).Close();
}
File.AppendAllText(ERROR_LOG_FILE, logEntry + Environment.NewLine);
Console.WriteLine($""Logged error: {message}"");
}
catch (IOException ex)
{
Console.WriteLine($""Failed to log error: {ex.Message}"");
}
}
public void LogInfo(string message)
{
var timestamp = DateTime.Now.ToString(""yyyy-MM-dd HH:mm:ss"");
var logEntry = $""[{timestamp}] INFO: {message}"";
try
{
if (!File.Exists(INFO_LOG_FILE))
{
File.Create(INFO_LOG_FILE).Close();
}
File.AppendAllText(INFO_LOG_FILE, logEntry + Environment.NewLine);
Console.WriteLine($""Logged info: {message}"");
}
catch (IOException ex)
{
Console.WriteLine($""Failed to log info: {ex.Message}"");
}
}
public void LogDebug(string message)
{
var timestamp = DateTime.Now.ToString(""yyyy-MM-dd HH:mm:ss"");
var logEntry = $""[{timestamp}] DEBUG: {message}"";
try
{
if (!File.Exists(DEBUG_LOG_FILE))
{
File.Create(DEBUG_LOG_FILE).Close();
}
File.AppendAllText(DEBUG_LOG_FILE, logEntry + Environment.NewLine);
Console.WriteLine($""Logged debug: {message}"");
}
catch (IOException ex)
{
Console.WriteLine($""Failed to log debug: {ex.Message}"");
}
}
// These methods have duplicate validation logic
public bool ValidateUserInput(string name, string email, int age)
{
if (string.IsNullOrEmpty(name))
{
LogError(""Name cannot be empty"");
return false;
}
if (name.Length < 2)
{
LogError(""Name must be at least 2 characters"");
return false;
}
if (string.IsNullOrEmpty(email))
{
LogError(""Email cannot be empty"");
return false;
}
if (!email.Contains(""@""))
{
LogError(""Email must contain @ symbol"");
return false;
}
if (age < 0 || age > 150)
{
LogError(""Age must be between 0 and 150"");
return false;
}
return true;
}
public bool ValidateProductInput(string productName, string description, decimal price)
{
if (string.IsNullOrEmpty(productName))
{
LogError(""Product name cannot be empty"");
return false;
}
if (productName.Length < 2)
{
LogError(""Product name must be at least 2 characters"");
return false;
}
if (string.IsNullOrEmpty(description))
{
LogError(""Description cannot be empty"");
return false;
}
if (description.Length < 10)
{
LogError(""Description must be at least 10 characters"");
return false;
}
if (price < 0)
{
LogError(""Price cannot be negative"");
return false;
}
return true;
}
// Duplicate string processing logic
public string FormatUserDisplayName(string firstName, string lastName)
{
if (string.IsNullOrEmpty(firstName)) firstName = ""Unknown"";
if (string.IsNullOrEmpty(lastName)) lastName = ""User"";
firstName = firstName.Trim();
lastName = lastName.Trim();
firstName = char.ToUpper(firstName[0]) + firstName.Substring(1).ToLower();
lastName = char.ToUpper(lastName[0]) + lastName.Substring(1).ToLower();
return $""{firstName} {lastName}"";
}
public string FormatProductDisplayName(string productName, string category)
{
if (string.IsNullOrEmpty(productName)) productName = ""Unknown"";
if (string.IsNullOrEmpty(category)) category = ""Product"";
productName = productName.Trim();
category = category.Trim();
productName = char.ToUpper(productName[0]) + productName.Substring(1).ToLower();
category = char.ToUpper(category[0]) + category.Substring(1).ToLower();
return $""{productName} ({category})"";
}
}
}";
await File.WriteAllTextAsync(Path.Combine(directory, "DuplicateLogic.cs"), content);
}
private async Task CreateLongParameterListSample(string directory)
{
var content = @"using System;
using System.Collections.Generic;
namespace AdvancedSamples
{
public class ParameterHeavyService
{
// This method has too many parameters - needs parameter object
public void CreateOrder(
string customerName,
string customerEmail,
string customerPhone,
string customerAddress,
string customerCity,
string customerState,
string customerZip,
string productName,
string productSku,
decimal productPrice,
int quantity,
decimal discountPercentage,
string shippingMethod,
string shippingAddress,
string shippingCity,
string shippingState,
string shippingZip,
bool expeditedShipping,
string paymentMethod,
string creditCardNumber,
string creditCardExpiry,
string creditCardCvv,
string specialInstructions)
{
// Order creation logic...
Console.WriteLine(""Creating order with many parameters..."");
}
// Another method with too many parameters
public void ProcessPayment(
decimal amount,
string currency,
string paymentMethod,
string cardNumber,
string cardExpiry,
string cardCvv,
string cardHolderName,
string billingAddress,
string billingCity,
string billingState,
string billingZip,
string billingCountry,
bool saveCard,
string merchantId,
string transactionId,
string description)
{
// Payment processing logic...
Console.WriteLine(""Processing payment with many parameters..."");
}
// Configuration method with many boolean flags
public void ConfigureSystem(
bool enableLogging,
bool enableCaching,
bool enableCompression,
bool enableSsl,
bool enableAuthentication,
bool enableAuthorization,
bool enableRateLimiting,
bool enableMonitoring,
bool enableBackups,
bool enableEncryption,
string logLevel,
int cacheTimeout,
int connectionTimeout,
int maxRetries,
string encryptionKey)
{
// System configuration logic...
Console.WriteLine(""Configuring system with many parameters..."");
}
// Report generation with many filter parameters
public void GenerateReport(
DateTime startDate,
DateTime endDate,
string reportType,
string customerId,
string productCategory,
string region,
decimal minAmount,
decimal maxAmount,
string status,
bool includeDetails,
bool includeCharts,
bool includeStatistics,
string outputFormat,
string emailTo,
bool scheduleRecurring,
int recurringInterval)
{
// Report generation logic...
Console.WriteLine(""Generating report with many parameters..."");
}
}
}";
await File.WriteAllTextAsync(Path.Combine(directory, "ParameterHeavyService.cs"), content);
}
public async Task TestActualRefactoring(string filePath, string operations, bool apply)
{
Console.WriteLine($"[REFACTOR TEST] Running actual code refactoring on: {Path.GetFileName(filePath)}");
Console.WriteLine($"[INFO] Operations: {operations}, Apply: {apply}");
Console.WriteLine(new string('=', 80));
try
{
var parameters = new Dictionary<string, object>
{
["filePath"] = filePath,
["operations"] = operations,
["applyChanges"] = apply,
["maxMethodLength"] = 25,
["maxClassSize"] = 300,
["minComplexityForExtraction"] = 6
};
var result = await _pluginRegistry.CallFunctionAsync("CodeRefactoring", parameters);
if (result.Success)
{
Console.WriteLine("[SUCCESS] Code refactoring completed!");
DisplayRefactoringResults(result.Data);
// Show before/after comparison if changes were applied
if (apply)
{
Console.WriteLine("\n[CHANGES APPLIED] File has been modified. Check the backup file for original version.");
}
else
{
Console.WriteLine("\n[PREVIEW MODE] No changes applied to file. Use --apply to make changes.");
}
}
else
{
Console.WriteLine($"[ERROR] Refactoring failed: {result.Message}");
}
}
catch (Exception ex)
{
Console.WriteLine($"[ERROR] Test failed: {ex.Message}");
}
}
public async Task PreviewReadmeAsync(string projectPath, string projectType)
{
Console.WriteLine($"[PREVIEW] README for: {projectPath}");
Console.WriteLine(new string('=', 60));
try
{
var parameters = new Dictionary<string, object>
{
["projectPath"] = projectPath,
["projectType"] = projectType,
["applyChanges"] = false
};
var result = await _pluginRegistry.CallFunctionAsync("ReadmeGenerator", parameters);
if (result.Success)
{
Console.WriteLine("[SUCCESS] README preview generated!");
DisplayReadmeResults(result.Data);
// Show preview content
var resultJson = JsonSerializer.Serialize(result.Data, new JsonSerializerOptions { WriteIndented = true });
var resultElement = JsonSerializer.Deserialize<JsonElement>(resultJson);
if (resultElement.TryGetProperty("PreviewContent", out var previewContent))
{
Console.WriteLine("\n[PREVIEW CONTENT]");
Console.WriteLine(new string('-', 40));
Console.WriteLine(previewContent.GetString());
}
}
else
{
Console.WriteLine($"[ERROR] Preview failed: {result.Message}");
}
}
catch (Exception ex)
{
Console.WriteLine($"[ERROR] Preview failed: {ex.Message}");
}
}
public async Task GenerateAIReadmeAsync(string projectPath, bool apply)
{
Console.WriteLine($"[AI README] Generating AI-enhanced README for: {projectPath}");
Console.WriteLine($"[INFO] Apply: {apply}");
Console.WriteLine(new string('=', 60));
try
{
var parameters = new Dictionary<string, object>
{
["projectPath"] = projectPath,
["projectType"] = "auto",
["enableAIEnhancement"] = true,
["aiGeneratedExamples"] = true,
["aiEnhancedApiDocs"] = true,
["applyChanges"] = apply
};
var result = await _pluginRegistry.CallFunctionAsync("AIReadmeGenerator", parameters);
if (result.Success)
{
Console.WriteLine("[SUCCESS] AI README generation completed!");
DisplayReadmeResults(result.Data);
}
else
{
Console.WriteLine($"[ERROR] AI README generation failed: {result.Message}");
}
}
catch (Exception ex)
{
Console.WriteLine($"[ERROR] AI README test failed: {ex.Message}");
}
}
public async Task TestReadmeGeneratorAsync()
{
Console.WriteLine("[TEST] Testing README Generator on current project");
Console.WriteLine(new string('=', 60));
// Get current project directory
var currentDir = Directory.GetCurrentDirectory();
var projectPath = FindProjectDirectory(currentDir);
if (projectPath == null)
{
Console.WriteLine("[ERROR] Could not find project file in current directory");
return;
}
Console.WriteLine($"[INFO] Found project at: {projectPath}");
await GenerateReadmeAsync(projectPath, "auto", false);
}
public async Task GenerateReadmeAsync(string projectPath, string projectType, bool apply)
{
Console.WriteLine($"[README] Generating README for: {projectPath}");
Console.WriteLine($"[INFO] Project type: {projectType}, Apply: {apply}");
Console.WriteLine(new string('=', 60));
try
{
var parameters = new Dictionary<string, object>
{
["projectPath"] = projectPath,
["projectType"] = projectType,
["includeApiDocs"] = true,
["includeArchitecture"] = true,
["includeSetup"] = true,
["includeExamples"] = true,
["applyChanges"] = apply
};
var result = await _pluginRegistry.CallFunctionAsync("ReadmeGenerator", parameters);
if (result.Success)
{
Console.WriteLine("[SUCCESS] README generation completed!");
DisplayReadmeResults(result.Data);
// Show preview if not applying
if (!apply)
{
var resultJson = JsonSerializer.Serialize(result.Data, new JsonSerializerOptions { WriteIndented = true });
var resultElement = JsonSerializer.Deserialize<JsonElement>(resultJson);
if (resultElement.TryGetProperty("PreviewContent", out var previewContent))
{
Console.WriteLine("\n[PREVIEW CONTENT - First 500 chars]");
Console.WriteLine(new string('-', 40));
var content = previewContent.GetString();
Console.WriteLine(content.Length > 500 ? content.Substring(0, 500) + "..." : content);
Console.WriteLine(new string('-', 40));
Console.WriteLine($"Full content length: {content.Length} characters");
}
}
}
else
{
Console.WriteLine($"[ERROR] README generation failed: {result.Message}");
}
}
catch (Exception ex)
{
Console.WriteLine($"[ERROR] Test failed: {ex.Message}");
}
}
private string FindProjectDirectory(string startPath)
{
var currentDir = new DirectoryInfo(startPath);
while (currentDir != null)
{
// Look for .csproj files
var projectFiles = currentDir.GetFiles("*.csproj");
if (projectFiles.Any())
{
return currentDir.FullName;
}
// Look for .sln files
var solutionFiles = currentDir.GetFiles("*.sln");
if (solutionFiles.Any())
{
return currentDir.FullName;
}
currentDir = currentDir.Parent;
}
return null;
}
private void DisplayReadmeResults(object data)
{
var json = JsonSerializer.Serialize(data, new JsonSerializerOptions { WriteIndented = true });
var resultElement = JsonSerializer.Deserialize<JsonElement>(json);
Console.WriteLine("\n[RESULTS]");
DisplayJsonProperty(resultElement, "Message");
DisplayJsonProperty(resultElement, "ProjectType");
DisplayJsonProperty(resultElement, "FilesAnalyzed");
DisplayJsonProperty(resultElement, "ContentLength");
DisplayJsonProperty(resultElement, "ChangesApplied");
if (resultElement.TryGetProperty("ReadmePath", out var readmePath))
{
Console.WriteLine($" README saved to: {readmePath.GetString()}");
}
}
public async Task TestCompleteRefactoringWorkflow()
{
Console.WriteLine("[WORKFLOW TEST] Running complete refactoring workflow...");
Console.WriteLine(new string('=', 80));
// Create advanced samples
await CreateAdvancedSampleFiles();
Console.WriteLine();
var advancedDirectory = Path.Combine(Directory.GetCurrentDirectory(), "advanced_samples");
var testFiles = new[]
{
("ComplexCalculator.cs", "extract-methods,simplify-conditionals"),
("UserManagementSystem.cs", "split-classes,extract-methods"),
("DuplicateLogic.cs", "remove-duplicates,extract-methods"),
("ParameterHeavyService.cs", "introduce-parameter-objects")
};
foreach (var (fileName, operations) in testFiles)
{
var filePath = Path.Combine(advancedDirectory, fileName);
Console.WriteLine($"\n[STEP 1] Analyzing {fileName}...");
await TestCodeAnalysisOnFile(filePath);
Console.WriteLine($"\n[STEP 2] Refactoring {fileName}...");
await TestActualRefactoring(filePath, operations, false); // Preview first
Console.WriteLine(new string('-', 40));
}
Console.WriteLine("\n[SUCCESS] Complete refactoring workflow test completed!");
Console.WriteLine("\nTo apply the refactoring changes, run:");
Console.WriteLine(" test-refactor --file <filename> --operations <ops> --apply");
}
public async Task TestCodeAnalysisOnFile(string filePath)
{
var parameters = new Dictionary<string, object>
{
["path"] = filePath,
["analysisDepth"] = "detailed",
["includeComplexity"] = true,
["includeCodeSmells"] = true,
["includeSuggestions"] = true
};
var result = await _pluginRegistry.CallFunctionAsync("CodeAnalysis", parameters);
if (result.Success)
{
var json = JsonSerializer.Serialize(result.Data, new JsonSerializerOptions { WriteIndented = true });
var analysisData = JsonSerializer.Deserialize<JsonElement>(json);
if (analysisData.TryGetProperty("Summary", out var summary))
{
DisplayJsonProperty(summary, "QualityScore");
DisplayJsonProperty(summary, "AverageComplexity");
}
}
}
private void DisplayRefactoringResults(object data)
{
var json = JsonSerializer.Serialize(data, new JsonSerializerOptions { WriteIndented = true });
var refactorData = JsonSerializer.Deserialize<JsonElement>(json);
DisplayJsonProperty(refactorData, "Message");
if (refactorData.TryGetProperty("Summary", out var summary))
{
Console.WriteLine("\n[REFACTORING SUMMARY]");
DisplayJsonProperty(summary, "TotalOperations");
DisplayJsonProperty(summary, "SuccessfulOperations");
DisplayJsonProperty(summary, "MethodsExtracted");
DisplayJsonProperty(summary, "ClassesSplit");
DisplayJsonProperty(summary, "ConditionalsSimplified");
DisplayJsonProperty(summary, "DuplicatesFound");
DisplayJsonProperty(summary, "ParameterObjectOpportunities");
}
if (refactorData.TryGetProperty("DetailedResult", out var detailed))
{
if (detailed.TryGetProperty("Operations", out var operations) && operations.ValueKind == JsonValueKind.Array)
{
Console.WriteLine("\n[DETAILED OPERATIONS]");
foreach (var operation in operations.EnumerateArray())
{
if (operation.TryGetProperty("Type", out var type) &&
operation.TryGetProperty("Success", out var success) &&
operation.TryGetProperty("Message", out var message))
{
var status = success.GetBoolean() ? "✓" : "✗";
Console.WriteLine($" {status} {type.GetString()}: {message.GetString()}");
// Show extracted methods
if (operation.TryGetProperty("ExtractedMethods", out var methods) && methods.ValueKind == JsonValueKind.Array)
{
foreach (var method in methods.EnumerateArray())
{
if (method.TryGetProperty("OriginalMethodName", out var orig) &&
method.TryGetProperty("ExtractedMethodName", out var extracted) &&
method.TryGetProperty("LinesExtracted", out var lines))
{
Console.WriteLine($" → Extracted {extracted.GetString()} from {orig.GetString()} ({lines.GetInt32()} lines)");
}
}
}
// Show duplicate findings
if (operation.TryGetProperty("DuplicatesRemoved", out var duplicates) && duplicates.ValueKind == JsonValueKind.Array)
{
foreach (var duplicate in duplicates.EnumerateArray())
{
Console.WriteLine($" → {duplicate.GetString()}");
}
}
// Show parameter object opportunities
if (operation.TryGetProperty("ParameterObjects", out var paramObjs) && paramObjs.ValueKind == JsonValueKind.Array)
{
foreach (var paramObj in paramObjs.EnumerateArray())
{
Console.WriteLine($" → {paramObj.GetString()}");
}
}
}
}
}
}
}
private void DisplayJsonProperty(JsonElement element, string propertyName)
{
if (element.TryGetProperty(propertyName, out var property))
{
var value = property.ValueKind switch
{
JsonValueKind.String => property.GetString(),
JsonValueKind.Number => property.GetDouble().ToString("F2"),
JsonValueKind.True => "True",
JsonValueKind.False => "False",
_ => property.ToString()
};
Console.WriteLine($" {propertyName}: {value}");
}
}
private async Task CreateComplexClassForExtraction(string directory)
{
await CreateComplexCalculator(directory);
}
}