unity-mcp/TestProjects/UnityMCPTests/Assets/Tests/EditMode/Tools/ManageScriptableObjectTests.cs

363 lines
16 KiB
C#
Raw Normal View History

using System;
Feature/run tests summary clean (#501) * Optimize run_tests to return summary by default, reducing token usage by 98% - Add includeFailedTests parameter: returns only failed/skipped test details - Add includeDetails parameter: returns all test details (original behavior) - Default behavior now returns summary only (~150 tokens vs ~13k tokens) - Make results field optional in Python schema for backward compatibility Token savings: - Default: ~13k tokens saved (98.9% reduction) - With failures: minimal tokens (only non-passing tests) - Full details: same as before when explicitly requested This prevents context bloat for typical test runs where you only need pass/fail counts, while still allowing detailed debugging when needed. * Add warning when run_tests filters match no tests; fix test organization TDD Feature: - Add warning message when filter criteria match zero tests - New RunTestsTests.cs validates message formatting logic - Modified RunTests.cs to append "(No tests matched the specified filters)" when total=0 Test Organization Fixes: - Move MCPToolParameterTests.cs from EditMode/ to EditMode/Tools/ (matches folder hierarchy) - Fix inconsistent namespaces to MCPForUnityTests.Editor.{Subfolder}: - MCPToolParameterTests: Tests.EditMode → MCPForUnityTests.Editor.Tools - DomainReloadResilienceTests: Tests.EditMode.Tools → MCPForUnityTests.Editor.Tools - Matrix4x4ConverterTests: MCPForUnityTests.EditMode.Helpers → MCPForUnityTests.Editor.Helpers * Refactor test result message formatting * Simplify RunTests warning assertions * Tests: de-flake cold-start EditMode runs - Make ManageScriptableObjectTests setup yield-based with longer Unity-ready timeout - Mark DomainReloadResilienceTests explicit to avoid triggering domain reload during Run All
2026-01-02 12:36:45 +08:00
using System.Collections;
using Newtonsoft.Json.Linq;
using NUnit.Framework;
using UnityEditor;
using UnityEngine;
Feature/run tests summary clean (#501) * Optimize run_tests to return summary by default, reducing token usage by 98% - Add includeFailedTests parameter: returns only failed/skipped test details - Add includeDetails parameter: returns all test details (original behavior) - Default behavior now returns summary only (~150 tokens vs ~13k tokens) - Make results field optional in Python schema for backward compatibility Token savings: - Default: ~13k tokens saved (98.9% reduction) - With failures: minimal tokens (only non-passing tests) - Full details: same as before when explicitly requested This prevents context bloat for typical test runs where you only need pass/fail counts, while still allowing detailed debugging when needed. * Add warning when run_tests filters match no tests; fix test organization TDD Feature: - Add warning message when filter criteria match zero tests - New RunTestsTests.cs validates message formatting logic - Modified RunTests.cs to append "(No tests matched the specified filters)" when total=0 Test Organization Fixes: - Move MCPToolParameterTests.cs from EditMode/ to EditMode/Tools/ (matches folder hierarchy) - Fix inconsistent namespaces to MCPForUnityTests.Editor.{Subfolder}: - MCPToolParameterTests: Tests.EditMode → MCPForUnityTests.Editor.Tools - DomainReloadResilienceTests: Tests.EditMode.Tools → MCPForUnityTests.Editor.Tools - Matrix4x4ConverterTests: MCPForUnityTests.EditMode.Helpers → MCPForUnityTests.Editor.Helpers * Refactor test result message formatting * Simplify RunTests warning assertions * Tests: de-flake cold-start EditMode runs - Make ManageScriptableObjectTests setup yield-based with longer Unity-ready timeout - Mark DomainReloadResilienceTests explicit to avoid triggering domain reload during Run All
2026-01-02 12:36:45 +08:00
using UnityEngine.TestTools;
using MCPForUnity.Editor.Helpers;
using MCPForUnity.Editor.Tools;
using MCPForUnityTests.Editor.Tools.Fixtures;
namespace MCPForUnityTests.Editor.Tools
{
public class ManageScriptableObjectTests
{
private const string TempRoot = "Assets/Temp/ManageScriptableObjectTests";
Feature/run tests summary clean (#501) * Optimize run_tests to return summary by default, reducing token usage by 98% - Add includeFailedTests parameter: returns only failed/skipped test details - Add includeDetails parameter: returns all test details (original behavior) - Default behavior now returns summary only (~150 tokens vs ~13k tokens) - Make results field optional in Python schema for backward compatibility Token savings: - Default: ~13k tokens saved (98.9% reduction) - With failures: minimal tokens (only non-passing tests) - Full details: same as before when explicitly requested This prevents context bloat for typical test runs where you only need pass/fail counts, while still allowing detailed debugging when needed. * Add warning when run_tests filters match no tests; fix test organization TDD Feature: - Add warning message when filter criteria match zero tests - New RunTestsTests.cs validates message formatting logic - Modified RunTests.cs to append "(No tests matched the specified filters)" when total=0 Test Organization Fixes: - Move MCPToolParameterTests.cs from EditMode/ to EditMode/Tools/ (matches folder hierarchy) - Fix inconsistent namespaces to MCPForUnityTests.Editor.{Subfolder}: - MCPToolParameterTests: Tests.EditMode → MCPForUnityTests.Editor.Tools - DomainReloadResilienceTests: Tests.EditMode.Tools → MCPForUnityTests.Editor.Tools - Matrix4x4ConverterTests: MCPForUnityTests.EditMode.Helpers → MCPForUnityTests.Editor.Helpers * Refactor test result message formatting * Simplify RunTests warning assertions * Tests: de-flake cold-start EditMode runs - Make ManageScriptableObjectTests setup yield-based with longer Unity-ready timeout - Mark DomainReloadResilienceTests explicit to avoid triggering domain reload during Run All
2026-01-02 12:36:45 +08:00
private const double UnityReadyTimeoutSeconds = 180.0;
Async Test Infrastructure & Editor Readiness Status + new refresh_unity tool (#507) * Add editor readiness v2, refresh tool, and preflight guards * Detect external package changes and harden refresh retry * feat: add TestRunnerNoThrottle and async test running with background stall prevention - Add TestRunnerNoThrottle.cs: Sets editor to 'No Throttling' mode during test runs with SessionState persistence across domain reload - Add run_tests_async and get_test_job tools for non-blocking test execution - Add TestJobManager for async test job tracking with progress monitoring - Add ForceSynchronousImport to all AssetDatabase.Refresh() calls to prevent stalls - Mark DomainReloadResilienceTests as [Explicit] with documentation explaining the test infrastructure limitation (internal coroutine waits vs MCP socket polling) - MCP workflow is unaffected - socket messages provide external stimulus that keeps Unity responsive even when backgrounded * refactor: simplify and clean up code - Remove unused Newtonsoft.Json.Linq import from TestJobManager - Add throttling to SessionState persistence (once per second) to reduce overhead - Critical job state changes (start/finish) still persist immediately - Fix duplicate XML summary tag in DomainReloadResilienceTests * docs: add async test tools to README, document domain reload limitation - Add run_tests_async and get_test_job to main README tools list - Document background stall limitation for domain reload tests in DEV readme * ci: add separate job for domain reload tests Run [Explicit] domain_reload tests in their own job using -testCategory * ci: run domain reload tests in same job as regular tests Combines into single job with two test steps to reuse cached Library * fix: address coderabbit review issues - Fix TOCTOU race in TestJobManager.StartJob (single lock scope for check-and-set) - Store TestRunnerApi reference with HideAndDontSave to prevent GC/serialization issues * docs: update tool descriptions to prefer run_tests_async - run_tests_async is now marked as preferred for long-running suites - run_tests description notes it blocks and suggests async alternative * docs: update README screenshot to v8.6 UI * docs: add v8.6 UI screenshot * Update README for MCP version and instructions for v8.7 * fix: handle preflight busy signals and derive job status from test results - manage_asset, manage_gameobject, manage_scene now check preflight return value and propagate busy/retry signals to clients (fixes Sourcery #1) - TestJobManager.FinalizeCurrentJobFromRunFinished now sets job status to Failed when resultPayload.Failed > 0, not always Succeeded (fixes Sourcery #2) * fix: increase HTTP server startup timeout for dev mode When 'Force fresh server install' is enabled, uvx uses --no-cache --refresh which rebuilds the package and takes significantly longer to start. - Increase timeout from 10s to 45s when dev mode is enabled - Add informative log message explaining the longer startup time - Show actual timeout value in warning message * fix: derive job status from test results in FinalizeFromTask fallback Apply same logic as FinalizeCurrentJobFromRunFinished: check result.Failed > 0 to correctly mark jobs as Failed when tests fail, even in the fallback path when RunFinished callback is not delivered.
2026-01-04 04:42:32 +08:00
private string _runRoot;
private string _nestedFolder;
private string _createdAssetPath;
private string _createdGuid;
private string _matAPath;
private string _matBPath;
Feature/run tests summary clean (#501) * Optimize run_tests to return summary by default, reducing token usage by 98% - Add includeFailedTests parameter: returns only failed/skipped test details - Add includeDetails parameter: returns all test details (original behavior) - Default behavior now returns summary only (~150 tokens vs ~13k tokens) - Make results field optional in Python schema for backward compatibility Token savings: - Default: ~13k tokens saved (98.9% reduction) - With failures: minimal tokens (only non-passing tests) - Full details: same as before when explicitly requested This prevents context bloat for typical test runs where you only need pass/fail counts, while still allowing detailed debugging when needed. * Add warning when run_tests filters match no tests; fix test organization TDD Feature: - Add warning message when filter criteria match zero tests - New RunTestsTests.cs validates message formatting logic - Modified RunTests.cs to append "(No tests matched the specified filters)" when total=0 Test Organization Fixes: - Move MCPToolParameterTests.cs from EditMode/ to EditMode/Tools/ (matches folder hierarchy) - Fix inconsistent namespaces to MCPForUnityTests.Editor.{Subfolder}: - MCPToolParameterTests: Tests.EditMode → MCPForUnityTests.Editor.Tools - DomainReloadResilienceTests: Tests.EditMode.Tools → MCPForUnityTests.Editor.Tools - Matrix4x4ConverterTests: MCPForUnityTests.EditMode.Helpers → MCPForUnityTests.Editor.Helpers * Refactor test result message formatting * Simplify RunTests warning assertions * Tests: de-flake cold-start EditMode runs - Make ManageScriptableObjectTests setup yield-based with longer Unity-ready timeout - Mark DomainReloadResilienceTests explicit to avoid triggering domain reload during Run All
2026-01-02 12:36:45 +08:00
[UnitySetUp]
public IEnumerator SetUp()
{
Feature/run tests summary clean (#501) * Optimize run_tests to return summary by default, reducing token usage by 98% - Add includeFailedTests parameter: returns only failed/skipped test details - Add includeDetails parameter: returns all test details (original behavior) - Default behavior now returns summary only (~150 tokens vs ~13k tokens) - Make results field optional in Python schema for backward compatibility Token savings: - Default: ~13k tokens saved (98.9% reduction) - With failures: minimal tokens (only non-passing tests) - Full details: same as before when explicitly requested This prevents context bloat for typical test runs where you only need pass/fail counts, while still allowing detailed debugging when needed. * Add warning when run_tests filters match no tests; fix test organization TDD Feature: - Add warning message when filter criteria match zero tests - New RunTestsTests.cs validates message formatting logic - Modified RunTests.cs to append "(No tests matched the specified filters)" when total=0 Test Organization Fixes: - Move MCPToolParameterTests.cs from EditMode/ to EditMode/Tools/ (matches folder hierarchy) - Fix inconsistent namespaces to MCPForUnityTests.Editor.{Subfolder}: - MCPToolParameterTests: Tests.EditMode → MCPForUnityTests.Editor.Tools - DomainReloadResilienceTests: Tests.EditMode.Tools → MCPForUnityTests.Editor.Tools - Matrix4x4ConverterTests: MCPForUnityTests.EditMode.Helpers → MCPForUnityTests.Editor.Helpers * Refactor test result message formatting * Simplify RunTests warning assertions * Tests: de-flake cold-start EditMode runs - Make ManageScriptableObjectTests setup yield-based with longer Unity-ready timeout - Mark DomainReloadResilienceTests explicit to avoid triggering domain reload during Run All
2026-01-02 12:36:45 +08:00
yield return WaitForUnityReady(UnityReadyTimeoutSeconds);
EnsureFolder("Assets/Temp");
Async Test Infrastructure & Editor Readiness Status + new refresh_unity tool (#507) * Add editor readiness v2, refresh tool, and preflight guards * Detect external package changes and harden refresh retry * feat: add TestRunnerNoThrottle and async test running with background stall prevention - Add TestRunnerNoThrottle.cs: Sets editor to 'No Throttling' mode during test runs with SessionState persistence across domain reload - Add run_tests_async and get_test_job tools for non-blocking test execution - Add TestJobManager for async test job tracking with progress monitoring - Add ForceSynchronousImport to all AssetDatabase.Refresh() calls to prevent stalls - Mark DomainReloadResilienceTests as [Explicit] with documentation explaining the test infrastructure limitation (internal coroutine waits vs MCP socket polling) - MCP workflow is unaffected - socket messages provide external stimulus that keeps Unity responsive even when backgrounded * refactor: simplify and clean up code - Remove unused Newtonsoft.Json.Linq import from TestJobManager - Add throttling to SessionState persistence (once per second) to reduce overhead - Critical job state changes (start/finish) still persist immediately - Fix duplicate XML summary tag in DomainReloadResilienceTests * docs: add async test tools to README, document domain reload limitation - Add run_tests_async and get_test_job to main README tools list - Document background stall limitation for domain reload tests in DEV readme * ci: add separate job for domain reload tests Run [Explicit] domain_reload tests in their own job using -testCategory * ci: run domain reload tests in same job as regular tests Combines into single job with two test steps to reuse cached Library * fix: address coderabbit review issues - Fix TOCTOU race in TestJobManager.StartJob (single lock scope for check-and-set) - Store TestRunnerApi reference with HideAndDontSave to prevent GC/serialization issues * docs: update tool descriptions to prefer run_tests_async - run_tests_async is now marked as preferred for long-running suites - run_tests description notes it blocks and suggests async alternative * docs: update README screenshot to v8.6 UI * docs: add v8.6 UI screenshot * Update README for MCP version and instructions for v8.7 * fix: handle preflight busy signals and derive job status from test results - manage_asset, manage_gameobject, manage_scene now check preflight return value and propagate busy/retry signals to clients (fixes Sourcery #1) - TestJobManager.FinalizeCurrentJobFromRunFinished now sets job status to Failed when resultPayload.Failed > 0, not always Succeeded (fixes Sourcery #2) * fix: increase HTTP server startup timeout for dev mode When 'Force fresh server install' is enabled, uvx uses --no-cache --refresh which rebuilds the package and takes significantly longer to start. - Increase timeout from 10s to 45s when dev mode is enabled - Add informative log message explaining the longer startup time - Show actual timeout value in warning message * fix: derive job status from test results in FinalizeFromTask fallback Apply same logic as FinalizeCurrentJobFromRunFinished: check result.Failed > 0 to correctly mark jobs as Failed when tests fail, even in the fallback path when RunFinished callback is not delivered.
2026-01-04 04:42:32 +08:00
// Avoid deleting/recreating the entire TempRoot each test (can trigger heavy reimport churn).
// Instead, isolate each test in its own unique subfolder under TempRoot.
EnsureFolder(TempRoot);
Async Test Infrastructure & Editor Readiness Status + new refresh_unity tool (#507) * Add editor readiness v2, refresh tool, and preflight guards * Detect external package changes and harden refresh retry * feat: add TestRunnerNoThrottle and async test running with background stall prevention - Add TestRunnerNoThrottle.cs: Sets editor to 'No Throttling' mode during test runs with SessionState persistence across domain reload - Add run_tests_async and get_test_job tools for non-blocking test execution - Add TestJobManager for async test job tracking with progress monitoring - Add ForceSynchronousImport to all AssetDatabase.Refresh() calls to prevent stalls - Mark DomainReloadResilienceTests as [Explicit] with documentation explaining the test infrastructure limitation (internal coroutine waits vs MCP socket polling) - MCP workflow is unaffected - socket messages provide external stimulus that keeps Unity responsive even when backgrounded * refactor: simplify and clean up code - Remove unused Newtonsoft.Json.Linq import from TestJobManager - Add throttling to SessionState persistence (once per second) to reduce overhead - Critical job state changes (start/finish) still persist immediately - Fix duplicate XML summary tag in DomainReloadResilienceTests * docs: add async test tools to README, document domain reload limitation - Add run_tests_async and get_test_job to main README tools list - Document background stall limitation for domain reload tests in DEV readme * ci: add separate job for domain reload tests Run [Explicit] domain_reload tests in their own job using -testCategory * ci: run domain reload tests in same job as regular tests Combines into single job with two test steps to reuse cached Library * fix: address coderabbit review issues - Fix TOCTOU race in TestJobManager.StartJob (single lock scope for check-and-set) - Store TestRunnerApi reference with HideAndDontSave to prevent GC/serialization issues * docs: update tool descriptions to prefer run_tests_async - run_tests_async is now marked as preferred for long-running suites - run_tests description notes it blocks and suggests async alternative * docs: update README screenshot to v8.6 UI * docs: add v8.6 UI screenshot * Update README for MCP version and instructions for v8.7 * fix: handle preflight busy signals and derive job status from test results - manage_asset, manage_gameobject, manage_scene now check preflight return value and propagate busy/retry signals to clients (fixes Sourcery #1) - TestJobManager.FinalizeCurrentJobFromRunFinished now sets job status to Failed when resultPayload.Failed > 0, not always Succeeded (fixes Sourcery #2) * fix: increase HTTP server startup timeout for dev mode When 'Force fresh server install' is enabled, uvx uses --no-cache --refresh which rebuilds the package and takes significantly longer to start. - Increase timeout from 10s to 45s when dev mode is enabled - Add informative log message explaining the longer startup time - Show actual timeout value in warning message * fix: derive job status from test results in FinalizeFromTask fallback Apply same logic as FinalizeCurrentJobFromRunFinished: check result.Failed > 0 to correctly mark jobs as Failed when tests fail, even in the fallback path when RunFinished callback is not delivered.
2026-01-04 04:42:32 +08:00
_runRoot = $"{TempRoot}/Run_{Guid.NewGuid():N}";
EnsureFolder(_runRoot);
_nestedFolder = _runRoot + "/Nested/Deeper";
_createdAssetPath = null;
_createdGuid = null;
// Create two Materials we can reference by guid/path.
_matAPath = $"{TempRoot}/MatA_{Guid.NewGuid():N}.mat";
_matBPath = $"{TempRoot}/MatB_{Guid.NewGuid():N}.mat";
var shader = Shader.Find("Universal Render Pipeline/Lit")
?? Shader.Find("HDRP/Lit")
?? Shader.Find("Standard")
?? Shader.Find("Unlit/Color");
Assert.IsNotNull(shader, "A fallback shader must be available for creating Material assets in tests.");
AssetDatabase.CreateAsset(new Material(shader), _matAPath);
AssetDatabase.CreateAsset(new Material(shader), _matBPath);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
Feature/run tests summary clean (#501) * Optimize run_tests to return summary by default, reducing token usage by 98% - Add includeFailedTests parameter: returns only failed/skipped test details - Add includeDetails parameter: returns all test details (original behavior) - Default behavior now returns summary only (~150 tokens vs ~13k tokens) - Make results field optional in Python schema for backward compatibility Token savings: - Default: ~13k tokens saved (98.9% reduction) - With failures: minimal tokens (only non-passing tests) - Full details: same as before when explicitly requested This prevents context bloat for typical test runs where you only need pass/fail counts, while still allowing detailed debugging when needed. * Add warning when run_tests filters match no tests; fix test organization TDD Feature: - Add warning message when filter criteria match zero tests - New RunTestsTests.cs validates message formatting logic - Modified RunTests.cs to append "(No tests matched the specified filters)" when total=0 Test Organization Fixes: - Move MCPToolParameterTests.cs from EditMode/ to EditMode/Tools/ (matches folder hierarchy) - Fix inconsistent namespaces to MCPForUnityTests.Editor.{Subfolder}: - MCPToolParameterTests: Tests.EditMode → MCPForUnityTests.Editor.Tools - DomainReloadResilienceTests: Tests.EditMode.Tools → MCPForUnityTests.Editor.Tools - Matrix4x4ConverterTests: MCPForUnityTests.EditMode.Helpers → MCPForUnityTests.Editor.Helpers * Refactor test result message formatting * Simplify RunTests warning assertions * Tests: de-flake cold-start EditMode runs - Make ManageScriptableObjectTests setup yield-based with longer Unity-ready timeout - Mark DomainReloadResilienceTests explicit to avoid triggering domain reload during Run All
2026-01-02 12:36:45 +08:00
yield return WaitForUnityReady(UnityReadyTimeoutSeconds);
}
[TearDown]
public void TearDown()
{
// Best-effort cleanup
if (!string.IsNullOrEmpty(_createdAssetPath) && AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(_createdAssetPath) != null)
{
AssetDatabase.DeleteAsset(_createdAssetPath);
}
if (!string.IsNullOrEmpty(_matAPath) && AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(_matAPath) != null)
{
AssetDatabase.DeleteAsset(_matAPath);
}
if (!string.IsNullOrEmpty(_matBPath) && AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(_matBPath) != null)
{
AssetDatabase.DeleteAsset(_matBPath);
}
Async Test Infrastructure & Editor Readiness Status + new refresh_unity tool (#507) * Add editor readiness v2, refresh tool, and preflight guards * Detect external package changes and harden refresh retry * feat: add TestRunnerNoThrottle and async test running with background stall prevention - Add TestRunnerNoThrottle.cs: Sets editor to 'No Throttling' mode during test runs with SessionState persistence across domain reload - Add run_tests_async and get_test_job tools for non-blocking test execution - Add TestJobManager for async test job tracking with progress monitoring - Add ForceSynchronousImport to all AssetDatabase.Refresh() calls to prevent stalls - Mark DomainReloadResilienceTests as [Explicit] with documentation explaining the test infrastructure limitation (internal coroutine waits vs MCP socket polling) - MCP workflow is unaffected - socket messages provide external stimulus that keeps Unity responsive even when backgrounded * refactor: simplify and clean up code - Remove unused Newtonsoft.Json.Linq import from TestJobManager - Add throttling to SessionState persistence (once per second) to reduce overhead - Critical job state changes (start/finish) still persist immediately - Fix duplicate XML summary tag in DomainReloadResilienceTests * docs: add async test tools to README, document domain reload limitation - Add run_tests_async and get_test_job to main README tools list - Document background stall limitation for domain reload tests in DEV readme * ci: add separate job for domain reload tests Run [Explicit] domain_reload tests in their own job using -testCategory * ci: run domain reload tests in same job as regular tests Combines into single job with two test steps to reuse cached Library * fix: address coderabbit review issues - Fix TOCTOU race in TestJobManager.StartJob (single lock scope for check-and-set) - Store TestRunnerApi reference with HideAndDontSave to prevent GC/serialization issues * docs: update tool descriptions to prefer run_tests_async - run_tests_async is now marked as preferred for long-running suites - run_tests description notes it blocks and suggests async alternative * docs: update README screenshot to v8.6 UI * docs: add v8.6 UI screenshot * Update README for MCP version and instructions for v8.7 * fix: handle preflight busy signals and derive job status from test results - manage_asset, manage_gameobject, manage_scene now check preflight return value and propagate busy/retry signals to clients (fixes Sourcery #1) - TestJobManager.FinalizeCurrentJobFromRunFinished now sets job status to Failed when resultPayload.Failed > 0, not always Succeeded (fixes Sourcery #2) * fix: increase HTTP server startup timeout for dev mode When 'Force fresh server install' is enabled, uvx uses --no-cache --refresh which rebuilds the package and takes significantly longer to start. - Increase timeout from 10s to 45s when dev mode is enabled - Add informative log message explaining the longer startup time - Show actual timeout value in warning message * fix: derive job status from test results in FinalizeFromTask fallback Apply same logic as FinalizeCurrentJobFromRunFinished: check result.Failed > 0 to correctly mark jobs as Failed when tests fail, even in the fallback path when RunFinished callback is not delivered.
2026-01-04 04:42:32 +08:00
if (!string.IsNullOrEmpty(_runRoot) && AssetDatabase.IsValidFolder(_runRoot))
{
Async Test Infrastructure & Editor Readiness Status + new refresh_unity tool (#507) * Add editor readiness v2, refresh tool, and preflight guards * Detect external package changes and harden refresh retry * feat: add TestRunnerNoThrottle and async test running with background stall prevention - Add TestRunnerNoThrottle.cs: Sets editor to 'No Throttling' mode during test runs with SessionState persistence across domain reload - Add run_tests_async and get_test_job tools for non-blocking test execution - Add TestJobManager for async test job tracking with progress monitoring - Add ForceSynchronousImport to all AssetDatabase.Refresh() calls to prevent stalls - Mark DomainReloadResilienceTests as [Explicit] with documentation explaining the test infrastructure limitation (internal coroutine waits vs MCP socket polling) - MCP workflow is unaffected - socket messages provide external stimulus that keeps Unity responsive even when backgrounded * refactor: simplify and clean up code - Remove unused Newtonsoft.Json.Linq import from TestJobManager - Add throttling to SessionState persistence (once per second) to reduce overhead - Critical job state changes (start/finish) still persist immediately - Fix duplicate XML summary tag in DomainReloadResilienceTests * docs: add async test tools to README, document domain reload limitation - Add run_tests_async and get_test_job to main README tools list - Document background stall limitation for domain reload tests in DEV readme * ci: add separate job for domain reload tests Run [Explicit] domain_reload tests in their own job using -testCategory * ci: run domain reload tests in same job as regular tests Combines into single job with two test steps to reuse cached Library * fix: address coderabbit review issues - Fix TOCTOU race in TestJobManager.StartJob (single lock scope for check-and-set) - Store TestRunnerApi reference with HideAndDontSave to prevent GC/serialization issues * docs: update tool descriptions to prefer run_tests_async - run_tests_async is now marked as preferred for long-running suites - run_tests description notes it blocks and suggests async alternative * docs: update README screenshot to v8.6 UI * docs: add v8.6 UI screenshot * Update README for MCP version and instructions for v8.7 * fix: handle preflight busy signals and derive job status from test results - manage_asset, manage_gameobject, manage_scene now check preflight return value and propagate busy/retry signals to clients (fixes Sourcery #1) - TestJobManager.FinalizeCurrentJobFromRunFinished now sets job status to Failed when resultPayload.Failed > 0, not always Succeeded (fixes Sourcery #2) * fix: increase HTTP server startup timeout for dev mode When 'Force fresh server install' is enabled, uvx uses --no-cache --refresh which rebuilds the package and takes significantly longer to start. - Increase timeout from 10s to 45s when dev mode is enabled - Add informative log message explaining the longer startup time - Show actual timeout value in warning message * fix: derive job status from test results in FinalizeFromTask fallback Apply same logic as FinalizeCurrentJobFromRunFinished: check result.Failed > 0 to correctly mark jobs as Failed when tests fail, even in the fallback path when RunFinished callback is not delivered.
2026-01-04 04:42:32 +08:00
AssetDatabase.DeleteAsset(_runRoot);
}
// Clean up parent Temp folder if empty
if (AssetDatabase.IsValidFolder("Assets/Temp"))
{
var remainingDirs = System.IO.Directory.GetDirectories("Assets/Temp");
var remainingFiles = System.IO.Directory.GetFiles("Assets/Temp");
if (remainingDirs.Length == 0 && remainingFiles.Length == 0)
{
AssetDatabase.DeleteAsset("Assets/Temp");
}
}
AssetDatabase.Refresh();
}
[Test]
Async Test Infrastructure & Editor Readiness Status + new refresh_unity tool (#507) * Add editor readiness v2, refresh tool, and preflight guards * Detect external package changes and harden refresh retry * feat: add TestRunnerNoThrottle and async test running with background stall prevention - Add TestRunnerNoThrottle.cs: Sets editor to 'No Throttling' mode during test runs with SessionState persistence across domain reload - Add run_tests_async and get_test_job tools for non-blocking test execution - Add TestJobManager for async test job tracking with progress monitoring - Add ForceSynchronousImport to all AssetDatabase.Refresh() calls to prevent stalls - Mark DomainReloadResilienceTests as [Explicit] with documentation explaining the test infrastructure limitation (internal coroutine waits vs MCP socket polling) - MCP workflow is unaffected - socket messages provide external stimulus that keeps Unity responsive even when backgrounded * refactor: simplify and clean up code - Remove unused Newtonsoft.Json.Linq import from TestJobManager - Add throttling to SessionState persistence (once per second) to reduce overhead - Critical job state changes (start/finish) still persist immediately - Fix duplicate XML summary tag in DomainReloadResilienceTests * docs: add async test tools to README, document domain reload limitation - Add run_tests_async and get_test_job to main README tools list - Document background stall limitation for domain reload tests in DEV readme * ci: add separate job for domain reload tests Run [Explicit] domain_reload tests in their own job using -testCategory * ci: run domain reload tests in same job as regular tests Combines into single job with two test steps to reuse cached Library * fix: address coderabbit review issues - Fix TOCTOU race in TestJobManager.StartJob (single lock scope for check-and-set) - Store TestRunnerApi reference with HideAndDontSave to prevent GC/serialization issues * docs: update tool descriptions to prefer run_tests_async - run_tests_async is now marked as preferred for long-running suites - run_tests description notes it blocks and suggests async alternative * docs: update README screenshot to v8.6 UI * docs: add v8.6 UI screenshot * Update README for MCP version and instructions for v8.7 * fix: handle preflight busy signals and derive job status from test results - manage_asset, manage_gameobject, manage_scene now check preflight return value and propagate busy/retry signals to clients (fixes Sourcery #1) - TestJobManager.FinalizeCurrentJobFromRunFinished now sets job status to Failed when resultPayload.Failed > 0, not always Succeeded (fixes Sourcery #2) * fix: increase HTTP server startup timeout for dev mode When 'Force fresh server install' is enabled, uvx uses --no-cache --refresh which rebuilds the package and takes significantly longer to start. - Increase timeout from 10s to 45s when dev mode is enabled - Add informative log message explaining the longer startup time - Show actual timeout value in warning message * fix: derive job status from test results in FinalizeFromTask fallback Apply same logic as FinalizeCurrentJobFromRunFinished: check result.Failed > 0 to correctly mark jobs as Failed when tests fail, even in the fallback path when RunFinished callback is not delivered.
2026-01-04 04:42:32 +08:00
public void Create_CreatesNestedFolders_PlacesAssetCorrectly()
{
var create = new JObject
{
["action"] = "create",
["typeName"] = typeof(ManageScriptableObjectTestDefinition).FullName,
Async Test Infrastructure & Editor Readiness Status + new refresh_unity tool (#507) * Add editor readiness v2, refresh tool, and preflight guards * Detect external package changes and harden refresh retry * feat: add TestRunnerNoThrottle and async test running with background stall prevention - Add TestRunnerNoThrottle.cs: Sets editor to 'No Throttling' mode during test runs with SessionState persistence across domain reload - Add run_tests_async and get_test_job tools for non-blocking test execution - Add TestJobManager for async test job tracking with progress monitoring - Add ForceSynchronousImport to all AssetDatabase.Refresh() calls to prevent stalls - Mark DomainReloadResilienceTests as [Explicit] with documentation explaining the test infrastructure limitation (internal coroutine waits vs MCP socket polling) - MCP workflow is unaffected - socket messages provide external stimulus that keeps Unity responsive even when backgrounded * refactor: simplify and clean up code - Remove unused Newtonsoft.Json.Linq import from TestJobManager - Add throttling to SessionState persistence (once per second) to reduce overhead - Critical job state changes (start/finish) still persist immediately - Fix duplicate XML summary tag in DomainReloadResilienceTests * docs: add async test tools to README, document domain reload limitation - Add run_tests_async and get_test_job to main README tools list - Document background stall limitation for domain reload tests in DEV readme * ci: add separate job for domain reload tests Run [Explicit] domain_reload tests in their own job using -testCategory * ci: run domain reload tests in same job as regular tests Combines into single job with two test steps to reuse cached Library * fix: address coderabbit review issues - Fix TOCTOU race in TestJobManager.StartJob (single lock scope for check-and-set) - Store TestRunnerApi reference with HideAndDontSave to prevent GC/serialization issues * docs: update tool descriptions to prefer run_tests_async - run_tests_async is now marked as preferred for long-running suites - run_tests description notes it blocks and suggests async alternative * docs: update README screenshot to v8.6 UI * docs: add v8.6 UI screenshot * Update README for MCP version and instructions for v8.7 * fix: handle preflight busy signals and derive job status from test results - manage_asset, manage_gameobject, manage_scene now check preflight return value and propagate busy/retry signals to clients (fixes Sourcery #1) - TestJobManager.FinalizeCurrentJobFromRunFinished now sets job status to Failed when resultPayload.Failed > 0, not always Succeeded (fixes Sourcery #2) * fix: increase HTTP server startup timeout for dev mode When 'Force fresh server install' is enabled, uvx uses --no-cache --refresh which rebuilds the package and takes significantly longer to start. - Increase timeout from 10s to 45s when dev mode is enabled - Add informative log message explaining the longer startup time - Show actual timeout value in warning message * fix: derive job status from test results in FinalizeFromTask fallback Apply same logic as FinalizeCurrentJobFromRunFinished: check result.Failed > 0 to correctly mark jobs as Failed when tests fail, even in the fallback path when RunFinished callback is not delivered.
2026-01-04 04:42:32 +08:00
["folderPath"] = _nestedFolder,
["assetName"] = "My_Test_Def_Placement",
["overwrite"] = true,
};
var raw = ManageScriptableObject.HandleCommand(create);
var result = raw as JObject ?? JObject.FromObject(raw);
Assert.IsTrue(result.Value<bool>("success"), result.ToString());
var data = result["data"] as JObject;
Assert.IsNotNull(data, "Expected data payload");
_createdGuid = data!["guid"]?.ToString();
_createdAssetPath = data["path"]?.ToString();
Assert.IsTrue(AssetDatabase.IsValidFolder(_nestedFolder), "Nested folder should be created.");
Assert.IsTrue(_createdAssetPath!.StartsWith(_nestedFolder, StringComparison.Ordinal), $"Asset should be created under {_nestedFolder}: {_createdAssetPath}");
Assert.IsTrue(_createdAssetPath.EndsWith(".asset", StringComparison.OrdinalIgnoreCase), "Asset should have .asset extension.");
Assert.IsFalse(string.IsNullOrWhiteSpace(_createdGuid), "Expected guid in response.");
var asset = AssetDatabase.LoadAssetAtPath<ManageScriptableObjectTestDefinition>(_createdAssetPath);
Assert.IsNotNull(asset, "Created asset should load as TestDefinition.");
}
[Test]
public void Create_AppliesPatches_ToCreatedAsset()
{
var create = new JObject
{
["action"] = "create",
["typeName"] = typeof(ManageScriptableObjectTestDefinition).FullName,
// Patching correctness does not depend on nested folder creation; keep this lightweight.
["folderPath"] = _runRoot,
["assetName"] = "My_Test_Def_Patches",
["overwrite"] = true,
["patches"] = new JArray
{
new JObject { ["propertyPath"] = "displayName", ["op"] = "set", ["value"] = "Hello" },
new JObject { ["propertyPath"] = "baseNumber", ["op"] = "set", ["value"] = 42 },
new JObject { ["propertyPath"] = "nested.note", ["op"] = "set", ["value"] = "note!" }
}
};
var raw = ManageScriptableObject.HandleCommand(create);
var result = raw as JObject ?? JObject.FromObject(raw);
Assert.IsTrue(result.Value<bool>("success"), result.ToString());
Async Test Infrastructure & Editor Readiness Status + new refresh_unity tool (#507) * Add editor readiness v2, refresh tool, and preflight guards * Detect external package changes and harden refresh retry * feat: add TestRunnerNoThrottle and async test running with background stall prevention - Add TestRunnerNoThrottle.cs: Sets editor to 'No Throttling' mode during test runs with SessionState persistence across domain reload - Add run_tests_async and get_test_job tools for non-blocking test execution - Add TestJobManager for async test job tracking with progress monitoring - Add ForceSynchronousImport to all AssetDatabase.Refresh() calls to prevent stalls - Mark DomainReloadResilienceTests as [Explicit] with documentation explaining the test infrastructure limitation (internal coroutine waits vs MCP socket polling) - MCP workflow is unaffected - socket messages provide external stimulus that keeps Unity responsive even when backgrounded * refactor: simplify and clean up code - Remove unused Newtonsoft.Json.Linq import from TestJobManager - Add throttling to SessionState persistence (once per second) to reduce overhead - Critical job state changes (start/finish) still persist immediately - Fix duplicate XML summary tag in DomainReloadResilienceTests * docs: add async test tools to README, document domain reload limitation - Add run_tests_async and get_test_job to main README tools list - Document background stall limitation for domain reload tests in DEV readme * ci: add separate job for domain reload tests Run [Explicit] domain_reload tests in their own job using -testCategory * ci: run domain reload tests in same job as regular tests Combines into single job with two test steps to reuse cached Library * fix: address coderabbit review issues - Fix TOCTOU race in TestJobManager.StartJob (single lock scope for check-and-set) - Store TestRunnerApi reference with HideAndDontSave to prevent GC/serialization issues * docs: update tool descriptions to prefer run_tests_async - run_tests_async is now marked as preferred for long-running suites - run_tests description notes it blocks and suggests async alternative * docs: update README screenshot to v8.6 UI * docs: add v8.6 UI screenshot * Update README for MCP version and instructions for v8.7 * fix: handle preflight busy signals and derive job status from test results - manage_asset, manage_gameobject, manage_scene now check preflight return value and propagate busy/retry signals to clients (fixes Sourcery #1) - TestJobManager.FinalizeCurrentJobFromRunFinished now sets job status to Failed when resultPayload.Failed > 0, not always Succeeded (fixes Sourcery #2) * fix: increase HTTP server startup timeout for dev mode When 'Force fresh server install' is enabled, uvx uses --no-cache --refresh which rebuilds the package and takes significantly longer to start. - Increase timeout from 10s to 45s when dev mode is enabled - Add informative log message explaining the longer startup time - Show actual timeout value in warning message * fix: derive job status from test results in FinalizeFromTask fallback Apply same logic as FinalizeCurrentJobFromRunFinished: check result.Failed > 0 to correctly mark jobs as Failed when tests fail, even in the fallback path when RunFinished callback is not delivered.
2026-01-04 04:42:32 +08:00
var data = result["data"] as JObject;
Assert.IsNotNull(data, "Expected data payload");
_createdGuid = data!["guid"]?.ToString();
_createdAssetPath = data["path"]?.ToString();
Async Test Infrastructure & Editor Readiness Status + new refresh_unity tool (#507) * Add editor readiness v2, refresh tool, and preflight guards * Detect external package changes and harden refresh retry * feat: add TestRunnerNoThrottle and async test running with background stall prevention - Add TestRunnerNoThrottle.cs: Sets editor to 'No Throttling' mode during test runs with SessionState persistence across domain reload - Add run_tests_async and get_test_job tools for non-blocking test execution - Add TestJobManager for async test job tracking with progress monitoring - Add ForceSynchronousImport to all AssetDatabase.Refresh() calls to prevent stalls - Mark DomainReloadResilienceTests as [Explicit] with documentation explaining the test infrastructure limitation (internal coroutine waits vs MCP socket polling) - MCP workflow is unaffected - socket messages provide external stimulus that keeps Unity responsive even when backgrounded * refactor: simplify and clean up code - Remove unused Newtonsoft.Json.Linq import from TestJobManager - Add throttling to SessionState persistence (once per second) to reduce overhead - Critical job state changes (start/finish) still persist immediately - Fix duplicate XML summary tag in DomainReloadResilienceTests * docs: add async test tools to README, document domain reload limitation - Add run_tests_async and get_test_job to main README tools list - Document background stall limitation for domain reload tests in DEV readme * ci: add separate job for domain reload tests Run [Explicit] domain_reload tests in their own job using -testCategory * ci: run domain reload tests in same job as regular tests Combines into single job with two test steps to reuse cached Library * fix: address coderabbit review issues - Fix TOCTOU race in TestJobManager.StartJob (single lock scope for check-and-set) - Store TestRunnerApi reference with HideAndDontSave to prevent GC/serialization issues * docs: update tool descriptions to prefer run_tests_async - run_tests_async is now marked as preferred for long-running suites - run_tests description notes it blocks and suggests async alternative * docs: update README screenshot to v8.6 UI * docs: add v8.6 UI screenshot * Update README for MCP version and instructions for v8.7 * fix: handle preflight busy signals and derive job status from test results - manage_asset, manage_gameobject, manage_scene now check preflight return value and propagate busy/retry signals to clients (fixes Sourcery #1) - TestJobManager.FinalizeCurrentJobFromRunFinished now sets job status to Failed when resultPayload.Failed > 0, not always Succeeded (fixes Sourcery #2) * fix: increase HTTP server startup timeout for dev mode When 'Force fresh server install' is enabled, uvx uses --no-cache --refresh which rebuilds the package and takes significantly longer to start. - Increase timeout from 10s to 45s when dev mode is enabled - Add informative log message explaining the longer startup time - Show actual timeout value in warning message * fix: derive job status from test results in FinalizeFromTask fallback Apply same logic as FinalizeCurrentJobFromRunFinished: check result.Failed > 0 to correctly mark jobs as Failed when tests fail, even in the fallback path when RunFinished callback is not delivered.
2026-01-04 04:42:32 +08:00
Assert.IsTrue(_createdAssetPath!.StartsWith(_runRoot, StringComparison.Ordinal), $"Asset should be created under {_runRoot}: {_createdAssetPath}");
Assert.IsFalse(string.IsNullOrWhiteSpace(_createdGuid), "Expected guid in response.");
var asset = AssetDatabase.LoadAssetAtPath<ManageScriptableObjectTestDefinition>(_createdAssetPath);
Assert.IsNotNull(asset, "Created asset should load as TestDefinition.");
Assert.AreEqual("Hello", asset!.DisplayName, "Private [SerializeField] string should be set via SerializedProperty.");
Assert.AreEqual(42, asset.BaseNumber, "Inherited serialized field should be set via SerializedProperty.");
Assert.AreEqual("note!", asset.NestedNote, "Nested struct field should be set via SerializedProperty path.");
}
[Test]
public void Modify_ArrayResize_ThenAssignObjectRefs_ByGuidAndByPath()
{
// Create base asset first with no patches.
var create = new JObject
{
["action"] = "create",
["typeName"] = typeof(ManageScriptableObjectTestDefinition).FullName,
Async Test Infrastructure & Editor Readiness Status + new refresh_unity tool (#507) * Add editor readiness v2, refresh tool, and preflight guards * Detect external package changes and harden refresh retry * feat: add TestRunnerNoThrottle and async test running with background stall prevention - Add TestRunnerNoThrottle.cs: Sets editor to 'No Throttling' mode during test runs with SessionState persistence across domain reload - Add run_tests_async and get_test_job tools for non-blocking test execution - Add TestJobManager for async test job tracking with progress monitoring - Add ForceSynchronousImport to all AssetDatabase.Refresh() calls to prevent stalls - Mark DomainReloadResilienceTests as [Explicit] with documentation explaining the test infrastructure limitation (internal coroutine waits vs MCP socket polling) - MCP workflow is unaffected - socket messages provide external stimulus that keeps Unity responsive even when backgrounded * refactor: simplify and clean up code - Remove unused Newtonsoft.Json.Linq import from TestJobManager - Add throttling to SessionState persistence (once per second) to reduce overhead - Critical job state changes (start/finish) still persist immediately - Fix duplicate XML summary tag in DomainReloadResilienceTests * docs: add async test tools to README, document domain reload limitation - Add run_tests_async and get_test_job to main README tools list - Document background stall limitation for domain reload tests in DEV readme * ci: add separate job for domain reload tests Run [Explicit] domain_reload tests in their own job using -testCategory * ci: run domain reload tests in same job as regular tests Combines into single job with two test steps to reuse cached Library * fix: address coderabbit review issues - Fix TOCTOU race in TestJobManager.StartJob (single lock scope for check-and-set) - Store TestRunnerApi reference with HideAndDontSave to prevent GC/serialization issues * docs: update tool descriptions to prefer run_tests_async - run_tests_async is now marked as preferred for long-running suites - run_tests description notes it blocks and suggests async alternative * docs: update README screenshot to v8.6 UI * docs: add v8.6 UI screenshot * Update README for MCP version and instructions for v8.7 * fix: handle preflight busy signals and derive job status from test results - manage_asset, manage_gameobject, manage_scene now check preflight return value and propagate busy/retry signals to clients (fixes Sourcery #1) - TestJobManager.FinalizeCurrentJobFromRunFinished now sets job status to Failed when resultPayload.Failed > 0, not always Succeeded (fixes Sourcery #2) * fix: increase HTTP server startup timeout for dev mode When 'Force fresh server install' is enabled, uvx uses --no-cache --refresh which rebuilds the package and takes significantly longer to start. - Increase timeout from 10s to 45s when dev mode is enabled - Add informative log message explaining the longer startup time - Show actual timeout value in warning message * fix: derive job status from test results in FinalizeFromTask fallback Apply same logic as FinalizeCurrentJobFromRunFinished: check result.Failed > 0 to correctly mark jobs as Failed when tests fail, even in the fallback path when RunFinished callback is not delivered.
2026-01-04 04:42:32 +08:00
["folderPath"] = _runRoot,
["assetName"] = "Modify_Target",
["overwrite"] = true
};
var createRes = ToJObject(ManageScriptableObject.HandleCommand(create));
Assert.IsTrue(createRes.Value<bool>("success"), createRes.ToString());
_createdGuid = createRes["data"]?["guid"]?.ToString();
_createdAssetPath = createRes["data"]?["path"]?.ToString();
var matAGuid = AssetDatabase.AssetPathToGUID(_matAPath);
var modify = new JObject
{
["action"] = "modify",
["target"] = new JObject { ["guid"] = _createdGuid },
["patches"] = new JArray
{
// Resize list to 2
new JObject { ["propertyPath"] = "materials.Array.size", ["op"] = "array_resize", ["value"] = 2 },
// Assign element 0 by guid
new JObject
{
["propertyPath"] = "materials.Array.data[0]",
["op"] = "set",
["ref"] = new JObject { ["guid"] = matAGuid }
},
// Assign element 1 by path
new JObject
{
["propertyPath"] = "materials.Array.data[1]",
["op"] = "set",
["ref"] = new JObject { ["path"] = _matBPath }
}
}
};
var modRes = ToJObject(ManageScriptableObject.HandleCommand(modify));
Assert.IsTrue(modRes.Value<bool>("success"), modRes.ToString());
// Assert patch results are ok so failures are visible even if the tool returns success.
var results = modRes["data"]?["results"] as JArray;
Assert.IsNotNull(results, "Expected per-patch results in response.");
foreach (var r in results!)
{
Assert.IsTrue(r.Value<bool>("ok"), $"Patch failed: {r}");
}
var asset = AssetDatabase.LoadAssetAtPath<ManageScriptableObjectTestDefinition>(_createdAssetPath);
Assert.IsNotNull(asset);
Assert.AreEqual(2, asset!.Materials.Count, "List should be resized to 2.");
var matA = AssetDatabase.LoadAssetAtPath<Material>(_matAPath);
var matB = AssetDatabase.LoadAssetAtPath<Material>(_matBPath);
Assert.AreEqual(matA, asset.Materials[0], "Element 0 should be set by GUID ref.");
Assert.AreEqual(matB, asset.Materials[1], "Element 1 should be set by path ref.");
}
[Test]
public void Errors_InvalidAction_TypeNotFound_TargetNotFound()
{
// invalid action
var badAction = ToJObject(ManageScriptableObject.HandleCommand(new JObject { ["action"] = "nope" }));
Assert.IsFalse(badAction.Value<bool>("success"));
Assert.AreEqual("invalid_params", badAction.Value<string>("error"));
// type not found
var badType = ToJObject(ManageScriptableObject.HandleCommand(new JObject
{
["action"] = "create",
["typeName"] = "Nope.MissingType",
["folderPath"] = TempRoot,
["assetName"] = "X",
}));
Assert.IsFalse(badType.Value<bool>("success"));
Assert.AreEqual("type_not_found", badType.Value<string>("error"));
// target not found
var badTarget = ToJObject(ManageScriptableObject.HandleCommand(new JObject
{
["action"] = "modify",
["target"] = new JObject { ["guid"] = "00000000000000000000000000000000" },
["patches"] = new JArray(),
}));
Assert.IsFalse(badTarget.Value<bool>("success"));
Assert.AreEqual("target_not_found", badTarget.Value<string>("error"));
}
[Test]
public void Create_RejectsNonAssetsRootFolders()
{
var badPackages = ToJObject(ManageScriptableObject.HandleCommand(new JObject
{
["action"] = "create",
["typeName"] = typeof(ManageScriptableObjectTestDefinition).FullName,
["folderPath"] = "Packages/NotAllowed",
["assetName"] = "BadFolder",
["overwrite"] = true,
}));
Assert.IsFalse(badPackages.Value<bool>("success"));
Assert.AreEqual("invalid_folder_path", badPackages.Value<string>("error"));
var badAbsolute = ToJObject(ManageScriptableObject.HandleCommand(new JObject
{
["action"] = "create",
["typeName"] = typeof(ManageScriptableObjectTestDefinition).FullName,
["folderPath"] = "/tmp/not_allowed",
["assetName"] = "BadFolder2",
["overwrite"] = true,
}));
Assert.IsFalse(badAbsolute.Value<bool>("success"));
Assert.AreEqual("invalid_folder_path", badAbsolute.Value<string>("error"));
var badFileUri = ToJObject(ManageScriptableObject.HandleCommand(new JObject
{
["action"] = "create",
["typeName"] = typeof(ManageScriptableObjectTestDefinition).FullName,
["folderPath"] = "file:///tmp/not_allowed",
["assetName"] = "BadFolder3",
["overwrite"] = true,
}));
Assert.IsFalse(badFileUri.Value<bool>("success"));
Assert.AreEqual("invalid_folder_path", badFileUri.Value<string>("error"));
}
[Test]
public void Create_NormalizesRelativeAndBackslashPaths_AndAvoidsDoubleSlashesInResult()
{
var create = new JObject
{
["action"] = "create",
["typeName"] = typeof(ManageScriptableObjectTestDefinition).FullName,
["folderPath"] = @"Temp\ManageScriptableObjectTests\SlashProbe\\Deep",
["assetName"] = "SlashProbe",
["overwrite"] = true,
};
var res = ToJObject(ManageScriptableObject.HandleCommand(create));
Assert.IsTrue(res.Value<bool>("success"), res.ToString());
var path = res["data"]?["path"]?.ToString();
Assert.IsNotNull(path, "Expected path in response.");
Assert.IsTrue(path!.StartsWith("Assets/Temp/ManageScriptableObjectTests/SlashProbe/Deep", StringComparison.Ordinal),
$"Expected sanitized Assets-rooted path, got: {path}");
Assert.IsFalse(path.Contains("//", StringComparison.Ordinal), $"Path should not contain double slashes: {path}");
}
private static void EnsureFolder(string folderPath)
{
if (AssetDatabase.IsValidFolder(folderPath))
return;
// Only used for Assets/... paths in tests.
var sanitized = AssetPathUtility.SanitizeAssetPath(folderPath);
if (string.Equals(sanitized, "Assets", StringComparison.OrdinalIgnoreCase))
return;
var parts = sanitized.Split('/');
string current = "Assets";
for (int i = 1; i < parts.Length; i++)
{
var next = current + "/" + parts[i];
if (!AssetDatabase.IsValidFolder(next))
{
AssetDatabase.CreateFolder(current, parts[i]);
}
current = next;
}
}
private static JObject ToJObject(object result)
{
return result as JObject ?? JObject.FromObject(result);
}
Payload-safe paging for hierarchy/components + safer asset search + docs (#490) * Fix test teardown to avoid dropping MCP bridge CodexConfigHelperTests was calling MCPServiceLocator.Reset() in TearDown, which disposes the active bridge/transport during MCP-driven test runs. Replace with restoring only the mutated service (IPlatformService). * Avoid leaking PlatformService in CodexConfigHelperTests Capture the original IPlatformService before this fixture runs and restore it in TearDown. This preserves the MCP connection safety fix (no MCPServiceLocator.Reset()) while avoiding global state leakage to subsequent tests. * Fix SO MCP tooling: validate folder roots, normalize paths, expand tests; remove vestigial SO tools * Remove UnityMCPTests stress artifacts and ignore Assets/Temp * Ignore UnityMCPTests Assets/Temp only * Clarify array_resize fallback logic comments * Refactor: simplify action set and reuse slash sanitization * Enhance: preserve GUID on overwrite & support Vector/Color types in ScriptableObject tools * Fix: ensure asset name matches filename to suppress Unity warnings * Fix: resolve Unity warnings by ensuring asset name match and removing redundant import * Refactor: Validate assetName, strict object parsing for vectors, remove broken SO logic from ManageAsset * Hardening: reject Windows drive paths; clarify supported asset types * Delete FixscriptableobjecPlan.md * Paginate get_hierarchy and get_components to prevent large payload crashes * dev: add uvx dev-mode refresh + safer HTTP stop; fix server typing eval * Payload-safe paging defaults + docs; harden asset search; stabilize Codex tests * chore: align uvx args + coercion helpers; tighten safety guidance * chore: minor cleanup + stabilize EditMode SO tests
2025-12-29 12:57:57 +08:00
Feature/run tests summary clean (#501) * Optimize run_tests to return summary by default, reducing token usage by 98% - Add includeFailedTests parameter: returns only failed/skipped test details - Add includeDetails parameter: returns all test details (original behavior) - Default behavior now returns summary only (~150 tokens vs ~13k tokens) - Make results field optional in Python schema for backward compatibility Token savings: - Default: ~13k tokens saved (98.9% reduction) - With failures: minimal tokens (only non-passing tests) - Full details: same as before when explicitly requested This prevents context bloat for typical test runs where you only need pass/fail counts, while still allowing detailed debugging when needed. * Add warning when run_tests filters match no tests; fix test organization TDD Feature: - Add warning message when filter criteria match zero tests - New RunTestsTests.cs validates message formatting logic - Modified RunTests.cs to append "(No tests matched the specified filters)" when total=0 Test Organization Fixes: - Move MCPToolParameterTests.cs from EditMode/ to EditMode/Tools/ (matches folder hierarchy) - Fix inconsistent namespaces to MCPForUnityTests.Editor.{Subfolder}: - MCPToolParameterTests: Tests.EditMode → MCPForUnityTests.Editor.Tools - DomainReloadResilienceTests: Tests.EditMode.Tools → MCPForUnityTests.Editor.Tools - Matrix4x4ConverterTests: MCPForUnityTests.EditMode.Helpers → MCPForUnityTests.Editor.Helpers * Refactor test result message formatting * Simplify RunTests warning assertions * Tests: de-flake cold-start EditMode runs - Make ManageScriptableObjectTests setup yield-based with longer Unity-ready timeout - Mark DomainReloadResilienceTests explicit to avoid triggering domain reload during Run All
2026-01-02 12:36:45 +08:00
private static IEnumerator WaitForUnityReady(double timeoutSeconds = 30.0)
Payload-safe paging for hierarchy/components + safer asset search + docs (#490) * Fix test teardown to avoid dropping MCP bridge CodexConfigHelperTests was calling MCPServiceLocator.Reset() in TearDown, which disposes the active bridge/transport during MCP-driven test runs. Replace with restoring only the mutated service (IPlatformService). * Avoid leaking PlatformService in CodexConfigHelperTests Capture the original IPlatformService before this fixture runs and restore it in TearDown. This preserves the MCP connection safety fix (no MCPServiceLocator.Reset()) while avoiding global state leakage to subsequent tests. * Fix SO MCP tooling: validate folder roots, normalize paths, expand tests; remove vestigial SO tools * Remove UnityMCPTests stress artifacts and ignore Assets/Temp * Ignore UnityMCPTests Assets/Temp only * Clarify array_resize fallback logic comments * Refactor: simplify action set and reuse slash sanitization * Enhance: preserve GUID on overwrite & support Vector/Color types in ScriptableObject tools * Fix: ensure asset name matches filename to suppress Unity warnings * Fix: resolve Unity warnings by ensuring asset name match and removing redundant import * Refactor: Validate assetName, strict object parsing for vectors, remove broken SO logic from ManageAsset * Hardening: reject Windows drive paths; clarify supported asset types * Delete FixscriptableobjecPlan.md * Paginate get_hierarchy and get_components to prevent large payload crashes * dev: add uvx dev-mode refresh + safer HTTP stop; fix server typing eval * Payload-safe paging defaults + docs; harden asset search; stabilize Codex tests * chore: align uvx args + coercion helpers; tighten safety guidance * chore: minor cleanup + stabilize EditMode SO tests
2025-12-29 12:57:57 +08:00
{
// Some EditMode tests trigger script compilation/domain reload. Tools like ManageScriptableObject
// intentionally return "compiling_or_reloading" during these windows. Wait until Unity is stable
// to make tests deterministic.
double start = EditorApplication.timeSinceStartup;
while (EditorApplication.isCompiling || EditorApplication.isUpdating)
{
if (EditorApplication.timeSinceStartup - start > timeoutSeconds)
{
Assert.Fail($"Timed out waiting for Unity to finish compiling/updating (>{timeoutSeconds:0.0}s).");
}
Feature/run tests summary clean (#501) * Optimize run_tests to return summary by default, reducing token usage by 98% - Add includeFailedTests parameter: returns only failed/skipped test details - Add includeDetails parameter: returns all test details (original behavior) - Default behavior now returns summary only (~150 tokens vs ~13k tokens) - Make results field optional in Python schema for backward compatibility Token savings: - Default: ~13k tokens saved (98.9% reduction) - With failures: minimal tokens (only non-passing tests) - Full details: same as before when explicitly requested This prevents context bloat for typical test runs where you only need pass/fail counts, while still allowing detailed debugging when needed. * Add warning when run_tests filters match no tests; fix test organization TDD Feature: - Add warning message when filter criteria match zero tests - New RunTestsTests.cs validates message formatting logic - Modified RunTests.cs to append "(No tests matched the specified filters)" when total=0 Test Organization Fixes: - Move MCPToolParameterTests.cs from EditMode/ to EditMode/Tools/ (matches folder hierarchy) - Fix inconsistent namespaces to MCPForUnityTests.Editor.{Subfolder}: - MCPToolParameterTests: Tests.EditMode → MCPForUnityTests.Editor.Tools - DomainReloadResilienceTests: Tests.EditMode.Tools → MCPForUnityTests.Editor.Tools - Matrix4x4ConverterTests: MCPForUnityTests.EditMode.Helpers → MCPForUnityTests.Editor.Helpers * Refactor test result message formatting * Simplify RunTests warning assertions * Tests: de-flake cold-start EditMode runs - Make ManageScriptableObjectTests setup yield-based with longer Unity-ready timeout - Mark DomainReloadResilienceTests explicit to avoid triggering domain reload during Run All
2026-01-02 12:36:45 +08:00
yield return null; // yield to the editor loop so importing/compiling can actually progress
Payload-safe paging for hierarchy/components + safer asset search + docs (#490) * Fix test teardown to avoid dropping MCP bridge CodexConfigHelperTests was calling MCPServiceLocator.Reset() in TearDown, which disposes the active bridge/transport during MCP-driven test runs. Replace with restoring only the mutated service (IPlatformService). * Avoid leaking PlatformService in CodexConfigHelperTests Capture the original IPlatformService before this fixture runs and restore it in TearDown. This preserves the MCP connection safety fix (no MCPServiceLocator.Reset()) while avoiding global state leakage to subsequent tests. * Fix SO MCP tooling: validate folder roots, normalize paths, expand tests; remove vestigial SO tools * Remove UnityMCPTests stress artifacts and ignore Assets/Temp * Ignore UnityMCPTests Assets/Temp only * Clarify array_resize fallback logic comments * Refactor: simplify action set and reuse slash sanitization * Enhance: preserve GUID on overwrite & support Vector/Color types in ScriptableObject tools * Fix: ensure asset name matches filename to suppress Unity warnings * Fix: resolve Unity warnings by ensuring asset name match and removing redundant import * Refactor: Validate assetName, strict object parsing for vectors, remove broken SO logic from ManageAsset * Hardening: reject Windows drive paths; clarify supported asset types * Delete FixscriptableobjecPlan.md * Paginate get_hierarchy and get_components to prevent large payload crashes * dev: add uvx dev-mode refresh + safer HTTP stop; fix server typing eval * Payload-safe paging defaults + docs; harden asset search; stabilize Codex tests * chore: align uvx args + coercion helpers; tighten safety guidance * chore: minor cleanup + stabilize EditMode SO tests
2025-12-29 12:57:57 +08:00
}
}
}
}