@atelierai/uco 1.0.7 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/package.json +1 -1
  3. package/vendor/plugin/com.atelierai.unity.copilot/Editor/DependencyResolver/NuGetConfig.cs +132 -132
  4. package/vendor/plugin/com.atelierai.unity.copilot/Editor/DependencyResolver/NuGetDependencyResolver.cs +237 -237
  5. package/vendor/plugin/com.atelierai.unity.copilot/Editor/DependencyResolver/NuGetDownloader.cs +82 -82
  6. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Resource/MenuItems.cs +247 -247
  7. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Resource/ToolGroups.cs +153 -153
  8. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/SystemTool/Skills.Create.SkillBody.cs +155 -155
  9. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Tool/Console.GetLogs.cs +95 -95
  10. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Tool/Docs.HttpFetcher.cs +139 -139
  11. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Tool/Instance.ListAll.cs +72 -72
  12. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Tool/PathReadHelper.cs +106 -106
  13. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Tool/Script.Validate.cs +252 -252
  14. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Tool/Tests/TestResultCollector.cs +537 -537
  15. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Tool/Tests.cs +400 -400
  16. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Branding/ProductInfo.cs +62 -62
  17. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/CopilotServerManager.cs +1034 -1034
  18. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Skills/Skill_InitialSetup.cs +197 -197
  19. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Startup.Editor.cs +201 -201
  20. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Startup.cs +67 -67
  21. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/CopilotListWindowBase.cs +393 -393
  22. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/CopilotWindowBase.cs +113 -113
  23. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/MainWindowEditor.Connection.cs +3 -3
  24. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/MainWindowEditor.CopilotFeatures.cs +195 -195
  25. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/MainWindowEditor.CopilotServer.cs +20 -20
  26. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/MainWindowEditor.CreateGUI.cs +354 -354
  27. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/MainWindowEditor.cs +78 -78
  28. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/MainWindowInitializer.cs +47 -47
  29. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/SerializationCheckWindow.cs +190 -190
  30. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UnityCopilotPluginEditor.Build.cs +91 -91
  31. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UnityCopilotPluginEditor.Config.cs +298 -298
  32. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UnityCopilotPluginEditor.Static.cs +296 -296
  33. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UnityCopilotPluginEditor.cs +69 -69
  34. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/PackageUtils.cs +168 -168
  35. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/PrefsKeyMigration.cs +119 -119
  36. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/SafeDefaultsGuard.cs +180 -180
  37. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/ScriptUtils.cs +229 -229
  38. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/ToolsManifestGenerator.cs +200 -200
  39. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/UnityAuthoringAdapters.cs +1467 -1467
  40. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/UnityAuthoringSafetyReloadGuard.cs +65 -65
  41. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/UnityCopilotUpdateProjectSettings.cs +66 -66
  42. package/vendor/plugin/com.atelierai.unity.copilot/Plugins/ReflectorNet.dll +0 -0
  43. package/vendor/plugin/com.atelierai.unity.copilot/Plugins/Uco.Framework.Common.dll +0 -0
  44. package/vendor/plugin/com.atelierai.unity.copilot/Plugins/Uco.Framework.dll +0 -0
  45. package/vendor/plugin/com.atelierai.unity.copilot/Runtime/Converter/Json/Structures/EntityIdConverter.cs +120 -120
  46. package/vendor/plugin/com.atelierai.unity.copilot/Runtime/Data/GameObjectMetadata.cs +110 -110
  47. package/vendor/plugin/com.atelierai.unity.copilot/Runtime/Data/GameObjectMetadata.pre-Unity.6.5.cs +110 -110
  48. package/vendor/plugin/com.atelierai.unity.copilot/Runtime/Unity/Logs/FileLogStorage.cs +547 -547
  49. package/vendor/plugin/com.atelierai.unity.copilot/Runtime/UnityCopilotPlugin.Build.cs +243 -243
  50. package/vendor/plugin/com.atelierai.unity.copilot/Runtime/UnityCopilotPlugin.Config.cs +3 -3
  51. package/vendor/plugin/com.atelierai.unity.copilot/Runtime/UnityCopilotPlugin.cs +295 -295
  52. package/vendor/plugin/com.atelierai.unity.copilot/Runtime/UnityCopilotPluginBuilder.cs +105 -105
  53. package/vendor/plugin/com.atelierai.unity.copilot/Runtime/UnityCopilotPluginRuntime.Static.cs +155 -155
  54. package/vendor/plugin/com.atelierai.unity.copilot/Runtime/UnityCopilotPluginRuntime.cs +59 -59
  55. package/vendor/plugin/com.atelierai.unity.copilot/Runtime/Utils/EnvironmentUtils.cs +11 -11
  56. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/AtomicApi/AtomicApiTestFixtures.cs +99 -99
  57. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/AtomicApi/TryModifyAtTests.cs +227 -227
  58. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/AuthoringSafetyPilotTests.cs +1050 -1050
  59. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/DependencyResolver/NuGetLegacyMigrationTests.cs +304 -304
  60. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Environment/EnvironmentUtilsTests.cs +1 -1
  61. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/BlacklistTypeTests.cs +416 -416
  62. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/DataFieldScriptableObjectPopulationTests.cs +172 -172
  63. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/DataFieldScriptableObjectPopulationTests.pre-Unity.6.5.cs +169 -169
  64. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/DataPopulationTests.cs +182 -182
  65. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/DataPopulationTests.pre-Unity.6.5.cs +179 -179
  66. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/DataPropertyPopulationTests.cs +175 -175
  67. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/DataPropertyPopulationTests.pre-Unity.6.5.cs +174 -174
  68. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/DataPropertyScriptableObjectPopulationTests.cs +171 -171
  69. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/DataPropertyScriptableObjectPopulationTests.pre-Unity.6.5.cs +170 -170
  70. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Assets/AssetsCreateFolderTests.cs +243 -243
  71. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Assets/AssetsMaterialTests.cs +101 -101
  72. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Assets/AssetsPrefabCreateTests.cs +348 -348
  73. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Assets/AssetsPrefabCreateTests.pre-Unity.6.5.cs +348 -348
  74. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Assets/AssetsShaderTests.cs +194 -194
  75. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/PathBasedToolTests.cs +573 -573
  76. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/PathBasedToolTests.pre-Unity.6.5.cs +513 -513
  77. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Screenshot/ScreenshotCameraTests.cs +154 -154
  78. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Screenshot/ScreenshotCameraTests.pre-Unity.6.5.cs +154 -154
  79. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Screenshot/ScreenshotGameViewTests.cs +164 -164
  80. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Screenshot/ScreenshotSceneViewTests.cs +155 -155
  81. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/ToolParameterTests.cs +56 -56
  82. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/ToolThreadSafetyTests.cs +651 -651
  83. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/ToolThreadSafetyTests.pre-Unity.6.5.cs +651 -651
  84. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ToolBatchExecutionIntegrationTests.cs +407 -407
  85. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/{McpPluginTests.cs → UcoPluginTests.cs} +105 -105
  86. package/vendor/plugin/com.atelierai.unity.copilot/package.json +1 -1
  87. /package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/{McpPluginTests.cs.meta → UcoPluginTests.cs.meta} +0 -0
