Browse Source

Prefab link UUID is now properly returned
More fixes for prefab unit test

BearishSun 10 years ago
parent
commit
1e7ee6bd82
3 changed files with 475 additions and 428 deletions
  1. 1 0
      BansheeCore/Source/BsPrefab.cpp
  2. 1 1
      BansheeCore/Source/BsSceneObject.cpp
  3. 473 427
      MBansheeEditor/UnitTests.cs

+ 1 - 0
BansheeCore/Source/BsPrefab.cpp

@@ -25,6 +25,7 @@ namespace BansheeEngine
 
 		HPrefab handle = static_resource_cast<Prefab>(gResources()._createResourceHandle(newPrefab));
 		sceneObject->mPrefabLinkUUID = handle.getUUID();
+		newPrefab->_getRoot()->mPrefabLinkUUID = sceneObject->mPrefabLinkUUID;
 
 		return handle;
 	}

+ 1 - 1
BansheeCore/Source/BsSceneObject.cpp

@@ -111,7 +111,7 @@ namespace BansheeEngine
 	{
 		const SceneObject* curObj = this;
 
-		while (curObj == nullptr)
+		while (curObj != nullptr)
 		{
 			if (!curObj->mPrefabLinkUUID.empty())
 				return curObj->mPrefabLinkUUID;

+ 473 - 427
MBansheeEditor/UnitTests.cs

@@ -14,6 +14,16 @@ namespace BansheeEditor
     /// </summary>
     class UnitTests
     {
+        /// <summary>
+        /// Triggers an exception when a unit test condition fails.
+        /// </summary>
+        /// <param name="success">True if the unit test condition succeeded, false otherwise.</param>
+        static void Assert(bool success)
+        {
+            if (!success)
+                throw new InvalidOperationException("Unit test failed.");
+        }
+
         /// <summary>
         /// Tests managed object serialization and deserialization.
         /// </summary>
@@ -230,473 +240,509 @@ namespace BansheeEditor
                 return;
             }
 
-            string oldScene = Scene.ActiveSceneUUID;
-            Scene.Clear();
-
-            // Simple scene save & load
+            Action PrintSceneState = () =>
             {
-                {
-                    // unitTest4Scene_0.prefab:
-                    // so0 (Comp1)
-                    //  - so0_0
-                    //  - so0_1 (Comp1)
-                    //    - so0_1_0 (Comp1)
-                    // so1 (Comp2)
-                    //  - so1_0
-
-                    SceneObject so0 = new SceneObject("so0");
-                    SceneObject so1 = new SceneObject("so1");
-                    SceneObject so0_0 = new SceneObject("so0_0");
-                    SceneObject so0_1 = new SceneObject("so0_1");
-                    SceneObject so1_0 = new SceneObject("so1_0");
-                    SceneObject so0_1_0 = new SceneObject("so0_1_0");
-
-                    so0_0.Parent = so0;
-                    so0_1.Parent = so0;
-                    so1_0.Parent = so1;
-                    so0_1_0.Parent = so0_1;
-
-                    so0_1_0.Position = new Vector3(10.0f, 15.0f, 20.0f);
-                    so0_1.Position = new Vector3(1.0f, 2.0f, 3.0f);
-                    so1_0.Position = new Vector3(0, 123.0f, 0.0f);
-
-                    UT1_Component1 comp0 = so0.AddComponent<UT1_Component1>();
-                    UT1_Component2 comp1 = so1.AddComponent<UT1_Component2>();
-                    UT1_Component1 comp1_1 = so0_1.AddComponent<UT1_Component1>();
-                    UT1_Component1 comp0_1_0 = so0_1_0.AddComponent<UT1_Component1>();
-
-                    comp0.otherSO = so0_1_0;
-                    comp0.otherComponent = comp1;
-
-                    comp1_1.b = "originalValue2";
-
-                    comp0_1_0.b = "testValue";
-                    comp0_1_0.otherSO = so0;
-                    comp0_1_0.otherComponent2 = comp0;
-
-                    EditorApplication.SaveScene("unitTest4Scene_0.prefab");
-                }
-                {
-                    EditorApplication.LoadScene("unitTest4Scene_0.prefab");
-
-                    SceneObject sceneRoot = Scene.Root;
-                    SceneObject so0 = sceneRoot.FindChild("so0", false);
-                    SceneObject so1 = sceneRoot.FindChild("so1", false);
-                    SceneObject so0_0 = so0.FindChild("so0_0", false);
-                    SceneObject so0_1 = so0.FindChild("so0_1", false);
-                    SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false);
-
-                    DebugUnit.Assert(so0_0 != null);
-                    DebugUnit.Assert(so0_1 != null);
-                    DebugUnit.Assert(so0_1_0 != null);
-
-                    UT1_Component1 comp0 = so0.GetComponent<UT1_Component1>();
-                    UT1_Component2 comp1 = so1.GetComponent<UT1_Component2>();
-                    UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>();
-
-                    DebugUnit.Assert(comp0 != null);
-                    DebugUnit.Assert(comp1 != null);
-                    DebugUnit.Assert(comp0_1_0 != null);
-                    DebugUnit.Assert(comp0_1_0.b == "testValue");
-                    DebugUnit.Assert(comp0.otherSO == so0_1_0);
-                    DebugUnit.Assert(comp0.otherComponent == comp1);
-                    DebugUnit.Assert(comp0_1_0.otherSO == so0);
-                    DebugUnit.Assert(comp0_1_0.otherComponent2 == comp0);
-                }
-            }
+                SceneObject root = Scene.Root;
 
-            // Load & save a scene that contains a prefab and references its objects
-            {
-                {
-                    // unitTest4Scene_1.prefab:
-                    // parentSO0
-                    //  - [unitTest4Scene_0.prefab]
-                    // parentSO1
-                    //  - parentSO1_0 (Comp1)
-
-                    Scene.Clear();
+                Stack<SceneObject> todo = new Stack<SceneObject>();
+                todo.Push(root);
 
-                    SceneObject parentSO0 = new SceneObject("parentSO0", false);
-                    SceneObject parentSO1 = new SceneObject("parentSO1", false);
-                    SceneObject parentSO1_0 = new SceneObject("parentSO1_0", false);
-
-                    parentSO1_0.Parent = parentSO1;
-
-                    UT1_Component1 parentComp1_0 = parentSO1_0.AddComponent<UT1_Component1>();
-
-                    Prefab scene0Prefab = ProjectLibrary.Load<Prefab>("unitTest4Scene_0.prefab");
-                    SceneObject prefabInstance = scene0Prefab.Instantiate();
-                    prefabInstance.Parent = parentSO0;
-
-                    SceneObject so0 = prefabInstance.FindChild("so0", false);
-                    SceneObject so1 = prefabInstance.FindChild("so1", false);
-                    SceneObject so0_1 = so0.FindChild("so0_1", false);
-                    SceneObject so1_0 = so1.FindChild("so1_0", false);
-                    SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false);
-
-                    UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>();
-
-                    parentComp1_0.otherSO = so1_0;
-                    parentComp1_0.otherComponent2 = comp0_1_0;
-
-                    EditorApplication.SaveScene("unitTest4Scene_1.prefab");
-                }
+                StringBuilder output = new StringBuilder();
+                while (todo.Count > 0)
                 {
-                    EditorApplication.LoadScene("unitTest4Scene_1.prefab");
+                    SceneObject so = todo.Pop();
 
-                    SceneObject parentSO0 = Scene.Root.FindChild("parentSO0", false);
-                    SceneObject parentSO1_0 = parentSO0.FindChild("parentSO1_0", false);
+                    int numChildren = so.GetNumChildren();
+                    for (int i = numChildren - 1; i >= 0; i--)
+                    {
+                        SceneObject child = so.GetChild(i);
 
-                    UT1_Component1 parentComp1_0 = parentSO1_0.GetComponent<UT1_Component1>();
-
-                    SceneObject prefabInstance = parentSO0.GetChild(0);
-                    SceneObject so0 = prefabInstance.FindChild("so0", false);
-                    SceneObject so1 = prefabInstance.FindChild("so1", false);
-                    SceneObject so0_1 = so0.FindChild("so0_1", false);
-                    SceneObject so1_0 = so1.FindChild("so1_0", false);
-                    SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false);
-
-                    UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>();
-
-                    DebugUnit.Assert(parentComp1_0.otherSO == so1_0);
-                    DebugUnit.Assert(parentComp1_0.otherComponent2 == comp0_1_0);
+                        output.AppendLine(child.Name);
+                        todo.Push(child);
+                    }  
                 }
