77
88namespace PereViader . ManualReserialization . Tests
99{
10- public class DeleteAssetsTearDown
10+ public class DeleteAssetsTearDown : IDisposable
1111 {
1212 private readonly List < string > assetsToDestroy = new List < string > ( ) ;
1313
@@ -59,7 +59,8 @@ public Action<Action<T>> CreatePrefabWithComponent<T>(string name) where T : Mon
5959 /// <param name="name">Name to identify the objects</param>
6060 /// <param name="alterVariant">Action where to change the prefab variant</param>
6161 /// <returns>Action where the first element is the prefab and the second is the variant</returns>
62- public Action < Action < T , T > > CreatePrefabAndVariantWithComponent < T > ( string name , Action < T > alterVariant ) where T : MonoBehaviour
62+ public Action < Action < T , T > > CreatePrefabAndVariantWithComponent < T > ( string name , Action < T > alterVariant )
63+ where T : MonoBehaviour
6364 {
6465 var pathPrefab = AssetDatabase . GenerateUniqueAssetPath ( "Assets/TestPrefabAsset.prefab" ) ;
6566 var pathVariant = AssetDatabase . GenerateUniqueAssetPath ( "Assets/TestPrefabVariantAsset.prefab" ) ;
@@ -128,7 +129,102 @@ public Action<Action<T>> CreateSceneWithGameObjectComponent<T>(string name) wher
128129 } ;
129130 }
130131
131- public void TearDown ( )
132+ public ( string rootPath , string variantPath ) CreateVariantWhereRootLacksComponent < T > ( string baseName )
133+ where T : MonoBehaviour
134+ {
135+ var rootPath = AssetDatabase . GenerateUniqueAssetPath ( $ "Assets/{ baseName } _Root.prefab") ;
136+ var variantPath = AssetDatabase . GenerateUniqueAssetPath ( $ "Assets/{ baseName } _Variant.prefab") ;
137+ // Ensure these paths are registered for deletion in TearDown
138+ assetsToDestroy . Add ( variantPath ) ;
139+ assetsToDestroy . Add ( rootPath ) ;
140+
141+ GameObject rootGo = null ;
142+ GameObject variantGo = null ; // Instance used to create the variant asset
143+ GameObject rootPrefabAsset = null ;
144+ GameObject variantPrefabAsset = null ;
145+
146+ try
147+ {
148+ // 1. Create the root GameObject (without the component)
149+ rootGo = new GameObject ( $ "{ baseName } _Root") ;
150+
151+ // --- Use SaveAsPrefabAssetAndConnect for the root ---
152+ // This creates the asset and connects rootGo to it.
153+ // It also handles destroying rootGo automatically on success.
154+ rootPrefabAsset = PrefabUtility . SaveAsPrefabAssetAndConnect (
155+ rootGo ,
156+ rootPath ,
157+ InteractionMode . AutomatedAction ) ;
158+
159+ if ( rootPrefabAsset == null )
160+ {
161+ // If rootGo wasn't destroyed automatically due to failure, clean it up.
162+ if ( rootGo != null ) GameObject . DestroyImmediate ( rootGo ) ;
163+ throw new Exception ( $ "Failed to save root prefab at { rootPath } ") ;
164+ }
165+ // Note: rootGo is likely destroyed or invalid after SaveAsPrefabAssetAndConnect succeeds.
166+ // We work with rootPrefabAsset asset from now on.
167+
168+ // 2. Create the variant instance based on the saved root prefab *asset*
169+ variantGo = ( GameObject ) PrefabUtility . InstantiatePrefab ( rootPrefabAsset ) ;
170+ if ( variantGo == null ) throw new Exception ( "Failed to instantiate prefab asset for variant creation." ) ;
171+ variantGo . name = $ "{ baseName } _Variant";
172+
173+ // 3. Add the component ONLY to the variant instance
174+ var component = variantGo . AddComponent < T > ( ) ;
175+ // --- Mark the instance dirty after adding component ---
176+ EditorUtility . SetDirty ( component ) ;
177+ EditorUtility . SetDirty ( variantGo ) ;
178+
179+ // 4. Save the modified variant instance as a new prefab asset (the variant)
180+ // Use SaveAsPrefabAsset, we don't want to connect variantGo back.
181+ variantPrefabAsset = PrefabUtility . SaveAsPrefabAsset ( variantGo , variantPath ) ;
182+ if ( variantPrefabAsset == null ) throw new Exception ( $ "Failed to save variant prefab at { variantPath } ") ;
183+ // --- Mark the new variant asset dirty ---
184+ EditorUtility . SetDirty ( variantPrefabAsset ) ;
185+
186+ // 5. Save assets *after* both prefabs are created and potentially dirtied
187+ AssetDatabase . SaveAssets ( ) ;
188+ AssetDatabase . Refresh ( ) ;
189+
190+ // --- Verification (Optional but recommended) ---
191+ // Reload assets fresh from disk to ensure links are correct after save/refresh
192+ var loadedRoot = AssetDatabase . LoadAssetAtPath < GameObject > ( rootPath ) ;
193+ var loadedVariant = AssetDatabase . LoadAssetAtPath < GameObject > ( variantPath ) ;
194+ if ( loadedRoot == null || loadedVariant == null )
195+ throw new Exception ( "Failed to load created prefabs after save." ) ;
196+ if ( loadedRoot . GetComponent < T > ( ) != null )
197+ throw new Exception ( "Test Setup Error: Root prefab incorrectly has the component." ) ;
198+ if ( loadedVariant . GetComponent < T > ( ) == null )
199+ throw new Exception ( "Test Setup Error: Variant prefab lacks the component." ) ;
200+
201+ var sourceOfVariant = PrefabUtility . GetCorrespondingObjectFromSource ( loadedVariant ) ;
202+ if ( sourceOfVariant == null )
203+ throw new Exception ( "Test Setup Error: Variant link to source is null after save." ) ;
204+ if ( sourceOfVariant . GetInstanceID ( ) != loadedRoot . GetInstanceID ( ) )
205+ throw new Exception (
206+ $ "Test Setup Error: Variant points to the wrong source. Expected { loadedRoot . name } , got { sourceOfVariant . name } ") ;
207+
208+ return ( rootPath , variantPath ) ;
209+ }
210+ finally
211+ {
212+ // Clean up the temporary scene instance used for the variant
213+ // rootGo should have been handled by SaveAsPrefabAssetAndConnect
214+ if ( variantGo != null )
215+ {
216+ GameObject . DestroyImmediate ( variantGo ) ;
217+ }
218+
219+ // Belt-and-suspenders: Ensure rootGo is gone if SaveAsPrefabAssetAndConnect failed early
220+ if ( rootGo != null && rootPrefabAsset == null )
221+ {
222+ GameObject . DestroyImmediate ( rootGo ) ;
223+ }
224+ }
225+ }
226+
227+ public void Dispose ( )
132228 {
133229 AssetDatabase . Refresh ( ) ;
134230 foreach ( var path in assetsToDestroy )
@@ -143,6 +239,7 @@ public void TearDown()
143239 Debug . LogError ( $ "Could not delete asset with path { path } ") ;
144240 }
145241 }
242+
146243 assetsToDestroy . Clear ( ) ;
147244 }
148245 }
0 commit comments