UnitTests.cs 32 KB

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