-            }
-
-            // Modify prefab, reload the scene and ensure it is updated with modified prefab
-            {
-                {
-                    // unitTest4Scene_0.prefab:
-                    // so0
-                    //  - so0_1 (Comp1)
-                    //    - so0_1_0 (Comp1)
-                    // so1 (Comp1, Comp2)
-                    //  - so1_0
-                    //  - so1_1
-
-                    Scene.Load("unitTest4Scene_0.prefab");
 
-                    SceneObject sceneRoot = Scene.Root;
-                    SceneObject so0 = sceneRoot.FindChild("so0", false);
-                    SceneObject so0_0 = so0.FindChild("so0_0", false);
-                    SceneObject so0_1 = so0.FindChild("so0_1", false);
-                    SceneObject so1 = sceneRoot.FindChild("so1", false);
-                    SceneObject so1_0 = so1.FindChild("so1_0", false);
-                    SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false);
+                Debug.Log(output);
+            };
 
-                    SceneObject so1_1 = new SceneObject("so1_1");
-                    so1_1.Parent = so1;
-
-                    so0.RemoveComponent<UT1_Component1>();
-                    UT1_Component1 comp1 = so1.AddComponent<UT1_Component1>();
-                    UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>();
-
-                    so0_0.Destroy();
-
-                    comp1.otherSO = so1_0;
-                    comp1.otherComponent2 = comp0_1_0;
-
-                    comp0_1_0.otherSO = so1_1;
-                    comp0_1_0.otherComponent2 = comp1;
-                    comp0_1_0.a = 123;
-                    comp0_1_0.b = "modifiedValue";
-
-                    so1.Name = "so1_modified";
-                    so1.Position = new Vector3(0, 999.0f, 0.0f);
-
-                    EditorApplication.SaveScene("unitTest4Scene_0.prefab");
-                }
+            string oldScene = Scene.ActiveSceneUUID;
+            Scene.Clear();
 
