UnitTests.cs 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Runtime.CompilerServices;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using BansheeEngine;
  10. using DebugUnit = System.Diagnostics.Debug;
  11. namespace BansheeEditor
  12. {
  13. /// <summary>
  14. /// Contains various managed unit tests.
  15. /// </summary>
  16. class UnitTests
  17. {
  18. /// <summary>
  19. /// Triggers an exception when a unit test condition fails.
  20. /// </summary>
  21. /// <param name="success">True if the unit test condition succeeded, false otherwise.</param>
  22. static void Assert(bool success)
  23. {
  24. if (!success)
  25. throw new InvalidOperationException("Unit test failed.");
  26. }
  27. /// <summary>
  28. /// Tests managed object serialization and deserialization.
  29. /// </summary>
  30. static void UnitTest1_ManagedSerialization()
  31. {
  32. SceneObject otherSO = new SceneObject("OtherSO");
  33. UT1_Component2 dbgComponent2 = otherSO.AddComponent<UT1_Component2>();
  34. dbgComponent2.a2 = 33;
  35. SceneObject so = new SceneObject("TestSO");
  36. UT1_Component1 dbgComponent = so.AddComponent<UT1_Component1>();
  37. dbgComponent.a = 5;
  38. dbgComponent.b = "SomeTestVal";
  39. dbgComponent.complex.someValue = 19;
  40. dbgComponent.complex.anotherValue = "AnotherValue";
  41. dbgComponent.complex2.someValue2 = 21;
  42. dbgComponent.complex2.anotherValue2 = "AnotherValue2";
  43. dbgComponent.arrA = new int[5];
  44. dbgComponent.arrA[4] = 5;
  45. dbgComponent.arrB = new string[5];
  46. dbgComponent.arrB[4] = "ArrAnotherValue";
  47. dbgComponent.arrComplex = new UT1_SerzObj[5];
  48. dbgComponent.arrComplex[4].someValue = 99;
  49. dbgComponent.arrComplex[4].anotherValue = "ArrComplexAnotherValue";
  50. dbgComponent.arrComplex2 = new UT1_SerzCls[5];
  51. dbgComponent.arrComplex2[4] = new UT1_SerzCls();
  52. dbgComponent.arrComplex2[4].someValue2 = 101;
  53. dbgComponent.arrComplex2[4].anotherValue2 = "ArrComplex2AnotherValue";
  54. dbgComponent.listA = new List<int>();
  55. dbgComponent.listA.Add(5);
  56. dbgComponent.listB = new List<string>();
  57. dbgComponent.listB.Add("ListAnotherValue");
  58. dbgComponent.listB.Add(null);
  59. dbgComponent.listComplex = new List<UT1_SerzObj>();
  60. dbgComponent.listComplex.Add(new UT1_SerzObj());
  61. dbgComponent.listComplex.Add(new UT1_SerzObj(99, "ListComplexAnotherValue"));
  62. dbgComponent.listComplex2 = new List<UT1_SerzCls>();
  63. dbgComponent.listComplex2.Add(new UT1_SerzCls());
  64. dbgComponent.listComplex2[0].someValue2 = 101;
  65. dbgComponent.listComplex2[0].anotherValue2 = "ListComplexAnotherValue";
  66. dbgComponent.listComplex2.Add(null);
  67. dbgComponent.dictA = new Dictionary<int, string>();
  68. dbgComponent.dictA[5] = "value";
  69. dbgComponent.dictA[10] = "anotherValue";
  70. dbgComponent.dictB = new Dictionary<string, UT1_SerzObj>();
  71. dbgComponent.dictB["key1"] = new UT1_SerzObj(99, "DictComplexValue");
  72. dbgComponent.otherComponent = dbgComponent2;
  73. dbgComponent.otherSO = otherSO;
  74. Internal_UT1_GameObjectClone(so);
  75. System.Diagnostics.Debug.Assert(so.GetNumChildren() == 1);
  76. for (int i = 0; i < so.GetNumChildren(); i++)
  77. {
  78. SceneObject childSO = so.GetChild(i);
  79. UT1_Component1 otherComponent = childSO.GetComponent<UT1_Component1>();
  80. DebugUnit.Assert(otherComponent.a == 5);
  81. DebugUnit.Assert(otherComponent.b == "SomeTestVal");
  82. DebugUnit.Assert(otherComponent.complex.someValue == 19);
  83. DebugUnit.Assert(otherComponent.complex2.anotherValue2 == "AnotherValue2");
  84. DebugUnit.Assert(otherComponent.arrA[4] == 5);
  85. DebugUnit.Assert(otherComponent.arrB[4] == "ArrAnotherValue");
  86. DebugUnit.Assert(otherComponent.arrComplex[4].someValue == 99);
  87. DebugUnit.Assert(otherComponent.arrComplex2[4].anotherValue2 == "ArrComplex2AnotherValue");
  88. DebugUnit.Assert(otherComponent.listA[0] == 5);
  89. DebugUnit.Assert(otherComponent.listB[0] == "ListAnotherValue");
  90. DebugUnit.Assert(otherComponent.listComplex[1].someValue == 99);
  91. DebugUnit.Assert(otherComponent.listComplex2[0].anotherValue2 == "ListComplexAnotherValue");
  92. }
  93. so.Destroy();
  94. otherSO.Destroy();
  95. }
  96. /// <summary>
  97. /// Tests serializable properties used for inspection.
  98. /// </summary>
  99. static void UnitTest2_SerializableProperties()
  100. {
  101. SerializableObject obj = new SerializableObject(typeof(UT1_SerzCls), new UT1_SerzCls());
  102. SerializableProperty prop = obj.Fields[0].GetProperty();
  103. prop.SetValue(33);
  104. DebugUnit.Assert(prop.GetValue<int>() == 33);
  105. SerializableProperty prop2 = obj.Fields[2].GetProperty();
  106. UT1_SerzCls child = new UT1_SerzCls();
  107. child.anotherValue2 = "potato";
  108. prop2.SetValue<UT1_SerzCls>(child);
  109. DebugUnit.Assert(prop2.GetValue<UT1_SerzCls>() != null);
  110. DebugUnit.Assert(prop2.GetValue<UT1_SerzCls>().anotherValue2 == "potato");
  111. }
  112. /// <summary>
  113. /// Tests managed diff creation used by prefabs.
  114. /// </summary>
  115. static void UnitTest3_ManagedDiff()
  116. {
  117. UT_DiffObj original = new UT_DiffObj();
  118. UT_DiffObj modified = new UT_DiffObj();
  119. modified.plain2 = "banana";
  120. modified.complex = new UT_DiffChildObj();
  121. modified.complex2 = null;
  122. modified.complex3.plain2 = "tomato";
  123. modified.arrPlain1 = new[] {-1, -2, -3, -4};
  124. modified.arrPlain2[2] = "cherry";
  125. modified.arrComplex = new UT_DiffChildObj[3];
  126. modified.arrComplex2[0].plain1 = -10;
  127. modified.listPlain1[0] = -20;
  128. modified.listPlain2 = new List<string>();
  129. modified.listComplex = new List<UT_DiffChildObj>();
  130. modified.listComplex.Add(new UT_DiffChildObj());
  131. modified.listComplex2[1].plain2 = "orange";
  132. modified.dictPlain1.Remove(20);
  133. modified.dictPlain1[-30] = -30;
  134. modified.dictComplex = new Dictionary<int, UT_DiffChildObj>();
  135. modified.dictComplex[-40] = new UT_DiffChildObj();
  136. modified.dictComplex2[31].plain1 = -50;
  137. Internal_UT3_GenerateDiff(original, modified);
  138. Internal_UT3_ApplyDiff(original);
  139. DebugUnit.Assert(original.plain1 == modified.plain1);
  140. DebugUnit.Assert(original.plain2 == modified.plain2);
  141. DebugUnit.Assert(original.complex.plain2 == modified.complex.plain2);
  142. DebugUnit.Assert(original.complex2 == modified.complex2);
  143. DebugUnit.Assert(original.complex3.plain2 == modified.complex3.plain2);
  144. DebugUnit.Assert(original.arrPlain1.Length == modified.arrPlain1.Length);
  145. for (int i = 0; i < original.arrPlain1.Length; i++)
  146. DebugUnit.Assert(original.arrPlain1[i] == modified.arrPlain1[i]);
  147. for (int i = 0; i < original.arrPlain2.Length; i++)
  148. DebugUnit.Assert(original.arrPlain2[i] == modified.arrPlain2[i]);
  149. for (int i = 0; i < original.arrComplex.Length; i++)
  150. DebugUnit.Assert(original.arrComplex[i] == modified.arrComplex[i]);
  151. DebugUnit.Assert(original.arrComplex2[0].plain1 == modified.arrComplex2[0].plain1);
  152. for (int i = 0; i < original.listPlain1.Count; i++)
  153. DebugUnit.Assert(original.listPlain1[i] == modified.listPlain1[i]);
  154. DebugUnit.Assert(original.listPlain2.Count == modified.listPlain2.Count);
  155. for (int i = 0; i < original.listComplex.Count; i++)
  156. DebugUnit.Assert(original.listComplex[i].plain1 == modified.listComplex[i].plain1);
  157. DebugUnit.Assert(original.listComplex2[1].plain2 == modified.listComplex2[1].plain2);
  158. foreach (var entry in modified.dictPlain1)
  159. {
  160. if (!original.dictPlain1.ContainsKey(entry.Key))
  161. DebugUnit.Assert(false);
  162. DebugUnit.Assert(entry.Value == original.dictPlain1[entry.Key]);
  163. }
  164. foreach (var entry in modified.dictPlain2)
  165. {
  166. if (!original.dictPlain2.ContainsKey(entry.Key))
  167. DebugUnit.Assert(false);
  168. DebugUnit.Assert(entry.Value == original.dictPlain2[entry.Key]);
  169. }
  170. foreach (var entry in modified.dictComplex)
  171. {
  172. if (!original.dictComplex.ContainsKey(entry.Key))
  173. DebugUnit.Assert(false);
  174. DebugUnit.Assert(entry.Value.plain1 == original.dictComplex[entry.Key].plain1);
  175. }
  176. foreach (var entry in modified.dictComplex2)
  177. {
  178. if (!original.dictComplex2.ContainsKey(entry.Key))
  179. DebugUnit.Assert(false);
  180. DebugUnit.Assert(entry.Value.plain1 == original.dictComplex2[entry.Key].plain1);
  181. }
  182. }
  183. /// <summary>
  184. /// Tests saving, loading and updating of prefabs.
  185. /// </summary>
  186. private static void UnitTest4_Prefabs()
  187. {
  188. if (!EditorApplication.IsProjectLoaded)
  189. {
  190. Debug.LogWarning("Skipping unit test as no project is loaded.");
  191. return;
  192. }
  193. if (EditorApplication.IsSceneModified())
  194. {
  195. Debug.LogWarning("Cannot perform unit test as the current scene is modified.");
  196. return;
  197. }
  198. Action PrintSceneState = () =>
  199. {
  200. SceneObject root = Scene.Root;
  201. Stack<SceneObject> todo = new Stack<SceneObject>();
  202. todo.Push(root);
  203. StringBuilder output = new StringBuilder();
  204. while (todo.Count > 0)
  205. {
  206. SceneObject so = todo.Pop();
  207. int numChildren = so.GetNumChildren();
  208. for (int i = numChildren - 1; i >= 0; i--)
  209. {
  210. SceneObject child = so.GetChild(i);
  211. output.AppendLine(child.Name);
  212. todo.Push(child);
  213. }
  214. }
  215. Debug.Log(output);
  216. };
  217. // Disabled because it's a slow test, enable only when relevant (or when a build machine is set up)
  218. return;
  219. string oldScene = Scene.ActiveSceneUUID;
  220. Scene.Clear();
  221. try
  222. {
  223. // Simple scene save & load
  224. {
  225. {
  226. // unitTest4Scene_0.prefab:
  227. // so0 (Comp1)
  228. // - so0_0
  229. // - so0_1 (Comp1)
  230. // - so0_1_0 (Comp1)
  231. // so1 (Comp2)
  232. // - so1_0
  233. SceneObject so0 = new SceneObject("so0");
  234. SceneObject so1 = new SceneObject("so1");
  235. SceneObject so0_0 = new SceneObject("so0_0");
  236. SceneObject so0_1 = new SceneObject("so0_1");
  237. SceneObject so1_0 = new SceneObject("so1_0");
  238. SceneObject so0_1_0 = new SceneObject("so0_1_0");
  239. so0_0.Parent = so0;
  240. so0_1.Parent = so0;
  241. so1_0.Parent = so1;
  242. so0_1_0.Parent = so0_1;
  243. so0_1_0.LocalPosition = new Vector3(10.0f, 15.0f, 20.0f);
  244. so0_1.LocalPosition = new Vector3(1.0f, 2.0f, 3.0f);
  245. so1_0.LocalPosition = new Vector3(0, 123.0f, 0.0f);
  246. UT1_Component1 comp0 = so0.AddComponent<UT1_Component1>();
  247. UT1_Component2 comp1 = so1.AddComponent<UT1_Component2>();
  248. UT1_Component1 comp1_1 = so0_1.AddComponent<UT1_Component1>();
  249. UT1_Component1 comp0_1_0 = so0_1_0.AddComponent<UT1_Component1>();
  250. comp0.otherSO = so0_1_0;
  251. comp0.otherComponent = comp1;
  252. comp1_1.b = "originalValue2";
  253. comp0_1_0.b = "testValue";
  254. comp0_1_0.otherSO = so0;
  255. comp0_1_0.otherComponent2 = comp0;
  256. EditorApplication.SaveScene("unitTest4Scene_0.prefab");
  257. }
  258. {
  259. EditorApplication.LoadScene("unitTest4Scene_0.prefab");
  260. SceneObject sceneRoot = Scene.Root;
  261. SceneObject so0 = sceneRoot.FindChild("so0", false);
  262. SceneObject so1 = sceneRoot.FindChild("so1", false);
  263. SceneObject so0_0 = so0.FindChild("so0_0", false);
  264. SceneObject so0_1 = so0.FindChild("so0_1", false);
  265. SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false);
  266. Assert(so0_0 != null);
  267. Assert(so0_1 != null);
  268. Assert(so0_1_0 != null);
  269. UT1_Component1 comp0 = so0.GetComponent<UT1_Component1>();
  270. UT1_Component2 comp1 = so1.GetComponent<UT1_Component2>();
  271. UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>();
  272. Assert(comp0 != null);
  273. Assert(comp1 != null);
  274. Assert(comp0_1_0 != null);
  275. Assert(comp0_1_0.b == "testValue");
  276. Assert(comp0.otherSO == so0_1_0);
  277. Assert(comp0.otherComponent == comp1);
  278. Assert(comp0_1_0.otherSO == so0);
  279. Assert(comp0_1_0.otherComponent2 == comp0);
  280. }
  281. }
  282. Debug.Log("Passed stage 1");
  283. // Load & save a scene that contains a prefab and references its objects
  284. {
  285. {
  286. // unitTest4Scene_1.prefab:
  287. // parentSO0
  288. // - [unitTest4Scene_0.prefab]
  289. // parentSO1
  290. // - parentSO1_0 (Comp1)
  291. Scene.Clear();
  292. SceneObject parentSO0 = new SceneObject("parentSO0", false);
  293. SceneObject parentSO1 = new SceneObject("parentSO1", false);
  294. SceneObject parentSO1_0 = new SceneObject("parentSO1_0", false);
  295. parentSO1_0.Parent = parentSO1;
  296. parentSO0.LocalPosition = new Vector3(50.0f, 50.0f, 50.0f);
  297. UT1_Component1 parentComp1_0 = parentSO1_0.AddComponent<UT1_Component1>();
  298. Prefab scene0Prefab = ProjectLibrary.Load<Prefab>("unitTest4Scene_0.prefab");
  299. SceneObject prefabInstance = scene0Prefab.Instantiate();
  300. prefabInstance.Parent = parentSO0;
  301. prefabInstance.LocalPosition = Vector3.Zero;
  302. SceneObject so0 = prefabInstance.FindChild("so0", false);
  303. SceneObject so1 = prefabInstance.FindChild("so1", false);
  304. SceneObject so0_1 = so0.FindChild("so0_1", false);
  305. SceneObject so1_0 = so1.FindChild("so1_0", false);
  306. SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false);
  307. UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>();
  308. parentComp1_0.otherSO = so1_0;
  309. parentComp1_0.otherComponent2 = comp0_1_0;
  310. EditorApplication.SaveScene("unitTest4Scene_1.prefab");
  311. }
  312. {
  313. EditorApplication.LoadScene("unitTest4Scene_1.prefab");
  314. SceneObject parentSO0 = Scene.Root.FindChild("parentSO0", false);
  315. SceneObject parentSO1 = Scene.Root.FindChild("parentSO1", false);
  316. SceneObject parentSO1_0 = parentSO1.FindChild("parentSO1_0", false);
  317. UT1_Component1 parentComp1_0 = parentSO1_0.GetComponent<UT1_Component1>();
  318. SceneObject prefabInstance = parentSO0.GetChild(0);
  319. SceneObject so0 = prefabInstance.FindChild("so0", false);
  320. SceneObject so1 = prefabInstance.FindChild("so1", false);
  321. SceneObject so0_1 = so0.FindChild("so0_1", false);
  322. SceneObject so1_0 = so1.FindChild("so1_0", false);
  323. SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false);
  324. UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>();
  325. Assert(parentComp1_0.otherSO == so1_0);
  326. Assert(parentComp1_0.otherComponent2 == comp0_1_0);
  327. }
  328. }
  329. Debug.Log("Passed stage 2");
  330. // Modify prefab, reload the scene and ensure it is updated with modified prefab
  331. {
  332. {
  333. // unitTest4Scene_0.prefab:
  334. // so0
  335. // - so0_1 (Comp1)
  336. // - so0_1_0 (Comp1)
  337. // so1 (Comp1, Comp2)
  338. // - so1_0
  339. // - so1_1
  340. Scene.Load("unitTest4Scene_0.prefab");
  341. SceneObject sceneRoot = Scene.Root;
  342. SceneObject so0 = sceneRoot.FindChild("so0", false);
  343. SceneObject so0_0 = so0.FindChild("so0_0", false);
  344. SceneObject so0_1 = so0.FindChild("so0_1", false);
  345. SceneObject so1 = sceneRoot.FindChild("so1", false);
  346. SceneObject so1_0 = so1.FindChild("so1_0", false);
  347. SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false);
  348. SceneObject so1_1 = new SceneObject("so1_1");
  349. so1_1.Parent = so1;
  350. so0.RemoveComponent<UT1_Component1>();
  351. UT1_Component1 comp1 = so1.AddComponent<UT1_Component1>();
  352. UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>();
  353. so0_0.Destroy();
  354. comp1.otherSO = so1_0;
  355. comp1.otherComponent2 = comp0_1_0;
  356. comp0_1_0.otherSO = so1_1;
  357. comp0_1_0.otherComponent2 = comp1;
  358. comp0_1_0.a = 123;
  359. comp0_1_0.b = "modifiedValue";
  360. so1.Name = "so1_modified";
  361. so1.LocalPosition = new Vector3(0, 999.0f, 0.0f);
  362. EditorApplication.SaveScene("unitTest4Scene_0.prefab");
  363. }
  364. {
  365. EditorApplication.LoadScene("unitTest4Scene_1.prefab");
  366. SceneObject parentSO0 = Scene.Root.FindChild("parentSO0", false);
  367. SceneObject parentSO1 = Scene.Root.FindChild("parentSO1", false);
  368. SceneObject parentSO1_0 = parentSO1.FindChild("parentSO1_0", false);
  369. UT1_Component1 parentComp1_0 = parentSO1_0.GetComponent<UT1_Component1>();
  370. SceneObject prefabInstance = parentSO0.GetChild(0);
  371. SceneObject so0 = prefabInstance.FindChild("so0", false);
  372. SceneObject so1 = prefabInstance.FindChild("so1_modified", false);
  373. SceneObject so0_0 = so0.FindChild("so0_0", false);
  374. SceneObject so0_1 = so0.FindChild("so0_1", false);
  375. SceneObject so1_0 = so1.FindChild("so1_0", false);
  376. SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false);
  377. SceneObject so1_1 = so1.FindChild("so1_1", false);
  378. UT1_Component1 comp0 = so0.GetComponent<UT1_Component1>();
  379. UT1_Component1 comp1 = so1.GetComponent<UT1_Component1>();
  380. UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>();
  381. Assert(parentComp1_0.otherSO == so1_0);
  382. Assert(parentComp1_0.otherComponent2 == comp0_1_0);
  383. Assert(so1_1 != null);
  384. Assert(so0_0 == null);
  385. Assert(comp0 == null);
  386. Assert(comp0_1_0.otherSO == so1_1);
  387. Assert(comp0_1_0.otherComponent2 == comp1);
  388. Assert(comp0_1_0.a == 123);
  389. Assert(comp0_1_0.b == "modifiedValue");
  390. Assert(comp1.otherSO == so1_0);
  391. Assert(comp1.otherComponent2 == comp0_1_0);
  392. Assert(MathEx.ApproxEquals(so1.LocalPosition.y, 999.0f));
  393. }
  394. }
  395. Debug.Log("Passed stage 3");
  396. // Make instance specific changes to the prefab, modify the prefab itself and ensure
  397. // both changes persist
  398. {
  399. // Create new scene referencing the prefab and make instance modifications
  400. {
  401. // unitTest4Scene_2.prefab:
  402. // parent2SO0
  403. // - [unitTest4Scene_0.prefab]
  404. // parent2SO1
  405. // - parent2SO1_0 (Comp1)
  406. // unitTest4Scene_0.prefab (unitTest4Scene_2.prefab instance):
  407. // so0 (Comp1(INSTANCE))
  408. // - so0_0 (INSTANCE)
  409. // - so0_1 (Comp1)
  410. // - so0_1_0 (Comp1)
  411. // so1 (Comp2)
  412. // - so1_0
  413. Scene.Clear();
  414. SceneObject parent2SO0 = new SceneObject("parent2SO0");
  415. SceneObject parent2SO1 = new SceneObject("parent2SO1");
  416. SceneObject parent2SO1_0 = new SceneObject("parent2SO1_0");
  417. parent2SO1_0.Parent = parent2SO1;
  418. UT1_Component1 parentComp1_0 = parent2SO1_0.AddComponent<UT1_Component1>();
  419. Prefab scene0Prefab = ProjectLibrary.Load<Prefab>("unitTest4Scene_0.prefab");
  420. SceneObject prefabInstance = scene0Prefab.Instantiate();
  421. prefabInstance.Parent = parent2SO0;
  422. SceneObject so0 = prefabInstance.FindChild("so0", false);
  423. SceneObject so1 = prefabInstance.FindChild("so1_modified", false);
  424. SceneObject so0_1 = so0.FindChild("so0_1", false);
  425. SceneObject so1_0 = so1.FindChild("so1_0", false);
  426. SceneObject so1_1 = so1.FindChild("so1_1", false);
  427. SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false);
  428. UT1_Component2 comp1 = so1.GetComponent<UT1_Component2>();
  429. UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>();
  430. UT1_Component1 comp0_1 = so0_1.GetComponent<UT1_Component1>();
  431. SceneObject so0_0 = new SceneObject("so0_0");
  432. so0_0.Parent = so0;
  433. UT1_Component1 comp0 = so0.AddComponent<UT1_Component1>();
  434. so1.RemoveComponent<UT1_Component1>();
  435. so1_1.Destroy();
  436. comp0.otherSO = so0_1_0;
  437. comp0.otherComponent = comp1;
  438. parentComp1_0.otherSO = so1_0;
  439. parentComp1_0.otherComponent2 = comp0_1_0;
  440. comp0_1_0.otherSO = parent2SO1_0;
  441. comp0_1_0.otherComponent2 = parentComp1_0;
  442. comp0_1_0.b = "instanceValue";
  443. comp0_1.b = "instanceValue2";
  444. EditorApplication.SaveScene("unitTest4Scene_2.prefab");
  445. }
  446. Debug.Log("Passed stage 4.1");
  447. // Reload the scene and ensure instance modifications remain
  448. {
  449. EditorApplication.LoadScene("unitTest4Scene_2.prefab");
  450. SceneObject root = Scene.Root;
  451. SceneObject parent2SO0 = root.FindChild("parent2SO0", false);
  452. SceneObject parent2SO1 = root.FindChild("parent2SO1", false);
  453. SceneObject parent2SO1_0 = parent2SO1.FindChild("parent2SO1_0", false);
  454. SceneObject prefabInstance = parent2SO0.GetChild(0);
  455. SceneObject so0 = prefabInstance.FindChild("so0", false);
  456. SceneObject so1 = prefabInstance.FindChild("so1_modified", false);
  457. SceneObject so0_0 = so0.FindChild("so0_0", false);
  458. SceneObject so0_1 = so0.FindChild("so0_1", false);
  459. SceneObject so1_0 = so1.FindChild("so1_0", false);
  460. SceneObject so1_1 = so1.FindChild("so1_1", false);
  461. SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false);
  462. UT1_Component1 parentComp1_0 = parent2SO1_0.GetComponent<UT1_Component1>();
  463. UT1_Component1 comp0 = so0.GetComponent<UT1_Component1>();
  464. UT1_Component2 comp1 = so1.GetComponent<UT1_Component2>();
  465. UT1_Component1 comp11 = so1.GetComponent<UT1_Component1>();
  466. UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>();
  467. UT1_Component1 comp0_1 = so0_1.GetComponent<UT1_Component1>();
  468. Assert(so0_0 != null);
  469. Assert(comp0 != null);
  470. Assert(so1_1 == null);
  471. Assert(comp11 == null);
  472. Assert(comp0.otherSO == so0_1_0);
  473. Assert(comp0.otherComponent == comp1);
  474. Assert(parentComp1_0.otherSO == so1_0);
  475. Assert(parentComp1_0.otherComponent2 == comp0_1_0);
  476. Debug.Log(comp0_1_0.otherSO == null);
  477. if (comp0_1_0.otherSO != null)
  478. Debug.Log(comp0_1_0.otherSO.InstanceId + " - " + parent2SO1_0.InstanceId);
  479. Assert(comp0_1_0.otherSO == parent2SO1_0);
  480. Assert(comp0_1_0.otherComponent2 == parentComp1_0);
  481. Assert(comp0_1_0.b == "instanceValue");
  482. Assert(comp0_1.b == "instanceValue2");
  483. }
  484. Debug.Log("Passed stage 4.2");
  485. // Load original scene and ensure instance modifications didn't influence it
  486. {
  487. EditorApplication.LoadScene("unitTest4Scene_1.prefab");
  488. SceneObject parentSO0 = Scene.Root.FindChild("parentSO0", false);
  489. SceneObject parentSO1 = Scene.Root.FindChild("parentSO1", false);
  490. SceneObject parentSO1_0 = parentSO1.FindChild("parentSO1_0", false);
  491. UT1_Component1 parentComp1_0 = parentSO1_0.GetComponent<UT1_Component1>();
  492. SceneObject prefabInstance = parentSO0.GetChild(0);
  493. SceneObject so0 = prefabInstance.FindChild("so0", false);
  494. SceneObject so1 = prefabInstance.FindChild("so1_modified", false);
  495. SceneObject so0_0 = so0.FindChild("so0_0", false);
  496. SceneObject so0_1 = so0.FindChild("so0_1", false);
  497. SceneObject so1_0 = so1.FindChild("so1_0", false);
  498. SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false);
  499. SceneObject so1_1 = so1.FindChild("so1_1", false);
  500. UT1_Component1 comp0 = so0.GetComponent<UT1_Component1>();
  501. UT1_Component1 comp1 = so1.GetComponent<UT1_Component1>();
  502. UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>();
  503. UT1_Component1 comp0_1 = so0_1.GetComponent<UT1_Component1>();
  504. Assert(parentComp1_0.otherSO == so1_0);
  505. Assert(parentComp1_0.otherComponent2 == comp0_1_0);
  506. Assert(so1_1 != null);
  507. Assert(so0_0 == null);
  508. Assert(comp0 == null);
  509. Assert(comp0_1_0.otherSO == so1_1);
  510. Assert(comp0_1_0.otherComponent2 == comp1);
  511. Assert(comp0_1_0.a == 123);
  512. Assert(comp0_1_0.b == "modifiedValue");
  513. Assert(comp1.otherSO == so1_0);
  514. Assert(comp1.otherComponent2 == comp0_1_0);
  515. Assert(comp0_1.b == "originalValue2");
  516. Assert(MathEx.ApproxEquals(so1.LocalPosition.y, 999.0f));
  517. }
  518. Debug.Log("Passed stage 4.3");
  519. // Modify prefab and ensure both prefab and instance modifications remain
  520. {
  521. // unitTest4Scene_0.prefab:
  522. // so0 (Comp1)
  523. // - so0_1
  524. // - so0_1_0 (Comp1)
  525. // so1 (Comp1, Comp2)
  526. // - so1_1
  527. // - so1_2 (Comp1)
  528. // unitTest4Scene_0.prefab (unitTest4Scene_2.prefab instance):
  529. // so0 (Comp1)
  530. // - so0_0
  531. // - so0_1 (Comp1)
  532. // - so0_1_0 (Comp1)
  533. // so1 (Comp2)
  534. // - so1_2 (Comp1)
  535. Scene.Load("unitTest4Scene_0.prefab");
  536. SceneObject sceneRoot = Scene.Root;
  537. SceneObject so0 = sceneRoot.FindChild("so0", false);
  538. SceneObject so0_1 = so0.FindChild("so0_1", false);
  539. SceneObject so1 = sceneRoot.FindChild("so1_modified", false);
  540. SceneObject so1_0 = so1.FindChild("so1_0", false);
  541. SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false);
  542. SceneObject so1_2 = new SceneObject("so1_2");
  543. so1_2.Parent = so1;
  544. so0.AddComponent<UT1_Component1>();
  545. so0_1.RemoveComponent<UT1_Component1>();
  546. so1_0.Destroy();
  547. UT1_Component1 comp3 = so1_2.AddComponent<UT1_Component1>();
  548. UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>();
  549. comp0_1_0.b = "modifiedValueAgain";
  550. so1.Name = "so1_modifiedAgain";
  551. comp3.otherSO = so0_1;
  552. comp3.otherComponent2 = comp0_1_0;
  553. EditorApplication.SaveScene("unitTest4Scene_0.prefab");
  554. }
  555. Debug.Log("Passed stage 4.4");
  556. // Reload the scene and ensure both instance and prefab modifications remain
  557. {
  558. EditorApplication.LoadScene("unitTest4Scene_2.prefab");
  559. SceneObject root = Scene.Root;
  560. SceneObject parent2SO0 = root.FindChild("parent2SO0", false);
  561. SceneObject parent2SO1 = root.FindChild("parent2SO1", false);
  562. SceneObject parent2SO1_0 = parent2SO1.FindChild("parent2SO1_0", false);
  563. SceneObject prefabInstance = parent2SO0.GetChild(0);
  564. SceneObject so0 = prefabInstance.FindChild("so0", false);
  565. SceneObject so1 = prefabInstance.FindChild("so1_modifiedAgain", false);
  566. SceneObject so0_0 = so0.FindChild("so0_0", false);
  567. SceneObject so0_1 = so0.FindChild("so0_1", false);
  568. SceneObject so1_0 = so1.FindChild("so1_0", false);
  569. SceneObject so1_1 = so1.FindChild("so1_1", false);
  570. SceneObject so1_2 = so1.FindChild("so1_2", false);
  571. SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false);
  572. UT1_Component1 parentComp1_0 = parent2SO1_0.GetComponent<UT1_Component1>();
  573. UT1_Component1 comp0 = so0.GetComponent<UT1_Component1>();
  574. UT1_Component2 comp1 = so1.GetComponent<UT1_Component2>();
  575. UT1_Component1 comp11 = so1.GetComponent<UT1_Component1>();
  576. UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>();
  577. UT1_Component1 comp3 = so1_2.AddComponent<UT1_Component1>();
  578. // Check instance modifications (they should override any prefab modifications)
  579. Assert(so0_0 != null);
  580. Assert(comp0 != null);
  581. Assert(so1_1 == null);
  582. Assert(comp11 == null);
  583. Assert(comp0.otherSO == so0_1_0);
  584. Assert(comp0.otherComponent == comp1);
  585. Assert(parentComp1_0.otherSO == so1_0);
  586. Assert(parentComp1_0.otherComponent2 == comp0_1_0);
  587. Assert(comp0_1_0.otherSO == parent2SO1_0);
  588. Assert(comp0_1_0.otherComponent2 == parentComp1_0);
  589. Assert(comp0_1_0.b == "instanceValue");
  590. // Check prefab modifications
  591. Assert(so1_0 == null);
  592. Assert(so1.Name == "so1_modifiedAgain");
  593. Assert(comp3.otherSO == so0_1);
  594. Assert(comp3.otherComponent2 == comp0_1_0);
  595. }
  596. Debug.Log("Passed stage 4.5");
  597. }
  598. }
  599. catch
  600. {
  601. PrintSceneState();
  602. throw;
  603. }
  604. finally
  605. {
  606. if (!string.IsNullOrEmpty(oldScene))
  607. Scene.Load(ProjectLibrary.GetPath(oldScene));
  608. else
  609. Scene.Clear();
  610. ProjectLibrary.Delete("unitTest4Scene_0.prefab");
  611. ProjectLibrary.Delete("unitTest4Scene_1.prefab");
  612. ProjectLibrary.Delete("unitTest4Scene_2.prefab");
  613. }
  614. }
  615. /// <summary>
  616. /// Runs all tests.
  617. /// </summary>
  618. static void RunTests()
  619. {
  620. UnitTest1_ManagedSerialization();
  621. UnitTest2_SerializableProperties();
  622. UnitTest3_ManagedDiff();
  623. UnitTest4_Prefabs();
  624. }
  625. [MethodImpl(MethodImplOptions.InternalCall)]
  626. private static extern void Internal_UT1_GameObjectClone(SceneObject so);
  627. [MethodImpl(MethodImplOptions.InternalCall)]
  628. private static extern void Internal_UT3_GenerateDiff(UT_DiffObj oldObj, UT_DiffObj newObj);
  629. [MethodImpl(MethodImplOptions.InternalCall)]
  630. private static extern void Internal_UT3_ApplyDiff(UT_DiffObj obj);
  631. }
  632. }