182 lines
7.2 KiB
C#
182 lines
7.2 KiB
C#
|
|
using System;
|
||
|
|
using NUnit.Framework;
|
||
|
|
using UnityEngine;
|
||
|
|
using Newtonsoft.Json.Linq;
|
||
|
|
using MCPForUnity.Editor.Tools;
|
||
|
|
using System.Reflection;
|
||
|
|
|
||
|
|
namespace MCPForUnityTests.Editor.Tools
|
||
|
|
{
|
||
|
|
/// <summary>
|
||
|
|
/// In-memory tests for ManageScript validation logic.
|
||
|
|
/// These tests focus on the validation methods directly without creating files.
|
||
|
|
/// </summary>
|
||
|
|
public class ManageScriptValidationTests
|
||
|
|
{
|
||
|
|
[Test]
|
||
|
|
public void HandleCommand_NullParams_ReturnsError()
|
||
|
|
{
|
||
|
|
var result = ManageScript.HandleCommand(null);
|
||
|
|
Assert.IsNotNull(result, "Should handle null parameters gracefully");
|
||
|
|
}
|
||
|
|
|
||
|
|
[Test]
|
||
|
|
public void HandleCommand_InvalidAction_ReturnsError()
|
||
|
|
{
|
||
|
|
var paramsObj = new JObject
|
||
|
|
{
|
||
|
|
["action"] = "invalid_action",
|
||
|
|
["name"] = "TestScript",
|
||
|
|
["path"] = "Assets/Scripts"
|
||
|
|
};
|
||
|
|
|
||
|
|
var result = ManageScript.HandleCommand(paramsObj);
|
||
|
|
Assert.IsNotNull(result, "Should return error result for invalid action");
|
||
|
|
}
|
||
|
|
|
||
|
|
[Test]
|
||
|
|
public void CheckBalancedDelimiters_ValidCode_ReturnsTrue()
|
||
|
|
{
|
||
|
|
string validCode = "using UnityEngine;\n\npublic class TestClass : MonoBehaviour\n{\n void Start()\n {\n Debug.Log(\"test\");\n }\n}";
|
||
|
|
|
||
|
|
bool result = CallCheckBalancedDelimiters(validCode, out int line, out char expected);
|
||
|
|
Assert.IsTrue(result, "Valid C# code should pass balance check");
|
||
|
|
}
|
||
|
|
|
||
|
|
[Test]
|
||
|
|
public void CheckBalancedDelimiters_UnbalancedBraces_ReturnsFalse()
|
||
|
|
{
|
||
|
|
string unbalancedCode = "using UnityEngine;\n\npublic class TestClass : MonoBehaviour\n{\n void Start()\n {\n Debug.Log(\"test\");\n // Missing closing brace";
|
||
|
|
|
||
|
|
bool result = CallCheckBalancedDelimiters(unbalancedCode, out int line, out char expected);
|
||
|
|
Assert.IsFalse(result, "Unbalanced code should fail balance check");
|
||
|
|
}
|
||
|
|
|
||
|
|
[Test]
|
||
|
|
public void CheckBalancedDelimiters_StringWithBraces_ReturnsTrue()
|
||
|
|
{
|
||
|
|
string codeWithStringBraces = "using UnityEngine;\n\npublic class TestClass : MonoBehaviour\n{\n public string json = \"{key: value}\";\n void Start() { Debug.Log(json); }\n}";
|
||
|
|
|
||
|
|
bool result = CallCheckBalancedDelimiters(codeWithStringBraces, out int line, out char expected);
|
||
|
|
Assert.IsTrue(result, "Code with braces in strings should pass balance check");
|
||
|
|
}
|
||
|
|
|
||
|
|
[Test]
|
||
|
|
public void CheckScopedBalance_ValidCode_ReturnsTrue()
|
||
|
|
{
|
||
|
|
string validCode = "{ Debug.Log(\"test\"); }";
|
||
|
|
|
||
|
|
bool result = CallCheckScopedBalance(validCode, 0, validCode.Length);
|
||
|
|
Assert.IsTrue(result, "Valid scoped code should pass balance check");
|
||
|
|
}
|
||
|
|
|
||
|
|
[Test]
|
||
|
|
public void CheckScopedBalance_ShouldTolerateOuterContext_ReturnsTrue()
|
||
|
|
{
|
||
|
|
// This simulates a snippet extracted from a larger context
|
||
|
|
string contextSnippet = " Debug.Log(\"inside method\");\n} // This closing brace is from outer context";
|
||
|
|
|
||
|
|
bool result = CallCheckScopedBalance(contextSnippet, 0, contextSnippet.Length);
|
||
|
|
|
||
|
|
// Scoped balance should tolerate some imbalance from outer context
|
||
|
|
Assert.IsTrue(result, "Scoped balance should tolerate outer context imbalance");
|
||
|
|
}
|
||
|
|
|
||
|
|
[Test]
|
||
|
|
public void TicTacToe3D_ValidationScenario_DoesNotCrash()
|
||
|
|
{
|
||
|
|
// Test the scenario that was causing issues without file I/O
|
||
|
|
string ticTacToeCode = "using UnityEngine;\n\npublic class TicTacToe3D : MonoBehaviour\n{\n public string gameState = \"active\";\n void Start() { Debug.Log(\"Game started\"); }\n public void MakeMove(int position) { if (gameState == \"active\") Debug.Log($\"Move {position}\"); }\n}";
|
||
|
|
|
||
|
|
// Test that the validation methods don't crash on this code
|
||
|
|
bool balanceResult = CallCheckBalancedDelimiters(ticTacToeCode, out int line, out char expected);
|
||
|
|
bool scopedResult = CallCheckScopedBalance(ticTacToeCode, 0, ticTacToeCode.Length);
|
||
|
|
|
||
|
|
Assert.IsTrue(balanceResult, "TicTacToe3D code should pass balance validation");
|
||
|
|
Assert.IsTrue(scopedResult, "TicTacToe3D code should pass scoped balance validation");
|
||
|
|
}
|
||
|
|
|
||
|
|
// Helper methods to access private ManageScript methods via reflection
|
||
|
|
private bool CallCheckBalancedDelimiters(string contents, out int line, out char expected)
|
||
|
|
{
|
||
|
|
line = 0;
|
||
|
|
expected = ' ';
|
||
|
|
|
||
|
|
try
|
||
|
|
{
|
||
|
|
var method = typeof(ManageScript).GetMethod("CheckBalancedDelimiters",
|
||
|
|
BindingFlags.NonPublic | BindingFlags.Static);
|
||
|
|
|
||
|
|
if (method != null)
|
||
|
|
{
|
||
|
|
var parameters = new object[] { contents, line, expected };
|
||
|
|
var result = (bool)method.Invoke(null, parameters);
|
||
|
|
line = (int)parameters[1];
|
||
|
|
expected = (char)parameters[2];
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
Debug.LogWarning($"Could not test CheckBalancedDelimiters directly: {ex.Message}");
|
||
|
|
}
|
||
|
|
|
||
|
|
// Fallback: basic structural check
|
||
|
|
return BasicBalanceCheck(contents);
|
||
|
|
}
|
||
|
|
|
||
|
|
private bool CallCheckScopedBalance(string text, int start, int end)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
var method = typeof(ManageScript).GetMethod("CheckScopedBalance",
|
||
|
|
BindingFlags.NonPublic | BindingFlags.Static);
|
||
|
|
|
||
|
|
if (method != null)
|
||
|
|
{
|
||
|
|
return (bool)method.Invoke(null, new object[] { text, start, end });
|
||
|
|
}
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
Debug.LogWarning($"Could not test CheckScopedBalance directly: {ex.Message}");
|
||
|
|
}
|
||
|
|
|
||
|
|
return true; // Default to passing if we can't test the actual method
|
||
|
|
}
|
||
|
|
|
||
|
|
private bool BasicBalanceCheck(string contents)
|
||
|
|
{
|
||
|
|
// Simple fallback balance check
|
||
|
|
int braceCount = 0;
|
||
|
|
bool inString = false;
|
||
|
|
bool escaped = false;
|
||
|
|
|
||
|
|
for (int i = 0; i < contents.Length; i++)
|
||
|
|
{
|
||
|
|
char c = contents[i];
|
||
|
|
|
||
|
|
if (escaped)
|
||
|
|
{
|
||
|
|
escaped = false;
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (inString)
|
||
|
|
{
|
||
|
|
if (c == '\\') escaped = true;
|
||
|
|
else if (c == '"') inString = false;
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (c == '"') inString = true;
|
||
|
|
else if (c == '{') braceCount++;
|
||
|
|
else if (c == '}') braceCount--;
|
||
|
|
|
||
|
|
if (braceCount < 0) return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
return braceCount == 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|