+            try
+            {
+                // Simple scene save & load
                 {
-                    EditorApplication.LoadScene("unitTest4Scene_1.prefab");
-
-                    SceneObject parentSO0 = Scene.Root.FindChild("parentSO0", false);
-                    SceneObject parentSO1_0 = parentSO0.FindChild("parentSO1_0", false);
-
-                    UT1_Component1 parentComp1_0 = parentSO1_0.GetComponent<UT1_Component1>();
-
-                    SceneObject prefabInstance = parentSO0.GetChild(0);
-                    SceneObject so0 = prefabInstance.FindChild("so0", false);
-                    SceneObject so1 = prefabInstance.FindChild("so1_modified", false);
-                    SceneObject so0_0 = so0.FindChild("so0_0", false);
-                    SceneObject so0_1 = so0.FindChild("so0_1", false);
-                    SceneObject so1_0 = so1.FindChild("so1_0", false);
-                    SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false);
-                    SceneObject so1_1 = so1.FindChild("so1_1", false);
-
-                    UT1_Component1 comp0 = so0.GetComponent<UT1_Component1>();
-                    UT1_Component1 comp1 = so1.GetComponent<UT1_Component1>();
-                    UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>();
-
-                    DebugUnit.Assert(parentComp1_0.otherSO == so1_0);
-                    DebugUnit.Assert(parentComp1_0.otherComponent2 == comp0_1_0);
-                    DebugUnit.Assert(so1_1 != null);
-                    DebugUnit.Assert(so0_0 == null);
-                    DebugUnit.Assert(comp0 == null);
-                    DebugUnit.Assert(comp0_1_0.otherSO == so1_1);
-                    DebugUnit.Assert(comp0_1_0.otherComponent2 == comp1);
-                    DebugUnit.Assert(comp0_1_0.a == 123);
-                    DebugUnit.Assert(comp0_1_0.b == "modifiedValue");
-                    DebugUnit.Assert(comp1.otherSO == so1_0);
-                    DebugUnit.Assert(comp1.otherComponent2 == comp0_1_0);
-                    DebugUnit.Assert(MathEx.ApproxEquals(so1.Position.y, 999.0f));
+                    {
+                        // unitTest4Scene_0.prefab:
+                        // so0 (Comp1)
+                        //  - so0_0
+                        //  - so0_1 (Comp1)
+                        //    - so0_1_0 (Comp1)
+                        // so1 (Comp2)
+                        //  - so1_0
+
+                        SceneObject so0 = new SceneObject("so0");
+                        SceneObject so1 = new SceneObject("so1");
+                        SceneObject so0_0 = new SceneObject("so0_0");
+                        SceneObject so0_1 = new SceneObject("so0_1");
+                        SceneObject so1_0 = new SceneObject("so1_0");
+                        SceneObject so0_1_0 = new SceneObject("so0_1_0");
+
+                        so0_0.Parent = so0;
+                        so0_1.Parent = so0;
+                        so1_0.Parent = so1;
+                        so0_1_0.Parent = so0_1;
+
+                        so0_1_0.Position = new Vector3(10.0f, 15.0f, 20.0f);
+                        so0_1.Position = new Vector3(1.0f, 2.0f, 3.0f);
+                        so1_0.Position = new Vector3(0, 123.0f, 0.0f);
+
+                        UT1_Component1 comp0 = so0.AddComponent<UT1_Component1>();
+                        UT1_Component2 comp1 = so1.AddComponent<UT1_Component2>();
+                        UT1_Component1 comp1_1 = so0_1.AddComponent<UT1_Component1>();
+                        UT1_Component1 comp0_1_0 = so0_1_0.AddComponent<UT1_Component1>();
+
+                        comp0.otherSO = so0_1_0;
+                        comp0.otherComponent = comp1;
+
+                        comp1_1.b = "originalValue2";
+
+                        comp0_1_0.b = "testValue";
+                        comp0_1_0.otherSO = so0;
+                        comp0_1_0.otherComponent2 = comp0;
+
+                        EditorApplication.SaveScene("unitTest4Scene_0.prefab");
+                    }
+                    {
+                        EditorApplication.LoadScene("unitTest4Scene_0.prefab");
+
+                        SceneObject sceneRoot = Scene.Root;
+                        SceneObject so0 = sceneRoot.FindChild("so0", false);
+                        SceneObject so1 = sceneRoot.FindChild("so1", false);
+                        SceneObject so0_0 = so0.FindChild("so0_0", false);
+                        SceneObject so0_1 = so0.FindChild("so0_1", false);
+                        SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false);
+
+                        Assert(so0_0 != null);
+                        Assert(so0_1 != null);
+                        Assert(so0_1_0 != null);
+
+                        UT1_Component1 comp0 = so0.GetComponent<UT1_Component1>();
+                        UT1_Component2 comp1 = so1.GetComponent<UT1_Component2>();
+                        UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>();
+
+                        Assert(comp0 != null);
+                        Assert(comp1 != null);
+                        Assert(comp0_1_0 != null);
+                        Assert(comp0_1_0.b == "testValue");
+                        Assert(comp0.otherSO == so0_1_0);
+                        Assert(comp0.otherComponent == comp1);
+                        Assert(comp0_1_0.otherSO == so0);
+                        Assert(comp0_1_0.otherComponent2 == comp0);
+                    }
                 }
-            }
 
