Skip to main content
Glama
ManageScriptValidationTests.cs7.08 kB
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; } } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/CoplayDev/unity-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server