Base.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. // ***********************************************************************
  2. // Copyright (c) 2017 Unity Technologies. All rights reserved.
  3. //
  4. // Licensed under the ##LICENSENAME##.
  5. // See LICENSE.md file in the project root for full license information.
  6. // ***********************************************************************
  7. using NUnit.Framework;
  8. using Autodesk.Fbx;
  9. using System.Collections.Generic;
  10. namespace Autodesk.Fbx.UnitTests
  11. {
  12. public abstract class Base<T> : TestBase<T> where T: Autodesk.Fbx.FbxObject
  13. {
  14. // T.Create(FbxManager, string)
  15. static System.Reflection.MethodInfo s_createFromMgrAndName;
  16. // T.Create(FbxObject, string)
  17. static System.Reflection.MethodInfo s_createFromObjAndName;
  18. static Base() {
  19. s_createFromMgrAndName = typeof(T).GetMethod("Create", new System.Type[] {typeof(FbxManager), typeof(string)});
  20. s_createFromObjAndName = typeof(T).GetMethod("Create", new System.Type[] {typeof(FbxObject), typeof(string)});
  21. #if ENABLE_COVERAGE_TEST
  22. // Register the calls we make through reflection.
  23. // We use reflection in CreateObject(FbxManager, string) and CreateObject(FbxObject, string).
  24. if (s_createFromMgrAndName != null) {
  25. var createFromMgrAndName = typeof(Base<T>).GetMethod("CreateObject", new System.Type[] {typeof(FbxManager), typeof(string)});
  26. CoverageTester.RegisterReflectionCall(createFromMgrAndName, s_createFromMgrAndName);
  27. }
  28. if (s_createFromObjAndName != null) {
  29. var createFromObjAndName = typeof(Base<T>).GetMethod("CreateObject", new System.Type[] {typeof(FbxObject), typeof(string)});
  30. CoverageTester.RegisterReflectionCall(createFromObjAndName, s_createFromObjAndName);
  31. }
  32. #endif
  33. }
  34. protected FbxManager Manager {
  35. get;
  36. private set;
  37. }
  38. /* Create an object with the default manager. */
  39. public T CreateObject (string name = "") {
  40. return CreateObject(Manager, name);
  41. }
  42. /* Test all the equality functions we can find. */
  43. [Test]
  44. public virtual void TestEquality() {
  45. var a = CreateObject("a");
  46. var b = CreateObject("b");
  47. var acopy = a; // TODO: get a different proxy to the same underlying object
  48. EqualityTester<T>.TestEquality(a, b, acopy);
  49. }
  50. /* Create an object with another manager. Default implementation uses
  51. * reflection to call T.Create(...); override if reflection is wrong. */
  52. public virtual T CreateObject (FbxManager mgr, string name = "") {
  53. return Invoker.InvokeStatic<T>(s_createFromMgrAndName, mgr, name);
  54. }
  55. /* Create an object with an object as container. Default implementation uses
  56. * reflection to call T.Create(...); override if reflection is wrong. */
  57. public virtual T CreateObject (FbxObject container, string name = "") {
  58. return Invoker.InvokeStatic<T>(s_createFromObjAndName, container, name);
  59. }
  60. [SetUp]
  61. public virtual void Init ()
  62. {
  63. Manager = FbxManager.Create ();
  64. }
  65. [TearDown]
  66. public virtual void Term ()
  67. {
  68. try {
  69. Manager.Destroy ();
  70. }
  71. catch (System.ArgumentNullException) {
  72. }
  73. }
  74. /// <summary>
  75. /// Test that an object created within a scene knows its scene.
  76. /// Override for objects that can't be in a scene.
  77. /// </summary>
  78. protected virtual void TestSceneContainer()
  79. {
  80. using(var scene = FbxScene.Create(Manager, "thescene")) {
  81. var obj = CreateObject(scene, "scene_object");
  82. Assert.AreEqual(scene, obj.GetScene());
  83. var child = CreateObject(obj, "scene_object_child");
  84. Assert.AreEqual(scene, child.GetScene());
  85. }
  86. {
  87. var obj = CreateObject(Manager, "not_scene_object");
  88. Assert.AreEqual(null, obj.GetScene());
  89. }
  90. }
  91. [Test]
  92. public virtual void TestCreate()
  93. {
  94. var obj = CreateObject("MyObject");
  95. Assert.IsInstanceOf<T> (obj);
  96. Assert.AreEqual(Manager, obj.GetFbxManager());
  97. using(var manager2 = FbxManager.Create()) {
  98. var obj2 = CreateObject(manager2, "MyOtherObject");
  99. Assert.AreEqual(manager2, obj2.GetFbxManager());
  100. Assert.AreNotEqual(Manager, obj2.GetFbxManager());
  101. }
  102. var obj3 = CreateObject(obj, "MySubObject");
  103. Assert.AreEqual(Manager, obj3.GetFbxManager());
  104. // Test with a null manager or container. Should throw.
  105. Assert.That (() => { CreateObject((FbxManager)null, "MyObject"); }, Throws.Exception.TypeOf<System.ArgumentNullException>());
  106. Assert.That (() => { CreateObject((FbxObject)null, "MyObject"); }, Throws.Exception.TypeOf<System.ArgumentNullException>());
  107. // Test having a scene as the container.
  108. TestSceneContainer();
  109. // Test with a null string. Should work.
  110. Assert.IsNotNull(CreateObject((string)null));
  111. // Test with a destroyed manager. Should throw.
  112. var mgr = FbxManager.Create();
  113. mgr.Destroy();
  114. Assert.That (() => { CreateObject(mgr, "MyObject"); }, Throws.Exception.TypeOf<System.ArgumentNullException>());
  115. // Test with a disposed manager. Should throw.
  116. mgr = FbxManager.Create();
  117. mgr.Dispose();
  118. Assert.That (() => { CreateObject(mgr, "MyObject"); }, Throws.Exception.TypeOf<System.ArgumentNullException>());
  119. }
  120. [Test]
  121. public virtual void TestDisposeDestroy ()
  122. {
  123. DoTestDisposeDestroy(canDestroyNonRecursive: true);
  124. }
  125. public virtual void DoTestDisposeDestroy (bool canDestroyNonRecursive)
  126. {
  127. T a, b;
  128. // Test destroying just yourself.
  129. a = CreateObject ("a");
  130. b = CreateObject(a, "b");
  131. a.Destroy ();
  132. Assert.That(() => a.GetName(), Throws.Exception.TypeOf<System.ArgumentNullException>());
  133. if (canDestroyNonRecursive) {
  134. b.GetName(); // does not throw! tests that the implicit 'pRecursive: false' got through
  135. b.Destroy();
  136. } else {
  137. Assert.That(() => b.GetName(), Throws.Exception.TypeOf<System.ArgumentNullException>());
  138. }
  139. // Test destroying just yourself, explicitly non-recursive.
  140. a = CreateObject ("a");
  141. b = CreateObject(a, "b");
  142. a.Destroy (false);
  143. Assert.That(() => a.GetName(), Throws.Exception.TypeOf<System.ArgumentNullException>());
  144. if (canDestroyNonRecursive) {
  145. b.GetName(); // does not throw! tests that the explicit 'false' got through
  146. b.Destroy();
  147. } else {
  148. Assert.That(() => b.GetName(), Throws.Exception.TypeOf<System.ArgumentNullException>());
  149. }
  150. // Test destroying recursively.
  151. a = CreateObject ("a");
  152. b = CreateObject(a, "b");
  153. a.Destroy(true);
  154. Assert.That(() => b.GetName(), Throws.Exception.TypeOf<System.ArgumentNullException>());
  155. Assert.That(() => a.GetName(), Throws.Exception.TypeOf<System.ArgumentNullException>());
  156. // Test disposing. TODO: how to test that a was actually destroyed?
  157. a = CreateObject("a");
  158. a.Dispose();
  159. Assert.That(() => a.GetName(), Throws.Exception.TypeOf<System.ArgumentNullException>());
  160. // Test that the using statement works.
  161. using (a = CreateObject ("a")) {
  162. a.GetName (); // works here, throws outside using
  163. }
  164. Assert.That(() => a.GetName(), Throws.Exception.TypeOf<System.ArgumentNullException>());
  165. // Test that if we try to use an object after Destroy()ing its
  166. // manager, the object was destroyed as well.
  167. a = CreateObject("a");
  168. Assert.IsNotNull (a);
  169. Manager.Destroy();
  170. Assert.That (() => { a.GetName (); }, Throws.Exception.TypeOf<System.ArgumentNullException>());
  171. }
  172. [Test]
  173. public void TestVarious()
  174. {
  175. FbxObject obj;
  176. /************************************************************
  177. * Test selection
  178. ************************************************************/
  179. obj = CreateObject ();
  180. Assert.IsFalse (obj.GetSelected ());
  181. obj.SetSelected (true);
  182. Assert.IsTrue (obj.GetSelected ());
  183. /************************************************************
  184. * Test name-related functions.
  185. ************************************************************/
  186. /*
  187. * We use this also for testing that string handling works.
  188. * Make sure we can pass const char*, FbxString, and const
  189. * FbxString&.
  190. * Make sure we can return those too (though I'm not actually
  191. * seeing a return of a const-ref anywhere).
  192. */
  193. // Test a function that takes const char*.
  194. obj = FbxObject.Create(Manager, "MyObject");
  195. Assert.IsNotNull (obj);
  196. // Test a function that returns const char*.
  197. Assert.AreEqual ("MyObject", obj.GetName ());
  198. // Test a function that takes an FbxString with an accent in it.
  199. obj.SetNameSpace("Accentué");
  200. // Test a function that returns FbxString.
  201. Assert.AreEqual ("MyObject", obj.GetNameWithoutNameSpacePrefix ());
  202. // Test a function that returns FbxString with an accent in it.
  203. Assert.AreEqual ("Accentué", obj.GetNameSpaceOnly());
  204. // Test a function that takes a const char* and returns an FbxString.
  205. // We don't want to convert the other StripPrefix functions, which
  206. // modify their argument in-place.
  207. Assert.AreEqual("MyObject", FbxObject.StripPrefix("NameSpace::MyObject"));
  208. obj.SetName("new name");
  209. Assert.AreEqual("new name", obj.GetName());
  210. obj.SetInitialName("init");
  211. Assert.AreEqual("init", obj.GetInitialName());
  212. /************************************************************
  213. * Test shader implementations
  214. ************************************************************/
  215. using (obj = FbxObject.Create(Manager, "MyObject")) {
  216. var impl = FbxImplementation.Create(obj, "impl");
  217. Assert.IsTrue(obj.AddImplementation(impl));
  218. Assert.IsTrue(obj.RemoveImplementation(impl));
  219. Assert.IsTrue(obj.AddImplementation(impl));
  220. Assert.IsTrue(obj.SetDefaultImplementation(impl));
  221. Assert.AreEqual(impl, obj.GetDefaultImplementation());
  222. Assert.IsTrue(obj.HasDefaultImplementation());
  223. }
  224. /************************************************************
  225. * Test property functions
  226. ************************************************************/
  227. using (obj = CreateObject("theobj")) {
  228. using(var obj2 = CreateObject("otherobj")) {
  229. // Make a property and connect it from obj to obj2.
  230. var prop = FbxProperty.Create(obj, Globals.FbxBoolDT, "maybe");
  231. var prop2 = FbxProperty.Create(obj, Globals.FbxFloatDT, "probability");
  232. Assert.IsTrue(obj.ConnectSrcProperty(prop));
  233. Assert.IsTrue(obj.ConnectSrcProperty(prop2));
  234. Assert.IsTrue(obj2.ConnectDstProperty(prop));
  235. Assert.IsTrue(obj.IsConnectedSrcProperty(prop));
  236. Assert.IsTrue(obj2.IsConnectedDstProperty(prop));
  237. Assert.AreEqual(2, obj.GetSrcPropertyCount());
  238. Assert.AreEqual(1, obj2.GetDstPropertyCount());
  239. Assert.AreEqual(prop, obj.GetSrcProperty());
  240. Assert.AreEqual(prop, obj.GetSrcProperty(0));
  241. Assert.AreEqual(prop2, obj.GetSrcProperty(1));
  242. Assert.AreEqual(prop, obj2.GetDstProperty());
  243. Assert.AreEqual(prop, obj2.GetDstProperty(0));
  244. Assert.AreEqual(prop, obj.FindSrcProperty("maybe"));
  245. Assert.AreEqual(prop, obj2.FindDstProperty("maybe"));
  246. Assert.IsFalse(obj.FindSrcProperty("maybe", 1).IsValid());
  247. Assert.IsFalse(obj2.FindDstProperty("maybe", 1).IsValid());
  248. // Iterating over properties
  249. Assert.IsTrue(obj.GetFirstProperty().IsValid());
  250. Assert.IsTrue(obj.GetNextProperty(obj.GetFirstProperty()).IsValid());
  251. Assert.IsTrue(obj.GetClassRootProperty().IsValid());
  252. // FindProperty
  253. Assert.AreEqual(prop, obj.FindProperty("maybe"));
  254. Assert.AreEqual(prop, obj.FindProperty("mayBE", false));
  255. Assert.IsFalse(obj.FindProperty("mayBE", true).IsValid());
  256. Assert.AreEqual(prop, obj.FindProperty("maybe", Globals.FbxBoolDT));
  257. Assert.AreEqual(prop, obj.FindProperty("mayBE", Globals.FbxBoolDT, false));
  258. // FindPropertyHierarchical
  259. Assert.AreEqual(prop, obj.FindPropertyHierarchical("maybe"));
  260. Assert.AreEqual(prop, obj.FindPropertyHierarchical("mayBE", false));
  261. Assert.IsFalse(obj.FindPropertyHierarchical("mayBE", true).IsValid());
  262. Assert.AreEqual(prop, obj.FindPropertyHierarchical("maybe", Globals.FbxBoolDT));
  263. Assert.AreEqual(prop, obj.FindPropertyHierarchical("mayBE", Globals.FbxBoolDT, false));
  264. // Disconnecting
  265. int nSrc = obj.GetSrcPropertyCount();
  266. int nDst = obj2.GetDstPropertyCount();
  267. Assert.IsTrue(obj.DisconnectSrcProperty(prop));
  268. Assert.IsTrue(obj2.DisconnectDstProperty(prop));
  269. Assert.AreEqual(nSrc - 1, obj.GetSrcPropertyCount());
  270. Assert.AreEqual(nDst - 1, obj2.GetDstPropertyCount());
  271. }
  272. }
  273. /************************************************************
  274. * Test object connection functions
  275. ************************************************************/
  276. // need to order them this way for FbxScene, which deletes obj if Source Object is destroyed
  277. using (var ownerObj = CreateObject ("ownerObj")) {
  278. using (obj = CreateObject ("obj")) {
  279. // Test ConnectSrcObject functions
  280. int origCount = ownerObj.GetSrcObjectCount ();
  281. bool result = ownerObj.ConnectSrcObject (obj);
  282. Assert.IsTrue (result);
  283. Assert.IsTrue (ownerObj.IsConnectedSrcObject (obj));
  284. Assert.AreEqual (origCount + 1, ownerObj.GetSrcObjectCount ());
  285. if (origCount == 0) {
  286. Assert.AreEqual (obj, ownerObj.GetSrcObject ());
  287. } else {
  288. // FbxScene has more than one object set as source
  289. Assert.AreNotEqual (obj, ownerObj.GetSrcObject ());
  290. }
  291. Assert.AreEqual (obj, ownerObj.GetSrcObject (origCount));
  292. Assert.AreEqual (obj, ownerObj.FindSrcObject ("obj"));
  293. Assert.IsNull (ownerObj.FindSrcObject ("obj", origCount + 1));
  294. // TODO: Fix so this doesn't crash
  295. /*Assert.That (() => {
  296. ownerObj.FindSrcObject (null);
  297. }, Throws.Exception.TypeOf<System.ArgumentNullException> ());*/
  298. result = ownerObj.DisconnectSrcObject (obj);
  299. Assert.IsTrue (result);
  300. Assert.IsFalse (ownerObj.IsConnectedSrcObject (obj));
  301. Assert.That (() => {
  302. ownerObj.ConnectSrcObject (null);
  303. }, Throws.Exception.TypeOf<System.ArgumentNullException> ());
  304. result = ownerObj.ConnectSrcObject (obj, FbxConnection.EType.eData);
  305. Assert.IsTrue (result);
  306. }
  307. }
  308. // need to order them this way for FbxScene, which deletes ownerObj if Destination Object is destroyed
  309. using (obj = CreateObject ("obj")) {
  310. using (var ownerObj = CreateObject ("ownerObj")) {
  311. // Test ConnectDstObject functions
  312. int origCount = ownerObj.GetDstObjectCount ();
  313. bool result = ownerObj.ConnectDstObject (obj);
  314. Assert.IsTrue (result);
  315. Assert.IsTrue (ownerObj.IsConnectedDstObject (obj));
  316. Assert.AreEqual (origCount + 1, ownerObj.GetDstObjectCount ());
  317. if (origCount == 0) {
  318. Assert.AreEqual (obj, ownerObj.GetDstObject ());
  319. } else {
  320. // FbxAnimCurve has the scene as a DstObject
  321. Assert.AreNotEqual (obj, ownerObj.GetDstObject ());
  322. }
  323. Assert.AreEqual (obj, ownerObj.GetDstObject (origCount));
  324. Assert.AreEqual (obj, ownerObj.FindDstObject ("obj"));
  325. Assert.IsNull (ownerObj.FindDstObject ("obj", origCount+1));
  326. // TODO: Fix so this doesn't crash
  327. /*Assert.That (() => {
  328. ownerObj.FindDstObject (null);
  329. }, Throws.Exception.TypeOf<System.ArgumentNullException> ());*/
  330. result = ownerObj.DisconnectDstObject (obj);
  331. Assert.IsTrue (result);
  332. Assert.IsFalse (ownerObj.IsConnectedDstObject (obj));
  333. Assert.That (() => {
  334. ownerObj.ConnectDstObject (null);
  335. }, Throws.Exception.TypeOf<System.ArgumentNullException> ());
  336. result = ownerObj.ConnectDstObject (obj, FbxConnection.EType.eData);
  337. Assert.IsTrue (result);
  338. }
  339. }
  340. }
  341. }
  342. }