-            // Make instance specific changes to the prefab, modify the prefab itself and ensure
-            // both changes persist
-            {
-                // Create new scene referencing the prefab and make instance modifications
+                // Load & save a scene that contains a prefab and references its objects
                 {
-                    // unitTest4Scene_2.prefab:
-                    // parent2SO0
-                    //  - [unitTest4Scene_0.prefab]
-                    // parent2SO1
-                    //  - parent2SO1_0 (Comp1)
-
-                    // unitTest4Scene_0.prefab (unitTest4Scene_2.prefab instance):
-                    // so0 (Comp1(INSTANCE))
-                    //  - so0_0 (INSTANCE)
-                    //  - so0_1 (Comp1)
-                    //    - so0_1_0 (Comp1)
-                    // so1 (Comp2)
-                    //  - so1_0
+                    {
+                        // unitTest4Scene_1.prefab:
+                        // parentSO0
+                        //  - [unitTest4Scene_0.prefab]
+                        // parentSO1
+                        //  - parentSO1_0 (Comp1)
 
-                    Scene.Clear();
-
-                    SceneObject parent2SO0 = new SceneObject("parent2SO0");
-                    SceneObject parent2SO1 = new SceneObject("parent2SO1");
-                    SceneObject parent2SO1_0 = new SceneObject("parent2SO1_0");
+                        Scene.Clear();
 
-                    parent2SO1_0.Parent = parent2SO1;
+                        SceneObject parentSO0 = new SceneObject("parentSO0", false);
+                        SceneObject parentSO1 = new SceneObject("parentSO1", false);
+                        SceneObject parentSO1_0 = new SceneObject("parentSO1_0", false);
 
-                    UT1_Component1 parentComp1_0 = parent2SO1_0.AddComponent<UT1_Component1>();
+                        parentSO1_0.Parent = parentSO1;
 
-                    Prefab scene0Prefab = ProjectLibrary.Load<Prefab>("unitTest4Scene_0.prefab");
-                    SceneObject prefabInstance = scene0Prefab.Instantiate();
-                    prefabInstance.Parent = parent2SO0;
+                        UT1_Component1 parentComp1_0 = parentSO1_0.AddComponent<UT1_Component1>();
 
-                    SceneObject so0 = prefabInstance.FindChild("so0", false);
-                    SceneObject so1 = prefabInstance.FindChild("so1", false);
+                        Prefab scene0Prefab = ProjectLibrary.Load<Prefab>("unitTest4Scene_0.prefab");
+                        SceneObject prefabInstance = scene0Prefab.Instantiate();
+                        prefabInstance.Parent = parentSO0;
 
-                    SceneObject so0_1 = so1.FindChild("so0_1", false);
-                    SceneObject so1_0 = so1.FindChild("so1_0", false);
-                    SceneObject so1_1 = so1.FindChild("so1_1", false);
-                    SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false);
+                        SceneObject so0 = prefabInstance.FindChild("so0", false);
+                        SceneObject so1 = prefabInstance.FindChild("so1", false);
+                        SceneObject so0_1 = so0.FindChild("so0_1", false);
+                        SceneObject so1_0 = so1.FindChild("so1_0", false);
+                        SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false);
 
-                    UT1_Component2 comp1 = so1.GetComponent<UT1_Component2>();
-                    UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>();
-                    UT1_Component1 comp0_1 = so0_1.GetComponent<UT1_Component1>();
+                        UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>();
 
-                    SceneObject so0_0 = new SceneObject("so0_0");
-                    so0_0.Parent = so0;
-                    UT1_Component1 comp0 = so0.AddComponent<UT1_Component1>();
+                        parentComp1_0.otherSO = so1_0;
+                        parentComp1_0.otherComponent2 = comp0_1_0;
 
-                    so1.RemoveComponent<UT1_Component1>();
-                    so1_1.Destroy();
+                        EditorApplication.SaveScene("unitTest4Scene_1.prefab");
+                    }
+                    {
+                        EditorApplication.LoadScene("unitTest4Scene_1.prefab");
 
-                    comp0.otherSO = so0_1_0;
-                    comp0.otherComponent = comp1;
+                        SceneObject parentSO0 = Scene.Root.FindChild("parentSO0", false);
+                        SceneObject parentSO1 = Scene.Root.FindChild("parentSO1", false);
+                        SceneObject parentSO1_0 = parentSO1.FindChild("parentSO1_0", false);
 
-                    parentComp1_0.otherSO = so1_0;
-                    parentComp1_0.otherComponent2 = comp0_1_0;
+                        UT1_Component1 parentComp1_0 = parentSO1_0.GetComponent<UT1_Component1>();
 
-                    comp0_1_0.otherSO = parent2SO1_0;
-                    comp0_1_0.otherComponent2 = parentComp1_0;
-                    comp0_1_0.b = "instanceValue";
+                        SceneObject prefabInstance = parentSO0.GetChild(0);
+                        SceneObject so0 = prefabInstance.FindChild("so0", false);
+                        SceneObject so1 = prefabInstance.FindChild("so1", false);
+                        SceneObject so0_1 = so0.FindChild("so0_1", false);
+                        SceneObject so1_0 = so1.FindChild("so1_0", false);
+                        SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false);
 
-                    comp0_1.b = "instanceValue2";
+                        UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>();
 
-                    EditorApplication.SaveScene("unitTest4Scene_2.prefab");
+                        Assert(parentComp1_0.otherSO == so1_0);
+                        Assert(parentComp1_0.otherComponent2 == comp0_1_0);
+                    }
                 }
 
