123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- // ***********************************************************************
- // Copyright (c) 2017 Unity Technologies. All rights reserved.
- //
- // Licensed under the ##LICENSENAME##.
- // See LICENSE.md file in the project root for full license information.
- // ***********************************************************************
- using NUnit.Framework;
- using System.Collections.Generic;
- namespace Autodesk.Fbx.UnitTests
- {
- public static class EqualityTester<T>
- {
- // T.Equals(T), T.Equals(base(T), ...
- static List<System.Reflection.MethodInfo> s_Equals = new List<System.Reflection.MethodInfo>();
- // operator== (T, T), operator== (base(T), base(T), ...
- static List<System.Reflection.MethodInfo> s_op_Equality = new List<System.Reflection.MethodInfo>();
- // operator!= (T, T), operator== (base(T), base(T), ...
- static List<System.Reflection.MethodInfo> s_op_Inequality = new List<System.Reflection.MethodInfo>();
- static EqualityTester() {
- // For T and its base classes B1, B2, ...
- // get the following functions so we can test equality:
- // bool Equals(U)
- // static bool operator == (U, U)
- // static bool operator != (U, U)
- var U = typeof(T);
- do {
- // Get all the methods, look for Equals(U), op_Equality(U,U), and op_Inequality(U,U)
- var methods = U.GetMethods();
- foreach(var method in methods) {
- if (method.Name == "Equals") {
- var parms = method.GetParameters();
- if (parms.Length == 1 && parms[0].ParameterType == U) {
- s_Equals.Add(method);
- }
- } else if (method.Name == "op_Equality") {
- var parms = method.GetParameters();
- if (parms.Length == 2 && parms[0].ParameterType == U && parms[1].ParameterType == U) {
- s_op_Equality.Add(method);
- }
- } else if (method.Name == "op_Inequality") {
- var parms = method.GetParameters();
- if (parms.Length == 2 && parms[0].ParameterType == U && parms[1].ParameterType == U) {
- s_op_Inequality.Add(method);
- }
- }
- }
- // Repeat on the base type, if there is one.
- U = U.BaseType;
- } while (U != null);
- #if ENABLE_COVERAGE_TEST
- // Register the calls we make through reflection.
- var testEquality = typeof(EqualityTester<T>).GetMethod("TestEquality");
- foreach(var equals in s_Equals) { CoverageTester.RegisterReflectionCall(testEquality, equals); }
- foreach(var equals in s_op_Equality) { CoverageTester.RegisterReflectionCall(testEquality, equals); }
- foreach(var equals in s_op_Inequality) { CoverageTester.RegisterReflectionCall(testEquality, equals); }
- #endif
- }
- /* Instances of this class definitely don't cast to T. */
- class WrongClass { };
- /*
- * Test all the equality and hashing functions on type T.
- *
- * 'a' is an arbitrary non-null instance of class T.
- *
- * 'b' should be a different non-null instance.
- *
- * 'acopy' should be equal, but not reference-equal, to 'a' (unless the
- * notion of equality for this type is reference equality)
- */
- public static void TestEquality(T a, T b, T acopy) {
- // Test Equals(object) on a.
- Assert.IsTrue(a.Equals((object) acopy));
- Assert.IsFalse(a.Equals((object) b));
- Assert.IsFalse(a.Equals((object) new WrongClass()));
- // Test all the Equals functions on a.
- // a.Equals(a) is true
- // a.Equals(b) is false
- // a.Equals(null) is false and doesn't throw an exception
- foreach(var equals in s_Equals) {
- Assert.IsTrue(Invoker.Invoke<bool>(equals, a, a));
- Assert.IsTrue(Invoker.Invoke<bool>(equals, a, acopy));
- Assert.IsFalse(Invoker.Invoke<bool>(equals, a, b));
- Assert.IsFalse(Invoker.Invoke<bool>(equals, a, null));
- }
- // test operator== in various cases including null handling
- foreach(var equals in s_op_Equality) {
- Assert.IsTrue(Invoker.InvokeStatic<bool>(equals, a, a));
- Assert.IsTrue(Invoker.InvokeStatic<bool>(equals, a, acopy));
- Assert.IsFalse(Invoker.InvokeStatic<bool>(equals, a, b));
- Assert.IsFalse(Invoker.InvokeStatic<bool>(equals, a, null));
- Assert.IsFalse(Invoker.InvokeStatic<bool>(equals, null, b));
- Assert.IsTrue(Invoker.InvokeStatic<bool>(equals, null, null));
- }
- // test operator!= in the same cases; should always return ! the answer
- foreach(var equals in s_op_Inequality) {
- Assert.IsTrue(!Invoker.InvokeStatic<bool>(equals, a, a));
- Assert.IsTrue(!Invoker.InvokeStatic<bool>(equals, a, acopy));
- Assert.IsFalse(!Invoker.InvokeStatic<bool>(equals, a, b));
- Assert.IsFalse(!Invoker.InvokeStatic<bool>(equals, a, null));
- Assert.IsFalse(!Invoker.InvokeStatic<bool>(equals, null, b));
- Assert.IsTrue(!Invoker.InvokeStatic<bool>(equals, null, null));
- }
- // test hashing. This is very minimal: just testing that two
- // instances that test equal have equal hash code.
- Assert.AreEqual(a.GetHashCode(), acopy.GetHashCode());
- }
- }
- }
|