@@ -1,348 +1,348 @@
1
- /*
2
- ┌──────────────────────────────────────────────────────────────────┐
3
- │ Author: Ivan Murzak (https://github.com/IvanMurzak) │
4
- │ Repository: GitHub (https://github.com/IvanMurzak/Unity-MCP) │
5
- │ Copyright (c) 2025 Ivan Murzak │
6
- │ Licensed under the Apache License, Version 2.0. │
7
- │ See the LICENSE file in the project root for more information. │
8
- └──────────────────────────────────────────────────────────────────┘
9
- */
10
-
11
- #nullable enable
12
- #if !UNITY_6000_5_OR_NEWER
13
- using System.Collections;
14
- using com.AtelierAI.Unity.Copilot.Editor.API;
15
- using NUnit.Framework;
16
- using UnityEditor;
17
- using UnityEngine;
18
- using UnityEngine.TestTools;
19
-
20
- namespace com.AtelierAI.Unity.Copilot.Editor.Tests
21
- {
22
- public class AssetsPrefabCreateTests : BaseTest
23
- {
24
- const string TestFolderName = "Unity-MCP-Test-PrefabCreate";
25
- const string TestFolder = "Assets/" + TestFolderName;
26
-
27
- [TearDown]
28
- public void PrefabTearDown()
29
- {
30
- if (AssetDatabase.IsValidFolder(TestFolder))
31
- AssetDatabase.DeleteAsset(TestFolder);
32
- }
33
-
34
- void EnsureTestFolder()
35
- {
36
- if (!AssetDatabase.IsValidFolder(TestFolder))
37
- AssetDatabase.CreateFolder("Assets", TestFolderName);
38
- }
39
-
40
- // ================================================================
41
- // Main thread — create from scene GameObject
42
- // ================================================================
43
-
44
- [UnityTest]
45
- public IEnumerator Prefab_Create_Connected_MainThread()
46
- {
47
- EnsureTestFolder();
48
- var prefabPath = $"{TestFolder}/Connected_Main.prefab";
49
- var go = new GameObject("TestGO_Connected_Main");
50
- var id = go.GetInstanceID();
51
-
52
- yield return RunToolMainThreadCoop(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
53
- $@"{{""prefabAssetPath"":""{prefabPath}"",""gameObjectRef"":{{""instanceID"":{id}}},""connectGameObjectToPrefab"":true}}");
54
-
55
- var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
56
- Assert.IsNotNull(prefab, $"Prefab should be created at: {prefabPath}");
57
- Assert.IsTrue(PrefabUtility.IsPartOfPrefabInstance(go),
58
- "Scene GameObject should be connected to the prefab (prefab instance).");
59
- }
60
-
61
- [UnityTest]
62
- public IEnumerator Prefab_Create_NotConnected_MainThread()
63
- {
64
- EnsureTestFolder();
65
- var prefabPath = $"{TestFolder}/Disconnected_Main.prefab";
66
- var go = new GameObject("TestGO_Disconnected_Main");
67
- var id = go.GetInstanceID();
68
-
69
- yield return RunToolMainThreadCoop(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
70
- $@"{{""prefabAssetPath"":""{prefabPath}"",""gameObjectRef"":{{""instanceID"":{id}}},""connectGameObjectToPrefab"":false}}");
71
-
72
- var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
73
- Assert.IsNotNull(prefab, $"Prefab should be created at: {prefabPath}");
74
- Assert.IsFalse(PrefabUtility.IsPartOfPrefabInstance(go),
75
- "Scene GameObject should NOT be connected to the prefab.");
76
- }
77
-
78
- [UnityTest]
79
- public IEnumerator Prefab_Create_DefaultConnected_MainThread()
80
- {
81
- EnsureTestFolder();
82
- var prefabPath = $"{TestFolder}/Default_Main.prefab";
83
- var go = new GameObject("TestGO_Default_Main");
84
- var id = go.GetInstanceID();
85
-
86
- yield return RunToolMainThreadCoop(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
87
- $@"{{""prefabAssetPath"":""{prefabPath}"",""gameObjectRef"":{{""instanceID"":{id}}}}}");
88
-
89
- var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
90
- Assert.IsNotNull(prefab, $"Prefab should be created at: {prefabPath}");
91
- Assert.IsTrue(PrefabUtility.IsPartOfPrefabInstance(go),
92
- "Default should connect scene GameObject to the prefab.");
93
- }
94
-
95
- [UnityTest]
96
- public IEnumerator Prefab_Create_AutoCreatesFolders_MainThread()
97
- {
98
- EnsureTestFolder();
99
- var prefabPath = $"{TestFolder}/Nested/Deep/Folder/AutoCreated.prefab";
100
- var go = new GameObject("TestGO_Nested_Main");
101
- var id = go.GetInstanceID();
102
-
103
- yield return RunToolMainThreadCoop(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
104
- $@"{{""prefabAssetPath"":""{prefabPath}"",""gameObjectRef"":{{""instanceID"":{id}}}}}");
105
-
106
- var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
107
- Assert.IsNotNull(prefab, $"Prefab should be created at nested path: {prefabPath}");
108
- Assert.IsTrue(AssetDatabase.IsValidFolder($"{TestFolder}/Nested/Deep/Folder"),
109
- "Nested folders should have been created.");
110
- }
111
-
112
- [UnityTest]
113
- public IEnumerator Prefab_Create_WithComponents_MainThread()
114
- {
115
- EnsureTestFolder();
116
- var prefabPath = $"{TestFolder}/Components_Main.prefab";
117
- var go = new GameObject("TestGO_Components_Main");
118
- go.AddComponent<BoxCollider>();
119
- go.AddComponent<Rigidbody>();
120
- var id = go.GetInstanceID();
121
-
122
- yield return RunToolMainThreadCoop(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
123
- $@"{{""prefabAssetPath"":""{prefabPath}"",""gameObjectRef"":{{""instanceID"":{id}}},""connectGameObjectToPrefab"":false}}");
124
-
125
- var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
126
- Assert.IsNotNull(prefab, $"Prefab should be created at: {prefabPath}");
127
- Assert.IsNotNull(prefab!.GetComponent<BoxCollider>(), "Prefab should have BoxCollider.");
128
- Assert.IsNotNull(prefab.GetComponent<Rigidbody>(), "Prefab should have Rigidbody.");
129
- }
130
-
131
- // ================================================================
132
- // Main thread — Prefab Variant from scene prefab instance
133
- // ================================================================
134
-
135
- [UnityTest]
136
- public IEnumerator Prefab_CreateVariant_FromScenePrefabInstance_MainThread()
137
- {
138
- EnsureTestFolder();
139
-
140
- // Step 1: create a base prefab
141
- var basePath = $"{TestFolder}/Base_Variant.prefab";
142
- var baseGo = new GameObject("TestGO_Base_Variant");
143
- baseGo.AddComponent<BoxCollider>();
144
- var baseId = baseGo.GetInstanceID();
145
-
146
- yield return RunToolMainThreadCoop(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
147
- $@"{{""prefabAssetPath"":""{basePath}"",""gameObjectRef"":{{""instanceID"":{baseId}}},""connectGameObjectToPrefab"":true}}");
148
-
149
- // baseGo is now a prefab instance — modify it and save as variant
150
- baseGo.AddComponent<SphereCollider>();
151
- var variantPath = $"{TestFolder}/Variant_FromInstance.prefab";
152
-
153
- yield return RunToolMainThreadCoop(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
154
- $@"{{""prefabAssetPath"":""{variantPath}"",""gameObjectRef"":{{""instanceID"":{baseId}}},""connectGameObjectToPrefab"":true}}");
155
-
156
- var variant = AssetDatabase.LoadAssetAtPath<GameObject>(variantPath);
157
- Assert.IsNotNull(variant, $"Variant prefab should be created at: {variantPath}");
158
- Assert.IsTrue(PrefabUtility.IsPartOfVariantPrefab(variant!),
159
- "Created prefab should be a Prefab Variant.");
160
- }
161
-
162
- // ================================================================
163
- // Main thread — Prefab Variant from asset path
164
- // ================================================================
165
-
166
- [UnityTest]
167
- public IEnumerator Prefab_CreateVariant_FromAssetPath_MainThread()
168
- {
169
- EnsureTestFolder();
170
-
171
- // Step 1: create a base prefab
172
- var basePath = $"{TestFolder}/Base_AssetVariant.prefab";
173
- var baseGo = new GameObject("TestGO_Base_AssetVariant");
174
- baseGo.AddComponent<BoxCollider>();
175
- var baseId = baseGo.GetInstanceID();
176
-
177
- yield return RunToolMainThreadCoop(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
178
- $@"{{""prefabAssetPath"":""{basePath}"",""gameObjectRef"":{{""instanceID"":{baseId}}},""connectGameObjectToPrefab"":false}}");
179
-
180
- // Step 2: create a variant from the asset path
181
- var variantPath = $"{TestFolder}/Variant_FromAsset.prefab";
182
- yield return RunToolMainThreadCoop(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
183
- $@"{{""prefabAssetPath"":""{variantPath}"",""sourcePrefabAssetPath"":""{basePath}""}}");
184
-
185
- var variant = AssetDatabase.LoadAssetAtPath<GameObject>(variantPath);
186
- Assert.IsNotNull(variant, $"Variant prefab should be created at: {variantPath}");
187
- Assert.IsTrue(PrefabUtility.IsPartOfVariantPrefab(variant!),
188
- "Created prefab from asset path should be a Prefab Variant.");
189
- Assert.IsNotNull(variant!.GetComponent<BoxCollider>(),
190
- "Variant should inherit BoxCollider from the base prefab.");
191
- }
192
-
193
- // ================================================================
194
- // Background thread tests
195
- // ================================================================
196
-
197
- [UnityTest]
198
- public IEnumerator Prefab_Create_Connected_BackgroundThread()
199
- {
200
- EnsureTestFolder();
201
- var prefabPath = $"{TestFolder}/Connected_Bg.prefab";
202
- var go = new GameObject("TestGO_Connected_Bg");
203
- var id = go.GetInstanceID();
204
-
205
- yield return RunToolFromBackgroundThread(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
206
- $@"{{""prefabAssetPath"":""{prefabPath}"",""gameObjectRef"":{{""instanceID"":{id}}},""connectGameObjectToPrefab"":true}}");
207
-
208
- var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
209
- Assert.IsNotNull(prefab, $"Prefab should be created at: {prefabPath}");
210
- Assert.IsTrue(PrefabUtility.IsPartOfPrefabInstance(go),
211
- "Scene GameObject should be connected to the prefab (background thread).");
212
- }
213
-
214
- [UnityTest]
215
- public IEnumerator Prefab_Create_NotConnected_BackgroundThread()
216
- {
217
- EnsureTestFolder();
218
- var prefabPath = $"{TestFolder}/Disconnected_Bg.prefab";
219
- var go = new GameObject("TestGO_Disconnected_Bg");
220
- var id = go.GetInstanceID();
221
-
222
- yield return RunToolFromBackgroundThread(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
223
- $@"{{""prefabAssetPath"":""{prefabPath}"",""gameObjectRef"":{{""instanceID"":{id}}},""connectGameObjectToPrefab"":false}}");
224
-
225
- var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
226
- Assert.IsNotNull(prefab, $"Prefab should be created at: {prefabPath}");
227
- Assert.IsFalse(PrefabUtility.IsPartOfPrefabInstance(go),
228
- "Scene GameObject should NOT be connected to the prefab (background thread).");
229
- }
230
-
231
- [UnityTest]
232
- public IEnumerator Prefab_Create_AutoCreatesFolders_BackgroundThread()
233
- {
234
- EnsureTestFolder();
235
- var prefabPath = $"{TestFolder}/NestedBg/DeepBg/AutoCreatedBg.prefab";
236
- var go = new GameObject("TestGO_Nested_Bg");
237
- var id = go.GetInstanceID();
238
-
239
- yield return RunToolFromBackgroundThread(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
240
- $@"{{""prefabAssetPath"":""{prefabPath}"",""gameObjectRef"":{{""instanceID"":{id}}}}}");
241
-
242
- var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
243
- Assert.IsNotNull(prefab, $"Prefab should be created at nested path (background thread): {prefabPath}");
244
- }
245
-
246
- [UnityTest]
247
- public IEnumerator Prefab_CreateVariant_FromAssetPath_BackgroundThread()
248
- {
249
- EnsureTestFolder();
250
-
251
- // Step 1: create a base prefab (on main thread for setup)
252
- var basePath = $"{TestFolder}/Base_AssetVariant_Bg.prefab";
253
- var baseGo = new GameObject("TestGO_Base_AssetVariant_Bg");
254
- var baseId = baseGo.GetInstanceID();
255
-
256
- yield return RunToolMainThreadCoop(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
257
- $@"{{""prefabAssetPath"":""{basePath}"",""gameObjectRef"":{{""instanceID"":{baseId}}},""connectGameObjectToPrefab"":false}}");
258
-
259
- // Step 2: create variant from background thread
260
- var variantPath = $"{TestFolder}/Variant_FromAsset_Bg.prefab";
261
- yield return RunToolFromBackgroundThread(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
262
- $@"{{""prefabAssetPath"":""{variantPath}"",""sourcePrefabAssetPath"":""{basePath}""}}");
263
-
264
- var variant = AssetDatabase.LoadAssetAtPath<GameObject>(variantPath);
265
- Assert.IsNotNull(variant, $"Variant prefab should be created at: {variantPath}");
266
- Assert.IsTrue(PrefabUtility.IsPartOfVariantPrefab(variant!),
267
- "Created prefab from asset path should be a Prefab Variant (background thread).");
268
- }
269
-
270
- // ================================================================
271
- // Error cases
272
- // ================================================================
273
- // Console separation (COCli-07): the runner/manager failure logs these
274
- // tests used to pin with LogAssert no longer reach the Unity Console
275
- // while the plugin diagnostics channel is installed. Each error test
276
- // asserts the same evidence through the LogCollector API after the
277
- // call (see BaseTest.AssertToolErrorDiagnostics).
278
-
279
- [UnityTest]
280
- public IEnumerator Prefab_Create_EmptyPath_ReturnsError()
281
- {
282
- var go = new GameObject("TestGO_EmptyPath");
283
- var id = go.GetInstanceID();
284
-
285
- var jsonResult = RunToolRaw(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
286
- $@"{{""prefabAssetPath"":"""",""gameObjectRef"":{{""instanceID"":{id}}}}}");
287
-
288
- StringAssert.Contains("Prefab path is empty", jsonResult);
289
- AssertToolErrorDiagnostics("Prefab path is empty");
290
- yield return null;
291
- }
292
-
293
- [UnityTest]
294
- public IEnumerator Prefab_Create_InvalidExtension_ReturnsError()
295
- {
296
- EnsureTestFolder();
297
- var go = new GameObject("TestGO_InvalidExt");
298
- var id = go.GetInstanceID();
299
-
300
- var jsonResult = RunToolRaw(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
301
- $@"{{""prefabAssetPath"":""{TestFolder}/NotAPrefab.txt"",""gameObjectRef"":{{""instanceID"":{id}}}}}");
302
-
303
- StringAssert.Contains("invalid", jsonResult);
304
- AssertToolErrorDiagnostics("is invalid");
305
- yield return null;
306
- }
307
-
308
- [UnityTest]
309
- public IEnumerator Prefab_Create_InvalidGameObjectRef_ReturnsError()
310
- {
311
- EnsureTestFolder();
312
-
313
- var jsonResult = RunToolRaw(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
314
- $@"{{""prefabAssetPath"":""{TestFolder}/ShouldFail.prefab"",""gameObjectRef"":{{""instanceID"":-999999}}}}");
315
-
316
- StringAssert.Contains("Not found", jsonResult);
317
- AssertToolErrorDiagnostics("Not found");
318
- yield return null;
319
- }
320
-
321
- [UnityTest]
322
- public IEnumerator Prefab_Create_NoGameObjectRefOrSourcePath_ReturnsError()
323
- {
324
- EnsureTestFolder();
325
-
326
- var jsonResult = RunToolRaw(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
327
- $@"{{""prefabAssetPath"":""{TestFolder}/ShouldFail.prefab""}}");
328
-
329
- StringAssert.Contains("must be provided", jsonResult);
330
- AssertToolErrorDiagnostics("must be provided");
331
- yield return null;
332
- }
333
-
334
- [UnityTest]
335
- public IEnumerator Prefab_Create_InvalidSourcePrefabPath_ReturnsError()
336
- {
337
- EnsureTestFolder();
338
-
339
- var jsonResult = RunToolRaw(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
340
- $@"{{""prefabAssetPath"":""{TestFolder}/ShouldFail.prefab"",""sourcePrefabAssetPath"":""{TestFolder}/NonExistent.prefab""}}");
341
-
342
- StringAssert.Contains("not found", jsonResult);
343
- AssertToolErrorDiagnostics("not found");
344
- yield return null;
345
- }
346
- }
347
- }
348
- #endif
1
+ /*
2
+ ┌──────────────────────────────────────────────────────────────────┐
3
+ │ Author: Ivan Murzak (https://github.com/IvanMurzak) │
4
+ │ Repository: GitHub (https://github.com/IvanMurzak/Unity-MCP) │
5
+ │ Copyright (c) 2025 Ivan Murzak │
6
+ │ Licensed under the Apache License, Version 2.0. │
7
+ │ See the LICENSE file in the project root for more information. │
8
+ └──────────────────────────────────────────────────────────────────┘
9
+ */
10
+
11
+ #nullable enable
12
+ #if !UNITY_6000_5_OR_NEWER
13
+ using System.Collections;
14
+ using com.AtelierAI.Unity.Copilot.Editor.API;
15
+ using NUnit.Framework;
16
+ using UnityEditor;
17
+ using UnityEngine;
18
+ using UnityEngine.TestTools;
19
+
20
+ namespace com.AtelierAI.Unity.Copilot.Editor.Tests
21
+ {
22
+ public class AssetsPrefabCreateTests : BaseTest
23
+ {
24
+ const string TestFolderName = "Unity-Uco-Test-PrefabCreate";
25
+ const string TestFolder = "Assets/" + TestFolderName;
26
+
27
+ [TearDown]
28
+ public void PrefabTearDown()
29
+ {
30
+ if (AssetDatabase.IsValidFolder(TestFolder))
31
+ AssetDatabase.DeleteAsset(TestFolder);
32
+ }
33
+
34
+ void EnsureTestFolder()
35
+ {
36
+ if (!AssetDatabase.IsValidFolder(TestFolder))
37
+ AssetDatabase.CreateFolder("Assets", TestFolderName);
38
+ }
39
+
40
+ // ================================================================
41
+ // Main thread — create from scene GameObject
42
+ // ================================================================
43
+
44
+ [UnityTest]
45
+ public IEnumerator Prefab_Create_Connected_MainThread()
46
+ {
47
+ EnsureTestFolder();
48
+ var prefabPath = $"{TestFolder}/Connected_Main.prefab";
49
+ var go = new GameObject("TestGO_Connected_Main");
50
+ var id = go.GetInstanceID();
51
+
52
+ yield return RunToolMainThreadCoop(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
53
+ $@"{{""prefabAssetPath"":""{prefabPath}"",""gameObjectRef"":{{""instanceID"":{id}}},""connectGameObjectToPrefab"":true}}");
54
+
55
+ var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
56
+ Assert.IsNotNull(prefab, $"Prefab should be created at: {prefabPath}");
57
+ Assert.IsTrue(PrefabUtility.IsPartOfPrefabInstance(go),
58
+ "Scene GameObject should be connected to the prefab (prefab instance).");
59
+ }
60
+
61
+ [UnityTest]
62
+ public IEnumerator Prefab_Create_NotConnected_MainThread()
63
+ {
64
+ EnsureTestFolder();
65
+ var prefabPath = $"{TestFolder}/Disconnected_Main.prefab";
66
+ var go = new GameObject("TestGO_Disconnected_Main");
67
+ var id = go.GetInstanceID();
68
+
69
+ yield return RunToolMainThreadCoop(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
70
+ $@"{{""prefabAssetPath"":""{prefabPath}"",""gameObjectRef"":{{""instanceID"":{id}}},""connectGameObjectToPrefab"":false}}");
71
+
72
+ var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
73
+ Assert.IsNotNull(prefab, $"Prefab should be created at: {prefabPath}");
74
+ Assert.IsFalse(PrefabUtility.IsPartOfPrefabInstance(go),
75
+ "Scene GameObject should NOT be connected to the prefab.");
76
+ }
77
+
78
+ [UnityTest]
79
+ public IEnumerator Prefab_Create_DefaultConnected_MainThread()
80
+ {
81
+ EnsureTestFolder();
82
+ var prefabPath = $"{TestFolder}/Default_Main.prefab";
83
+ var go = new GameObject("TestGO_Default_Main");
84
+ var id = go.GetInstanceID();
85
+
86
+ yield return RunToolMainThreadCoop(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
87
+ $@"{{""prefabAssetPath"":""{prefabPath}"",""gameObjectRef"":{{""instanceID"":{id}}}}}");
88
+
89
+ var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
90
+ Assert.IsNotNull(prefab, $"Prefab should be created at: {prefabPath}");
91
+ Assert.IsTrue(PrefabUtility.IsPartOfPrefabInstance(go),
92
+ "Default should connect scene GameObject to the prefab.");
93
+ }
94
+
95
+ [UnityTest]
96
+ public IEnumerator Prefab_Create_AutoCreatesFolders_MainThread()
97
+ {
98
+ EnsureTestFolder();
99
+ var prefabPath = $"{TestFolder}/Nested/Deep/Folder/AutoCreated.prefab";
100
+ var go = new GameObject("TestGO_Nested_Main");
101
+ var id = go.GetInstanceID();
102
+
103
+ yield return RunToolMainThreadCoop(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
104
+ $@"{{""prefabAssetPath"":""{prefabPath}"",""gameObjectRef"":{{""instanceID"":{id}}}}}");
105
+
106
+ var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
107
+ Assert.IsNotNull(prefab, $"Prefab should be created at nested path: {prefabPath}");
108
+ Assert.IsTrue(AssetDatabase.IsValidFolder($"{TestFolder}/Nested/Deep/Folder"),
109
+ "Nested folders should have been created.");
110
+ }
111
+
112
+ [UnityTest]
113
+ public IEnumerator Prefab_Create_WithComponents_MainThread()
114
+ {
115
+ EnsureTestFolder();
116
+ var prefabPath = $"{TestFolder}/Components_Main.prefab";
117
+ var go = new GameObject("TestGO_Components_Main");
118
+ go.AddComponent<BoxCollider>();
119
+ go.AddComponent<Rigidbody>();
120
+ var id = go.GetInstanceID();
121
+
122
+ yield return RunToolMainThreadCoop(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
123
+ $@"{{""prefabAssetPath"":""{prefabPath}"",""gameObjectRef"":{{""instanceID"":{id}}},""connectGameObjectToPrefab"":false}}");
124
+
125
+ var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
126
+ Assert.IsNotNull(prefab, $"Prefab should be created at: {prefabPath}");
127
+ Assert.IsNotNull(prefab!.GetComponent<BoxCollider>(), "Prefab should have BoxCollider.");
128
+ Assert.IsNotNull(prefab.GetComponent<Rigidbody>(), "Prefab should have Rigidbody.");
129
+ }
130
+
131
+ // ================================================================
132
+ // Main thread — Prefab Variant from scene prefab instance
133
+ // ================================================================
134
+
135
+ [UnityTest]
136
+ public IEnumerator Prefab_CreateVariant_FromScenePrefabInstance_MainThread()
137
+ {
138
+ EnsureTestFolder();
139
+
140
+ // Step 1: create a base prefab
141
+ var basePath = $"{TestFolder}/Base_Variant.prefab";
142
+ var baseGo = new GameObject("TestGO_Base_Variant");
143
+ baseGo.AddComponent<BoxCollider>();
144
+ var baseId = baseGo.GetInstanceID();
145
+
146
+ yield return RunToolMainThreadCoop(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
147
+ $@"{{""prefabAssetPath"":""{basePath}"",""gameObjectRef"":{{""instanceID"":{baseId}}},""connectGameObjectToPrefab"":true}}");
148
+
149
+ // baseGo is now a prefab instance — modify it and save as variant
150
+ baseGo.AddComponent<SphereCollider>();
151
+ var variantPath = $"{TestFolder}/Variant_FromInstance.prefab";
152
+
153
+ yield return RunToolMainThreadCoop(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
154
+ $@"{{""prefabAssetPath"":""{variantPath}"",""gameObjectRef"":{{""instanceID"":{baseId}}},""connectGameObjectToPrefab"":true}}");
155
+
156
+ var variant = AssetDatabase.LoadAssetAtPath<GameObject>(variantPath);
157
+ Assert.IsNotNull(variant, $"Variant prefab should be created at: {variantPath}");
158
+ Assert.IsTrue(PrefabUtility.IsPartOfVariantPrefab(variant!),
159
+ "Created prefab should be a Prefab Variant.");
160
+ }
161
+
162
+ // ================================================================
163
+ // Main thread — Prefab Variant from asset path
164
+ // ================================================================
165
+
166
+ [UnityTest]
167
+ public IEnumerator Prefab_CreateVariant_FromAssetPath_MainThread()
168
+ {
169
+ EnsureTestFolder();
170
+
171
+ // Step 1: create a base prefab
172
+ var basePath = $"{TestFolder}/Base_AssetVariant.prefab";
173
+ var baseGo = new GameObject("TestGO_Base_AssetVariant");
174
+ baseGo.AddComponent<BoxCollider>();
175
+ var baseId = baseGo.GetInstanceID();
176
+
177
+ yield return RunToolMainThreadCoop(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
178
+ $@"{{""prefabAssetPath"":""{basePath}"",""gameObjectRef"":{{""instanceID"":{baseId}}},""connectGameObjectToPrefab"":false}}");
179
+
180
+ // Step 2: create a variant from the asset path
181
+ var variantPath = $"{TestFolder}/Variant_FromAsset.prefab";
182
+ yield return RunToolMainThreadCoop(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
183
+ $@"{{""prefabAssetPath"":""{variantPath}"",""sourcePrefabAssetPath"":""{basePath}""}}");
184
+
185
+ var variant = AssetDatabase.LoadAssetAtPath<GameObject>(variantPath);
186
+ Assert.IsNotNull(variant, $"Variant prefab should be created at: {variantPath}");
187
+ Assert.IsTrue(PrefabUtility.IsPartOfVariantPrefab(variant!),
188
+ "Created prefab from asset path should be a Prefab Variant.");
189
+ Assert.IsNotNull(variant!.GetComponent<BoxCollider>(),
190
+ "Variant should inherit BoxCollider from the base prefab.");
191
+ }
192
+
193
+ // ================================================================
194
+ // Background thread tests
195
+ // ================================================================
196
+
197
+ [UnityTest]
198
+ public IEnumerator Prefab_Create_Connected_BackgroundThread()
199
+ {
200
+ EnsureTestFolder();
201
+ var prefabPath = $"{TestFolder}/Connected_Bg.prefab";
202
+ var go = new GameObject("TestGO_Connected_Bg");
203
+ var id = go.GetInstanceID();
204
+
205
+ yield return RunToolFromBackgroundThread(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
206
+ $@"{{""prefabAssetPath"":""{prefabPath}"",""gameObjectRef"":{{""instanceID"":{id}}},""connectGameObjectToPrefab"":true}}");
207
+
208
+ var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
209
+ Assert.IsNotNull(prefab, $"Prefab should be created at: {prefabPath}");
210
+ Assert.IsTrue(PrefabUtility.IsPartOfPrefabInstance(go),
211
+ "Scene GameObject should be connected to the prefab (background thread).");
212
+ }
213
+
214
+ [UnityTest]
215
+ public IEnumerator Prefab_Create_NotConnected_BackgroundThread()
216
+ {
217
+ EnsureTestFolder();
218
+ var prefabPath = $"{TestFolder}/Disconnected_Bg.prefab";
219
+ var go = new GameObject("TestGO_Disconnected_Bg");
220
+ var id = go.GetInstanceID();
221
+
222
+ yield return RunToolFromBackgroundThread(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
223
+ $@"{{""prefabAssetPath"":""{prefabPath}"",""gameObjectRef"":{{""instanceID"":{id}}},""connectGameObjectToPrefab"":false}}");
224
+
225
+ var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
226
+ Assert.IsNotNull(prefab, $"Prefab should be created at: {prefabPath}");
227
+ Assert.IsFalse(PrefabUtility.IsPartOfPrefabInstance(go),
228
+ "Scene GameObject should NOT be connected to the prefab (background thread).");
229
+ }
230
+
231
+ [UnityTest]
232
+ public IEnumerator Prefab_Create_AutoCreatesFolders_BackgroundThread()
233
+ {
234
+ EnsureTestFolder();
235
+ var prefabPath = $"{TestFolder}/NestedBg/DeepBg/AutoCreatedBg.prefab";
236
+ var go = new GameObject("TestGO_Nested_Bg");
237
+ var id = go.GetInstanceID();
238
+
239
+ yield return RunToolFromBackgroundThread(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
240
+ $@"{{""prefabAssetPath"":""{prefabPath}"",""gameObjectRef"":{{""instanceID"":{id}}}}}");
241
+
242
+ var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
243
+ Assert.IsNotNull(prefab, $"Prefab should be created at nested path (background thread): {prefabPath}");
244
+ }
245
+
246
+ [UnityTest]
247
+ public IEnumerator Prefab_CreateVariant_FromAssetPath_BackgroundThread()
248
+ {
249
+ EnsureTestFolder();
250
+
251
+ // Step 1: create a base prefab (on main thread for setup)
252
+ var basePath = $"{TestFolder}/Base_AssetVariant_Bg.prefab";
253
+ var baseGo = new GameObject("TestGO_Base_AssetVariant_Bg");
254
+ var baseId = baseGo.GetInstanceID();
255
+
256
+ yield return RunToolMainThreadCoop(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
257
+ $@"{{""prefabAssetPath"":""{basePath}"",""gameObjectRef"":{{""instanceID"":{baseId}}},""connectGameObjectToPrefab"":false}}");
258
+
259
+ // Step 2: create variant from background thread
260
+ var variantPath = $"{TestFolder}/Variant_FromAsset_Bg.prefab";
261
+ yield return RunToolFromBackgroundThread(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
262
+ $@"{{""prefabAssetPath"":""{variantPath}"",""sourcePrefabAssetPath"":""{basePath}""}}");
263
+
264
+ var variant = AssetDatabase.LoadAssetAtPath<GameObject>(variantPath);
265
+ Assert.IsNotNull(variant, $"Variant prefab should be created at: {variantPath}");
266
+ Assert.IsTrue(PrefabUtility.IsPartOfVariantPrefab(variant!),
267
+ "Created prefab from asset path should be a Prefab Variant (background thread).");
268
+ }
269
+
270
+ // ================================================================
271
+ // Error cases
272
+ // ================================================================
273
+ // Console separation (COCli-07): the runner/manager failure logs these
274
+ // tests used to pin with LogAssert no longer reach the Unity Console
275
+ // while the plugin diagnostics channel is installed. Each error test
276
+ // asserts the same evidence through the LogCollector API after the
277
+ // call (see BaseTest.AssertToolErrorDiagnostics).
278
+
279
+ [UnityTest]
280
+ public IEnumerator Prefab_Create_EmptyPath_ReturnsError()
281
+ {
282
+ var go = new GameObject("TestGO_EmptyPath");
283
+ var id = go.GetInstanceID();
284
+
285
+ var jsonResult = RunToolRaw(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
286
+ $@"{{""prefabAssetPath"":"""",""gameObjectRef"":{{""instanceID"":{id}}}}}");
287
+
288
+ StringAssert.Contains("Prefab path is empty", jsonResult);
289
+ AssertToolErrorDiagnostics("Prefab path is empty");
290
+ yield return null;
291
+ }
292
+
293
+ [UnityTest]
294
+ public IEnumerator Prefab_Create_InvalidExtension_ReturnsError()
295
+ {
296
+ EnsureTestFolder();
297
+ var go = new GameObject("TestGO_InvalidExt");
298
+ var id = go.GetInstanceID();
299
+
300
+ var jsonResult = RunToolRaw(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
301
+ $@"{{""prefabAssetPath"":""{TestFolder}/NotAPrefab.txt"",""gameObjectRef"":{{""instanceID"":{id}}}}}");
302
+
303
+ StringAssert.Contains("invalid", jsonResult);
304
+ AssertToolErrorDiagnostics("is invalid");
305
+ yield return null;
306
+ }
307
+
308
+ [UnityTest]
309
+ public IEnumerator Prefab_Create_InvalidGameObjectRef_ReturnsError()
310
+ {
311
+ EnsureTestFolder();
312
+
313
+ var jsonResult = RunToolRaw(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
314
+ $@"{{""prefabAssetPath"":""{TestFolder}/ShouldFail.prefab"",""gameObjectRef"":{{""instanceID"":-999999}}}}");
315
+
316
+ StringAssert.Contains("Not found", jsonResult);
317
+ AssertToolErrorDiagnostics("Not found");
318
+ yield return null;
319
+ }
320
+
321
+ [UnityTest]
322
+ public IEnumerator Prefab_Create_NoGameObjectRefOrSourcePath_ReturnsError()
323
+ {
324
+ EnsureTestFolder();
325
+
326
+ var jsonResult = RunToolRaw(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
327
+ $@"{{""prefabAssetPath"":""{TestFolder}/ShouldFail.prefab""}}");
328
+
329
+ StringAssert.Contains("must be provided", jsonResult);
330
+ AssertToolErrorDiagnostics("must be provided");
331
+ yield return null;
332
+ }
333
+
334
+ [UnityTest]
335
+ public IEnumerator Prefab_Create_InvalidSourcePrefabPath_ReturnsError()
336
+ {
337
+ EnsureTestFolder();
338
+
339
+ var jsonResult = RunToolRaw(Tool_Assets_Prefab.AssetsPrefabCreateToolId,
340
+ $@"{{""prefabAssetPath"":""{TestFolder}/ShouldFail.prefab"",""sourcePrefabAssetPath"":""{TestFolder}/NonExistent.prefab""}}");
341
+
342
+ StringAssert.Contains("not found", jsonResult);
343
+ AssertToolErrorDiagnostics("not found");
344
+ yield return null;
345
+ }
346
+ }
347
+ }
348
+ #endif