-                // Reload the scene and ensure instance modifications remain
+                // Modify prefab, reload the scene and ensure it is updated with modified prefab
                 {
-                    EditorApplication.LoadScene("unitTest4Scene_2.prefab");
-
-                    SceneObject root = Scene.Root;
-                    SceneObject parent2SO0 = root.FindChild("parent2SO0", false);
-                    SceneObject parent2SO1_0 = root.FindChild("parent2SO1_0", false);
-
-                    SceneObject prefabInstance = parent2SO0.GetChild(0);
-
-                    SceneObject so0 = prefabInstance.FindChild("so0", false);
-                    SceneObject so1 = prefabInstance.FindChild("so1", false);
-                    SceneObject so0_0 = so0.FindChild("so0_0", false);
-                    SceneObject so0_1 = so0.FindChild("so0_1", false);
-                    SceneObject so1_0 = so1.FindChild("so1_0", false);
-                    SceneObject so1_1 = so1.FindChild("so1_1", false);
-                    SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false);
-
-                    UT1_Component1 parentComp1_0 = parent2SO1_0.GetComponent<UT1_Component1>();
-                    UT1_Component1 comp0 = so0.GetComponent<UT1_Component1>();
-                    UT1_Component2 comp1 = so1.GetComponent<UT1_Component2>();
-                    UT1_Component1 comp11 = so1.GetComponent<UT1_Component1>();
-                    UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>();
-                    UT1_Component1 comp0_1 = so0_1.GetComponent<UT1_Component1>();
-
-                    DebugUnit.Assert(so0_0 != null);
-                    DebugUnit.Assert(comp0 != null);
-                    DebugUnit.Assert(so1_1 == null);
-                    DebugUnit.Assert(comp11 == null);
-
-                    DebugUnit.Assert(comp0.otherSO == so0_1_0);
-                    DebugUnit.Assert(comp0.otherComponent == comp1);
-
-                    DebugUnit.Assert(parentComp1_0.otherSO == so1_0);
-                    DebugUnit.Assert(parentComp1_0.otherComponent2 == comp0_1_0);
-
-                    DebugUnit.Assert(comp0_1_0.otherSO == parent2SO1_0);
-                    DebugUnit.Assert(comp0_1_0.otherComponent2 == parentComp1_0);
-                    DebugUnit.Assert(comp0_1_0.b == "instanceValue");
-
-                    DebugUnit.Assert(comp0_1.b == "instanceValue2");
+                    {
+                        // unitTest4Scene_0.prefab:
+                        // so0
+                        //  - so0_1 (Comp1)
+                        //    - so0_1_0 (Comp1)
+                        // so1 (Comp1, Comp2)
+                        //  - so1_0
+                        //  - so1_1
+
+                        Scene.Load("unitTest4Scene_0.prefab");
+
+                        SceneObject sceneRoot = Scene.Root;
+                        SceneObject so0 = sceneRoot.FindChild("so0", false);
+                        SceneObject so0_0 = so0.FindChild("so0_0", false);
+                        SceneObject so0_1 = so0.FindChild("so0_1", false);
+                        SceneObject so1 = sceneRoot.FindChild("so1", false);
+                        SceneObject so1_0 = so1.FindChild("so1_0", false);
+                        SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false);
+
+                        SceneObject so1_1 = new SceneObject("so1_1");
+                        so1_1.Parent = so1;
+
+                        so0.RemoveComponent<UT1_Component1>();
+                        UT1_Component1 comp1 = so1.AddComponent<UT1_Component1>();
+                        UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>();
+
+                        so0_0.Destroy();
+
+                        comp1.otherSO = so1_0;
+                        comp1.otherComponent2 = comp0_1_0;
+
+                        comp0_1_0.otherSO = so1_1;
+                        comp0_1_0.otherComponent2 = comp1;
+                        comp0_1_0.a = 123;
+                        comp0_1_0.b = "modifiedValue";
+
+                        so1.Name = "so1_modified";
+                        so1.Position = new Vector3(0, 999.0f, 0.0f);
+
+                        EditorApplication.SaveScene("unitTest4Scene_0.prefab");
+                    }
+
+                    {
+                        EditorApplication.LoadScene("unitTest4Scene_1.prefab");
+
+                        SceneObject parentSO0 = Scene.Root.FindChild("parentSO0", false);
+                        SceneObject parentSO1 = Scene.Root.FindChild("parentSO1", false);
+                        SceneObject parentSO1_0 = parentSO1.FindChild("parentSO1_0", false);
+
+                        UT1_Component1 parentComp1_0 = parentSO1_0.GetComponent<UT1_Component1>();
+
+                        SceneObject prefabInstance = parentSO0.GetChild(0);
+                        SceneObject so0 = prefabInstance.FindChild("so0", false);
+                        SceneObject so1 = prefabInstance.FindChild("so1_modified", false);
+                        SceneObject so0_0 = so0.FindChild("so0_0", false);
+                        SceneObject so0_1 = so0.FindChild("so0_1", false);
+                        SceneObject so1_0 = so1.FindChild("so1_0", false);
+                        SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false);
+                        SceneObject so1_1 = so1.FindChild("so1_1", false);
+
+                        UT1_Component1 comp0 = so0.GetComponent<UT1_Component1>();
+                        UT1_Component1 comp1 = so1.GetComponent<UT1_Component1>();
+                        UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>();
+
+                        Assert(parentComp1_0.otherSO == so1_0);
+                        Assert(parentComp1_0.otherComponent2 == comp0_1_0);
+                        Assert(so1_1 != null);
+                        Assert(so0_0 == null);
+                        Assert(comp0 == null);
+                        Assert(comp0_1_0.otherSO == so1_1);
+                        Assert(comp0_1_0.otherComponent2 == comp1);
+                        Assert(comp0_1_0.a == 123);
+                        Assert(comp0_1_0.b == "modifiedValue");
+                        Assert(comp1.otherSO == so1_0);
+                        Assert(comp1.otherComponent2 == comp0_1_0);
+                        Assert(MathEx.ApproxEquals(so1.Position.y, 999.0f));
+                    }
                 }
 
-                // Load original scene and ensure instance modifications didn't influence it
+                // Make instance specific changes to the prefab, modify the prefab itself and ensure
+                // both changes persist
                 {
-                    EditorApplication.LoadScene("unitTest4Scene_1.prefab");
-
-                    SceneObject parentSO0 = Scene.Root.FindChild("parentSO0", false);
-                    SceneObject parentSO1_0 = parentSO0.FindChild("parentSO1_0", false);
-
-                    UT1_Component1 parentComp1_0 = parentSO1_0.GetComponent<UT1_Component1>();
-
-                    SceneObject prefabInstance = parentSO0.GetChild(0);
-                    SceneObject so0 = prefabInstance.FindChild("so0", false);
-                    SceneObject so1 = prefabInstance.FindChild("so1_modified", false);
-                    SceneObject so0_0 = so0.FindChild("so0_0", false);
-                    SceneObject so0_1 = so0.FindChild("so0_1", false);
-                    SceneObject so1_0 = so1.FindChild("so1_0", false);
-                    SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false);
-                    SceneObject so1_1 = so1.FindChild("so1_1", false);
-
-                    UT1_Component1 comp0 = so0.GetComponent<UT1_Component1>();
-                    UT1_Component1 comp1 = so1.GetComponent<UT1_Component1>();
-                    UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>();
-                    UT1_Component1 comp0_1 = so0_1.GetComponent<UT1_Component1>();
-
-                    DebugUnit.Assert(parentComp1_0.otherSO == so1_0);
-                    DebugUnit.Assert(parentComp1_0.otherComponent2 == comp0_1_0);
-                    DebugUnit.Assert(so1_1 != null);
-                    DebugUnit.Assert(so0_0 == null);
-                    DebugUnit.Assert(comp0 == null);
-                    DebugUnit.Assert(comp0_1_0.otherSO == so1_1);
-                    DebugUnit.Assert(comp0_1_0.otherComponent2 == comp1);
-                    DebugUnit.Assert(comp0_1_0.a == 123);
-                    DebugUnit.Assert(comp0_1_0.b == "modifiedValue");
-                    DebugUnit.Assert(comp1.otherSO == so1_0);
-                    DebugUnit.Assert(comp1.otherComponent2 == comp0_1_0);
-                    DebugUnit.Assert(comp0_1.b == "originalValue2");
-                    DebugUnit.Assert(MathEx.ApproxEquals(so1.Position.y, 999.0f));
-                }
+                    // Create new scene referencing the prefab and make instance modifications
+                    {
+                        // unitTest4Scene_2.prefab:
+                        // parent2SO0
+                        //  - [unitTest4Scene_0.prefab]
+                        // parent2SO1
+                        //  - parent2SO1_0 (Comp1)
 
-                // Modify prefab and ensure both prefab and instance modifications remain
-                {
-                    // unitTest4Scene_0.prefab:
-                    // so0 (Comp1)
-                    //  - so0_1
-                    //    - so0_1_0 (Comp1)
-                    // so1 (Comp1, Comp2)
-                    //  - so1_1
-                    //  - so1_2 (Comp1)
-
-                    // unitTest4Scene_0.prefab (unitTest4Scene_2.prefab instance):
-                    // so0 (Comp1)
-                    //  - so0_0
-                    //  - so0_1 (Comp1)
-                    //    - so0_1_0 (Comp1)
-                    // so1 (Comp2)
-                    //  - so1_2 (Comp1)
-
-                    Scene.Load("unitTest4Scene_0.prefab");
-
-                    SceneObject sceneRoot = Scene.Root;
-                    SceneObject so0 = sceneRoot.FindChild("so0", false);
-                    SceneObject so0_1 = so0.FindChild("so0_1", false);
-                    SceneObject so1 = sceneRoot.FindChild("so1_modified", false);
-                    SceneObject so1_0 = so1.FindChild("so1_0", false);
-                    SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false);
-
-                    SceneObject so1_2 = new SceneObject("so1_2");
-                    so1_2.Parent = so1;
-
-                    so0.AddComponent<UT1_Component1>();
-                    so0_1.RemoveComponent<UT1_Component1>();
-                    so1_0.Destroy();
-
-                    UT1_Component1 comp3 = so1_2.AddComponent<UT1_Component1>();
-                    UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>();
-                    comp0_1_0.b = "modifiedValueAgain";
-                    so1.Name = "so1_modifiedAgain";
-
-                    comp3.otherSO = so0_1;
-                    comp3.otherComponent2 = comp0_1_0;
-
-                    EditorApplication.SaveScene("unitTest4Scene_0.prefab");
-                }
+                        // unitTest4Scene_0.prefab (unitTest4Scene_2.prefab instance):
+                        // so0 (Comp1(INSTANCE))
+                        //  - so0_0 (INSTANCE)
+                        //  - so0_1 (Comp1)
+                        //    - so0_1_0 (Comp1)
+                        // so1 (Comp2)
+                        //  - so1_0
 
-                // Reload the scene and ensure both instance and prefab modifications remain
-                {
-                    EditorApplication.LoadScene("unitTest4Scene_2.prefab");
-
-                    SceneObject root = Scene.Root;
-                    SceneObject parent2SO0 = root.FindChild("parent2SO0", false);
-                    SceneObject parent2SO1_0 = root.FindChild("parent2SO1_0", false);
-
-                    SceneObject prefabInstance = parent2SO0.GetChild(0);
-
-                    SceneObject so0 = prefabInstance.FindChild("so0", false);
-                    SceneObject so1 = prefabInstance.FindChild("so1", false);
-                    SceneObject so0_0 = so0.FindChild("so0_0", false);
-                    SceneObject so0_1 = so0.FindChild("so0_1", false);
-                    SceneObject so1_0 = so1.FindChild("so1_0", false);
-                    SceneObject so1_1 = so1.FindChild("so1_1", false);
-                    SceneObject so1_2 = so1.FindChild("so1_2", false);
-                    SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false);
-
-                    UT1_Component1 parentComp1_0 = parent2SO1_0.GetComponent<UT1_Component1>();
-                    UT1_Component1 comp0 = so0.GetComponent<UT1_Component1>();
-                    UT1_Component2 comp1 = so1.GetComponent<UT1_Component2>();
-                    UT1_Component1 comp11 = so1.GetComponent<UT1_Component1>();
-                    UT1_Component1 comp0_1 = so1_1.GetComponent<UT1_Component1>();
-                    UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>();
-                    UT1_Component1 comp3 = so1_2.AddComponent<UT1_Component1>();
-
-                    // Check instance modifications (they should override any prefab modifications)
-                    DebugUnit.Assert(so0_0 != null);
-                    DebugUnit.Assert(comp0 != null);
-                    DebugUnit.Assert(so1_1 == null);
-                    DebugUnit.Assert(comp11 == null);
-
-                    DebugUnit.Assert(comp0.otherSO == so0_1_0);
-                    DebugUnit.Assert(comp0.otherComponent == comp1);
-
-                    DebugUnit.Assert(parentComp1_0.otherSO == so1_0);
-                    DebugUnit.Assert(parentComp1_0.otherComponent2 == comp0_1_0);
-
-                    DebugUnit.Assert(comp0_1_0.otherSO == parent2SO1_0);
-                    DebugUnit.Assert(comp0_1_0.otherComponent2 == parentComp1_0);
-                    DebugUnit.Assert(comp0_1_0.b == "instanceValue");
-
-                    // Check prefab modifications
-                    DebugUnit.Assert(comp0_1 != null);
-                    DebugUnit.Assert(so1_0 == null);
-                    DebugUnit.Assert(so1.Name == "so1_modifiedAgain");
-                    DebugUnit.Assert(comp3.otherSO == so0_1);
-                    DebugUnit.Assert(comp3.otherComponent2 == comp0_1_0);
+                        Scene.Clear();
+
+                        SceneObject parent2SO0 = new SceneObject("parent2SO0");
+                        SceneObject parent2SO1 = new SceneObject("parent2SO1");
+                        SceneObject parent2SO1_0 = new SceneObject("parent2SO1_0");
+
+                        parent2SO1_0.Parent = parent2SO1;
+
+                        UT1_Component1 parentComp1_0 = parent2SO1_0.AddComponent<UT1_Component1>();
+
+                        Prefab scene0Prefab = ProjectLibrary.Load<Prefab>("unitTest4Scene_0.prefab");
+                        SceneObject prefabInstance = scene0Prefab.Instantiate();
+                        prefabInstance.Parent = parent2SO0;
+
+                        SceneObject so0 = prefabInstance.FindChild("so0", false);
+                        SceneObject so1 = prefabInstance.FindChild("so1", false);
+
+                        SceneObject so0_1 = so1.FindChild("so0_1", false);
+                        SceneObject so1_0 = so1.FindChild("so1_0", false);
+                        SceneObject so1_1 = so1.FindChild("so1_1", false);
+                        SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false);
+
+                        UT1_Component2 comp1 = so1.GetComponent<UT1_Component2>();
+                        UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>();
+                        UT1_Component1 comp0_1 = so0_1.GetComponent<UT1_Component1>();
+
+                        SceneObject so0_0 = new SceneObject("so0_0");
+                        so0_0.Parent = so0;
+                        UT1_Component1 comp0 = so0.AddComponent<UT1_Component1>();
+
+                        so1.RemoveComponent<UT1_Component1>();
+                        so1_1.Destroy();
+
+                        comp0.otherSO = so0_1_0;
+                        comp0.otherComponent = comp1;
+
+                        parentComp1_0.otherSO = so1_0;
+                        parentComp1_0.otherComponent2 = comp0_1_0;
+
+                        comp0_1_0.otherSO = parent2SO1_0;
+                        comp0_1_0.otherComponent2 = parentComp1_0;
+                        comp0_1_0.b = "instanceValue";
+
+                        comp0_1.b = "instanceValue2";
+
+                        EditorApplication.SaveScene("unitTest4Scene_2.prefab");
+                    }
+
+                    // Reload the scene and ensure instance modifications remain
+                    {
+                        EditorApplication.LoadScene("unitTest4Scene_2.prefab");
+
+                        SceneObject root = Scene.Root;
+                        SceneObject parent2SO0 = root.FindChild("parent2SO0", false);
+                        SceneObject parent2SO1 = root.FindChild("parent2SO1", false);
+                        SceneObject parent2SO1_0 = parent2SO1.FindChild("parent2SO1_0", false);
+
+                        SceneObject prefabInstance = parent2SO0.GetChild(0);
+
+                        SceneObject so0 = prefabInstance.FindChild("so0", false);
+                        SceneObject so1 = prefabInstance.FindChild("so1", false);
+                        SceneObject so0_0 = so0.FindChild("so0_0", false);
+                        SceneObject so0_1 = so0.FindChild("so0_1", false);
+                        SceneObject so1_0 = so1.FindChild("so1_0", false);
+                        SceneObject so1_1 = so1.FindChild("so1_1", false);
+                        SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false);
+
+                        UT1_Component1 parentComp1_0 = parent2SO1_0.GetComponent<UT1_Component1>();
+                        UT1_Component1 comp0 = so0.GetComponent<UT1_Component1>();
+                        UT1_Component2 comp1 = so1.GetComponent<UT1_Component2>();
+                        UT1_Component1 comp11 = so1.GetComponent<UT1_Component1>();
+                        UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>();
+                        UT1_Component1 comp0_1 = so0_1.GetComponent<UT1_Component1>();
+
+                        Assert(so0_0 != null);
+                        Assert(comp0 != null);
+                        Assert(so1_1 == null);
+                        Assert(comp11 == null);
+
+                        Assert(comp0.otherSO == so0_1_0);
+                        Assert(comp0.otherComponent == comp1);
+
+                        Assert(parentComp1_0.otherSO == so1_0);
+                        Assert(parentComp1_0.otherComponent2 == comp0_1_0);
+
+                        Assert(comp0_1_0.otherSO == parent2SO1_0);
+                        Assert(comp0_1_0.otherComponent2 == parentComp1_0);
+                        Assert(comp0_1_0.b == "instanceValue");
+
+                        Assert(comp0_1.b == "instanceValue2");
+                    }
+
+                    // Load original scene and ensure instance modifications didn't influence it
+                    {
+                        EditorApplication.LoadScene("unitTest4Scene_1.prefab");
+
+                        SceneObject parentSO0 = Scene.Root.FindChild("parentSO0", false);
+                        SceneObject parentSO1 = Scene.Root.FindChild("parentSO1", false);
+                        SceneObject parentSO1_0 = parentSO1.FindChild("parentSO1_0", false);
+
+                        UT1_Component1 parentComp1_0 = parentSO1_0.GetComponent<UT1_Component1>();
+
+                        SceneObject prefabInstance = parentSO0.GetChild(0);
+                        SceneObject so0 = prefabInstance.FindChild("so0", false);
+                        SceneObject so1 = prefabInstance.FindChild("so1_modified", false);
+                        SceneObject so0_0 = so0.FindChild("so0_0", false);
+                        SceneObject so0_1 = so0.FindChild("so0_1", false);
+                        SceneObject so1_0 = so1.FindChild("so1_0", false);
+                        SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false);
+                        SceneObject so1_1 = so1.FindChild("so1_1", false);
+
+                        UT1_Component1 comp0 = so0.GetComponent<UT1_Component1>();
+                        UT1_Component1 comp1 = so1.GetComponent<UT1_Component1>();
+                        UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>();
+                        UT1_Component1 comp0_1 = so0_1.GetComponent<UT1_Component1>();
+
+                        Assert(parentComp1_0.otherSO == so1_0);
+                        Assert(parentComp1_0.otherComponent2 == comp0_1_0);
+                        Assert(so1_1 != null);
+                        Assert(so0_0 == null);
+                        Assert(comp0 == null);
+                        Assert(comp0_1_0.otherSO == so1_1);
+                        Assert(comp0_1_0.otherComponent2 == comp1);
+                        Assert(comp0_1_0.a == 123);
+                        Assert(comp0_1_0.b == "modifiedValue");
+                        Assert(comp1.otherSO == so1_0);
+                        Assert(comp1.otherComponent2 == comp0_1_0);
+                        Assert(comp0_1.b == "originalValue2");
+                        Assert(MathEx.ApproxEquals(so1.Position.y, 999.0f));
+                    }
+
+                    // Modify prefab and ensure both prefab and instance modifications remain
+                    {
+                        // unitTest4Scene_0.prefab:
+                        // so0 (Comp1)
+                        //  - so0_1
+                        //    - so0_1_0 (Comp1)
+                        // so1 (Comp1, Comp2)
+                        //  - so1_1
+                        //  - so1_2 (Comp1)
+
+                        // unitTest4Scene_0.prefab (unitTest4Scene_2.prefab instance):
+                        // so0 (Comp1)
+                        //  - so0_0
+                        //  - so0_1 (Comp1)
+                        //    - so0_1_0 (Comp1)
+                        // so1 (Comp2)
+                        //  - so1_2 (Comp1)
+
+                        Scene.Load("unitTest4Scene_0.prefab");
+
+                        SceneObject sceneRoot = Scene.Root;
+                        SceneObject so0 = sceneRoot.FindChild("so0", false);
+                        SceneObject so0_1 = so0.FindChild("so0_1", false);
+                        SceneObject so1 = sceneRoot.FindChild("so1_modified", false);
+                        SceneObject so1_0 = so1.FindChild("so1_0", false);
+                        SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false);
+
+                        SceneObject so1_2 = new SceneObject("so1_2");
+                        so1_2.Parent = so1;
+
+                        so0.AddComponent<UT1_Component1>();
+                        so0_1.RemoveComponent<UT1_Component1>();
+                        so1_0.Destroy();
+
+                        UT1_Component1 comp3 = so1_2.AddComponent<UT1_Component1>();
+                        UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>();
+                        comp0_1_0.b = "modifiedValueAgain";
+                        so1.Name = "so1_modifiedAgain";
+
+                        comp3.otherSO = so0_1;
+                        comp3.otherComponent2 = comp0_1_0;
+
+                        EditorApplication.SaveScene("unitTest4Scene_0.prefab");
+                    }
+
+                    // Reload the scene and ensure both instance and prefab modifications remain
+                    {
+                        EditorApplication.LoadScene("unitTest4Scene_2.prefab");
+
+                        SceneObject root = Scene.Root;
+                        SceneObject parent2SO0 = root.FindChild("parent2SO0", false);
+                        SceneObject parent2SO1 = root.FindChild("parent2SO1", false);
+                        SceneObject parent2SO1_0 = parent2SO1.FindChild("parent2SO1_0", false);
+
+                        SceneObject prefabInstance = parent2SO0.GetChild(0);
+
+                        SceneObject so0 = prefabInstance.FindChild("so0", false);
+                        SceneObject so1 = prefabInstance.FindChild("so1", false);
+                        SceneObject so0_0 = so0.FindChild("so0_0", false);
+                        SceneObject so0_1 = so0.FindChild("so0_1", false);
+                        SceneObject so1_0 = so1.FindChild("so1_0", false);
+                        SceneObject so1_1 = so1.FindChild("so1_1", false);
+                        SceneObject so1_2 = so1.FindChild("so1_2", false);
+                        SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false);
+
+                        UT1_Component1 parentComp1_0 = parent2SO1_0.GetComponent<UT1_Component1>();
+                        UT1_Component1 comp0 = so0.GetComponent<UT1_Component1>();
+                        UT1_Component2 comp1 = so1.GetComponent<UT1_Component2>();
+                        UT1_Component1 comp11 = so1.GetComponent<UT1_Component1>();
+                        UT1_Component1 comp0_1 = so1_1.GetComponent<UT1_Component1>();
+                        UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>();
+                        UT1_Component1 comp3 = so1_2.AddComponent<UT1_Component1>();
+
+                        // Check instance modifications (they should override any prefab modifications)
+                        Assert(so0_0 != null);
+                        Assert(comp0 != null);
+                        Assert(so1_1 == null);
+                        Assert(comp11 == null);
+
+                        Assert(comp0.otherSO == so0_1_0);
+                        Assert(comp0.otherComponent == comp1);
+
+                        Assert(parentComp1_0.otherSO == so1_0);
+                        Assert(parentComp1_0.otherComponent2 == comp0_1_0);
+
+                        Assert(comp0_1_0.otherSO == parent2SO1_0);
+                        Assert(comp0_1_0.otherComponent2 == parentComp1_0);
+                        Assert(comp0_1_0.b == "instanceValue");
+
+                        // Check prefab modifications
+                        Assert(comp0_1 != null);
+                        Assert(so1_0 == null);
+                        Assert(so1.Name == "so1_modifiedAgain");
+                        Assert(comp3.otherSO == so0_1);
+                        Assert(comp3.otherComponent2 == comp0_1_0);
+                    }
                 }
             }
+            finally
+            {
+                PrintSceneState();
 
-            if (!string.IsNullOrEmpty(oldScene))
-                Scene.Load(ProjectLibrary.GetPath(oldScene));
-            else
-                Scene.Clear();
+                if (!string.IsNullOrEmpty(oldScene))
+                    Scene.Load(ProjectLibrary.GetPath(oldScene));
+                else
+                    Scene.Clear();
 
-            // TODO - This cleanup should happen regardless if unit test fails or succeeds
-            ProjectLibrary.Delete("unitTest4Scene_0.prefab");
-            ProjectLibrary.Delete("unitTest4Scene_1.prefab");
-            ProjectLibrary.Delete("unitTest4Scene_2.prefab");
+                ProjectLibrary.Delete("unitTest4Scene_0.prefab");
+                ProjectLibrary.Delete("unitTest4Scene_1.prefab");
+                ProjectLibrary.Delete("unitTest4Scene_2.prefab");
+            }
         }
 
         /// <summary>